├── index.js ├── CHANGELOG.md ├── bin └── index.js ├── lib └── index.js ├── README.md ├── .nsprc ├── .travis.yml ├── .editorconfig ├── npm ├── test.js ├── build-docs.js ├── build-wiki.js ├── test-lint.js ├── test-unit.js ├── test-integration.js └── test-system.js ├── .jsdoc-config.json ├── test └── system │ ├── travis-yml.test.js │ ├── nsp.test.js │ ├── appveyor-yml.test.js │ └── repository.test.js ├── .gitignore ├── .npmignore ├── appveyor.yml ├── package.json ├── .eslintrc └── LICENSE.md /index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ical-json 2 | -------------------------------------------------------------------------------- /.nsprc: -------------------------------------------------------------------------------- 1 | { 2 | "exceptions": [], 3 | "exclusions": ["postman-collection", "postman-runtime"] 4 | } 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '4' 4 | - '5' 5 | - '6' 6 | notifications: 7 | slack: 8 | secure: Fdl/sQMTl86jYN1r1CRRRQRgyFoslvrhkkfnM2JSdx4gODPgyg4nCPSKtU5j9wpSbbkq9A+YBeFv+Suh+xYNviegqa0AZbztydfFzVDS7xw43B/uR9Y4LwaP5Kis1WGuIOHawwFISNO3hTUei6aybKiKKlxvfqrARJaO01+Xxrg= 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | max_length = 120 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [*.{json, yml, html, hbs}] 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /npm/test.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('shelljs/global'); 3 | require('colors'); 4 | 5 | var prettyms = require('pretty-ms'), 6 | startedAt = Date.now(); 7 | 8 | require('async').series([ 9 | require('./test-lint'), 10 | require('./test-system') 11 | // require('./test-unit'), 12 | // require('./test-integration'), 13 | // require('./test-cli') 14 | ], function (code) { 15 | console.info(`\nnewman: duration ${prettyms(Date.now() - startedAt)}\nnewman: ${code ? 'not ok' : 'ok'}!`[code ? 16 | 'red' : 'green']); 17 | exit(code && (typeof code === 'number' ? code : 1) || 0); 18 | }); 19 | -------------------------------------------------------------------------------- /npm/build-docs.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // --------------------------------------------------------------------------------------------------------------------- 3 | // This script is intended to generate documentation for this module 4 | // --------------------------------------------------------------------------------------------------------------------- 5 | 6 | require('shelljs/global'); 7 | require('colors'); 8 | 9 | // stop on encountering the first error 10 | set('-e'); 11 | echo('-e', 'Generating documentation...'); 12 | 13 | test('-d', './out/docs') && rm('-rf', './out/docs'); 14 | 15 | exec('jsdoc -c .jsdoc-config.json -u lib/*;'); 16 | echo(' - documentation can be found at ./out/docs'); 17 | -------------------------------------------------------------------------------- /.jsdoc-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true, 4 | "dictionaries": ["jsdoc", "closure"] 5 | }, 6 | "source": { 7 | "include": [ ], 8 | "includePattern": ".+\\.js(doc)?$", 9 | "excludePattern": "(^|\\/|\\\\)_" 10 | }, 11 | 12 | "plugins": [ 13 | "plugins/markdown" 14 | ], 15 | 16 | "templates": { 17 | "cleverLinks": false, 18 | "monospaceLinks": false, 19 | "highlightTutorialCode" : true 20 | }, 21 | 22 | "opts": { 23 | "template": "./node_modules/postman-jsdoc-theme", 24 | "encoding": "utf8", 25 | "destination": "./out/docs", 26 | "recurse": true, 27 | "readme": "README.md" 28 | }, 29 | 30 | "markdown": { 31 | "parser": "gfm", 32 | "hardwrap": false 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /npm/build-wiki.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // --------------------------------------------------------------------------------------------------------------------- 3 | // This script is intended to generate a wiki for this module 4 | // --------------------------------------------------------------------------------------------------------------------- 5 | 6 | require('shelljs/global'); 7 | require('colors'); 8 | 9 | // stop on encountering the first error 10 | set('-e'); 11 | echo('-e', 'Generating wiki...'); 12 | echo('-e', 'jsdoc2md'); 13 | 14 | // some variables 15 | var OUT_DIR = 'out/wiki', 16 | OUT_FILE = 'REFERENCE.md', 17 | OUT_PATH = `${OUT_DIR}/${OUT_FILE}`; 18 | 19 | // clean directory 20 | test('-d', OUT_DIR) && rm('-rf', OUT_DIR); 21 | mkdir('-p', OUT_DIR); 22 | 23 | // execute command 24 | exec(`jsdoc2md --src lib/**/*.js > ${OUT_PATH};`); 25 | echo(` - wiki generated at ${OUT_PATH}\n`); 26 | -------------------------------------------------------------------------------- /test/system/travis-yml.test.js: -------------------------------------------------------------------------------- 1 | /* global describe, it */ 2 | var expect = require('expect.js'); 3 | 4 | describe('travis.yml', function () { 5 | var fs = require('fs'), 6 | yaml = require('js-yaml'), 7 | travisYAML, 8 | travisYAMLError; 9 | 10 | try { 11 | travisYAML = yaml.safeLoad(fs.readFileSync('.travis.yml').toString()); 12 | } 13 | catch (e) { 14 | travisYAMLError = e; 15 | } 16 | 17 | it('must exist', function (done) { 18 | fs.stat('.travis.yml', done); 19 | }); 20 | 21 | it('must be a valid yml', function () { 22 | expect(travisYAMLError && travisYAMLError.message || travisYAMLError).to.not.be.ok(); 23 | }); 24 | 25 | describe('strucure', function () { 26 | it('language must be set to node', function () { 27 | expect(travisYAML.language).to.be('node_js'); 28 | expect(travisYAML.node_js).to.eql(['4', '5', '6']); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # PLATFORM 2 | # ======== 3 | # All exclusions that are specific to the NPM, GIT, IDE and Operating Systems. 4 | 5 | # - Do not allow installed node modules to be committed. Doing `npm install -d` will bring them in root or other places. 6 | node_modules 7 | 8 | # - Do not commit any log file from anywhere 9 | *.log 10 | *.log.* 11 | 12 | # - Prevent addition of OS specific file explorer files 13 | Thumbs.db 14 | .DS_Store 15 | 16 | # Prevent IDE stuff 17 | .idea 18 | 19 | 20 | # PROJECT 21 | # ======= 22 | # Configuration pertaining to project specific repository structure. 23 | 24 | # - Prevent Sublime text IDE files from being commited to repository 25 | *.sublime-* 26 | 27 | # - Allow sublime text project file to be commited in the development directory. 28 | !/develop/*.sublime-project 29 | 30 | # - Prevent CI output files from being Added 31 | /out/ 32 | 33 | # - Prevent diff backups from SourceTree from showing as commit. 34 | *.BACKUP.* 35 | *.BASE.* 36 | *.LOCAL.* 37 | *.REMOTE.* 38 | *.orig 39 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # PLATFORM 2 | # ======== 3 | # All exclusions that are specific to the NPM, GIT, IDE and Operating Systems. 4 | 5 | # - Do not allow installed node modules to be committed. Doing `npm install -d` will bring them in root or other places. 6 | node_modules 7 | 8 | # - Do not commit any log file from anywhere 9 | *.log 10 | *.log.* 11 | 12 | # - Prevent addition of OS specific file explorer files 13 | Thumbs.db 14 | .DS_Store 15 | 16 | # Prevent IDE stuff 17 | .idea 18 | 19 | 20 | # PROJECT 21 | # ======= 22 | # Configuration pertaining to project specific repository structure. 23 | 24 | # - Prevent Sublime text IDE files from being commited to repository 25 | *.sublime-* 26 | 27 | # - Allow sublime text project file to be commited in the development directory. 28 | !/develop/*.sublime-project 29 | 30 | # - Prevent CI output files from being Added 31 | /out/ 32 | 33 | # - Prevent diff backups from SourceTree from showing as commit. 34 | *.BACKUP.* 35 | *.BASE.* 36 | *.LOCAL.* 37 | *.REMOTE.* 38 | *.orig 39 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | #---------------------------------# 2 | # environment configuration # 3 | #---------------------------------# 4 | 5 | # scripts that are called at very beginning, before repo cloning 6 | init: 7 | - git config --global core.autocrlf input 8 | 9 | # environment variables 10 | environment: 11 | matrix: 12 | - nodejs_version: "4" 13 | - nodejs_version: "5" 14 | - nodejs_version: "6" 15 | 16 | # scripts that run after cloning repository 17 | install: 18 | - ps: Install-Product node $env:nodejs_version 19 | - npm install 20 | 21 | build: off # Disable MSBuilds, not related to the regular build process 22 | 23 | # to run your custom scripts instead of automatic tests 24 | test_script: 25 | - node --version && npm --version 26 | - cmd: "npm test" 27 | 28 | # to disable deployment 29 | deploy: off 30 | 31 | #---------------------------------# 32 | # notifications # 33 | #---------------------------------# 34 | 35 | notifications: 36 | - provider: Slack 37 | incoming_webhook: 38 | secure: PRDZ1nhG/cQrwMgCLXsWvTDJtYxv78GJrSlVYpMzpUploVWDzBlpMqmFr9WxZQkY/lxsqCSpGX4zgTYzlte1WMWnghqTIFE8u7svlXHa/tk= 39 | -------------------------------------------------------------------------------- /npm/test-lint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('shelljs/global'); 3 | require('colors'); 4 | 5 | var async = require('async'), 6 | ESLintCLIEngine = require('eslint').CLIEngine, 7 | 8 | LINT_SOURCE_DIRS = [ 9 | './lib', 10 | './bin', 11 | './test', 12 | './npm/*.js', 13 | './index.js' 14 | ]; 15 | 16 | module.exports = function (exit) { 17 | // banner line 18 | console.info('\nLinting files using eslint...'.yellow.bold); 19 | 20 | async.waterfall([ 21 | // execute the CLI engine 22 | function (next) { 23 | next(null, (new ESLintCLIEngine()).executeOnFiles(LINT_SOURCE_DIRS)); 24 | }, 25 | 26 | // output results 27 | function (report, next) { 28 | var errorReport = ESLintCLIEngine.getErrorResults(report.results); 29 | // log the result to CLI 30 | console.info(ESLintCLIEngine.getFormatter()(report.results)); 31 | // log the success of the parser if it has no errors 32 | (errorReport && !errorReport.length) && console.info('eslint ok!'.green); 33 | // ensure that the exit code is non zero in case there was an error 34 | next(Number(errorReport && errorReport.length) || 0); 35 | } 36 | ], exit); 37 | }; 38 | 39 | // ensure we run this script exports if this is a direct stdin.tty run 40 | !module.parent && module.exports(exit); 41 | -------------------------------------------------------------------------------- /npm/test-unit.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------------------------------------------- 2 | // This script is intended to execute all unit tests. 3 | // --------------------------------------------------------------------------------------------------------------------- 4 | 5 | require('shelljs/global'); 6 | require('colors'); 7 | 8 | // set directories and files for test and coverage report 9 | var path = require('path'), 10 | 11 | Mocha = require('mocha'), 12 | recursive = require('recursive-readdir'), 13 | 14 | SPEC_SOURCE_DIR = path.join(__dirname, '..', 'test', 'unit'); 15 | 16 | module.exports = function (exit) { 17 | // banner line 18 | console.info('Running unit tests using mocha on node...'.yellow.bold); 19 | 20 | // add all spec files to mocha 21 | recursive(SPEC_SOURCE_DIR, function (err, files) { 22 | if (err) { console.error(err); return exit(1); } 23 | 24 | var mocha = new Mocha({ timeout: 1000 * 60 }); 25 | 26 | files.filter(function (file) { // extract all test files 27 | return (file.substr(-8) === '.test.js'); 28 | }).forEach(mocha.addFile.bind(mocha)); 29 | 30 | mocha.run(function (err) { 31 | exit(err ? 1 : 0); 32 | }); 33 | }); 34 | }; 35 | 36 | // ensure we run this script exports if this is a direct stdin.tty run 37 | !module.parent && module.exports(exit); 38 | -------------------------------------------------------------------------------- /npm/test-integration.js: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------------------------------------------------- 2 | // This script is intended to execute all unit tests. 3 | // --------------------------------------------------------------------------------------------------------------------- 4 | 5 | require('shelljs/global'); 6 | require('colors'); 7 | 8 | // set directories and files for test and coverage report 9 | var path = require('path'), 10 | 11 | Mocha = require('mocha'), 12 | recursive = require('recursive-readdir'), 13 | 14 | SPEC_SOURCE_DIR = path.join(__dirname, '..', 'test', 'integration'); 15 | 16 | module.exports = function (exit) { 17 | // banner line 18 | console.info('Running integration tests using mocha on node...'.yellow.bold); 19 | 20 | // add all spec files to mocha 21 | recursive(SPEC_SOURCE_DIR, function (err, files) { 22 | if (err) { console.error(err); return exit(1); } 23 | 24 | var mocha = new Mocha({ timeout: 1000 * 60 }); 25 | 26 | files.filter(function (file) { // extract all test files 27 | return (file.substr(-8) === '.test.js'); 28 | }).forEach(mocha.addFile.bind(mocha)); 29 | 30 | mocha.run(function (err) { 31 | exit(err ? 1 : 0); 32 | }); 33 | }); 34 | }; 35 | 36 | // ensure we run this script exports if this is a direct stdin.tty run 37 | !module.parent && module.exports(exit); 38 | -------------------------------------------------------------------------------- /test/system/nsp.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileOverview Ensures nsprc is as expected 3 | */ 4 | 5 | var expect = require('expect.js'), 6 | fs = require('fs'); 7 | 8 | /* global describe, it, before */ 9 | describe('nsp', function () { 10 | var nsprc, 11 | pkg; 12 | 13 | before(function () { 14 | nsprc = JSON.parse(fs.readFileSync('./.nsprc').toString()); 15 | pkg = JSON.parse(fs.readFileSync('./package.json').toString()); 16 | }); 17 | 18 | it('must be a dev dependency', function () { 19 | expect(pkg.devDependencies && pkg.devDependencies.nsp).to.be.ok(); 20 | }); 21 | 22 | describe('nsprc', function () { 23 | it('must exist', function () { 24 | expect(nsprc).to.be.ok(); 25 | }); 26 | 27 | it('must not have any exclusion', function () { 28 | expect(nsprc.exceptions).to.eql([]); 29 | }); 30 | 31 | it('must exclude only a known set of packages', function () { 32 | expect(nsprc.exclusions).to.eql(['postman-collection', 'postman-runtime']); 33 | }); 34 | 35 | // if you are changing the version here, most probably you are better of removing the exclusion in first place. 36 | // remove the exclusion and check if nsp passes, else update the version here 37 | it('on excluded package\'s version change must reconsider removing exclusion', function () { 38 | // expect(pkg.dependencies).to.have.property('', ''); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /test/system/appveyor-yml.test.js: -------------------------------------------------------------------------------- 1 | /* global describe, it */ 2 | var expect = require('expect.js'); 3 | 4 | describe('appveyor.yml', function () { 5 | var fs = require('fs'), 6 | yaml = require('js-yaml'), 7 | 8 | appveyorYAML, 9 | appveyorYAMLError; 10 | 11 | try { 12 | appveyorYAML = yaml.safeLoad(fs.readFileSync('appveyor.yml').toString()); 13 | } 14 | catch (e) { 15 | appveyorYAMLError = e; 16 | } 17 | 18 | it('must exist', function (done) { 19 | fs.stat('appveyor.yml', done); 20 | }); 21 | 22 | it('must be a valid yml', function () { 23 | expect(appveyorYAMLError && appveyorYAMLError.message || appveyorYAMLError).to.not.be.ok(); 24 | }); 25 | 26 | describe('strucure', function () { 27 | it('init script must exist', function () { 28 | expect(appveyorYAML.init[0]).to.be('git config --global core.autocrlf input'); 29 | }); 30 | 31 | it('environment matrix must match that of Travis', function () { 32 | var travisYAML, 33 | travisYAMLError, 34 | appveyorNodeVersions = appveyorYAML.environment.matrix.map(function (member) { 35 | return member.nodejs_version; 36 | }); 37 | 38 | try { 39 | travisYAML = yaml.safeLoad(fs.readFileSync('.travis.yml').toString()); 40 | } 41 | catch (e) { 42 | travisYAMLError = e; 43 | } 44 | 45 | !travisYAMLError && expect(travisYAML.node_js).to.eql(appveyorNodeVersions); 46 | }); 47 | 48 | it('MS build script and deploy must be turned off', function () { 49 | expect(appveyorYAML.build).to.be('off'); 50 | expect(appveyorYAML.deploy).to.be('off'); 51 | }); 52 | 53 | it('notifications must be configured correctly', function () { 54 | expect(appveyorYAML.notifications).to.be.an(Array); 55 | expect(appveyorYAML.notifications[0].provider).to.be('Slack'); 56 | expect(appveyorYAML.notifications[0].incoming_webhook.secure).to.be.ok(); 57 | }); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ical-json", 3 | "version": "0.0.0", 4 | "description": "JSON representation of calendar entries (with cron compatibility)", 5 | "homepage": "https://github.com/postmanlabs/ical-json", 6 | "bugs": "https://github.com/postmanlabs/ical-json/issues", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/postmanlabs/ical-json.git" 10 | }, 11 | "keywords": [ 12 | "ical-json", 13 | "postman", 14 | "ical", 15 | "json", 16 | "calendar", 17 | "cron" 18 | ], 19 | "main": "index.js", 20 | "bin": { 21 | "ical-json": "./bin/index.js" 22 | }, 23 | "preferGlobal": false, 24 | "scripts": { 25 | "test": "node npm/test.js", 26 | "test-system": "node npm/test-system.js", 27 | "test-lint": "node npm/test-lint.js", 28 | "test-unit": "node npm/test-unit.js", 29 | "test-integration": "node npm/test-integration.js", 30 | "build-docs": "node npm/build-docs.js", 31 | "build-wiki": "node npm/build-wiki.js" 32 | }, 33 | "author": "Postman Labs (=)", 34 | "license": "Apache-2.0", 35 | "dependencies": { 36 | "argparse": "1.0.7", 37 | "async": "2.0.1", 38 | "cli-progress": "1.2.0", 39 | "cli-table2": "0.2.0", 40 | "colors": "1.1.2", 41 | "csv-parse": "1.1.7", 42 | "eventemitter3": "2.0.0", 43 | "filesize": "3.3.0", 44 | "handlebars": "4.0.5", 45 | "lodash": "4.15.0", 46 | "mkdirp": "0.5.1", 47 | "parse-json": "2.2.0", 48 | "postman-collection": "0.4.14", 49 | "postman-collection-transformer": "1.7.4", 50 | "postman-request": "2.74.1-postman.1", 51 | "postman-runtime": "2.5.0", 52 | "pretty-ms": "2.1.0", 53 | "semver": "5.3.0", 54 | "serialised-error": "1.1.2", 55 | "shelljs": "0.7.4", 56 | "word-wrap": "1.1.0", 57 | "xmlbuilder": "8.2.2" 58 | }, 59 | "devDependencies": { 60 | "eslint": "3.6.0", 61 | "eslint-plugin-jsdoc": "2.3.1", 62 | "eslint-plugin-lodash": "1.10.3", 63 | "eslint-plugin-mocha": "4.5.1", 64 | "eslint-plugin-security": "1.2.0", 65 | "expect.js": "0.3.1", 66 | "js-yaml": "3.6.1", 67 | "jsdoc": "3.4.1", 68 | "jsdoc-to-markdown": "1.3.7", 69 | "mocha": "3.0.2", 70 | "nsp": "2.6.1", 71 | "packity": "0.3.2", 72 | "postman-jsdoc-theme": "0.0.2", 73 | "recursive-readdir": "2.0.0" 74 | }, 75 | "engines": { 76 | "node": ">=4" 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /npm/test-system.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('shelljs/global'); 3 | require('colors'); 4 | 5 | var async = require('async'), 6 | _ = require('lodash'), 7 | path = require('path'), 8 | packity = require('packity'), 9 | Mocha = require('mocha'), 10 | recursive = require('recursive-readdir'), 11 | 12 | SPEC_SOURCE_DIR = './test/system', 13 | 14 | /** 15 | * Load a JSON from file synchronously 16 | * 17 | * @param {String} file 18 | * @returns {String} 19 | */ 20 | loadJSON = function (file) { 21 | return JSON.parse(require('fs').readFileSync(path.join(__dirname, file)).toString()); 22 | }; 23 | 24 | module.exports = function (exit) { 25 | // banner line 26 | console.info('\nRunning system tests...\n'.yellow.bold); 27 | 28 | async.series([ 29 | // packity to ensure all modules are as per package.json 30 | function (next) { 31 | console.info('checking installed packages...\n'); 32 | packity({ path: '.' }, packity.cliReporter({}, next)); 33 | }, 34 | 35 | // run test specs using mocha 36 | function (next) { 37 | console.info('\nrunning system specs using mocha...'); 38 | 39 | var mocha = new Mocha(); 40 | 41 | recursive(SPEC_SOURCE_DIR, function (err, files) { 42 | files.filter(function (file) { 43 | return (file.substr(-8) === '.test.js'); 44 | }).forEach(function (file) { 45 | mocha.addFile(file); 46 | }); 47 | 48 | // start the mocha run 49 | mocha.run(next); 50 | mocha = null; // cleanup 51 | }); 52 | }, 53 | 54 | // execute nsp 55 | // In-program usage of nsp is a bit tricky as we have to emulate the cli script's usage of internal 56 | // nsp functions. 57 | function (next) { 58 | var nsp = require('nsp'), 59 | pkg = loadJSON('../package.json'), 60 | nsprc = loadJSON('../.nsprc'); 61 | 62 | console.info('processing nsp for security vulnerabilities...\n'); 63 | 64 | // we do not pass full package for privacy concerns and also to add the ability to ignore exclude packages, 65 | // hence we customise the package before we send it 66 | nsp.check({ 67 | offline: false, 68 | package: _.merge({ 69 | dependencies: _.omit(pkg.dependencies, nsprc.exclusions || []) 70 | }, _.pick(pkg, ['name', 'version', 'homepage', 'repository'])) 71 | }, function (err, result) { 72 | // if processing nsp had an error, simply print that and exit 73 | if (err) { 74 | console.error('There was an error processing NSP!\n'.red + (err.message || err).gray + '\n\n' + 75 | 'Since NSP server failure is not a blocker for tests, tests are not marked as failure!'); 76 | return next(); 77 | } 78 | 79 | // in case an nsp violation is found, we raise an error 80 | if (result.length) { 81 | console.error(nsp.formatters.default(err, result)); 82 | return next(1); 83 | } 84 | 85 | console.info('nsp ok!\n'.green); 86 | return next(); 87 | }); 88 | } 89 | ], exit); 90 | }; 91 | 92 | // ensure we run this script exports if this is a direct stdin.tty run 93 | !module.parent && module.exports(exit); 94 | -------------------------------------------------------------------------------- /test/system/repository.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileOverview This test specs runs tests on the package.json file of repository. It has a set of strict tests on the 3 | * content of the file as well. Any change to package.json must be accompanied by valid test case in this spec-sheet. 4 | */ 5 | var expect = require('expect.js'); 6 | 7 | /* global describe, it */ 8 | describe('project repository', function () { 9 | var fs = require('fs'); 10 | 11 | describe('package.json', function () { 12 | var content, 13 | json; 14 | 15 | try { 16 | content = fs.readFileSync('./package.json').toString(); 17 | json = JSON.parse(content); 18 | } 19 | catch (e) { 20 | console.error(e); 21 | content = ''; 22 | json = {}; 23 | } 24 | 25 | it('must have readable JSON content', function () { 26 | expect(content).to.be.ok(); 27 | expect(json).to.not.eql({}); 28 | }); 29 | 30 | describe('package.json JSON data', function () { 31 | it('must have valid name, description and author', function () { 32 | expect(json).to.have.property('name', 'ical-json'); 33 | expect(json).to.have.property('description'); 34 | expect(json.description).to.eql('JSON representation of calendar entries (with cron compatibility)'); 35 | expect(json).to.have.property('author', 'Postman Labs (=)'); 36 | expect(json).to.have.property('license', 'Apache-2.0'); 37 | expect(json).to.have.property('homepage', 'https://github.com/postmanlabs/ical-json'); 38 | expect(json).to.have.property('bugs', 'https://github.com/postmanlabs/ical-json/issues'); 39 | 40 | expect(json).to.have.property('repository'); 41 | expect(json.repository).to.eql({ 42 | type: 'git', 43 | url: 'git://github.com/postmanlabs/ical-json.git' 44 | }); 45 | 46 | expect(json).to.have.property('keywords'); 47 | expect(json.keywords).to.eql(['ical-json', 'postman', 'ical', 'json', 'calendar', 'cron']); 48 | 49 | expect(json).to.have.property('engines'); 50 | expect(json.engines).to.eql({ node: '>=4' }); 51 | 52 | expect(json).to.have.property('preferGlobal', false); 53 | }); 54 | 55 | it('must have a valid version string in form of ..', function () { 56 | // eslint-disable-next-line max-len 57 | expect(json.version).to.match(/^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/); 58 | }); 59 | }); 60 | 61 | describe('binary definitions', function () { 62 | it('must exits', function () { 63 | expect(json.bin).be.ok(); 64 | expect(json.bin).to.eql({ 'ical-json': './bin/index.js' }); 65 | }); 66 | }); 67 | 68 | describe('script definitions', function () { 69 | it('files must exist', function () { 70 | var scriptPathRegex = /^node\snpm\/.*\.js$/; 71 | expect(json.scripts).to.be.ok(); 72 | json.scripts && Object.keys(json.scripts).forEach(function (scriptName) { 73 | expect(fs.existsSync('npm/' + scriptName + '.js')).to.be.ok(); 74 | expect(scriptPathRegex.test(json.scripts[scriptName])).to.be.ok(); 75 | }); 76 | }); 77 | }); 78 | 79 | describe('dependencies', function () { 80 | it('must exist', function () { 81 | expect(json.dependencies).to.be.a('object'); 82 | }); 83 | 84 | it('must point to a valid and precise (no * or ^) semver', function () { 85 | json.dependencies && Object.keys(json.dependencies).forEach(function (item) { 86 | expect(json.dependencies[item]).to.match(new RegExp('^((\\d+)\\.(\\d+)\\.(\\d+))(?:-' + 87 | '([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?(?:\\+([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?$')); 88 | }); 89 | }); 90 | }); 91 | 92 | describe('devDependencies', function () { 93 | it('must exist', function () { 94 | expect(json.devDependencies).to.be.a('object'); 95 | }); 96 | 97 | it('must point to a valid and precise (no * or ^) semver', function () { 98 | json.devDependencies && Object.keys(json.devDependencies).forEach(function (item) { 99 | expect(json.devDependencies[item]).to.match(new RegExp('^((\\d+)\\.(\\d+)\\.(\\d+))(?:-' + 100 | '([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?(?:\\+([\\dA-Za-z\\-]+(?:\\.[\\dA-Za-z\\-]+)*))?$')); 101 | }); 102 | }); 103 | 104 | it('should not overlap devDependencies', function () { 105 | var clean = []; 106 | 107 | json.devDependencies && Object.keys(json.devDependencies).forEach(function (item) { 108 | !json.dependencies[item] && clean.push(item); 109 | }); 110 | 111 | expect(Object.keys(json.devDependencies)).to.eql(clean); 112 | }); 113 | }); 114 | 115 | describe('main entry script', function () { 116 | it('must point to a valid file', function (done) { 117 | expect(json.main).to.equal('index.js'); 118 | fs.stat(json.main, done); 119 | }); 120 | }); 121 | }); 122 | 123 | describe('README.md', function () { 124 | it('must exist', function (done) { 125 | fs.stat('./README.md', done); 126 | }); 127 | 128 | it('must have readable content', function () { 129 | expect(fs.readFileSync('./README.md').toString()).to.be.ok(); 130 | }); 131 | }); 132 | 133 | describe('LICENSE.md', function () { 134 | it('must exist', function (done) { 135 | fs.stat('./LICENSE.md', done); 136 | }); 137 | 138 | it('must have readable content', function () { 139 | expect(fs.readFileSync('./LICENSE.md').toString()).to.be.ok(); 140 | }); 141 | }); 142 | 143 | describe('.gitignore file', function () { 144 | it('must exist', function (done) { 145 | fs.stat('./.gitignore', done); 146 | }); 147 | 148 | it('must have readable content', function () { 149 | expect(fs.readFileSync('./.gitignore').toString()).to.be.ok(); 150 | }); 151 | }); 152 | 153 | describe('.npmignore file', function () { 154 | it('must exist', function (done) { 155 | fs.stat('./.npmignore', done); 156 | }); 157 | 158 | it('must have readable content', function () { 159 | expect(fs.readFileSync('./.npmignore').toString()).to.be.ok(); 160 | }); 161 | 162 | it('must match .gitignore', function () { 163 | expect(fs.readFileSync('./.npmignore').toString()).to.be(fs.readFileSync('./.gitignore').toString()); 164 | }); 165 | }); 166 | 167 | describe('.eslintrc', function () { 168 | it('must exist', function (done) { 169 | fs.stat('./.eslintrc', done); 170 | }); 171 | 172 | it('must have readable content', function () { 173 | expect(fs.readFileSync('./.eslintrc').toString()).to.be.ok(); 174 | }); 175 | }); 176 | 177 | describe('.nsprc', function () { 178 | it('must exist', function (done) { 179 | fs.stat('./.nsprc', done); 180 | }); 181 | 182 | it('must have readable content', function () { 183 | expect(fs.readFileSync('./.nsprc').toString()).to.be.ok(); 184 | }); 185 | }); 186 | }); 187 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "jsdoc", 4 | "security", 5 | "lodash", 6 | "mocha" 7 | ], 8 | "env": { 9 | "browser": true, 10 | "node": true, 11 | "es6": true 12 | }, 13 | "rules": { 14 | // Possible Errors 15 | "comma-dangle": ["error", "never"], 16 | "no-cond-assign": "error", 17 | "no-console": ["error", { "allow": ["info", "warn", "error"] }], 18 | "no-constant-condition": "error", 19 | "no-control-regex": "error", 20 | "no-debugger": "error", 21 | "no-dupe-args": "error", 22 | "no-dupe-keys": "error", 23 | "no-duplicate-case": "error", 24 | "no-empty": "error", 25 | "no-empty-character-class": "error", 26 | "no-ex-assign": "error", 27 | "no-extra-boolean-cast": "error", 28 | "no-extra-parens": "off", 29 | "no-extra-semi": "error", 30 | "no-func-assign": "error", 31 | "no-inner-declarations": "off", 32 | "no-invalid-regexp": "error", 33 | "no-irregular-whitespace": "error", 34 | "no-negated-in-lhs": "error", 35 | "no-obj-calls": "error", 36 | "no-regex-spaces": "error", 37 | "no-sparse-arrays": "error", 38 | "no-unexpected-multiline": "error", 39 | "no-unreachable": "error", 40 | "no-unsafe-finally": "error", 41 | "use-isnan": "error", 42 | "valid-jsdoc": "warn", 43 | "valid-typeof": "error", 44 | 45 | // Best Practices 46 | "accessor-pairs": "error", 47 | "array-callback-return": "error", 48 | "block-scoped-var": "error", 49 | "complexity": "off", 50 | "consistent-return": "warn", 51 | "curly": "error", 52 | "default-case": "error", 53 | "dot-location": ["error", "property"], 54 | "dot-notation": "error", 55 | "eqeqeq": "error", 56 | "guard-for-in": "warn", 57 | "no-alert": "error", 58 | "no-caller": "error", 59 | "no-case-declarations": "error", 60 | "no-div-regex": "error", 61 | "no-else-return": "error", 62 | "no-empty-function": "error", 63 | "no-empty-pattern": "error", 64 | "no-eq-null": "error", 65 | "no-eval": "error", 66 | "no-extend-native": "error", 67 | "no-extra-bind": "error", 68 | "no-extra-label": "error", 69 | "no-fallthrough": "error", 70 | "no-floating-decimal": "error", 71 | "no-implicit-coercion": "error", 72 | "no-implicit-globals": "error", 73 | "no-implied-eval": "error", 74 | "no-invalid-this": "error", 75 | "no-iterator": "error", 76 | "no-labels": "error", 77 | "no-lone-blocks": "error", 78 | "no-loop-func": "error", 79 | "no-magic-numbers": "off", 80 | "no-multi-spaces": "error", 81 | "no-multi-str": "error", 82 | "no-native-reassign": "error", 83 | "no-new": "error", 84 | "no-new-func": "error", 85 | "no-new-wrappers": "error", 86 | "no-octal": "error", 87 | "no-octal-escape": "error", 88 | // "_no-param-reassign": "error", 89 | "no-proto": "error", 90 | "no-redeclare": "error", 91 | "no-return-assign": "error", 92 | "no-script-url": "error", 93 | "no-self-assign": "error", 94 | "no-self-compare": "error", 95 | "no-sequences": "error", 96 | "no-throw-literal": "error", 97 | "no-unmodified-loop-condition": "error", 98 | "no-unused-expressions": "off", 99 | "no-unused-labels": "error", 100 | "no-useless-call": "error", 101 | "no-useless-concat": "error", 102 | "no-useless-escape": "error", 103 | "no-void": "error", 104 | "no-warning-comments": "off", 105 | "no-with": "error", 106 | "radix": "off", 107 | // "vars-on-top": "error", 108 | "wrap-iife": "error", 109 | "yoda": "error", 110 | 111 | // Strict Mode 112 | "strict": "off", 113 | 114 | // Variables 115 | "init-declarations": "off", 116 | "no-catch-shadow": "error", 117 | "no-delete-var": "error", 118 | "no-label-var": "error", 119 | "no-restricted-globals": "error", 120 | //"no-shadow": "error", 121 | "no-shadow-restricted-names": "error", 122 | "no-undef": "off", 123 | "no-undef-init": "error", 124 | "no-undefined": "off", 125 | "no-unused-vars": "error", 126 | "no-use-before-define": "error", 127 | 128 | // Stylistic Issues 129 | "array-bracket-spacing": "error", 130 | "block-spacing": "error", 131 | "brace-style": [2, "stroustrup", { "allowSingleLine": true }], 132 | "camelcase": "off", 133 | "comma-spacing": [2, { "before": false, "after": true }], 134 | "comma-style": ["error", "last"], 135 | "computed-property-spacing": "error", 136 | // "consistent-this": "warn", 137 | "eol-last": "error", 138 | "func-names": "off", 139 | "func-style": "off", 140 | "id-blacklist": "error", 141 | "id-length": "off", 142 | "id-match": "error", 143 | "indent": ["error", 4, { 144 | "VariableDeclarator": { "var": 1, "let": 1, "const": 1 }, 145 | "SwitchCase": 1, 146 | }], 147 | "jsx-quotes": ["error", "prefer-single"], 148 | "key-spacing": "error", 149 | "keyword-spacing": "error", 150 | "linebreak-style": ["error", "unix"], 151 | "lines-around-comment": ["error", { 152 | "beforeBlockComment": true, 153 | "afterBlockComment": false, 154 | "beforeLineComment": false, 155 | "afterLineComment": false, 156 | "allowBlockStart": true, 157 | "allowBlockEnd": false, 158 | "allowObjectStart": true, 159 | "allowObjectEnd": false, 160 | "allowArrayStart": true, 161 | "allowArrayEnd": false 162 | }], 163 | "max-depth": "error", 164 | "max-len": ["error", { 165 | "code": 120 166 | }], 167 | "max-nested-callbacks": "error", 168 | "max-params": "off", 169 | "max-statements": "off", 170 | "max-statements-per-line": "off", 171 | "new-cap": "off", 172 | "new-parens": "error", 173 | "newline-after-var": ["off", "always"], 174 | "newline-before-return": "off", 175 | "newline-per-chained-call": "off", 176 | "no-array-constructor": "error", 177 | // "no-bitwise": "error", 178 | // "no-continue": "error", 179 | "no-inline-comments": "off", 180 | "no-lonely-if": "error", 181 | "no-mixed-spaces-and-tabs": "error", 182 | "no-multiple-empty-lines": "error", 183 | "no-negated-condition": "off", 184 | "no-nested-ternary": "off", 185 | "no-new-object": "error", 186 | "no-plusplus": "off", 187 | "no-restricted-syntax": "error", 188 | "no-spaced-func": "error", 189 | "no-ternary": "off", 190 | "no-trailing-spaces": "error", 191 | "no-underscore-dangle": "off", 192 | "no-unneeded-ternary": "error", 193 | "no-whitespace-before-property": "error", 194 | "object-curly-spacing": ["error", "always"], 195 | "one-var": ["error", "always"], 196 | "one-var-declaration-per-line": "error", 197 | "operator-assignment": "error", 198 | "operator-linebreak": ["error", "after"], 199 | "padded-blocks": "off", 200 | "quote-props": "off", 201 | "quotes": ["error", "single"], 202 | "require-jsdoc": "warn", 203 | "semi": "error", 204 | "semi-spacing": "error", 205 | "sort-vars": "off", 206 | "space-before-blocks": "error", 207 | "space-in-parens": "error", 208 | "space-infix-ops": "error", 209 | "space-unary-ops": "error", 210 | "spaced-comment": ["error", "always", { 211 | "block": { 212 | "exceptions": ["!"] 213 | } 214 | }], 215 | "wrap-regex": "error", 216 | 217 | // ECMAScript 6 218 | "arrow-body-style": ["error", "always"], 219 | "arrow-parens": ["error", "always"], 220 | "arrow-spacing": "error", 221 | "constructor-super": "error", 222 | "generator-star-spacing": "error", 223 | "no-class-assign": "error", 224 | "no-confusing-arrow": "error", 225 | "no-const-assign": "error", 226 | "no-dupe-class-members": "error", 227 | "no-duplicate-imports": "error", 228 | "no-new-symbol": "error", 229 | "no-restricted-imports": "error", 230 | "no-this-before-super": "error", 231 | "no-useless-computed-key": "error", 232 | "no-useless-constructor": "off", 233 | "no-var": "off", 234 | "object-shorthand": "off", 235 | // "_prefer-arrow-callback": "error", 236 | "prefer-const": "off", 237 | "prefer-reflect": "off", 238 | // "prefer-rest-params": "error", 239 | "prefer-spread": "error", 240 | "prefer-template": "off", 241 | "require-yield": "error", 242 | "sort-imports": "off", 243 | "template-curly-spacing": "error", 244 | "yield-star-spacing": "error", 245 | 246 | // JSDoc 247 | "jsdoc/check-param-names": "off", 248 | "jsdoc/check-tag-names": "off", 249 | "jsdoc/check-types": "off", 250 | "jsdoc/newline-after-description": "off", 251 | "jsdoc/require-description-complete-sentence": "off", 252 | "jsdoc/require-hyphen-before-param-description": "off", 253 | "jsdoc/require-param": "off", 254 | "jsdoc/require-param-description": "off", 255 | "jsdoc/require-param-type": "off", 256 | "jsdoc/require-returns-description": "off", 257 | "jsdoc/require-returns-type": "off", 258 | 259 | // Lodash 260 | "lodash/callback-binding": 2, 261 | "lodash/chain-style": [2, "as-needed"], 262 | "lodash/collection-method-value": 1, 263 | "lodash/collection-return": 2, 264 | "lodash/consistent-compose": [2, "flow"], 265 | "lodash/identity-shorthand": [2, "always"], 266 | "lodash/matches-prop-shorthand": [2, "always"], 267 | "lodash/matches-shorthand": [2, "always", 3], 268 | "lodash/no-commit": 2, 269 | "lodash/no-double-unwrap": 2, 270 | "lodash/no-extra-args": 2, 271 | "lodash/no-single-chain": 2, 272 | "lodash/path-style": [2, "string"], 273 | "lodash/prefer-chain": [2, 3], 274 | "lodash/prefer-compact": 2, 275 | // "lodash/prefer-constant": 2, 276 | // "lodash/prefer-filter": [2, 3], 277 | "lodash/prefer-flat-map": 2, 278 | "lodash/prefer-get": [1, 4], 279 | // "lodash/prefer-includes": [2, { includeNative: true }], 280 | "lodash/prefer-invoke-map": 2, 281 | // "lodash/prefer-is-nil": 2, 282 | "lodash/prefer-lodash-chain": 2, 283 | // "lodash/prefer-lodash-method": 2, 284 | // "lodash/prefer-lodash-typecheck": 2, 285 | "lodash/prefer-map": 2, 286 | // "lodash/prefer-matches": [2, 3], 287 | // "lodash/prefer-noop": 2, 288 | // "lodash/prefer-over-quantifier": 1, 289 | "lodash/prefer-reject": [2, 3], 290 | // "lodash/prefer-startswith": 2, 291 | "lodash/prefer-thru": 2, 292 | // "lodash/prefer-times": 2, 293 | "lodash/prefer-wrapper-method": 2, 294 | "lodash/preferred-alias": 2, 295 | "lodash/prop-shorthand": [2, "always"], 296 | "lodash/unwrap": 2, 297 | 298 | // Mocha 299 | "mocha/no-exclusive-tests": 2, 300 | "mocha/no-skipped-tests": 1, 301 | "mocha/no-pending-tests": 2, 302 | "mocha/handle-done-callback": 2, 303 | "mocha/no-synchronous-tests": 0, 304 | "mocha/no-global-tests": 2, 305 | "mocha/no-return-and-callback": 2, 306 | "mocha/valid-test-description": 0, 307 | "mocha/valid-suite-description": 0, 308 | "mocha/no-sibling-hooks": 2, 309 | "mocha/no-mocha-arrows": 2, 310 | "mocha/no-hooks": 0, 311 | "mocha/no-hooks-for-single-case": 1, 312 | "mocha/no-top-level-hooks": 1, 313 | "mocha/no-identical-title": 2 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "{}" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2016 Postdot Technologies, Inc 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | --------------------------------------------------------------------------------