From 761f08694bbf238edff3c15629bf6980ff22bb71 Mon Sep 17 00:00:00 2001 From: Rosen Vladimirov Date: Tue, 18 Oct 2016 12:16:34 +0300 Subject: [PATCH 001/169] Initial commit --- .gitignore | 37 ++++++++++ LICENSE | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 3 files changed, 240 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..5148e527a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..38f352e027 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# nativescript-doctor +Library that helps identifying if the environment can be used for development of {N} apps. From f4fbf4c9f904de034c71c934ec3b2b10b5284b75 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 18 Oct 2016 12:28:17 +0300 Subject: [PATCH 002/169] Setup npm package --- lib/index.ts | 2 ++ package.json | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 lib/index.ts create mode 100644 package.json diff --git a/lib/index.ts b/lib/index.ts new file mode 100644 index 0000000000..196bd48948 --- /dev/null +++ b/lib/index.ts @@ -0,0 +1,2 @@ +// Entry point + diff --git a/package.json b/package.json new file mode 100644 index 0000000000..d56e1b3288 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "nativescript-doctor", + "version": "0.0.1", + "description": "Library that helps identifying if the environment can be used for development of {N} apps.", + "main": "lib/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/NativeScript/nativescript-doctor.git" + }, + "keywords": [ + "NativeScript", + "doctor", + "tns" + ], + "author": "Telerik ", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/NativeScript/nativescript-doctor/issues" + }, + "homepage": "https://github.com/NativeScript/nativescript-doctor#readme" +} From 569fd5c5dacf454db2fdefe473f005372d078f50 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 18 Oct 2016 13:10:03 +0300 Subject: [PATCH 003/169] Setup repo for TypeScript development with grunt --- .gitignore | 29 +++++++++++++++++++++++++++++ .npmignore | 30 ++++++++++++++++++++++++++++++ package.json | 13 ++++++++++++- tsconfig.json | 17 +++++++++++++++++ tslint.json | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 .npmignore create mode 100644 tsconfig.json create mode 100644 tslint.json diff --git a/.gitignore b/.gitignore index 5148e527a7..7622f82a24 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,32 @@ jspm_packages # Optional REPL history .node_repl_history + +npm-debug.log +node_modules +docs/html +tscommand*.tmp.txt +.tscache/ +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz +*.tgz +*.tmp +*.sublime-workspace + +pids +logs +results +scratch/ +.idea/ +.settings/ +.vscode/ +test-reports.xml + +*.js +*.js.map +/lib/.d.ts \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000000..5fa806c601 --- /dev/null +++ b/.npmignore @@ -0,0 +1,30 @@ +.idea +.gitattributes +.gitmodules +*.sublime-project +lint.* +.jshint* +.npmignore +*.tgz +test-reports.xml +for-developers.md +prepublish.js +Gruntfile.js +BuildPackage.cmd +tscommand.tmp.txt +.tscache/ + +bin/nativescript +bin/*.cmd + +lib/**/*.ts +lib/**/*.js.map + +test/ +.vscode +coverage/ +scratch/ +*.suo +.travis.yml +docs/html/ +dev/ \ No newline at end of file diff --git a/package.json b/package.json index d56e1b3288..883e766beb 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,16 @@ "bugs": { "url": "https://github.com/NativeScript/nativescript-doctor/issues" }, - "homepage": "https://github.com/NativeScript/nativescript-doctor#readme" + "homepage": "https://github.com/NativeScript/nativescript-doctor#readme", + "devDependencies": { + "grunt": "1.0.1", + "grunt-contrib-clean": "1.0.0", + "grunt-shell": "2.0.0", + "grunt-ts": "6.0.0-beta.3", + "grunt-tslint": "3.3.0", + "istanbul": "0.4.5", + "mocha": "3.1.2", + "tslint": "3.15.1", + "typescript": "2.0.3" + } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..b1a8406486 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "sourceMap": true, + "declaration": false, + "removeComments": false, + "noImplicitAny": true, + "experimentalDecorators": true + }, + "exclude": [ + "node_modules", + "lib/common/node_modules", + "scratch", + "coverage" + ] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000000..4f0f281bc8 --- /dev/null +++ b/tslint.json @@ -0,0 +1,49 @@ +{ + "rules": { + "class-name": true, + "curly": true, + "eofline": true, + "indent": true, + "interface-name": true, + "jsdoc-format": true, + "max-line-length": [false, 140], + "no-consecutive-blank-lines": true, + "no-construct": true, + "no-debugger": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-shadowed-variable": true, + "no-empty": true, + "no-eval": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unreachable": true, + "no-unused-expression": true, + "no-unused-variable": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "no-var-requires": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else" + ], + "quotemark": [false, "double"], + "semicolon": true, + "switch-default": false, + "triple-equals": [true, "allow-null-check"], + "use-strict": true, + "variable-name": [false, "allow-leading-underscore"], + "whitespace": [ + false, + "check-branch", + "check-decl", + "check-operator", + "check-module", + "check-separator", + "check-type", + "check-typecast" + ] + } +} \ No newline at end of file From ae806fe0906ddb6f1989d9e2b425959a91a4e54d Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 20 Oct 2016 18:11:22 +0300 Subject: [PATCH 004/169] Remove unnecessary directories from tsconfig.json --- tsconfig.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index b1a8406486..f161b72e79 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,8 +10,6 @@ }, "exclude": [ "node_modules", - "lib/common/node_modules", - "scratch", "coverage" ] } From f1edf66244ccaea746ab08d7e449ea3f96cb8842 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 20 Oct 2016 19:06:10 +0300 Subject: [PATCH 005/169] Edit .gitignore to include the .js files in root dir. --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7622f82a24..b67e3ae40d 100644 --- a/.gitignore +++ b/.gitignore @@ -63,4 +63,6 @@ test-reports.xml *.js *.js.map -/lib/.d.ts \ No newline at end of file +/lib/.d.ts + +!/*.js From 312182c25a9ac75532a46b36672152831ed36e70 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 20 Oct 2016 19:06:29 +0300 Subject: [PATCH 006/169] Add Gruntfile.js --- Gruntfile.js | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 2 files changed, 114 insertions(+) create mode 100644 Gruntfile.js diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000000..c728798ca4 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,112 @@ +module.exports = function (grunt) { + grunt.initConfig({ + ts: { + options: grunt.file.readJSON("tsconfig.json").compilerOptions, + + devlib: { + src: ["lib/**/*.ts"], + reference: "lib/.d.ts" + }, + + devall: { + src: ["lib/**/*.ts", "test/**/*.ts"], + reference: "lib/.d.ts" + }, + + release_build: { + src: ["lib/**/*.ts", "test/**/*.ts"], + reference: "lib/.d.ts", + options: { + sourceMap: false, + removeComments: true + } + } + }, + + tslint: { + build: { + files: { + src: ["lib/**/*.ts", "test/**/*.ts", "!**/*.d.ts"] + }, + options: { + configuration: grunt.file.readJSON("./tslint.json") + } + } + }, + + watch: { + devall: { + files: ["lib/**/*.ts", 'test/**/*.ts'], + tasks: [ + 'ts:devall', + 'shell:npm_test' + ], + options: { + atBegin: true, + interrupt: true + } + }, + ts: { + files: ["lib/**/*.ts", "test/**/*.ts"], + tasks: [ + 'ts:devall' + ], + options: { + atBegin: true, + interrupt: true + } + } + }, + + shell: { + options: { + stdout: true, + stderr: true, + failOnError: true + }, + build_package: { + command: "npm pack" + }, + npm_test: { + command: "npm test" + } + }, + + clean: { + src: ["test/**/*.js*", "lib/**/*.js*", "!lib/hooks/**/*.js", "!Gruntfile.js", "*.tgz"] + } + }); + + grunt.loadNpmTasks("grunt-contrib-clean"); + grunt.loadNpmTasks("grunt-contrib-watch"); + grunt.loadNpmTasks("grunt-shell"); + grunt.loadNpmTasks("grunt-ts"); + grunt.loadNpmTasks("grunt-tslint"); + + grunt.registerTask("delete_coverage_dir", function () { + var done = this.async(); + var rimraf = require("rimraf"); + rimraf("coverage", function (err) { + if (err) { + console.log("Error while deleting coverage directory from the package: ", err); + done(false); + } + + done(); + }); + }); + + grunt.registerTask("test", ["ts:devall", "shell:npm_test"]); + + grunt.registerTask("pack", [ + "clean", + "ts:release_build", + "shell:npm_test", + "delete_coverage_dir", + "shell:build_package" + ]); + grunt.registerTask("lint", ["tslint:build"]); + grunt.registerTask("all", ["clean", "test", "lint"]); + grunt.registerTask("rebuild", ["clean", "ts:devlib"]); + grunt.registerTask("default", "ts:devlib"); +}; diff --git a/package.json b/package.json index 883e766beb..d039396a11 100644 --- a/package.json +++ b/package.json @@ -24,11 +24,13 @@ "devDependencies": { "grunt": "1.0.1", "grunt-contrib-clean": "1.0.0", + "grunt-contrib-watch": "1.0.0", "grunt-shell": "2.0.0", "grunt-ts": "6.0.0-beta.3", "grunt-tslint": "3.3.0", "istanbul": "0.4.5", "mocha": "3.1.2", + "rimraf": "2.5.4", "tslint": "3.15.1", "typescript": "2.0.3" } From 4cb3ac63a5f0f707088448655c66d358b46655b9 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 25 Oct 2016 12:05:18 +0300 Subject: [PATCH 007/169] Integrate travis --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..b1358943b7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: +- '4' +git: + submodules: false +before_script: +- npm install grunt-cli +- npm install +script: +- node_modules/.bin/grunt pack --no-color From 906e3cfe5bd0b042225ede3682e621f95325b009 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 21 Oct 2016 13:42:53 +0300 Subject: [PATCH 008/169] Add bluebird and definitions for it --- lib/definitions/bluebird.d.ts | 782 ++++++++++ lib/definitions/node.d.ts | 2511 +++++++++++++++++++++++++++++++++ package.json | 3 + 3 files changed, 3296 insertions(+) create mode 100644 lib/definitions/bluebird.d.ts create mode 100644 lib/definitions/node.d.ts diff --git a/lib/definitions/bluebird.d.ts b/lib/definitions/bluebird.d.ts new file mode 100644 index 0000000000..32b41af4fe --- /dev/null +++ b/lib/definitions/bluebird.d.ts @@ -0,0 +1,782 @@ +// Type definitions for bluebird 3.0.0 +// Project: https://github.com/petkaantonov/bluebird +// Definitions by: Leonard Hecker +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/*! + * The code following this comment originates from: + * https://github.com/types/npm-bluebird + * + * Licensed under: + * The MIT License (MIT) + * + * Copyright (c) 2016 unional + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Generated by typings +// Source: bluebird.d.ts +declare module 'bluebird' { + // Type definitions for Bluebird v3.x.x + // Project: http://bluebirdjs.com + + class Bluebird implements Bluebird.Thenable, Bluebird.Inspection { + /** + * Create a new promise. The passed in function will receive functions `resolve` and `reject` as its arguments which can be called to seal the fate of the created promise. + * If promise cancellation is enabled, passed in function will receive one more function argument `onCancel` that allows to register an optional cancellation callback. + */ + constructor(callback: (resolve: (thenableOrResult?: R | Bluebird.Thenable) => void, reject: (error?: any) => void, onCancel?: (callback: () => void) => void) => void); + + /** + * Promises/A+ `.then()`. Returns a new promise chained from this promise. The new promise will be rejected or resolved dedefer on the passed `fulfilledHandler`, `rejectedHandler` and the state of this promise. + */ + then(onFulfill: (value: R) => U1 | Bluebird.Thenable, onReject: (error: any) => U2 | Bluebird.Thenable): Bluebird; + then(onFulfill: (value: R) => U | Bluebird.Thenable, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; + then(onFulfill: (value: R) => U | Bluebird.Thenable): Bluebird; + then(): Bluebird; + + /** + * This is a catch-all exception handler, shortcut for calling `.then(null, handler)` on this promise. Any exception happening in a `.then`-chain will propagate to nearest `.catch` handler. + * + * Alias `.caught();` for compatibility with earlier ECMAScript version. + */ + catch(onReject?: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + caught(onReject?: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + catch(onReject?: (error: any) => U | Bluebird.Thenable): Bluebird; + caught(onReject?: (error: any) => U | Bluebird.Thenable): Bluebird; + + /** + * This extends `.catch` to work more like catch-clauses in languages like Java or C#. Instead of manually checking `instanceof` or `.name === "SomeError"`, you may specify a number of error constructors which are eligible for this catch handler. The catch handler that is first met that has eligible constructors specified, is the one that will be called. + * + * This method also supports predicate-based filters. If you pass a predicate function instead of an error constructor, the predicate will receive the error as an argument. The return result of the predicate will be used determine whether the error handler should be called. + * + * Alias `.caught();` for compatibility with earlier ECMAScript version. + */ + catch(predicate: (error: any) => boolean, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + caught(predicate: (error: any) => boolean, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + catch(predicate: (error: any) => boolean, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; + caught(predicate: (error: any) => boolean, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; + catch(ErrorClass: Function, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + caught(ErrorClass: Function, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + catch(ErrorClass: Function, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; + caught(ErrorClass: Function, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; + catch(predicate: Object, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + caught(predicate: Object, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; + catch(predicate: Object, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; + caught(predicate: Object, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; + + /** + * Like `.catch` but instead of catching all types of exceptions, it only catches those that don't originate from thrown errors but rather from explicit rejections. + */ + error(onReject: (reason: any) => U | Bluebird.Thenable): Bluebird; + + /** + * Pass a handler that will be called regardless of this promise's fate. Returns a new promise chained from this promise. There are special semantics for `.finally()` in that the final value cannot be modified from the handler. + * + * Alias `.lastly();` for compatibility with earlier ECMAScript version. + */ + finally(handler: () => U | Bluebird.Thenable): Bluebird; + + lastly(handler: () => U | Bluebird.Thenable): Bluebird; + + /** + * Create a promise that follows this promise, but is bound to the given `thisArg` value. A bound promise will call its handlers with the bound value set to `this`. Additionally promises derived from a bound promise will also be bound promises with the same `thisArg` binding as the original promise. + */ + bind(thisArg: any): Bluebird; + + /** + * Like `.then()`, but any unhandled rejection that ends up here will be thrown as an error. + */ + done(onFulfilled?: (value: R) => U | Bluebird.Thenable, onRejected?: (error: any) => U | Bluebird.Thenable): void; + + /** + * Like `.finally()`, but not called for rejections. + */ + tap(onFulFill: (value: R) => Bluebird.Thenable): Bluebird; + tap(onFulfill: (value: R) => U): Bluebird; + + /** + * Same as calling `Promise.delay(ms, this)`. + */ + delay(ms: number): Bluebird; + + /** + * Returns a promise that will be fulfilled with this promise's fulfillment value or rejection reason. + * However, if this promise is not fulfilled or rejected within ms milliseconds, the returned promise + * is rejected with a TimeoutError or the error as the reason. + * + * You may specify a custom error message with the `message` parameter. + */ + timeout(ms: number, message?: string | Error): Bluebird; + + /** + * Register a node-style callback on this promise. When this promise is is either fulfilled or rejected, the node callback will be called back with the node.js convention where error reason is the first argument and success value is the second argument. The error argument will be `null` in case of success. + * If the `callback` argument is not a function, this method does not do anything. + */ + nodeify(callback: (err: any, value?: R) => void, options?: Bluebird.SpreadOption): this; + nodeify(...sink: any[]): this; + asCallback(callback: (err: any, value?: R) => void, options?: Bluebird.SpreadOption): this; + asCallback(...sink: any[]): this; + + /** + * See if this `promise` has been fulfilled. + */ + isFulfilled(): boolean; + + /** + * See if this `promise` has been rejected. + */ + isRejected(): boolean; + + /** + * See if this `promise` is still defer. + */ + isPending(): boolean; + + /** + * See if this `promise` has been cancelled. + */ + isCancelled(): boolean; + + /** + * See if this `promise` is resolved -> either fulfilled or rejected. + */ + isResolved(): boolean; + + /** + * Get the fulfillment value of the underlying promise. Throws if the promise isn't fulfilled yet. + * + * throws `TypeError` + */ + value(): R; + + /** + * Get the rejection reason for the underlying promise. Throws if the promise isn't rejected yet. + * + * throws `TypeError` + */ + reason(): any; + + /** + * Synchronously inspect the state of this `promise`. The `PromiseInspection` will represent the state of + * the promise as snapshotted at the time of calling `.reflect()`. + */ + reflect(): Bluebird>; + reflect(): Bluebird>; + + /** + * This is a convenience method for doing: + * + * + * promise.then(function(obj){ + * return obj[propertyName].call(obj, arg...); + * }); + * + */ + call(propertyName: string, ...args: any[]): Bluebird; + + /** + * This is a convenience method for doing: + * + * + * promise.then(function(obj){ + * return obj[propertyName]; + * }); + * + */ + // TODO: Use "type property type" once it's there + // @see https://github.com/Microsoft/TypeScript/issues/1295 + get(key: string | number): Bluebird; + + /** + * Convenience method for: + * + * + * .then(function() { + * return value; + * }); + * + * + * in the case where `value` doesn't change its value. That means `value` is bound at the time of calling `.return()` + * + * Alias `.thenReturn();` for compatibility with earlier ECMAScript version. + */ + return(): Bluebird; + thenReturn(): Bluebird; + return(value: U): Bluebird; + thenReturn(value: U): Bluebird; + + /** + * Convenience method for: + * + * + * .then(function() { + * throw reason; + * }); + * + * Same limitations apply as with `.return()`. + * + * Alias `.thenThrow();` for compatibility with earlier ECMAScript version. + */ + throw(reason: Error): Bluebird; + thenThrow(reason: Error): Bluebird; + + /** + * Convert to String. + */ + toString(): string; + + /** + * This is implicitly called by `JSON.stringify` when serializing the object. Returns a serialized representation of the `Promise`. + */ + toJSON(): Object; + + /** + * Like calling `.then`, but the fulfillment value or rejection reason is assumed to be an array, which is flattened to the formal parameters of the handlers. + */ + spread(fulfilledHandler: (...values: W[]) => U | Bluebird.Thenable): Bluebird; + spread(fulfilledHandler: Function): Bluebird; + + /** + * Same as calling `Promise.all(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + all(): Bluebird; + + /** + * Same as calling `Promise.props(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO how to model instance.props()? + props(): Bluebird; + + /** + * Same as calling `Promise.any(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + any(): Bluebird; + + /** + * Same as calling `Promise.some(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + some(count: number): Bluebird; + + /** + * Same as calling `Promise.race(thisPromise, count)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + race(): Bluebird; + + /** + * Same as calling `Bluebird.map(thisPromise, mapper)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + map(mapper: (item: Q, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; + + /** + * Same as calling `Promise.reduce(thisPromise, Function reducer, initialValue)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + reduce(reducer: (memo: U, item: Q, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; + + /** + * Same as calling ``Promise.filter(thisPromise, filterer)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + filter(filterer: (item: U, index: number, arrayLength: number) => boolean | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; + + /** + * Same as calling ``Bluebird.each(thisPromise, iterator)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + each(iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; + + /** + * Same as calling ``Bluebird.mapSeries(thisPromise, iterator)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + mapSeries(iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; + + /** + * Cancel this `promise`. Will not do anything if this promise is already settled or if the cancellation feature has not been enabled + */ + cancel(): void; + + /** + * Basically sugar for doing: somePromise.catch(function(){}); + * + * Which is needed in case error handlers are attached asynchronously to the promise later, which would otherwise result in premature unhandled rejection reporting. + */ + suppressUnhandledRejections(): void; + + /** + * Start the chain of promises with `Promise.try`. Any synchronous exceptions will be turned into rejections on the returned promise. + * + * Note about second argument: if it's specifically a true array, its values become respective arguments for the function call. Otherwise it is passed as is as the first argument for the function call. + * + * Alias for `attempt();` for compatibility with earlier ECMAScript version. + */ + static try(fn: () => R | Bluebird.Thenable): Bluebird; + static attempt(fn: () => R | Bluebird.Thenable): Bluebird; + + /** + * Returns a new function that wraps the given function `fn`. The new function will always return a promise that is fulfilled with the original functions return values or rejected with thrown exceptions from the original function. + * This method is convenient when a function can sometimes return synchronously or throw synchronously. + */ + static method(fn: Function): Function; + + /** + * Create a promise that is resolved with the given `value`. If `value` is a thenable or promise, the returned promise will assume its state. + */ + static resolve(): Bluebird; + static resolve(value: R | Bluebird.Thenable): Bluebird; + + /** + * Create a promise that is rejected with the given `reason`. + */ + static reject(reason: any): Bluebird; + static reject(reason: any): Bluebird; + + /** + * Create a promise with undecided fate and return a `PromiseResolver` to control it. See resolution?: Promise(#promise-resolution). + */ + static defer(): Bluebird.Resolver; + + /** + * Cast the given `value` to a trusted promise. If `value` is already a trusted `Promise`, it is returned as is. If `value` is not a thenable, a fulfilled is: Promise returned with `value` as its fulfillment value. If `value` is a thenable (Promise-like object, like those returned by jQuery's `$.ajax`), returns a trusted that: Promise assimilates the state of the thenable. + */ + static cast(value: R | Bluebird.Thenable): Bluebird; + + /** + * Sugar for `Promise.resolve(undefined).bind(thisArg);`. See `.bind()`. + */ + static bind(thisArg: any): Bluebird; + + /** + * See if `value` is a trusted Promise. + */ + static is(value: any): boolean; + + /** + * Call this right after the library is loaded to enabled long stack traces. Long stack traces cannot be disabled after being enabled, and cannot be enabled after promises have already been created. Long stack traces imply a substantial performance penalty, around 4-5x for throughput and 0.5x for latency. + */ + static longStackTraces(): void; + + /** + * Returns a promise that will be resolved with value (or undefined) after given ms milliseconds. + * If value is a promise, the delay will start counting down when it is fulfilled and the returned + * promise will be fulfilled with the fulfillment value of the value promise. + */ + static delay(ms: number, value: R | Bluebird.Thenable): Bluebird; + static delay(ms: number): Bluebird; + + /** + * Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. + * + * If the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be an array of them. + * + * If you pass a `receiver`, the `nodeFunction` will be called as a method on the `receiver`. + */ + static promisify(func: (callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): () => Bluebird; + static promisify(func: (arg1: A1, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1) => Bluebird; + static promisify(func: (arg1: A1, arg2: A2, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2) => Bluebird; + static promisify(func: (arg1: A1, arg2: A2, arg3: A3, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2, arg3: A3) => Bluebird; + static promisify(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2, arg3: A3, arg4: A4) => Bluebird; + static promisify(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5) => Bluebird; + static promisify(nodeFunction: Function, options?: Bluebird.PromisifyOptions): Function; + + /** + * Promisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain. The promisified method name will be the original method name postfixed with `Async`. Returns the input object. + * + * Note that the original methods on the object are not overwritten but new methods are created with the `Async`-postfix. For example, if you `promisifyAll()` the node.js `fs` object use `fs.statAsync()` to call the promisified `stat` method. + */ + // TODO how to model promisifyAll? + static promisifyAll(target: Object, options?: Bluebird.PromisifyAllOptions): Object; + + /** + * Returns a promise that is resolved by a node style callback function. + */ + static fromNode(resolver: (callback: (err: any, result?: any) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; + static fromNode(resolver: (callback: (err: any, result?: T) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; + static fromCallback(resolver: (callback: (err: any, result?: any) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; + static fromCallback(resolver: (callback: (err: any, result?: T) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; + + /** + * Returns a function that can use `yield` to run asynchronous code synchronously. This feature requires the support of generators which are drafted in the next version of the language. Node version greater than `0.11.2` is required and needs to be executed with the `--harmony-generators` (or `--harmony`) command-line switch. + */ + // TODO fix coroutine GeneratorFunction + static coroutine(generatorFunction: Function): Function; + + /** + * Add `handler` as the handler to call when there is a possibly unhandled rejection. The default handler logs the error stack to stderr or `console.error` in browsers. + * + * Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections. + */ + static onPossiblyUnhandledRejection(handler: (reason: any) => any): void; + + /** + * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled when all the items in the array are fulfilled. The promise's fulfillment value is an array with fulfillment values at respective positions to the original array. If any promise in the array rejects, the returned promise is rejected with the rejection reason. + */ + // TODO enable more overloads + // array with promises of different types + static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2, Bluebird.Thenable | T3, Bluebird.Thenable | T4, Bluebird.Thenable | T5]): Bluebird<[T1, T2, T3, T4, T5]>; + static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2, Bluebird.Thenable | T3, Bluebird.Thenable | T4]): Bluebird<[T1, T2, T3, T4]>; + static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2, Bluebird.Thenable | T3]): Bluebird<[T1, T2, T3]>; + static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2]): Bluebird<[T1, T2]>; + static all(values: [Bluebird.Thenable | T1]): Bluebird<[T1]>; + // array with values + static all(values: Bluebird.Thenable<(Bluebird.Thenable | R)[]> | (Bluebird.Thenable | R)[]): Bluebird; + + /** + * Like ``Promise.all`` but for object properties instead of array items. Returns a promise that is fulfilled when all the properties of the object are fulfilled. The promise's fulfillment value is an object with fulfillment values at respective keys to the original object. If any promise in the object rejects, the returned promise is rejected with the rejection reason. + * + * If `object` is a trusted `Promise`, then it will be treated as a promise for object rather than for its properties. All other objects are treated for their properties as is returned by `Object.keys` - the object's own enumerable properties. + * + * *The original object is not modified.* + */ + // TODO verify this is correct + // trusted promise for object + static props(object: Bluebird): Bluebird; + // object + static props(object: Object): Bluebird; + + /** + * Like `Promise.some()`, with 1 as `count`. However, if the promise fulfills, the fulfillment value is not an array of 1 but the value directly. + */ + static any(values: Bluebird.Thenable<(Bluebird.Thenable | R)[]> | (Bluebird.Thenable | R)[]): Bluebird; + + /** + * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled or rejected as soon as a promise in the array is fulfilled or rejected with the respective rejection reason or fulfillment value. + * + * **Note** If you pass empty array or a sparse array with no values, or a promise/thenable for such, it will be forever pending. + */ + static race(values: Bluebird.Thenable<(Bluebird.Thenable | R)[]> | (Bluebird.Thenable | R)[]): Bluebird; + + /** + * Initiate a competetive race between multiple promises or values (values will become immediately fulfilled promises). When `count` amount of promises have been fulfilled, the returned promise is fulfilled with an array that contains the fulfillment values of the winners in order of resolution. + * + * If too many promises are rejected so that the promise can never become fulfilled, it will be immediately rejected with an array of rejection reasons in the order they were thrown in. + * + * *The original array is not modified.* + */ + // promise of array with promises of value + static some(values: Bluebird.Thenable[]>, count: number): Bluebird; + // promise of array with values + static some(values: Bluebird.Thenable, count: number): Bluebird; + // array with promises of value + static some(values: Bluebird.Thenable[], count: number): Bluebird; + // array with values + static some(values: R[], count: number): Bluebird; + + /** + * Promise.join( + * Promise|any values..., + * function handler + * ) -> Promise + * For coordinating multiple concurrent discrete promises. + * + * Note: In 1.x and 0.x Promise.join used to be a Promise.all that took the values in as arguments instead in an array. This behavior has been deprecated but is still supported partially - when the last argument is an immediate function value the new semantics will apply + */ + static join(arg1: A1 | Bluebird.Thenable, handler: (arg1?: A1) => R | Bluebird.Thenable): Bluebird; + static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2) => R | Bluebird.Thenable): Bluebird; + static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, arg3: A3 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2, arg3?: A3) => R | Bluebird.Thenable): Bluebird; + static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, arg3: A3 | Bluebird.Thenable, arg4: A4 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2, arg3?: A3, arg4?: A4) => R | Bluebird.Thenable): Bluebird; + static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, arg3: A3 | Bluebird.Thenable, arg4: A4 | Bluebird.Thenable, arg5: A5 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2, arg3?: A3, arg4?: A4, arg5?: A5) => R | Bluebird.Thenable): Bluebird; + + // variadic array + /** @deprecated use .all instead */ + static join(...values: (R | Bluebird.Thenable)[]): Bluebird; + + /** + * Map an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `mapper` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. + * + * If the `mapper` function returns promises or thenables, the returned promise will wait for all the mapped results to be resolved as well. + * + * *The original array is not modified.* + */ + // promise of array with promises of value + static map(values: Bluebird.Thenable[]>, mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; + + // promise of array with values + static map(values: Bluebird.Thenable, mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; + + // array with promises of value + static map(values: Bluebird.Thenable[], mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; + + // array with values + static map(values: R[], mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; + + /** + * Reduce an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `reducer` function with the signature `(total, current, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. + * + * If the reducer function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration. + * + * *The original array is not modified. If no `intialValue` is given and the array doesn't contain at least 2 items, the callback will not be called and `undefined` is returned. If `initialValue` is given and the array doesn't have at least 1 item, `initialValue` is returned.* + */ + // promise of array with promises of value + static reduce(values: Bluebird.Thenable[]>, reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; + + // promise of array with values + static reduce(values: Bluebird.Thenable, reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; + + // array with promises of value + static reduce(values: Bluebird.Thenable[], reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; + + // array with values + static reduce(values: R[], reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; + + /** + * Filter an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `filterer` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. + * + * The return values from the filtered functions are coerced to booleans, with the exception of promises and thenables which are awaited for their eventual result. + * + * *The original array is not modified. + */ + // promise of array with promises of value + static filter(values: Bluebird.Thenable[]>, filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; + + // promise of array with values + static filter(values: Bluebird.Thenable, filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; + + // array with promises of value + static filter(values: Bluebird.Thenable[], filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; + + // array with values + static filter(values: R[], filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; + + /** + * Iterate over an array, or a promise of an array, which contains promises (or a mix of promises and values) with the given iterator function with the signature (item, index, value) where item is the resolved value of a respective promise in the input array. Iteration happens serially. If any promise in the input array is rejected the returned promise is rejected as well. + * + * Resolves to the original array unmodified, this method is meant to be used for side effects. If the iterator function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration. + */ + // promise of array with promises of value + static each(values: Bluebird.Thenable[]>, iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; + // array with promises of value + static each(values: Bluebird.Thenable[], iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; + // array with values OR promise of array with values + static each(values: R[] | Bluebird.Thenable, iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; + + /** + * Given an Iterable(arrays are Iterable), or a promise of an Iterable, which produces promises (or a mix of promises and values), iterate over all the values in the Iterable into an array and iterate over the array serially, in-order. + * + * Returns a promise for an array that contains the values returned by the iterator function in their respective positions. The iterator won't be called for an item until its previous item, and the promise returned by the iterator for that item are fulfilled. This results in a mapSeries kind of utility but it can also be used simply as a side effect iterator similar to Array#forEach. + * + * If any promise in the input array is rejected or any promise returned by the iterator function is rejected, the result will be rejected as well. + */ + static mapSeries(values: (R | Bluebird.Thenable)[] | Bluebird.Thenable<(R | Bluebird.Thenable)[]>, iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; + + /** + * A meta method used to specify the disposer method that cleans up a resource when using `Promise.using`. + * + * Returns a Disposer object which encapsulates both the resource as well as the method to clean it up. + * The user can pass this object to `Promise.using` to get access to the resource when it becomes available, + * as well as to ensure its automatically cleaned up. + * + * The second argument passed to a disposer is the result promise of the using block, which you can + * inspect synchronously. + */ + disposer(disposeFn: (arg: R, promise: Bluebird) => void | Bluebird.Thenable): Bluebird.Disposer; + + /** + * In conjunction with `.disposer`, using will make sure that no matter what, the specified disposer + * will be called when the promise returned by the callback passed to using has settled. The disposer is + * necessary because there is no standard interface in node for disposing resources. + */ + static using(disposer: Bluebird.Disposer, executor: (transaction: R) => Bluebird.Thenable): Bluebird; + static using(disposer: Bluebird.Disposer, disposer2: Bluebird.Disposer, executor: (transaction1: R1, transaction2: R2) => Bluebird.Thenable): Bluebird; + static using(disposer: Bluebird.Disposer, disposer2: Bluebird.Disposer, disposer3: Bluebird.Disposer, executor: (transaction1: R1, transaction2: R2, transaction3: R3) => Bluebird.Thenable): Bluebird; + + /** + * Add handler as the handler to call when there is a possibly unhandled rejection. + * The default handler logs the error stack to stderr or console.error in browsers. + * + * Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections. + * + * Note: this hook is specific to the bluebird instance its called on, application developers should use global rejection events. + */ + static onPossiblyUnhandledRejection(handler?: (error: Error, promise: Bluebird) => void): void; + + /** + * Configure long stack traces, warnings, monitoring and cancellation. + * Note that even though false is the default here, a development environment might be detected which automatically + * enables long stack traces and warnings. + */ + static config(options: { + /** Enable warnings */ + warnings?: boolean | { + /** Enables all warnings except forgotten return statements. */ + wForgottenReturn: boolean; + }; + /** Enable long stack traces */ + longStackTraces?: boolean; + /** Enable cancellation */ + cancellation?: boolean; + /** Enable monitoring */ + monitoring?: boolean; + }): void; + } + + namespace Bluebird { + export interface ConcurrencyOption { + concurrency: number; + } + export interface SpreadOption { + spread: boolean; + } + export interface FromNodeOptions { + multiArgs?: boolean; + } + export interface PromisifyOptions { + context?: any; + multiArgs?: boolean; + } + export interface PromisifyAllOptions extends PromisifyOptions { + suffix?: string; + filter?: (name: string, func: Function, target?: any, passesDefaultFilter?: boolean) => boolean; + // The promisifier gets a reference to the original method and should return a function which returns a promise + promisifier?: (originalMethod: Function) => () => Thenable; + } + + /** + * Represents an error is an explicit promise rejection as opposed to a thrown error. + * For example, if an error is errbacked by a callback API promisified through undefined or undefined + * and is not a typed error, it will be converted to a `OperationalError` which has the original error in + * the `.cause` property. + * + * `OperationalError`s are caught in `.error` handlers. + */ + export class OperationalError extends Error { } + + /** + * Signals that an operation has timed out. Used as a custom cancellation reason in `.timeout`. + */ + export class TimeoutError extends Error { } + + /** + * Signals that an operation has been aborted or cancelled. The default reason used by `.cancel`. + */ + export class CancellationError extends Error { } + + /** + * A collection of errors. `AggregateError` is an array-like object, with numeric indices and a `.length` property. + * It supports all generic array methods such as `.forEach` directly. + * + * `AggregateError`s are caught in `.error` handlers, even if the contained errors are not operational. + * + * `Promise.some` and `Promise.any` use `AggregateError` as rejection reason when they fail. + */ + export class AggregateError extends Error { } + + /** + * returned by `Bluebird.disposer()`. + */ + export class Disposer { + } + + export interface Thenable { + then(onFulfilled: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Thenable; + then(onFulfilled: (value: R) => U | Thenable, onRejected?: (error: any) => void | Thenable): Thenable; + } + + export interface Resolver { + /** + * Returns a reference to the controlled promise that can be passed to clients. + */ + promise: Bluebird; + + /** + * Resolve the underlying promise with `value` as the resolution value. If `value` is a thenable or a promise, the underlying promise will assume its state. + */ + resolve(value: R): void; + resolve(): void; + + /** + * Reject the underlying promise with `reason` as the rejection reason. + */ + reject(reason: any): void; + + /** + * Gives you a callback representation of the `PromiseResolver`. Note that this is not a method but a property. The callback accepts error object in first argument and success values on the 2nd parameter and the rest, I.E. node js conventions. + * + * If the the callback is called with multiple success values, the resolver fullfills its promise with an array of the values. + */ + // TODO specify resolver callback + callback: (err: any, value: R, ...values: R[]) => void; + } + + export interface Inspection { + /** + * See if the underlying promise was fulfilled at the creation time of this inspection object. + */ + isFulfilled(): boolean; + + /** + * See if the underlying promise was rejected at the creation time of this inspection object. + */ + isRejected(): boolean; + + /** + * See if the underlying promise was cancelled at the creation time of this inspection object. + */ + isCancelled(): boolean; + + /** + * See if the underlying promise was defer at the creation time of this inspection object. + */ + isPending(): boolean; + + /** + * Get the fulfillment value of the underlying promise. Throws if the promise wasn't fulfilled at the creation time of this inspection object. + * + * throws `TypeError` + */ + value(): R; + + /** + * Get the rejection reason for the underlying promise. Throws if the promise wasn't rejected at the creation time of this inspection object. + * + * throws `TypeError` + */ + reason(): any; + } + + /** + * Returns a new independent copy of the Bluebird library. + * + * This method should be used before you use any of the methods which would otherwise alter the global Bluebird object - to avoid polluting global state. + */ + export function getNewLibraryCopy(): typeof Bluebird; + + /** + * This is relevant to browser environments with no module loader. + * + * Release control of the Promise namespace to whatever it was before this library was loaded. Returns a reference to the library namespace so you can attach it to something else. + */ + export function noConflict(): typeof Bluebird; + + /** + * Changes how bluebird schedules calls a-synchronously. + * + * @param scheduler Should be a function that asynchronously schedules + * the calling of the passed in function + */ + export function setScheduler(scheduler: (callback: (...args: any[]) => void) => void): void; + } + + export = Bluebird; +} diff --git a/lib/definitions/node.d.ts b/lib/definitions/node.d.ts new file mode 100644 index 0000000000..ceab0ea608 --- /dev/null +++ b/lib/definitions/node.d.ts @@ -0,0 +1,2511 @@ +// Type definitions for Node.js v4.x +// Project: http://nodejs.org/ +// Definitions by: Microsoft TypeScript , DefinitelyTyped +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/************************************************ +* * +* Node.js v4.x API * +* * +************************************************/ + +interface Error { + stack?: string; +} + +interface ErrorConstructor { + captureStackTrace(targetObject: Object, constructorOpt?: Function): void; + stackTraceLimit: number; +} + +// compat for TypeScript 1.8 +// if you use with --target es3 or --target es5 and use below definitions, +// use the lib.es6.d.ts that is bundled with TypeScript 1.8. +interface MapConstructor { } +interface WeakMapConstructor { } +interface SetConstructor { } +interface WeakSetConstructor { } + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: NodeJS.Global; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +interface NodeRequireFunction { + (id: string): any; +} + +interface NodeRequire extends NodeRequireFunction { + resolve(id: string): string; + cache: any; + extensions: any; + main: any; +} + +declare var require: NodeRequire; + +interface NodeModule { + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +} + +declare var module: NodeModule; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (size: Uint8Array): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +type BufferEncoding = "ascii" | "utf8" | "utf16le" | "ucs2" | "binary" | "hex"; +interface Buffer extends NodeBuffer { } + +/** + * Raw data is stored in instances of the Buffer class. + * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. + * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + */ +declare var Buffer: { + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ + new (str: string, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ + new (size: number): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: Uint8Array): Buffer; + /** + * Produces a Buffer backed by the same allocated memory as + * the given {ArrayBuffer}. + * + * + * @param arrayBuffer The ArrayBuffer with which to share memory. + */ + new (arrayBuffer: ArrayBuffer): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: any[]): Buffer; + /** + * Copies the passed {buffer} data onto a new {Buffer} instance. + * + * @param buffer The buffer to copy. + */ + new (buffer: Buffer): Buffer; + prototype: Buffer; + /** + * Allocates a new Buffer using an {array} of octets. + * + * @param array + */ + from(array: any[]): Buffer; + /** + * When passed a reference to the .buffer property of a TypedArray instance, + * the newly created Buffer will share the same allocated memory as the TypedArray. + * The optional {byteOffset} and {length} arguments specify a memory range + * within the {arrayBuffer} that will be shared by the Buffer. + * + * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() + * @param byteOffset + * @param length + */ + from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + /** + * Copies the passed {buffer} data onto a new Buffer instance. + * + * @param buffer + */ + from(buffer: Buffer): Buffer; + /** + * Creates a new Buffer containing the given JavaScript string {str}. + * If provided, the {encoding} parameter identifies the character encoding. + * If not provided, {encoding} defaults to 'utf8'. + * + * @param str + */ + from(str: string, encoding?: string): Buffer; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + isBuffer(obj: any): obj is Buffer; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ + byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ + concat(list: Buffer[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + compare(buf1: Buffer, buf2: Buffer): number; +}; + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare namespace NodeJS { + export interface ErrnoException extends Error { + errno?: number; + code?: string; + path?: string; + syscall?: string; + stack?: string; + } + + export interface EventEmitter { + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string | Buffer; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer | string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream { } + + export interface Events extends EventEmitter { } + + export interface Domain extends Events { + run(fn: Function): void; + add(emitter: Events): void; + remove(emitter: Events): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + } + + export interface MemoryUsage { + rss: number; + heapTotal: number; + heapUsed: number; + } + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execArgv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + exitCode: number; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + modules: string; + openssl: string; + }; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string | number): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): MemoryUsage; + nextTick(callback: Function): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?: number[]): number[]; + domain: Domain; + + // Worker + send?(message: any, sendHandle?: any): void; + disconnect(): void; + connected: boolean; + } + + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + v8debug?: any; + } + + export interface Timer { + ref(): void; + unref(): void; + } +} + +/** + * @deprecated + */ +interface NodeBuffer extends Uint8Array { + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): { type: 'Buffer', data: any[] }; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): this; + // TODO: encoding param + indexOf(value: string | number | Buffer, byteOffset?: number): number; + // TODO: entries + // TODO: includes + // TODO: keys + // TODO: values +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module "buffer" { + export var INSPECT_MAX_BYTES: number; + var BuffType: typeof Buffer; + var SlowBuffType: typeof SlowBuffer; + export { BuffType as Buffer, SlowBuffType as SlowBuffer }; +} + +declare module "querystring" { + export interface StringifyOptions { + encodeURIComponent?: Function; + } + + export interface ParseOptions { + maxKeys?: number; + decodeURIComponent?: Function; + } + + export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; + export function escape(str: string): string; + export function unescape(str: string): string; +} + +declare module "events" { + export class EventEmitter implements NodeJS.EventEmitter { + static EventEmitter: EventEmitter; + static listenerCount(emitter: EventEmitter, event: string): number; // deprecated + static defaultMaxListeners: number; + + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; + } +} + +declare module "http" { + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; + + export interface RequestOptions { + protocol?: string; + host?: string; + hostname?: string; + family?: number; + port?: number; + localAddress?: string; + socketPath?: string; + method?: string; + path?: string; + headers?: { [key: string]: any }; + auth?: string; + agent?: Agent | boolean; + } + + export interface Server extends net.Server { + setTimeout(msecs: number, callback: Function): void; + maxHeadersCount: number; + timeout: number; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ServerRequest extends IncomingMessage { + connection: net.Socket; + } + export interface ServerResponse extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + statusMessage: string; + headersSent: boolean; + setHeader(name: string, value: string | string[]): void; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + setHeader(name: string, value: string | string[]): void; + getHeader(name: string): string; + removeHeader(name: string): void; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface IncomingMessage extends events.EventEmitter, stream.Readable { + httpVersion: string; + headers: any; + rawHeaders: string[]; + trailers: any; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; + /** + * Only valid for request obtained from http.Server. + */ + method?: string; + /** + * Only valid for request obtained from http.Server. + */ + url?: string; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusCode?: number; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusMessage?: string; + socket: net.Socket; + destroy(error?: Error): void; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ClientResponse extends IncomingMessage { } + + export interface AgentOptions { + /** + * Keep sockets around in a pool to be used by other requests in the future. Default = false + */ + keepAlive?: boolean; + /** + * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. + * Only relevant if keepAlive is set to true. + */ + keepAliveMsecs?: number; + /** + * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity + */ + maxSockets?: number; + /** + * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. + */ + maxFreeSockets?: number; + } + + export class Agent { + maxSockets: number; + sockets: any; + requests: any; + + constructor(opts?: AgentOptions); + + /** + * Destroy any sockets that are currently in use by the agent. + * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, + * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, + * sockets may hang open for quite a long time before the server terminates them. + */ + destroy(): void; + } + + export var METHODS: string[]; + + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; +} + +declare module "cluster" { + import * as child from "child_process"; + import * as events from "events"; + + export interface ClusterSettings { + exec?: string; + args?: string[]; + silent?: boolean; + } + + export interface Address { + address: string; + port: number; + addressType: string; + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): void; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + isConnected(): boolean; + isDead(): boolean; + } + + export var settings: ClusterSettings; + export var isMaster: boolean; + export var isWorker: boolean; + export function setupMaster(settings?: ClusterSettings): void; + export function fork(env?: any): Worker; + export function disconnect(callback?: Function): void; + export var worker: Worker; + export var workers: { + [index: string]: Worker + }; + + // Event emitter + export function addListener(event: string, listener: Function): void; + export function on(event: "disconnect", listener: (worker: Worker) => void): void; + export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): void; + export function on(event: "fork", listener: (worker: Worker) => void): void; + export function on(event: "listening", listener: (worker: Worker, address: any) => void): void; + export function on(event: "message", listener: (worker: Worker, message: any) => void): void; + export function on(event: "online", listener: (worker: Worker) => void): void; + export function on(event: "setup", listener: (settings: any) => void): void; + export function on(event: string, listener: Function): any; + export function once(event: string, listener: Function): void; + export function removeListener(event: string, listener: Function): void; + export function removeAllListeners(event?: string): void; + export function setMaxListeners(n: number): void; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; +} + +declare module "zlib" { + import * as stream from "stream"; + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function deflateSync(buf: Buffer, options?: ZlibOptions): any; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function gzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function gzipSync(buf: Buffer, options?: ZlibOptions): any; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; + export function inflate(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function inflateSync(buf: Buffer, options?: ZlibOptions): any; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function unzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function unzipSync(buf: Buffer, options?: ZlibOptions): any; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module "os" { + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + }; + } + + export interface NetworkInterfaceInfo { + address: string; + netmask: string; + family: string; + mac: string; + internal: boolean; + } + + export function tmpdir(): string; + export function homedir(): string; + export function endianness(): string; + export function hostname(): string; + export function type(): string; + export function platform(): string; + export function arch(): string; + export function release(): string; + export function uptime(): number; + export function loadavg(): number[]; + export function totalmem(): number; + export function freemem(): number; + export function cpus(): CpuInfo[]; + export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; + export var EOL: string; +} + +declare module "https" { + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string) => any; + } + + export interface RequestOptions extends http.RequestOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + } + + export interface Agent extends http.Agent { } + + export interface AgentOptions extends http.AgentOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + maxCachedSessions?: number; + } + + export var Agent: { + new (options?: AgentOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module "punycode" { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): number[]; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module "repl" { + import * as stream from "stream"; + import * as events from "events"; + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + } + export function start(options: ReplOptions): events.EventEmitter; +} + +declare module "readline" { + import * as events from "events"; + import * as stream from "stream"; + + export interface Key { + sequence?: string; + name?: string; + ctrl?: boolean; + meta?: boolean; + shift?: boolean; + } + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: (answer: string) => void): void; + pause(): ReadLine; + resume(): ReadLine; + close(): void; + write(data: string | Buffer, key?: Key): void; + } + + export interface Completer { + (line: string): CompleterResult; + (line: string, callback: (err: any, result: CompleterResult) => void): any; + } + + export interface CompleterResult { + completions: string[]; + line: string; + } + + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + completer?: Completer; + terminal?: boolean; + historySize?: number; + } + + export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer, terminal?: boolean): ReadLine; + export function createInterface(options: ReadLineOptions): ReadLine; + + export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; + export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; + export function clearLine(stream: NodeJS.WritableStream, dir: number): void; + export function clearScreenDown(stream: NodeJS.WritableStream): void; +} + +declare module "vm" { + export interface Context { } + export interface ScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + cachedData?: Buffer; + produceCachedData?: boolean; + } + export interface RunningScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + } + export class Script { + constructor(code: string, options?: ScriptOptions); + runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; + runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; + runInThisContext(options?: RunningScriptOptions): any; + } + export function createContext(sandbox?: Context): Context; + export function isContext(sandbox: Context): boolean; + export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; + export function runInDebugContext(code: string): any; + export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; + export function runInThisContext(code: string, options?: RunningScriptOptions): any; +} + +declare module "child_process" { + import * as events from "events"; + import * as stream from "stream"; + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + stdio: [stream.Writable, stream.Readable, stream.Readable]; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle?: any): void; + connected: boolean; + disconnect(): void; + unref(): void; + } + + export interface SpawnOptions { + cwd?: string; + env?: any; + stdio?: any; + detached?: boolean; + uid?: number; + gid?: number; + shell?: boolean | string; + } + export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; + + export interface ExecOptions { + cwd?: string; + env?: any; + shell?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecOptionsWithStringEncoding extends ExecOptions { + encoding: BufferEncoding; + } + export interface ExecOptionsWithBufferEncoding extends ExecOptions { + encoding: string; // specify `null`. + } + export function exec(command: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function exec(command: string, options: ExecOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.exec("tsc", {encoding: null as string}, (err, stdout, stderr) => {}); + export function exec(command: string, options: ExecOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function exec(command: string, options: ExecOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + + export interface ExecFileOptions { + cwd?: string; + env?: any; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { + encoding: BufferEncoding; + } + export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { + encoding: string; // specify `null`. + } + export function execFile(file: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", ["foo"], {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + + export interface ForkOptions { + cwd?: string; + env?: any; + execPath?: string; + execArgv?: string[]; + silent?: boolean; + uid?: number; + gid?: number; + } + export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; + + export interface SpawnSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + shell?: boolean | string; + } + export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { + encoding: BufferEncoding; + } + export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { + encoding: string; // specify `null`. + } + export interface SpawnSyncReturns { + pid: number; + output: string[]; + stdout: T; + stderr: T; + status: number; + signal: string; + error: Error; + } + export function spawnSync(command: string): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; + + export interface ExecSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + shell?: string; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { + encoding: BufferEncoding; + } + export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { + encoding: string; // specify `null`. + } + export function execSync(command: string): Buffer; + export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; + export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; + export function execSync(command: string, options?: ExecSyncOptions): Buffer; + + export interface ExecFileSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { + encoding: BufferEncoding; + } + export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { + encoding: string; // specify `null`. + } + export function execFileSync(command: string): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; +} + +declare module "url" { + export interface Url { + href?: string; + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: string | any; + slashes?: boolean; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean, slashesDenoteHost?: boolean): Url; + export function format(url: Url): string; + export function resolve(from: string, to: string): string; +} + +declare module "dns" { + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) => void): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) => void): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) => void): string[]; +} + +declare module "net" { + import * as stream from "stream"; + import * as events from "events"; + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): void; + resume(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; + + remoteAddress: string; + remoteFamily: string; + remotePort: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface ListenOptions { + port?: number; + host?: string; + backlog?: number; + path?: string; + exclusive?: boolean; + } + + export interface Server extends events.EventEmitter { + listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function): Server; + listen(port: number, hostname?: string, listeningListener?: Function): Server; + listen(port: number, backlog?: number, listeningListener?: Function): Server; + listen(port: number, listeningListener?: Function): Server; + listen(path: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, backlog?: number, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + listen(options: ListenOptions, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + getConnections(cb: (error: Error, count: number) => void): void; + ref(): Server; + unref(): Server; + maxConnections: number; + connections: number; + + /** + * events.EventEmitter + * 1. close + * 2. connection + * 3. error + * 4. listening + */ + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "connection", listener: (socket: Socket) => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "listening", listener: () => void): this; + + emit(event: string, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "connection", socket: Socket): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "listening"): boolean; + + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "connection", listener: (socket: Socket) => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "listening", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "connection", listener: (socket: Socket) => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "listening", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "connection", listener: (socket: Socket) => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "listening", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "connection", listener: (socket: Socket) => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "listening", listener: () => void): this; + } + export function createServer(connectionListener?: (socket: Socket) => void): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) => void): Server; + export function connect(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module "dgram" { + import * as events from "events"; + + interface RemoteInfo { + address: string; + port: number; + size: number; + } + + interface AddressInfo { + address: string; + family: string; + port: number; + } + + export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + + interface Socket extends events.EventEmitter { + send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port: number, address?: string, callback?: () => void): void; + close(): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + } +} + +declare module "fs" { + import * as stream from "stream"; + import * as events from "events"; + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + } + + export interface ReadStream extends stream.Readable { + close(): void; + } + export interface WriteStream extends stream.Writable { + close(): void; + bytesWritten: number; + } + + /** + * Asynchronous rename. + * @param oldPath + * @param newPath + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rename + * @param oldPath + * @param newPath + */ + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string, uid: number, gid: number): void; + export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string, mode: number): void; + export function chmodSync(path: string, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string, mode: number): void; + export function lchmodSync(path: string, mode: string): void; + export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string): Stats; + export function lstatSync(path: string): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string, dstpath: string): void; + export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; + export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string): string; + export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string, cache: { [path: string]: string }, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpathSync(path: string, cache?: { [path: string]: string }): string; + /* + * Asynchronous unlink - deletes the file specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous unlink - deletes the file specified in {path} + * + * @param path + */ + export function unlinkSync(path: string): void; + /* + * Asynchronous rmdir - removes the directory specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous rmdir - removes the directory specified in {path} + * + * @param path + */ + export function rmdirSync(path: string): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string, mode?: number): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string, mode?: string): void; + /* + * Asynchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @param callback The created folder path is passed as a string to the callback's second parameter. + */ + export function mkdtemp(prefix: string, callback?: (err: NodeJS.ErrnoException, folder: string) => void): void; + /* + * Synchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @returns Returns the created folder path. + */ + export function mkdtempSync(prefix: string): string; + export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function openSync(path: string, flags: string, mode?: number): number; + export function openSync(path: string, flags: string, mode?: string): number; + export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string, atime: number, mtime: number): void; + export function utimesSync(path: string, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number; + export function writeSync(fd: number, data: any, position?: number, enconding?: string): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + */ + export function readFileSync(filename: string, encoding: string): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; + export function exists(path: string, callback?: (exists: boolean) => void): void; + export function existsSync(path: string): boolean; + /** Constant for fs.access(). File is visible to the calling process. */ + export var F_OK: number; + /** Constant for fs.access(). File can be read by the calling process. */ + export var R_OK: number; + /** Constant for fs.access(). File can be written by the calling process. */ + export var W_OK: number; + /** Constant for fs.access(). File can be executed by the calling process. */ + export var X_OK: number; + /** Tests a user's permissions for the file specified by path. */ + export function access(path: string, callback: (err: NodeJS.ErrnoException) => void): void; + export function access(path: string, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; + /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ + export function accessSync(path: string, mode?: number): void; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + }): ReadStream; + export function createWriteStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + }): WriteStream; +} + +declare module "path" { + + /** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ + export interface ParsedPath { + /** + * The root of the path such as '/' or 'c:\' + */ + root: string; + /** + * The full directory path such as '/home/user/dir' or 'c:\path\dir' + */ + dir: string; + /** + * The file name including extension (if any) such as 'index.html' + */ + base: string; + /** + * The file extension (if any) such as '.html' + */ + ext: string; + /** + * The file name without extension (if any) such as 'index' + */ + name: string; + } + + /** + * Normalize a string path, reducing '..' and '.' parts. + * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. + * + * @param p string path to normalize. + */ + export function normalize(p: string): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: any[]): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: string[]): string; + /** + * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. + * + * Starting from leftmost {from} paramter, resolves {to} to an absolute path. + * + * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. + * + * @param pathSegments string paths to join. Non-string arguments are ignored. + */ + export function resolve(...pathSegments: any[]): string; + /** + * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. + * + * @param path path to test. + */ + export function isAbsolute(path: string): boolean; + /** + * Solve the relative path from {from} to {to}. + * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. + * + * @param from + * @param to + */ + export function relative(from: string, to: string): string; + /** + * Return the directory name of a path. Similar to the Unix dirname command. + * + * @param p the path to evaluate. + */ + export function dirname(p: string): string; + /** + * Return the last portion of a path. Similar to the Unix basename command. + * Often used to extract the file name from a fully qualified path. + * + * @param p the path to evaluate. + * @param ext optionally, an extension to remove from the result. + */ + export function basename(p: string, ext?: string): string; + /** + * Return the extension of the path, from the last '.' to end of string in the last portion of the path. + * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string + * + * @param p the path to evaluate. + */ + export function extname(p: string): string; + /** + * The platform-specific file separator. '\\' or '/'. + */ + export var sep: string; + /** + * The platform-specific file delimiter. ';' or ':'. + */ + export var delimiter: string; + /** + * Returns an object from a path string - the opposite of format(). + * + * @param pathString path to evaluate. + */ + export function parse(pathString: string): ParsedPath; + /** + * Returns a path string from an object - the opposite of parse(). + * + * @param pathString path to evaluate. + */ + export function format(pathObject: ParsedPath): string; + + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } + + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } +} + +declare module "string_decoder" { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + end(): string; + } + export var StringDecoder: { + new (encoding?: string): NodeStringDecoder; + }; +} + +declare module "tls" { + import * as crypto from "crypto"; + import * as net from "net"; + import * as stream from "stream"; + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface TlsOptions { + host?: string; + port?: number; + pfx?: any; //string or buffer + key?: any; //string or buffer + passphrase?: string; + cert?: any; + ca?: any; //string or buffer + crl?: any; //string or string array + ciphers?: string; + honorCipherOrder?: any; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; //array or Buffer; + SNICallback?: (servername: string) => any; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: string | Buffer + key?: string | Buffer + passphrase?: string; + cert?: string | Buffer + ca?: (string | Buffer)[]; + rejectUnauthorized?: boolean; + NPNProtocols?: (string | Buffer)[]; + servername?: string; + } + + export interface Server extends net.Server { + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export interface SecureContextOptions { + pfx?: string | Buffer; + key?: string | Buffer; + passphrase?: string; + cert?: string | Buffer; + ca?: string | Buffer; + crl?: string | string[] + ciphers?: string; + honorCipherOrder?: boolean; + } + + export interface SecureContext { + context: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) => void): Server; + export function connect(options: TlsOptions, secureConnectionListener?: () => void): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; +} + +declare module "crypto" { + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: string | string[]; + crl: string | string[]; + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string): Hmac; + export function createHmac(algorithm: string, key: Buffer): Hmac; + export interface Hash { + update(data: any, input_encoding?: string): Hash; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + export interface Hmac extends NodeJS.ReadWriteStream { + update(data: any, input_encoding?: string): Hmac; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + export interface Cipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: "utf8" | "ascii" | "binary"): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: "binary" | "base64" | "hex"): string; + update(data: string, input_encoding: "utf8" | "ascii" | "binary", output_encoding: "binary" | "base64" | "hex"): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + getAuthTag(): Buffer; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + export interface Decipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: "binary" | "base64" | "hex"): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: "utf8" | "ascii" | "binary"): string; + update(data: string, input_encoding: "binary" | "base64" | "hex", output_encoding: "utf8" | "ascii" | "binary"): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + setAuthTag(tag: Buffer): void; + } + export function createSign(algorithm: string): Signer; + export interface Signer extends NodeJS.WritableStream { + update(data: any): void; + sign(private_key: string, output_format: string): string; + } + export function createVerify(algorith: string): Verify; + export interface Verify extends NodeJS.WritableStream { + update(data: any): void; + verify(object: string, signature: string, signature_format?: string): boolean; + } + export function createDiffieHellman(prime_length: number): DiffieHellman; + export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; + export interface DiffieHellman { + generateKeys(encoding?: string): string; + computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; + getPrime(encoding?: string): string; + getGenerator(encoding: string): string; + getPublicKey(encoding?: string): string; + getPrivateKey(encoding?: string): string; + setPublicKey(public_key: string, encoding?: string): void; + setPrivateKey(public_key: string, encoding?: string): void; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number): Buffer; + export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export interface RsaPublicKey { + key: string; + padding?: any; + } + export interface RsaPrivateKey { + key: string; + passphrase?: string, + padding?: any; + } + export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer + export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer +} + +declare module "stream" { + import * as events from "events"; + + export class Stream extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + protected _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + objectMode?: boolean; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + protected _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + writable: boolean; + constructor(opts?: DuplexOptions); + protected _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions { } + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + protected _transform(chunk: any, encoding: string, callback: Function): void; + protected _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform { } +} + +declare module "util" { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key: string): (msg: string, ...param: any[]) => void; +} + +declare module "assert" { + function internal(value: any, message?: string): void; + namespace internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: { + message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function + }); + } + + export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export function deepStrictEqual(actual: any, expected: any, message?: string): void; + export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module "tty" { + import * as net from "net"; + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + isTTY: boolean; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + isTTY: boolean; + } +} + +declare module "domain" { + import * as events from "events"; + + export class Domain extends events.EventEmitter implements NodeJS.Domain { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + } + + export function create(): Domain; +} + +declare module "constants" { + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; + export var EDQUOT: number; + export var EMULTIHOP: number; + export var ESTALE: number; + export var O_DIRECT: number; + export var O_DIRECTORY: number; + export var O_NOCTTY: number; + export var O_NOFOLLOW: number; + export var O_NONBLOCK: number; + export var O_SYNC: number; + export var SIGALRM: number; + export var SIGBUS: number; + export var SIGCHLD: number; + export var SIGCONT: number; + export var SIGIO: number; + export var SIGIOT: number; + export var SIGPIPE: number; + export var SIGPOLL: number; + export var SIGPROF: number; + export var SIGPWR: number; + export var SIGQUIT: number; + export var SIGSTKFLT: number; + export var SIGSTOP: number; + export var SIGSYS: number; + export var SIGTRAP: number; + export var SIGTSTP: number; + export var SIGTTIN: number; + export var SIGTTOU: number; + export var SIGUNUSED: number; + export var SIGURG: number; + export var SIGUSR1: number; + export var SIGUSR2: number; + export var SIGVTALRM: number; + export var SIGXCPU: number; + export var SIGXFSZ: number; + export var S_IFBLK: number; + export var S_IFIFO: number; + export var S_IFSOCK: number; + export var S_IRGRP: number; + export var S_IROTH: number; + export var S_IRUSR: number; + export var S_IRWXG: number; + export var S_IRWXO: number; + export var S_IRWXU: number; + export var S_IWGRP: number; + export var S_IWOTH: number; + export var S_IWUSR: number; + export var S_IXGRP: number; + export var S_IXOTH: number; + export var S_IXUSR: number; + export var defaultCipherList: string; + export var defaultCoreCipherList: string; +} + +declare module "process" { + export = process; +} + +declare module "console" { + export = console; +} diff --git a/package.json b/package.json index d039396a11..a3bebe9096 100644 --- a/package.json +++ b/package.json @@ -33,5 +33,8 @@ "rimraf": "2.5.4", "tslint": "3.15.1", "typescript": "2.0.3" + }, + "dependencies": { + "bluebird": "3.4.6" } } From 4e17b60196dd67adef51dec1564842e0711d76bc Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 21 Oct 2016 17:10:12 +0300 Subject: [PATCH 009/169] Add SysInfo class --- lib/declarations.d.ts | 19 +++++++++ lib/sys-info.ts | 56 +++++++++++++++++++++++++ lib/wrappers/child-process.ts | 78 +++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 lib/declarations.d.ts create mode 100644 lib/sys-info.ts create mode 100644 lib/wrappers/child-process.ts diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts new file mode 100644 index 0000000000..e49ed13afe --- /dev/null +++ b/lib/declarations.d.ts @@ -0,0 +1,19 @@ +/** + * Describes process properties. + */ +interface IProcessInfo { + /** + * The stdout of the process. + */ + stdout: string; + + /** + * The stderr of the process. + */ + stderr: string; + + /** + * The exit code of the process. + */ + exitCode?: number; +} diff --git a/lib/sys-info.ts b/lib/sys-info.ts new file mode 100644 index 0000000000..bd27507ce6 --- /dev/null +++ b/lib/sys-info.ts @@ -0,0 +1,56 @@ +import { ChildProcess } from "./wrappers/child-process"; +import * as Promise from "bluebird"; +import * as path from "path"; + +export class SysInfo { + // Different java has different format for `java -version` command. + private static JAVA_VERSION_REGEXP = /(?:openjdk|java) version \"((?:\d+\.)+(?:\d+))/i; + + // For other versions of java javac version output is not on first line. + // Thus can't use ^ for starts with in regex. + private static JAVA_COMPILER_VERSION_REGEXP = /javac (.*)/i; + + private javaVerCache: string; + private javaCompilerVerCache: string; + + constructor(private childProcess: ChildProcess) { } + + public getJavaVersion(): Promise { + if (!this.javaVerCache) { + return new Promise((resolve, reject) => { + this.childProcess.spawnFromEvent("java", ["-version"], "exit") + .then((spawnResult) => { + this.javaVerCache = SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr)[1]; + resolve(this.javaVerCache); + }) + .catch((err) => { + this.javaVerCache = null; + resolve(this.javaVerCache); + }); + }); + } + + return Promise.resolve(this.javaVerCache); + } + + public getJavaCompilerVersion(): Promise { + if (!this.javaCompilerVerCache) { + return new Promise((resolve, reject) => { + let javaCompileExecutableName = "javac"; + let javaHome = process.env.JAVA_HOME; + let pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName; + this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`) + .then((output) => { + this.javaCompilerVerCache = output ? SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1] : null; + resolve(this.javaCompilerVerCache); + }) + .catch((err) => { + this.javaCompilerVerCache = null; + resolve(this.javaCompilerVerCache); + }); + }); + } + + return Promise.resolve(this.javaCompilerVerCache); + } +} diff --git a/lib/wrappers/child-process.ts b/lib/wrappers/child-process.ts new file mode 100644 index 0000000000..43cd554bd2 --- /dev/null +++ b/lib/wrappers/child-process.ts @@ -0,0 +1,78 @@ +import * as childProcess from "child_process"; +import * as Promise from "bluebird"; + +export class ChildProcess { + public spawnFromEvent(command: string, args: string[], event: string, options?: childProcess.SpawnOptions, ignoreError: boolean = false): Promise { + return new Promise((resolve, reject) => { + let commandChildProcess = childProcess.spawn(command, args, options); + let capturedOut = ""; + let capturedErr = ""; + + if (commandChildProcess.stdout) { + commandChildProcess.stdout.on("data", (data: string) => { + capturedOut += data; + }); + } + + if (commandChildProcess.stderr) { + commandChildProcess.stderr.on("data", (data: string) => { + capturedErr += data; + }); + } + + commandChildProcess.on(event, (arg: any) => { + let exitCode = typeof arg === "number" ? arg : arg && arg.code; + let result = { + stdout: capturedOut, + stderr: capturedErr, + exitCode: exitCode + }; + + if (ignoreError) { + resolve(result); + } else { + if (exitCode === 0) { + resolve(result); + } else { + let errorMessage = `Command ${command} failed with exit code ${exitCode}`; + if (capturedErr) { + errorMessage += ` Error output: \n ${capturedErr}`; + } + + throw new Error(errorMessage); + } + } + }); + + commandChildProcess.once("error", (err: Error) => { + if (ignoreError) { + let result = { + stdout: capturedOut, + stderr: err.message, + exitCode: (err).code + }; + resolve(result); + } else { + throw err; + } + }); + }); + } + + public exec(command: string, options?: childProcess.ExecOptions): Promise { + return new Promise((resolve, reject) => { + childProcess.exec(command, options, (err, stdout, stderr) => { + if (err) { + throw err; + } + + let result: IProcessInfo = { + stdout, + stderr + }; + + resolve(result); + }); + }); + } +} From 93a4672ebae4357ba9384d14cc4dfecfd8f5f5c7 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 21 Oct 2016 17:25:30 +0300 Subject: [PATCH 010/169] Create the initial public api --- .npmignore | 5 ++++- lib/index.ts | 19 ++++++++++++++++++- package.json | 1 + typings/nativescript-doctor.d.ts | 10 ++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 typings/nativescript-doctor.d.ts diff --git a/.npmignore b/.npmignore index 5fa806c601..187bb49a9d 100644 --- a/.npmignore +++ b/.npmignore @@ -18,6 +18,7 @@ bin/nativescript bin/*.cmd lib/**/*.ts +!lib/**/*.d.ts lib/**/*.js.map test/ @@ -27,4 +28,6 @@ scratch/ *.suo .travis.yml docs/html/ -dev/ \ No newline at end of file +dev/ + +tscommand*.tmp.txt diff --git a/lib/index.ts b/lib/index.ts index 196bd48948..0b4609fb4d 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,2 +1,19 @@ -// Entry point +import * as Promise from "bluebird"; +import { ChildProcess } from "./wrappers/child-process"; +import { SysInfo } from "./sys-info"; +let childProcess = new ChildProcess(); +let sysInfo = new SysInfo(childProcess); + +function getJavaVersion(): Promise { + return sysInfo.getJavaVersion(); +}; + +function getJavaCompilerVersion(): Promise { + return sysInfo.getJavaCompilerVersion(); +}; + +export { + getJavaVersion, + getJavaCompilerVersion +}; diff --git a/package.json b/package.json index a3bebe9096..ddb270276a 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.0.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", + "types": "./typings/nativescript-doctor.d.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts new file mode 100644 index 0000000000..4d6fe20132 --- /dev/null +++ b/typings/nativescript-doctor.d.ts @@ -0,0 +1,10 @@ +/// + +import * as Promise from "bluebird"; + +declare namespace NativeScriptDoctor { + export function getJavaVersion(): Promise; + export function getJavaCompilerVersion(): Promise; +} + +export = NativeScriptDoctor; From 839b92decdaff867b43dc75af27645a895fad6fa Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Mon, 24 Oct 2016 14:12:38 +0300 Subject: [PATCH 011/169] Add first unit tests --- lib/declarations.d.ts | 4 + package.json | 2 +- test/definitions/mocha.d.ts | 205 ++++++++++++++++++++++++++++++++++++ test/sys-info.ts | 60 +++++++++++ 4 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 test/definitions/mocha.d.ts create mode 100644 test/sys-info.ts diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index e49ed13afe..4a14d719fa 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -17,3 +17,7 @@ interface IProcessInfo { */ exitCode?: number; } + +interface IDictionary { + [key: string]: T +} diff --git a/package.json b/package.json index ddb270276a..1798db3650 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "node_modules/.bin/istanbul cover node_modules/mocha/bin/_mocha" }, "repository": { "type": "git", diff --git a/test/definitions/mocha.d.ts b/test/definitions/mocha.d.ts new file mode 100644 index 0000000000..e55dd24055 --- /dev/null +++ b/test/definitions/mocha.d.ts @@ -0,0 +1,205 @@ +// Type definitions for mocha 2.2.5 +// Project: http://mochajs.org/ +// Definitions by: Kazi Manzur Rashid , otiai10 , jt000 , Vadim Macagon +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +interface MochaSetupOptions { + //milliseconds to wait before considering a test slow + slow?: number; + + // timeout in milliseconds + timeout?: number; + + // ui name "bdd", "tdd", "exports" etc + ui?: string; + + //array of accepted globals + globals?: any[]; + + // reporter instance (function or string), defaults to `mocha.reporters.Spec` + reporter?: any; + + // bail on the first test failure + bail?: boolean; + + // ignore global leaks + ignoreLeaks?: boolean; + + // grep string or regexp to filter tests with + grep?: any; +} + +declare var mocha: Mocha; +declare var describe: Mocha.IContextDefinition; +declare var xdescribe: Mocha.IContextDefinition; +// alias for `describe` +declare var context: Mocha.IContextDefinition; +// alias for `describe` +declare var suite: Mocha.IContextDefinition; +declare var it: Mocha.ITestDefinition; +declare var xit: Mocha.ITestDefinition; +// alias for `it` +declare var test: Mocha.ITestDefinition; +declare var specify: Mocha.ITestDefinition; + +interface MochaDone { + (error?: any): any; +} + +interface ActionFunction { + (done: MochaDone): any | PromiseLike +} + +declare function setup(action: ActionFunction): void; +declare function teardown(action: ActionFunction): void; +declare function suiteSetup(action: ActionFunction): void; +declare function suiteTeardown(action: ActionFunction): void; +declare function before(action: ActionFunction): void; +declare function before(description: string, action: ActionFunction): void; +declare function after(action: ActionFunction): void; +declare function after(description: string, action: ActionFunction): void; +declare function beforeEach(action: ActionFunction): void; +declare function beforeEach(description: string, action: ActionFunction): void; +declare function afterEach(action: ActionFunction): void; +declare function afterEach(description: string, action: ActionFunction): void; + +declare class Mocha { + currentTest: Mocha.ITestDefinition; + constructor(options?: { + grep?: RegExp; + ui?: string; + reporter?: string; + timeout?: number; + bail?: boolean; + }); + + /** Setup mocha with the given options. */ + setup(options: MochaSetupOptions): Mocha; + bail(value?: boolean): Mocha; + addFile(file: string): Mocha; + /** Sets reporter by name, defaults to "spec". */ + reporter(name: string): Mocha; + /** Sets reporter constructor, defaults to mocha.reporters.Spec. */ + reporter(reporter: (runner: Mocha.IRunner, options: any) => any): Mocha; + ui(value: string): Mocha; + grep(value: string): Mocha; + grep(value: RegExp): Mocha; + invert(): Mocha; + ignoreLeaks(value: boolean): Mocha; + checkLeaks(): Mocha; + /** + * Function to allow assertion libraries to throw errors directly into mocha. + * This is useful when running tests in a browser because window.onerror will + * only receive the 'message' attribute of the Error. + */ + throwError(error: Error): void; + /** Enables growl support. */ + growl(): Mocha; + globals(value: string): Mocha; + globals(values: string[]): Mocha; + useColors(value: boolean): Mocha; + useInlineDiffs(value: boolean): Mocha; + timeout(value: number): Mocha; + slow(value: number): Mocha; + enableTimeouts(value: boolean): Mocha; + asyncOnly(value: boolean): Mocha; + noHighlighting(value: boolean): Mocha; + /** Runs tests and invokes `onComplete()` when finished. */ + run(onComplete?: (failures: number) => void): Mocha.IRunner; +} + +// merge the Mocha class declaration with a module +declare namespace Mocha { + /** Partial interface for Mocha's `Runnable` class. */ + interface IRunnable { + title: string; + fn: Function; + async: boolean; + sync: boolean; + timedOut: boolean; + } + + /** Partial interface for Mocha's `Suite` class. */ + interface ISuite { + parent: ISuite; + title: string; + + fullTitle(): string; + } + + /** Partial interface for Mocha's `Test` class. */ + interface ITest extends IRunnable { + parent: ISuite; + pending: boolean; + + fullTitle(): string; + } + + /** Partial interface for Mocha's `Runner` class. */ + interface IRunner { } + + interface IContextDefinition { + (description: string, spec: () => void): ISuite; + only(description: string, spec: () => void): ISuite; + skip(description: string, spec: () => void): void; + timeout(ms: number): void; + } + + interface ITestDefinition { + (expectation: string, assertion?: ActionFunction): ITest; + only(expectation: string, assertion?: ActionFunction): ITest; + skip(expectation: string, assertion?: ActionFunction): void; + timeout(ms: number): void; + state: "failed" | "passed"; + } + + export module reporters { + export class Base { + stats: { + suites: number; + tests: number; + passes: number; + pending: number; + failures: number; + }; + + constructor(runner: IRunner); + } + + export class Doc extends Base { } + export class Dot extends Base { } + export class HTML extends Base { } + export class HTMLCov extends Base { } + export class JSON extends Base { } + export class JSONCov extends Base { } + export class JSONStream extends Base { } + export class Landing extends Base { } + export class List extends Base { } + export class Markdown extends Base { } + export class Min extends Base { } + export class Nyan extends Base { } + export class Progress extends Base { + /** + * @param options.open String used to indicate the start of the progress bar. + * @param options.complete String used to indicate a complete test on the progress bar. + * @param options.incomplete String used to indicate an incomplete test on the progress bar. + * @param options.close String used to indicate the end of the progress bar. + */ + constructor(runner: IRunner, options?: { + open?: string; + complete?: string; + incomplete?: string; + close?: string; + }); + } + export class Spec extends Base { } + export class TAP extends Base { } + export class XUnit extends Base { + constructor(runner: IRunner, options?: any); + } + } +} + +declare module "mocha" { + export = Mocha; +} diff --git a/test/sys-info.ts b/test/sys-info.ts new file mode 100644 index 0000000000..0c9e0a896d --- /dev/null +++ b/test/sys-info.ts @@ -0,0 +1,60 @@ +import * as assert from "assert"; +import * as Promise from "bluebird"; +import * as path from "path"; +import { SysInfo } from "../lib/sys-info"; +import { ChildProcess } from "../lib/wrappers/child-process"; + +const JavaHomeName = "JAVA_HOME"; + +describe("SysInfo unit tests", () => { + let sysInfo: SysInfo; + let spawnFromEventCommand: string; + let execCommand: string; + + beforeEach(() => { + let childProcess: ChildProcess = { + spawnFromEvent: (command: string, args: string[], event: string) => { + spawnFromEventCommand = `${command} ${args.join(" ")}`; + return Promise.resolve({ stdout: "", stderr: "" }); + }, + exec: (command: string) => { + execCommand = command; + return Promise.resolve({ stdout: "", stderr: "" }); + } + }; + + sysInfo = new SysInfo(childProcess); + }); + + describe("Should execute correct commands to check for", () => { + it("java version.", (done: MochaDone) => { + sysInfo.getJavaVersion() + .then(version => { + assert.deepEqual(spawnFromEventCommand, "java -version"); + done(); + }); + }); + + it("java compiler version when there is JAVA_HOME.", (done: MochaDone) => { + let pathToJavac = path.join(process.env[JavaHomeName], "bin", "javac"); + sysInfo.getJavaCompilerVersion() + .then(version => { + assert.deepEqual(execCommand, `"${pathToJavac}" -version`); + done(); + }); + }); + + it("java compiler version when there is no JAVA_HOME.", (done: MochaDone) => { + let originalJavaHome = process.env[JavaHomeName]; + + delete process.env[JavaHomeName]; + + sysInfo.getJavaCompilerVersion() + .then(version => { + assert.deepEqual(execCommand, `"javac" -version`); + process.env[JavaHomeName] = originalJavaHome; + done(); + }); + }); + }); +}); From cdc2964a4795af0750831b99c1765bc399464dec Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Tue, 1 Nov 2016 17:47:08 +0200 Subject: [PATCH 012/169] Fix PR comments --- .npmignore | 1 - lib/declarations.d.ts | 5 + lib/definitions/bluebird.d.ts | 782 ------------------------------- lib/index.ts | 9 +- lib/sys-info.ts | 50 +- lib/wrappers/child-process.ts | 24 +- package.json | 5 +- test/definitions/mocha.d.ts | 205 -------- test/sys-info.ts | 50 +- tsconfig.json | 2 +- typings/nativescript-doctor.d.ts | 6 +- 11 files changed, 65 insertions(+), 1074 deletions(-) delete mode 100644 lib/definitions/bluebird.d.ts delete mode 100644 test/definitions/mocha.d.ts diff --git a/.npmignore b/.npmignore index 187bb49a9d..48802e3bd6 100644 --- a/.npmignore +++ b/.npmignore @@ -18,7 +18,6 @@ bin/nativescript bin/*.cmd lib/**/*.ts -!lib/**/*.d.ts lib/**/*.js.map test/ diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 4a14d719fa..042adddbb5 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -18,6 +18,11 @@ interface IProcessInfo { exitCode?: number; } +interface ISpawnFromEventOptions { + spawnOptions?: any; + ignoreError?: boolean; +} + interface IDictionary { [key: string]: T } diff --git a/lib/definitions/bluebird.d.ts b/lib/definitions/bluebird.d.ts deleted file mode 100644 index 32b41af4fe..0000000000 --- a/lib/definitions/bluebird.d.ts +++ /dev/null @@ -1,782 +0,0 @@ -// Type definitions for bluebird 3.0.0 -// Project: https://github.com/petkaantonov/bluebird -// Definitions by: Leonard Hecker -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -/*! - * The code following this comment originates from: - * https://github.com/types/npm-bluebird - * - * Licensed under: - * The MIT License (MIT) - * - * Copyright (c) 2016 unional - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// Generated by typings -// Source: bluebird.d.ts -declare module 'bluebird' { - // Type definitions for Bluebird v3.x.x - // Project: http://bluebirdjs.com - - class Bluebird implements Bluebird.Thenable, Bluebird.Inspection { - /** - * Create a new promise. The passed in function will receive functions `resolve` and `reject` as its arguments which can be called to seal the fate of the created promise. - * If promise cancellation is enabled, passed in function will receive one more function argument `onCancel` that allows to register an optional cancellation callback. - */ - constructor(callback: (resolve: (thenableOrResult?: R | Bluebird.Thenable) => void, reject: (error?: any) => void, onCancel?: (callback: () => void) => void) => void); - - /** - * Promises/A+ `.then()`. Returns a new promise chained from this promise. The new promise will be rejected or resolved dedefer on the passed `fulfilledHandler`, `rejectedHandler` and the state of this promise. - */ - then(onFulfill: (value: R) => U1 | Bluebird.Thenable, onReject: (error: any) => U2 | Bluebird.Thenable): Bluebird; - then(onFulfill: (value: R) => U | Bluebird.Thenable, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; - then(onFulfill: (value: R) => U | Bluebird.Thenable): Bluebird; - then(): Bluebird; - - /** - * This is a catch-all exception handler, shortcut for calling `.then(null, handler)` on this promise. Any exception happening in a `.then`-chain will propagate to nearest `.catch` handler. - * - * Alias `.caught();` for compatibility with earlier ECMAScript version. - */ - catch(onReject?: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - caught(onReject?: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - catch(onReject?: (error: any) => U | Bluebird.Thenable): Bluebird; - caught(onReject?: (error: any) => U | Bluebird.Thenable): Bluebird; - - /** - * This extends `.catch` to work more like catch-clauses in languages like Java or C#. Instead of manually checking `instanceof` or `.name === "SomeError"`, you may specify a number of error constructors which are eligible for this catch handler. The catch handler that is first met that has eligible constructors specified, is the one that will be called. - * - * This method also supports predicate-based filters. If you pass a predicate function instead of an error constructor, the predicate will receive the error as an argument. The return result of the predicate will be used determine whether the error handler should be called. - * - * Alias `.caught();` for compatibility with earlier ECMAScript version. - */ - catch(predicate: (error: any) => boolean, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - caught(predicate: (error: any) => boolean, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - catch(predicate: (error: any) => boolean, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; - caught(predicate: (error: any) => boolean, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; - catch(ErrorClass: Function, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - caught(ErrorClass: Function, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - catch(ErrorClass: Function, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; - caught(ErrorClass: Function, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; - catch(predicate: Object, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - caught(predicate: Object, onReject: (error: any) => R | Bluebird.Thenable | void | Bluebird.Thenable): Bluebird; - catch(predicate: Object, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; - caught(predicate: Object, onReject: (error: any) => U | Bluebird.Thenable): Bluebird; - - /** - * Like `.catch` but instead of catching all types of exceptions, it only catches those that don't originate from thrown errors but rather from explicit rejections. - */ - error(onReject: (reason: any) => U | Bluebird.Thenable): Bluebird; - - /** - * Pass a handler that will be called regardless of this promise's fate. Returns a new promise chained from this promise. There are special semantics for `.finally()` in that the final value cannot be modified from the handler. - * - * Alias `.lastly();` for compatibility with earlier ECMAScript version. - */ - finally(handler: () => U | Bluebird.Thenable): Bluebird; - - lastly(handler: () => U | Bluebird.Thenable): Bluebird; - - /** - * Create a promise that follows this promise, but is bound to the given `thisArg` value. A bound promise will call its handlers with the bound value set to `this`. Additionally promises derived from a bound promise will also be bound promises with the same `thisArg` binding as the original promise. - */ - bind(thisArg: any): Bluebird; - - /** - * Like `.then()`, but any unhandled rejection that ends up here will be thrown as an error. - */ - done(onFulfilled?: (value: R) => U | Bluebird.Thenable, onRejected?: (error: any) => U | Bluebird.Thenable): void; - - /** - * Like `.finally()`, but not called for rejections. - */ - tap(onFulFill: (value: R) => Bluebird.Thenable): Bluebird; - tap(onFulfill: (value: R) => U): Bluebird; - - /** - * Same as calling `Promise.delay(ms, this)`. - */ - delay(ms: number): Bluebird; - - /** - * Returns a promise that will be fulfilled with this promise's fulfillment value or rejection reason. - * However, if this promise is not fulfilled or rejected within ms milliseconds, the returned promise - * is rejected with a TimeoutError or the error as the reason. - * - * You may specify a custom error message with the `message` parameter. - */ - timeout(ms: number, message?: string | Error): Bluebird; - - /** - * Register a node-style callback on this promise. When this promise is is either fulfilled or rejected, the node callback will be called back with the node.js convention where error reason is the first argument and success value is the second argument. The error argument will be `null` in case of success. - * If the `callback` argument is not a function, this method does not do anything. - */ - nodeify(callback: (err: any, value?: R) => void, options?: Bluebird.SpreadOption): this; - nodeify(...sink: any[]): this; - asCallback(callback: (err: any, value?: R) => void, options?: Bluebird.SpreadOption): this; - asCallback(...sink: any[]): this; - - /** - * See if this `promise` has been fulfilled. - */ - isFulfilled(): boolean; - - /** - * See if this `promise` has been rejected. - */ - isRejected(): boolean; - - /** - * See if this `promise` is still defer. - */ - isPending(): boolean; - - /** - * See if this `promise` has been cancelled. - */ - isCancelled(): boolean; - - /** - * See if this `promise` is resolved -> either fulfilled or rejected. - */ - isResolved(): boolean; - - /** - * Get the fulfillment value of the underlying promise. Throws if the promise isn't fulfilled yet. - * - * throws `TypeError` - */ - value(): R; - - /** - * Get the rejection reason for the underlying promise. Throws if the promise isn't rejected yet. - * - * throws `TypeError` - */ - reason(): any; - - /** - * Synchronously inspect the state of this `promise`. The `PromiseInspection` will represent the state of - * the promise as snapshotted at the time of calling `.reflect()`. - */ - reflect(): Bluebird>; - reflect(): Bluebird>; - - /** - * This is a convenience method for doing: - * - * - * promise.then(function(obj){ - * return obj[propertyName].call(obj, arg...); - * }); - * - */ - call(propertyName: string, ...args: any[]): Bluebird; - - /** - * This is a convenience method for doing: - * - * - * promise.then(function(obj){ - * return obj[propertyName]; - * }); - * - */ - // TODO: Use "type property type" once it's there - // @see https://github.com/Microsoft/TypeScript/issues/1295 - get(key: string | number): Bluebird; - - /** - * Convenience method for: - * - * - * .then(function() { - * return value; - * }); - * - * - * in the case where `value` doesn't change its value. That means `value` is bound at the time of calling `.return()` - * - * Alias `.thenReturn();` for compatibility with earlier ECMAScript version. - */ - return(): Bluebird; - thenReturn(): Bluebird; - return(value: U): Bluebird; - thenReturn(value: U): Bluebird; - - /** - * Convenience method for: - * - * - * .then(function() { - * throw reason; - * }); - * - * Same limitations apply as with `.return()`. - * - * Alias `.thenThrow();` for compatibility with earlier ECMAScript version. - */ - throw(reason: Error): Bluebird; - thenThrow(reason: Error): Bluebird; - - /** - * Convert to String. - */ - toString(): string; - - /** - * This is implicitly called by `JSON.stringify` when serializing the object. Returns a serialized representation of the `Promise`. - */ - toJSON(): Object; - - /** - * Like calling `.then`, but the fulfillment value or rejection reason is assumed to be an array, which is flattened to the formal parameters of the handlers. - */ - spread(fulfilledHandler: (...values: W[]) => U | Bluebird.Thenable): Bluebird; - spread(fulfilledHandler: Function): Bluebird; - - /** - * Same as calling `Promise.all(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - all(): Bluebird; - - /** - * Same as calling `Promise.props(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO how to model instance.props()? - props(): Bluebird; - - /** - * Same as calling `Promise.any(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - any(): Bluebird; - - /** - * Same as calling `Promise.some(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - some(count: number): Bluebird; - - /** - * Same as calling `Promise.race(thisPromise, count)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - race(): Bluebird; - - /** - * Same as calling `Bluebird.map(thisPromise, mapper)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - map(mapper: (item: Q, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; - - /** - * Same as calling `Promise.reduce(thisPromise, Function reducer, initialValue)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - reduce(reducer: (memo: U, item: Q, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; - - /** - * Same as calling ``Promise.filter(thisPromise, filterer)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - filter(filterer: (item: U, index: number, arrayLength: number) => boolean | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; - - /** - * Same as calling ``Bluebird.each(thisPromise, iterator)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - each(iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; - - /** - * Same as calling ``Bluebird.mapSeries(thisPromise, iterator)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - mapSeries(iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; - - /** - * Cancel this `promise`. Will not do anything if this promise is already settled or if the cancellation feature has not been enabled - */ - cancel(): void; - - /** - * Basically sugar for doing: somePromise.catch(function(){}); - * - * Which is needed in case error handlers are attached asynchronously to the promise later, which would otherwise result in premature unhandled rejection reporting. - */ - suppressUnhandledRejections(): void; - - /** - * Start the chain of promises with `Promise.try`. Any synchronous exceptions will be turned into rejections on the returned promise. - * - * Note about second argument: if it's specifically a true array, its values become respective arguments for the function call. Otherwise it is passed as is as the first argument for the function call. - * - * Alias for `attempt();` for compatibility with earlier ECMAScript version. - */ - static try(fn: () => R | Bluebird.Thenable): Bluebird; - static attempt(fn: () => R | Bluebird.Thenable): Bluebird; - - /** - * Returns a new function that wraps the given function `fn`. The new function will always return a promise that is fulfilled with the original functions return values or rejected with thrown exceptions from the original function. - * This method is convenient when a function can sometimes return synchronously or throw synchronously. - */ - static method(fn: Function): Function; - - /** - * Create a promise that is resolved with the given `value`. If `value` is a thenable or promise, the returned promise will assume its state. - */ - static resolve(): Bluebird; - static resolve(value: R | Bluebird.Thenable): Bluebird; - - /** - * Create a promise that is rejected with the given `reason`. - */ - static reject(reason: any): Bluebird; - static reject(reason: any): Bluebird; - - /** - * Create a promise with undecided fate and return a `PromiseResolver` to control it. See resolution?: Promise(#promise-resolution). - */ - static defer(): Bluebird.Resolver; - - /** - * Cast the given `value` to a trusted promise. If `value` is already a trusted `Promise`, it is returned as is. If `value` is not a thenable, a fulfilled is: Promise returned with `value` as its fulfillment value. If `value` is a thenable (Promise-like object, like those returned by jQuery's `$.ajax`), returns a trusted that: Promise assimilates the state of the thenable. - */ - static cast(value: R | Bluebird.Thenable): Bluebird; - - /** - * Sugar for `Promise.resolve(undefined).bind(thisArg);`. See `.bind()`. - */ - static bind(thisArg: any): Bluebird; - - /** - * See if `value` is a trusted Promise. - */ - static is(value: any): boolean; - - /** - * Call this right after the library is loaded to enabled long stack traces. Long stack traces cannot be disabled after being enabled, and cannot be enabled after promises have already been created. Long stack traces imply a substantial performance penalty, around 4-5x for throughput and 0.5x for latency. - */ - static longStackTraces(): void; - - /** - * Returns a promise that will be resolved with value (or undefined) after given ms milliseconds. - * If value is a promise, the delay will start counting down when it is fulfilled and the returned - * promise will be fulfilled with the fulfillment value of the value promise. - */ - static delay(ms: number, value: R | Bluebird.Thenable): Bluebird; - static delay(ms: number): Bluebird; - - /** - * Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. - * - * If the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be an array of them. - * - * If you pass a `receiver`, the `nodeFunction` will be called as a method on the `receiver`. - */ - static promisify(func: (callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): () => Bluebird; - static promisify(func: (arg1: A1, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1) => Bluebird; - static promisify(func: (arg1: A1, arg2: A2, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2) => Bluebird; - static promisify(func: (arg1: A1, arg2: A2, arg3: A3, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2, arg3: A3) => Bluebird; - static promisify(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2, arg3: A3, arg4: A4) => Bluebird; - static promisify(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5, callback: (err: any, result: T) => void) => void, options?: Bluebird.PromisifyOptions): (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5) => Bluebird; - static promisify(nodeFunction: Function, options?: Bluebird.PromisifyOptions): Function; - - /** - * Promisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain. The promisified method name will be the original method name postfixed with `Async`. Returns the input object. - * - * Note that the original methods on the object are not overwritten but new methods are created with the `Async`-postfix. For example, if you `promisifyAll()` the node.js `fs` object use `fs.statAsync()` to call the promisified `stat` method. - */ - // TODO how to model promisifyAll? - static promisifyAll(target: Object, options?: Bluebird.PromisifyAllOptions): Object; - - /** - * Returns a promise that is resolved by a node style callback function. - */ - static fromNode(resolver: (callback: (err: any, result?: any) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; - static fromNode(resolver: (callback: (err: any, result?: T) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; - static fromCallback(resolver: (callback: (err: any, result?: any) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; - static fromCallback(resolver: (callback: (err: any, result?: T) => void) => void, options?: Bluebird.FromNodeOptions): Bluebird; - - /** - * Returns a function that can use `yield` to run asynchronous code synchronously. This feature requires the support of generators which are drafted in the next version of the language. Node version greater than `0.11.2` is required and needs to be executed with the `--harmony-generators` (or `--harmony`) command-line switch. - */ - // TODO fix coroutine GeneratorFunction - static coroutine(generatorFunction: Function): Function; - - /** - * Add `handler` as the handler to call when there is a possibly unhandled rejection. The default handler logs the error stack to stderr or `console.error` in browsers. - * - * Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections. - */ - static onPossiblyUnhandledRejection(handler: (reason: any) => any): void; - - /** - * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled when all the items in the array are fulfilled. The promise's fulfillment value is an array with fulfillment values at respective positions to the original array. If any promise in the array rejects, the returned promise is rejected with the rejection reason. - */ - // TODO enable more overloads - // array with promises of different types - static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2, Bluebird.Thenable | T3, Bluebird.Thenable | T4, Bluebird.Thenable | T5]): Bluebird<[T1, T2, T3, T4, T5]>; - static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2, Bluebird.Thenable | T3, Bluebird.Thenable | T4]): Bluebird<[T1, T2, T3, T4]>; - static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2, Bluebird.Thenable | T3]): Bluebird<[T1, T2, T3]>; - static all(values: [Bluebird.Thenable | T1, Bluebird.Thenable | T2]): Bluebird<[T1, T2]>; - static all(values: [Bluebird.Thenable | T1]): Bluebird<[T1]>; - // array with values - static all(values: Bluebird.Thenable<(Bluebird.Thenable | R)[]> | (Bluebird.Thenable | R)[]): Bluebird; - - /** - * Like ``Promise.all`` but for object properties instead of array items. Returns a promise that is fulfilled when all the properties of the object are fulfilled. The promise's fulfillment value is an object with fulfillment values at respective keys to the original object. If any promise in the object rejects, the returned promise is rejected with the rejection reason. - * - * If `object` is a trusted `Promise`, then it will be treated as a promise for object rather than for its properties. All other objects are treated for their properties as is returned by `Object.keys` - the object's own enumerable properties. - * - * *The original object is not modified.* - */ - // TODO verify this is correct - // trusted promise for object - static props(object: Bluebird): Bluebird; - // object - static props(object: Object): Bluebird; - - /** - * Like `Promise.some()`, with 1 as `count`. However, if the promise fulfills, the fulfillment value is not an array of 1 but the value directly. - */ - static any(values: Bluebird.Thenable<(Bluebird.Thenable | R)[]> | (Bluebird.Thenable | R)[]): Bluebird; - - /** - * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled or rejected as soon as a promise in the array is fulfilled or rejected with the respective rejection reason or fulfillment value. - * - * **Note** If you pass empty array or a sparse array with no values, or a promise/thenable for such, it will be forever pending. - */ - static race(values: Bluebird.Thenable<(Bluebird.Thenable | R)[]> | (Bluebird.Thenable | R)[]): Bluebird; - - /** - * Initiate a competetive race between multiple promises or values (values will become immediately fulfilled promises). When `count` amount of promises have been fulfilled, the returned promise is fulfilled with an array that contains the fulfillment values of the winners in order of resolution. - * - * If too many promises are rejected so that the promise can never become fulfilled, it will be immediately rejected with an array of rejection reasons in the order they were thrown in. - * - * *The original array is not modified.* - */ - // promise of array with promises of value - static some(values: Bluebird.Thenable[]>, count: number): Bluebird; - // promise of array with values - static some(values: Bluebird.Thenable, count: number): Bluebird; - // array with promises of value - static some(values: Bluebird.Thenable[], count: number): Bluebird; - // array with values - static some(values: R[], count: number): Bluebird; - - /** - * Promise.join( - * Promise|any values..., - * function handler - * ) -> Promise - * For coordinating multiple concurrent discrete promises. - * - * Note: In 1.x and 0.x Promise.join used to be a Promise.all that took the values in as arguments instead in an array. This behavior has been deprecated but is still supported partially - when the last argument is an immediate function value the new semantics will apply - */ - static join(arg1: A1 | Bluebird.Thenable, handler: (arg1?: A1) => R | Bluebird.Thenable): Bluebird; - static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2) => R | Bluebird.Thenable): Bluebird; - static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, arg3: A3 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2, arg3?: A3) => R | Bluebird.Thenable): Bluebird; - static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, arg3: A3 | Bluebird.Thenable, arg4: A4 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2, arg3?: A3, arg4?: A4) => R | Bluebird.Thenable): Bluebird; - static join(arg1: A1 | Bluebird.Thenable, arg2: A2 | Bluebird.Thenable, arg3: A3 | Bluebird.Thenable, arg4: A4 | Bluebird.Thenable, arg5: A5 | Bluebird.Thenable, handler: (arg1?: A1, arg2?: A2, arg3?: A3, arg4?: A4, arg5?: A5) => R | Bluebird.Thenable): Bluebird; - - // variadic array - /** @deprecated use .all instead */ - static join(...values: (R | Bluebird.Thenable)[]): Bluebird; - - /** - * Map an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `mapper` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. - * - * If the `mapper` function returns promises or thenables, the returned promise will wait for all the mapped results to be resolved as well. - * - * *The original array is not modified.* - */ - // promise of array with promises of value - static map(values: Bluebird.Thenable[]>, mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; - - // promise of array with values - static map(values: Bluebird.Thenable, mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; - - // array with promises of value - static map(values: Bluebird.Thenable[], mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; - - // array with values - static map(values: R[], mapper: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable, options?: Bluebird.ConcurrencyOption): Bluebird; - - /** - * Reduce an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `reducer` function with the signature `(total, current, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. - * - * If the reducer function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration. - * - * *The original array is not modified. If no `intialValue` is given and the array doesn't contain at least 2 items, the callback will not be called and `undefined` is returned. If `initialValue` is given and the array doesn't have at least 1 item, `initialValue` is returned.* - */ - // promise of array with promises of value - static reduce(values: Bluebird.Thenable[]>, reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; - - // promise of array with values - static reduce(values: Bluebird.Thenable, reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; - - // array with promises of value - static reduce(values: Bluebird.Thenable[], reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; - - // array with values - static reduce(values: R[], reducer: (total: U, current: R, index: number, arrayLength: number) => U | Bluebird.Thenable, initialValue?: U): Bluebird; - - /** - * Filter an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `filterer` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. - * - * The return values from the filtered functions are coerced to booleans, with the exception of promises and thenables which are awaited for their eventual result. - * - * *The original array is not modified. - */ - // promise of array with promises of value - static filter(values: Bluebird.Thenable[]>, filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; - - // promise of array with values - static filter(values: Bluebird.Thenable, filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; - - // array with promises of value - static filter(values: Bluebird.Thenable[], filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; - - // array with values - static filter(values: R[], filterer: (item: R, index: number, arrayLength: number) => boolean | Bluebird.Thenable, option?: Bluebird.ConcurrencyOption): Bluebird; - - /** - * Iterate over an array, or a promise of an array, which contains promises (or a mix of promises and values) with the given iterator function with the signature (item, index, value) where item is the resolved value of a respective promise in the input array. Iteration happens serially. If any promise in the input array is rejected the returned promise is rejected as well. - * - * Resolves to the original array unmodified, this method is meant to be used for side effects. If the iterator function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration. - */ - // promise of array with promises of value - static each(values: Bluebird.Thenable[]>, iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; - // array with promises of value - static each(values: Bluebird.Thenable[], iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; - // array with values OR promise of array with values - static each(values: R[] | Bluebird.Thenable, iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; - - /** - * Given an Iterable(arrays are Iterable), or a promise of an Iterable, which produces promises (or a mix of promises and values), iterate over all the values in the Iterable into an array and iterate over the array serially, in-order. - * - * Returns a promise for an array that contains the values returned by the iterator function in their respective positions. The iterator won't be called for an item until its previous item, and the promise returned by the iterator for that item are fulfilled. This results in a mapSeries kind of utility but it can also be used simply as a side effect iterator similar to Array#forEach. - * - * If any promise in the input array is rejected or any promise returned by the iterator function is rejected, the result will be rejected as well. - */ - static mapSeries(values: (R | Bluebird.Thenable)[] | Bluebird.Thenable<(R | Bluebird.Thenable)[]>, iterator: (item: R, index: number, arrayLength: number) => U | Bluebird.Thenable): Bluebird; - - /** - * A meta method used to specify the disposer method that cleans up a resource when using `Promise.using`. - * - * Returns a Disposer object which encapsulates both the resource as well as the method to clean it up. - * The user can pass this object to `Promise.using` to get access to the resource when it becomes available, - * as well as to ensure its automatically cleaned up. - * - * The second argument passed to a disposer is the result promise of the using block, which you can - * inspect synchronously. - */ - disposer(disposeFn: (arg: R, promise: Bluebird) => void | Bluebird.Thenable): Bluebird.Disposer; - - /** - * In conjunction with `.disposer`, using will make sure that no matter what, the specified disposer - * will be called when the promise returned by the callback passed to using has settled. The disposer is - * necessary because there is no standard interface in node for disposing resources. - */ - static using(disposer: Bluebird.Disposer, executor: (transaction: R) => Bluebird.Thenable): Bluebird; - static using(disposer: Bluebird.Disposer, disposer2: Bluebird.Disposer, executor: (transaction1: R1, transaction2: R2) => Bluebird.Thenable): Bluebird; - static using(disposer: Bluebird.Disposer, disposer2: Bluebird.Disposer, disposer3: Bluebird.Disposer, executor: (transaction1: R1, transaction2: R2, transaction3: R3) => Bluebird.Thenable): Bluebird; - - /** - * Add handler as the handler to call when there is a possibly unhandled rejection. - * The default handler logs the error stack to stderr or console.error in browsers. - * - * Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections. - * - * Note: this hook is specific to the bluebird instance its called on, application developers should use global rejection events. - */ - static onPossiblyUnhandledRejection(handler?: (error: Error, promise: Bluebird) => void): void; - - /** - * Configure long stack traces, warnings, monitoring and cancellation. - * Note that even though false is the default here, a development environment might be detected which automatically - * enables long stack traces and warnings. - */ - static config(options: { - /** Enable warnings */ - warnings?: boolean | { - /** Enables all warnings except forgotten return statements. */ - wForgottenReturn: boolean; - }; - /** Enable long stack traces */ - longStackTraces?: boolean; - /** Enable cancellation */ - cancellation?: boolean; - /** Enable monitoring */ - monitoring?: boolean; - }): void; - } - - namespace Bluebird { - export interface ConcurrencyOption { - concurrency: number; - } - export interface SpreadOption { - spread: boolean; - } - export interface FromNodeOptions { - multiArgs?: boolean; - } - export interface PromisifyOptions { - context?: any; - multiArgs?: boolean; - } - export interface PromisifyAllOptions extends PromisifyOptions { - suffix?: string; - filter?: (name: string, func: Function, target?: any, passesDefaultFilter?: boolean) => boolean; - // The promisifier gets a reference to the original method and should return a function which returns a promise - promisifier?: (originalMethod: Function) => () => Thenable; - } - - /** - * Represents an error is an explicit promise rejection as opposed to a thrown error. - * For example, if an error is errbacked by a callback API promisified through undefined or undefined - * and is not a typed error, it will be converted to a `OperationalError` which has the original error in - * the `.cause` property. - * - * `OperationalError`s are caught in `.error` handlers. - */ - export class OperationalError extends Error { } - - /** - * Signals that an operation has timed out. Used as a custom cancellation reason in `.timeout`. - */ - export class TimeoutError extends Error { } - - /** - * Signals that an operation has been aborted or cancelled. The default reason used by `.cancel`. - */ - export class CancellationError extends Error { } - - /** - * A collection of errors. `AggregateError` is an array-like object, with numeric indices and a `.length` property. - * It supports all generic array methods such as `.forEach` directly. - * - * `AggregateError`s are caught in `.error` handlers, even if the contained errors are not operational. - * - * `Promise.some` and `Promise.any` use `AggregateError` as rejection reason when they fail. - */ - export class AggregateError extends Error { } - - /** - * returned by `Bluebird.disposer()`. - */ - export class Disposer { - } - - export interface Thenable { - then(onFulfilled: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Thenable; - then(onFulfilled: (value: R) => U | Thenable, onRejected?: (error: any) => void | Thenable): Thenable; - } - - export interface Resolver { - /** - * Returns a reference to the controlled promise that can be passed to clients. - */ - promise: Bluebird; - - /** - * Resolve the underlying promise with `value` as the resolution value. If `value` is a thenable or a promise, the underlying promise will assume its state. - */ - resolve(value: R): void; - resolve(): void; - - /** - * Reject the underlying promise with `reason` as the rejection reason. - */ - reject(reason: any): void; - - /** - * Gives you a callback representation of the `PromiseResolver`. Note that this is not a method but a property. The callback accepts error object in first argument and success values on the 2nd parameter and the rest, I.E. node js conventions. - * - * If the the callback is called with multiple success values, the resolver fullfills its promise with an array of the values. - */ - // TODO specify resolver callback - callback: (err: any, value: R, ...values: R[]) => void; - } - - export interface Inspection { - /** - * See if the underlying promise was fulfilled at the creation time of this inspection object. - */ - isFulfilled(): boolean; - - /** - * See if the underlying promise was rejected at the creation time of this inspection object. - */ - isRejected(): boolean; - - /** - * See if the underlying promise was cancelled at the creation time of this inspection object. - */ - isCancelled(): boolean; - - /** - * See if the underlying promise was defer at the creation time of this inspection object. - */ - isPending(): boolean; - - /** - * Get the fulfillment value of the underlying promise. Throws if the promise wasn't fulfilled at the creation time of this inspection object. - * - * throws `TypeError` - */ - value(): R; - - /** - * Get the rejection reason for the underlying promise. Throws if the promise wasn't rejected at the creation time of this inspection object. - * - * throws `TypeError` - */ - reason(): any; - } - - /** - * Returns a new independent copy of the Bluebird library. - * - * This method should be used before you use any of the methods which would otherwise alter the global Bluebird object - to avoid polluting global state. - */ - export function getNewLibraryCopy(): typeof Bluebird; - - /** - * This is relevant to browser environments with no module loader. - * - * Release control of the Promise namespace to whatever it was before this library was loaded. Returns a reference to the library namespace so you can attach it to something else. - */ - export function noConflict(): typeof Bluebird; - - /** - * Changes how bluebird schedules calls a-synchronously. - * - * @param scheduler Should be a function that asynchronously schedules - * the calling of the passed in function - */ - export function setScheduler(scheduler: (callback: (...args: any[]) => void) => void): void; - } - - export = Bluebird; -} diff --git a/lib/index.ts b/lib/index.ts index 0b4609fb4d..dbac53f416 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,15 +1,14 @@ -import * as Promise from "bluebird"; import { ChildProcess } from "./wrappers/child-process"; import { SysInfo } from "./sys-info"; -let childProcess = new ChildProcess(); -let sysInfo = new SysInfo(childProcess); +const childProcess = new ChildProcess(); +const sysInfo = new SysInfo(childProcess); -function getJavaVersion(): Promise { +const getJavaVersion = (): Promise => { return sysInfo.getJavaVersion(); }; -function getJavaCompilerVersion(): Promise { +const getJavaCompilerVersion = (): Promise => { return sysInfo.getJavaCompilerVersion(); }; diff --git a/lib/sys-info.ts b/lib/sys-info.ts index bd27507ce6..dd42a8bd85 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -1,56 +1,40 @@ import { ChildProcess } from "./wrappers/child-process"; -import * as Promise from "bluebird"; import * as path from "path"; export class SysInfo { // Different java has different format for `java -version` command. private static JAVA_VERSION_REGEXP = /(?:openjdk|java) version \"((?:\d+\.)+(?:\d+))/i; - // For other versions of java javac version output is not on first line. - // Thus can't use ^ for starts with in regex. - private static JAVA_COMPILER_VERSION_REGEXP = /javac (.*)/i; + private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im; private javaVerCache: string; private javaCompilerVerCache: string; constructor(private childProcess: ChildProcess) { } - public getJavaVersion(): Promise { + public async getJavaVersion(): Promise { if (!this.javaVerCache) { - return new Promise((resolve, reject) => { - this.childProcess.spawnFromEvent("java", ["-version"], "exit") - .then((spawnResult) => { - this.javaVerCache = SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr)[1]; - resolve(this.javaVerCache); - }) - .catch((err) => { - this.javaVerCache = null; - resolve(this.javaVerCache); - }); - }); + const spawnResult = await this.childProcess.spawnFromEvent("java", ["-version"], "exit", { ignoreError: true }); + const matches = spawnResult && SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr); + this.javaVerCache = matches && matches[1]; } - return Promise.resolve(this.javaVerCache); + return this.javaVerCache; } - public getJavaCompilerVersion(): Promise { + public async getJavaCompilerVersion(): Promise { if (!this.javaCompilerVerCache) { - return new Promise((resolve, reject) => { - let javaCompileExecutableName = "javac"; - let javaHome = process.env.JAVA_HOME; - let pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName; - this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`) - .then((output) => { - this.javaCompilerVerCache = output ? SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1] : null; - resolve(this.javaCompilerVerCache); - }) - .catch((err) => { - this.javaCompilerVerCache = null; - resolve(this.javaCompilerVerCache); - }); - }); + const javaCompileExecutableName = "javac"; + const javaHome = process.env.JAVA_HOME; + const pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName; + try { + const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`); + this.javaCompilerVerCache = SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1]; + } catch (err) { + this.javaCompilerVerCache = null; + } } - return Promise.resolve(this.javaCompilerVerCache); + return this.javaCompilerVerCache; } } diff --git a/lib/wrappers/child-process.ts b/lib/wrappers/child-process.ts index 43cd554bd2..15b7321187 100644 --- a/lib/wrappers/child-process.ts +++ b/lib/wrappers/child-process.ts @@ -1,10 +1,10 @@ import * as childProcess from "child_process"; -import * as Promise from "bluebird"; export class ChildProcess { - public spawnFromEvent(command: string, args: string[], event: string, options?: childProcess.SpawnOptions, ignoreError: boolean = false): Promise { + public spawnFromEvent(command: string, args: string[], event: string, options?: ISpawnFromEventOptions): Promise { return new Promise((resolve, reject) => { - let commandChildProcess = childProcess.spawn(command, args, options); + options = options || {}; + const commandChildProcess = childProcess.spawn(command, args, options.spawnOptions); let capturedOut = ""; let capturedErr = ""; @@ -21,14 +21,14 @@ export class ChildProcess { } commandChildProcess.on(event, (arg: any) => { - let exitCode = typeof arg === "number" ? arg : arg && arg.code; - let result = { + const exitCode = typeof arg === "number" ? arg : arg && arg.code; + const result = { stdout: capturedOut, stderr: capturedErr, exitCode: exitCode }; - if (ignoreError) { + if (options.ignoreError) { resolve(result); } else { if (exitCode === 0) { @@ -39,21 +39,21 @@ export class ChildProcess { errorMessage += ` Error output: \n ${capturedErr}`; } - throw new Error(errorMessage); + reject(errorMessage); } } }); commandChildProcess.once("error", (err: Error) => { - if (ignoreError) { - let result = { + if (options.ignoreError) { + const result = { stdout: capturedOut, stderr: err.message, exitCode: (err).code }; resolve(result); } else { - throw err; + reject(err); } }); }); @@ -63,10 +63,10 @@ export class ChildProcess { return new Promise((resolve, reject) => { childProcess.exec(command, options, (err, stdout, stderr) => { if (err) { - throw err; + reject(err); } - let result: IProcessInfo = { + const result: IProcessInfo = { stdout, stderr }; diff --git a/package.json b/package.json index 1798db3650..aa60c38612 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "homepage": "https://github.com/NativeScript/nativescript-doctor#readme", "devDependencies": { + "@types/mocha": "2.2.32", "grunt": "1.0.1", "grunt-contrib-clean": "1.0.0", "grunt-contrib-watch": "1.0.0", @@ -35,7 +36,5 @@ "tslint": "3.15.1", "typescript": "2.0.3" }, - "dependencies": { - "bluebird": "3.4.6" - } + "dependencies": {} } diff --git a/test/definitions/mocha.d.ts b/test/definitions/mocha.d.ts deleted file mode 100644 index e55dd24055..0000000000 --- a/test/definitions/mocha.d.ts +++ /dev/null @@ -1,205 +0,0 @@ -// Type definitions for mocha 2.2.5 -// Project: http://mochajs.org/ -// Definitions by: Kazi Manzur Rashid , otiai10 , jt000 , Vadim Macagon -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -interface MochaSetupOptions { - //milliseconds to wait before considering a test slow - slow?: number; - - // timeout in milliseconds - timeout?: number; - - // ui name "bdd", "tdd", "exports" etc - ui?: string; - - //array of accepted globals - globals?: any[]; - - // reporter instance (function or string), defaults to `mocha.reporters.Spec` - reporter?: any; - - // bail on the first test failure - bail?: boolean; - - // ignore global leaks - ignoreLeaks?: boolean; - - // grep string or regexp to filter tests with - grep?: any; -} - -declare var mocha: Mocha; -declare var describe: Mocha.IContextDefinition; -declare var xdescribe: Mocha.IContextDefinition; -// alias for `describe` -declare var context: Mocha.IContextDefinition; -// alias for `describe` -declare var suite: Mocha.IContextDefinition; -declare var it: Mocha.ITestDefinition; -declare var xit: Mocha.ITestDefinition; -// alias for `it` -declare var test: Mocha.ITestDefinition; -declare var specify: Mocha.ITestDefinition; - -interface MochaDone { - (error?: any): any; -} - -interface ActionFunction { - (done: MochaDone): any | PromiseLike -} - -declare function setup(action: ActionFunction): void; -declare function teardown(action: ActionFunction): void; -declare function suiteSetup(action: ActionFunction): void; -declare function suiteTeardown(action: ActionFunction): void; -declare function before(action: ActionFunction): void; -declare function before(description: string, action: ActionFunction): void; -declare function after(action: ActionFunction): void; -declare function after(description: string, action: ActionFunction): void; -declare function beforeEach(action: ActionFunction): void; -declare function beforeEach(description: string, action: ActionFunction): void; -declare function afterEach(action: ActionFunction): void; -declare function afterEach(description: string, action: ActionFunction): void; - -declare class Mocha { - currentTest: Mocha.ITestDefinition; - constructor(options?: { - grep?: RegExp; - ui?: string; - reporter?: string; - timeout?: number; - bail?: boolean; - }); - - /** Setup mocha with the given options. */ - setup(options: MochaSetupOptions): Mocha; - bail(value?: boolean): Mocha; - addFile(file: string): Mocha; - /** Sets reporter by name, defaults to "spec". */ - reporter(name: string): Mocha; - /** Sets reporter constructor, defaults to mocha.reporters.Spec. */ - reporter(reporter: (runner: Mocha.IRunner, options: any) => any): Mocha; - ui(value: string): Mocha; - grep(value: string): Mocha; - grep(value: RegExp): Mocha; - invert(): Mocha; - ignoreLeaks(value: boolean): Mocha; - checkLeaks(): Mocha; - /** - * Function to allow assertion libraries to throw errors directly into mocha. - * This is useful when running tests in a browser because window.onerror will - * only receive the 'message' attribute of the Error. - */ - throwError(error: Error): void; - /** Enables growl support. */ - growl(): Mocha; - globals(value: string): Mocha; - globals(values: string[]): Mocha; - useColors(value: boolean): Mocha; - useInlineDiffs(value: boolean): Mocha; - timeout(value: number): Mocha; - slow(value: number): Mocha; - enableTimeouts(value: boolean): Mocha; - asyncOnly(value: boolean): Mocha; - noHighlighting(value: boolean): Mocha; - /** Runs tests and invokes `onComplete()` when finished. */ - run(onComplete?: (failures: number) => void): Mocha.IRunner; -} - -// merge the Mocha class declaration with a module -declare namespace Mocha { - /** Partial interface for Mocha's `Runnable` class. */ - interface IRunnable { - title: string; - fn: Function; - async: boolean; - sync: boolean; - timedOut: boolean; - } - - /** Partial interface for Mocha's `Suite` class. */ - interface ISuite { - parent: ISuite; - title: string; - - fullTitle(): string; - } - - /** Partial interface for Mocha's `Test` class. */ - interface ITest extends IRunnable { - parent: ISuite; - pending: boolean; - - fullTitle(): string; - } - - /** Partial interface for Mocha's `Runner` class. */ - interface IRunner { } - - interface IContextDefinition { - (description: string, spec: () => void): ISuite; - only(description: string, spec: () => void): ISuite; - skip(description: string, spec: () => void): void; - timeout(ms: number): void; - } - - interface ITestDefinition { - (expectation: string, assertion?: ActionFunction): ITest; - only(expectation: string, assertion?: ActionFunction): ITest; - skip(expectation: string, assertion?: ActionFunction): void; - timeout(ms: number): void; - state: "failed" | "passed"; - } - - export module reporters { - export class Base { - stats: { - suites: number; - tests: number; - passes: number; - pending: number; - failures: number; - }; - - constructor(runner: IRunner); - } - - export class Doc extends Base { } - export class Dot extends Base { } - export class HTML extends Base { } - export class HTMLCov extends Base { } - export class JSON extends Base { } - export class JSONCov extends Base { } - export class JSONStream extends Base { } - export class Landing extends Base { } - export class List extends Base { } - export class Markdown extends Base { } - export class Min extends Base { } - export class Nyan extends Base { } - export class Progress extends Base { - /** - * @param options.open String used to indicate the start of the progress bar. - * @param options.complete String used to indicate a complete test on the progress bar. - * @param options.incomplete String used to indicate an incomplete test on the progress bar. - * @param options.close String used to indicate the end of the progress bar. - */ - constructor(runner: IRunner, options?: { - open?: string; - complete?: string; - incomplete?: string; - close?: string; - }); - } - export class Spec extends Base { } - export class TAP extends Base { } - export class XUnit extends Base { - constructor(runner: IRunner, options?: any); - } - } -} - -declare module "mocha" { - export = Mocha; -} diff --git a/test/sys-info.ts b/test/sys-info.ts index 0c9e0a896d..2b8de8c87c 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -1,5 +1,4 @@ import * as assert from "assert"; -import * as Promise from "bluebird"; import * as path from "path"; import { SysInfo } from "../lib/sys-info"; import { ChildProcess } from "../lib/wrappers/child-process"; @@ -12,14 +11,14 @@ describe("SysInfo unit tests", () => { let execCommand: string; beforeEach(() => { - let childProcess: ChildProcess = { - spawnFromEvent: (command: string, args: string[], event: string) => { + const childProcess: ChildProcess = { + spawnFromEvent: async (command: string, args: string[], event: string) => { spawnFromEventCommand = `${command} ${args.join(" ")}`; - return Promise.resolve({ stdout: "", stderr: "" }); + return { stdout: "", stderr: "" }; }, - exec: (command: string) => { + exec: async (command: string) => { execCommand = command; - return Promise.resolve({ stdout: "", stderr: "" }); + return { stdout: "", stderr: "" }; } }; @@ -27,34 +26,31 @@ describe("SysInfo unit tests", () => { }); describe("Should execute correct commands to check for", () => { - it("java version.", (done: MochaDone) => { - sysInfo.getJavaVersion() - .then(version => { - assert.deepEqual(spawnFromEventCommand, "java -version"); - done(); - }); + it("java version.", async () => { + await sysInfo.getJavaVersion(); + assert.deepEqual(spawnFromEventCommand, "java -version"); }); - it("java compiler version when there is JAVA_HOME.", (done: MochaDone) => { - let pathToJavac = path.join(process.env[JavaHomeName], "bin", "javac"); - sysInfo.getJavaCompilerVersion() - .then(version => { - assert.deepEqual(execCommand, `"${pathToJavac}" -version`); - done(); - }); + it("java compiler version when there is JAVA_HOME.", async () => { + const originalJavaHome = process.env[JavaHomeName]; + process.env[JavaHomeName] = "mock"; + + const pathToJavac = path.join(process.env[JavaHomeName], "bin", "javac"); + await sysInfo.getJavaCompilerVersion(); + + process.env[JavaHomeName] = originalJavaHome; + assert.deepEqual(execCommand, `"${pathToJavac}" -version`); }); - it("java compiler version when there is no JAVA_HOME.", (done: MochaDone) => { - let originalJavaHome = process.env[JavaHomeName]; + it("java compiler version when there is no JAVA_HOME.", async () => { + const originalJavaHome = process.env[JavaHomeName]; delete process.env[JavaHomeName]; - sysInfo.getJavaCompilerVersion() - .then(version => { - assert.deepEqual(execCommand, `"javac" -version`); - process.env[JavaHomeName] = originalJavaHome; - done(); - }); + await sysInfo.getJavaCompilerVersion(); + + process.env[JavaHomeName] = originalJavaHome; + assert.deepEqual(execCommand, `"javac" -version`); }); }); }); diff --git a/tsconfig.json b/tsconfig.json index f161b72e79..e1ddc075df 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "module": "commonjs", "sourceMap": true, "declaration": false, diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 4d6fe20132..3ba593b91c 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -1,8 +1,4 @@ -/// - -import * as Promise from "bluebird"; - -declare namespace NativeScriptDoctor { +declare module NativeScriptDoctor { export function getJavaVersion(): Promise; export function getJavaCompilerVersion(): Promise; } From a4329b55f79b9180f08d3e3f6dd638cc79b5bcc0 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 28 Oct 2016 21:36:00 +0300 Subject: [PATCH 013/169] Add more methods to sys info Added more methods to the sys info class. --- lib/constants.ts | 5 + lib/declarations.d.ts | 98 + lib/definitions/node.d.ts | 2511 ----------------- lib/definitions/osenv.d.ts | 4 + lib/definitions/unzip.d.ts | 3 + lib/doctor.ts | 163 ++ lib/helpers.ts | 27 + lib/host-info.ts | 43 + lib/index.ts | 27 +- .../android-local-build-requirements.ts | 16 + .../ios-local-build-requirements.ts | 17 + lib/sys-info.ts | 297 +- lib/winreg.ts | 41 + lib/wrappers/file-system.ts | 18 + package.json | 12 +- .../cocoapods-verification/cocoapods.zip | Bin 0 -> 16919 bytes test/sys-info.ts | 2 +- typings/nativescript-doctor.d.ts | 101 +- 18 files changed, 856 insertions(+), 2529 deletions(-) create mode 100644 lib/constants.ts delete mode 100644 lib/definitions/node.d.ts create mode 100644 lib/definitions/osenv.d.ts create mode 100644 lib/definitions/unzip.d.ts create mode 100644 lib/doctor.ts create mode 100644 lib/helpers.ts create mode 100644 lib/host-info.ts create mode 100644 lib/local-build-requirements/android-local-build-requirements.ts create mode 100644 lib/local-build-requirements/ios-local-build-requirements.ts create mode 100644 lib/winreg.ts create mode 100644 lib/wrappers/file-system.ts create mode 100644 resources/cocoapods-verification/cocoapods.zip diff --git a/lib/constants.ts b/lib/constants.ts new file mode 100644 index 0000000000..7af237f259 --- /dev/null +++ b/lib/constants.ts @@ -0,0 +1,5 @@ +export class Constants { + public static ANDROID_PLATFORM_NAME = "Android"; + public static IOS_PLATFORM_NAME = "iOS"; + public static SUPPORTED_PLATFORMS = [Constants.ANDROID_PLATFORM_NAME, Constants.IOS_PLATFORM_NAME]; +} diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 042adddbb5..94ad9c5107 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -23,6 +23,104 @@ interface ISpawnFromEventOptions { ignoreError?: boolean; } +interface ISysInfoData { + // os stuff + /** os platform flavour, reported by os.platform */ + platform: string; + /** Full os name, like `uname -a` on unix, registry query on win */ + os: string; + /** .net version, applicable to windows only */ + dotNetVer: string; + /** The command shell in use, usually bash or cmd */ + shell: string; + + // node stuff + /** node.js version, returned by `process.version` */ + nodeVer: string; + /** npm version, returned by `npm -v` */ + npmVer: string; + /** Process architecture, returned by `process.arch` */ + procArch: string; + /** node-gyp version as returned by `node-gyp -v`*/ + nodeGypVer: string; + + // dependencies + /** version of java, as returned by `java -version` */ + javaVer: string; + /** Xcode version string as returned by `xcodebuild -version`. Valid only on Mac */ + xcodeVer: string; + /** Version string of adb, as returned by `adb version` */ + adbVer: string; + /** Whether iTunes is installed on the machine */ + itunesInstalled: boolean; + /** Whether `android` executable can be run */ + androidInstalled: boolean; + /** mono version, relevant on Mac only **/ + monoVer: string; + /** git version string, as returned by `git --version` **/ + gitVer: string; + /** gradle version string as returned by `gradle -v` **/ + gradleVer: string; + /** javac version string as returned by `javac -version` **/ + javacVersion: string; + /** pod version string, as returned by `pod --version` **/ + cocoapodVer: string; + /** xcodeproj gem location, as returned by `which gem xcodeproj` **/ + xcodeprojGemLocation: string; + /** true id CocoaPods can successfully execute pod install **/ + isCocoaPodsWorkingCorrectly: boolean; +} + +/** + * Describes single registry available for search. + */ +interface IHiveId { + /** + * Name of the registry that will be checked. + */ + registry: string; +} + +/** + * Describes available for search registry ids. + */ +interface IHiveIds { + /** + * HKEY_LOCAL_MACHINE + */ + HKLM: IHiveId; + + /** + * HKEY_CURRENT_USER + */ + HKCU: IHiveId; + + /** + * HKEY_CLASSES_ROOT + */ + HKCR: IHiveId; + + /** + * HKEY_CURRENT_CONFIG + */ + HKCC: IHiveId; + + /** + * HKEY_USERS + */ + HKU: IHiveId; +} + +/** + * Describes warning returned from nativescript-doctor check. + */ +interface IWarning { + /** The warning. */ + warning: string; + /** Additional information for the warning. */ + additionalInformation: string; +} + interface IDictionary { [key: string]: T } diff --git a/lib/definitions/node.d.ts b/lib/definitions/node.d.ts deleted file mode 100644 index ceab0ea608..0000000000 --- a/lib/definitions/node.d.ts +++ /dev/null @@ -1,2511 +0,0 @@ -// Type definitions for Node.js v4.x -// Project: http://nodejs.org/ -// Definitions by: Microsoft TypeScript , DefinitelyTyped -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -/************************************************ -* * -* Node.js v4.x API * -* * -************************************************/ - -interface Error { - stack?: string; -} - -interface ErrorConstructor { - captureStackTrace(targetObject: Object, constructorOpt?: Function): void; - stackTraceLimit: number; -} - -// compat for TypeScript 1.8 -// if you use with --target es3 or --target es5 and use below definitions, -// use the lib.es6.d.ts that is bundled with TypeScript 1.8. -interface MapConstructor { } -interface WeakMapConstructor { } -interface SetConstructor { } -interface WeakSetConstructor { } - -/************************************************ -* * -* GLOBAL * -* * -************************************************/ -declare var process: NodeJS.Process; -declare var global: NodeJS.Global; - -declare var __filename: string; -declare var __dirname: string; - -declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearTimeout(timeoutId: NodeJS.Timer): void; -declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearInterval(intervalId: NodeJS.Timer): void; -declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; -declare function clearImmediate(immediateId: any): void; - -interface NodeRequireFunction { - (id: string): any; -} - -interface NodeRequire extends NodeRequireFunction { - resolve(id: string): string; - cache: any; - extensions: any; - main: any; -} - -declare var require: NodeRequire; - -interface NodeModule { - exports: any; - require: NodeRequireFunction; - id: string; - filename: string; - loaded: boolean; - parent: any; - children: any[]; -} - -declare var module: NodeModule; - -// Same as module.exports -declare var exports: any; -declare var SlowBuffer: { - new (str: string, encoding?: string): Buffer; - new (size: number): Buffer; - new (size: Uint8Array): Buffer; - new (array: any[]): Buffer; - prototype: Buffer; - isBuffer(obj: any): boolean; - byteLength(string: string, encoding?: string): number; - concat(list: Buffer[], totalLength?: number): Buffer; -}; - - -// Buffer class -type BufferEncoding = "ascii" | "utf8" | "utf16le" | "ucs2" | "binary" | "hex"; -interface Buffer extends NodeBuffer { } - -/** - * Raw data is stored in instances of the Buffer class. - * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. - * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' - */ -declare var Buffer: { - /** - * Allocates a new buffer containing the given {str}. - * - * @param str String to store in buffer. - * @param encoding encoding to use, optional. Default is 'utf8' - */ - new (str: string, encoding?: string): Buffer; - /** - * Allocates a new buffer of {size} octets. - * - * @param size count of octets to allocate. - */ - new (size: number): Buffer; - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - new (array: Uint8Array): Buffer; - /** - * Produces a Buffer backed by the same allocated memory as - * the given {ArrayBuffer}. - * - * - * @param arrayBuffer The ArrayBuffer with which to share memory. - */ - new (arrayBuffer: ArrayBuffer): Buffer; - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - new (array: any[]): Buffer; - /** - * Copies the passed {buffer} data onto a new {Buffer} instance. - * - * @param buffer The buffer to copy. - */ - new (buffer: Buffer): Buffer; - prototype: Buffer; - /** - * Allocates a new Buffer using an {array} of octets. - * - * @param array - */ - from(array: any[]): Buffer; - /** - * When passed a reference to the .buffer property of a TypedArray instance, - * the newly created Buffer will share the same allocated memory as the TypedArray. - * The optional {byteOffset} and {length} arguments specify a memory range - * within the {arrayBuffer} that will be shared by the Buffer. - * - * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() - * @param byteOffset - * @param length - */ - from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; - /** - * Copies the passed {buffer} data onto a new Buffer instance. - * - * @param buffer - */ - from(buffer: Buffer): Buffer; - /** - * Creates a new Buffer containing the given JavaScript string {str}. - * If provided, the {encoding} parameter identifies the character encoding. - * If not provided, {encoding} defaults to 'utf8'. - * - * @param str - */ - from(str: string, encoding?: string): Buffer; - /** - * Returns true if {obj} is a Buffer - * - * @param obj object to test. - */ - isBuffer(obj: any): obj is Buffer; - /** - * Returns true if {encoding} is a valid encoding argument. - * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' - * - * @param encoding string to test. - */ - isEncoding(encoding: string): boolean; - /** - * Gives the actual byte length of a string. encoding defaults to 'utf8'. - * This is not the same as String.prototype.length since that returns the number of characters in a string. - * - * @param string string to test. - * @param encoding encoding used to evaluate (defaults to 'utf8') - */ - byteLength(string: string, encoding?: string): number; - /** - * Returns a buffer which is the result of concatenating all the buffers in the list together. - * - * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. - * If the list has exactly one item, then the first item of the list is returned. - * If the list has more than one item, then a new Buffer is created. - * - * @param list An array of Buffer objects to concatenate - * @param totalLength Total length of the buffers when concatenated. - * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. - */ - concat(list: Buffer[], totalLength?: number): Buffer; - /** - * The same as buf1.compare(buf2). - */ - compare(buf1: Buffer, buf2: Buffer): number; -}; - -/************************************************ -* * -* GLOBAL INTERFACES * -* * -************************************************/ -declare namespace NodeJS { - export interface ErrnoException extends Error { - errno?: number; - code?: string; - path?: string; - syscall?: string; - stack?: string; - } - - export interface EventEmitter { - addListener(event: string, listener: Function): this; - on(event: string, listener: Function): this; - once(event: string, listener: Function): this; - removeListener(event: string, listener: Function): this; - removeAllListeners(event?: string): this; - setMaxListeners(n: number): this; - getMaxListeners(): number; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - listenerCount(type: string): number; - } - - export interface ReadableStream extends EventEmitter { - readable: boolean; - read(size?: number): string | Buffer; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: ReadableStream): ReadableStream; - } - - export interface WritableStream extends EventEmitter { - writable: boolean; - write(buffer: Buffer | string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface ReadWriteStream extends ReadableStream, WritableStream { } - - export interface Events extends EventEmitter { } - - export interface Domain extends Events { - run(fn: Function): void; - add(emitter: Events): void; - remove(emitter: Events): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - - addListener(event: string, listener: Function): this; - on(event: string, listener: Function): this; - once(event: string, listener: Function): this; - removeListener(event: string, listener: Function): this; - removeAllListeners(event?: string): this; - } - - export interface MemoryUsage { - rss: number; - heapTotal: number; - heapUsed: number; - } - - export interface Process extends EventEmitter { - stdout: WritableStream; - stderr: WritableStream; - stdin: ReadableStream; - argv: string[]; - execArgv: string[]; - execPath: string; - abort(): void; - chdir(directory: string): void; - cwd(): string; - env: any; - exit(code?: number): void; - exitCode: number; - getgid(): number; - setgid(id: number): void; - setgid(id: string): void; - getuid(): number; - setuid(id: number): void; - setuid(id: string): void; - version: string; - versions: { - http_parser: string; - node: string; - v8: string; - ares: string; - uv: string; - zlib: string; - modules: string; - openssl: string; - }; - config: { - target_defaults: { - cflags: any[]; - default_configuration: string; - defines: string[]; - include_dirs: string[]; - libraries: string[]; - }; - variables: { - clang: number; - host_arch: string; - node_install_npm: boolean; - node_install_waf: boolean; - node_prefix: string; - node_shared_openssl: boolean; - node_shared_v8: boolean; - node_shared_zlib: boolean; - node_use_dtrace: boolean; - node_use_etw: boolean; - node_use_openssl: boolean; - target_arch: string; - v8_no_strict_aliasing: number; - v8_use_snapshot: boolean; - visibility: string; - }; - }; - kill(pid: number, signal?: string | number): void; - pid: number; - title: string; - arch: string; - platform: string; - memoryUsage(): MemoryUsage; - nextTick(callback: Function): void; - umask(mask?: number): number; - uptime(): number; - hrtime(time?: number[]): number[]; - domain: Domain; - - // Worker - send?(message: any, sendHandle?: any): void; - disconnect(): void; - connected: boolean; - } - - export interface Global { - Array: typeof Array; - ArrayBuffer: typeof ArrayBuffer; - Boolean: typeof Boolean; - Buffer: typeof Buffer; - DataView: typeof DataView; - Date: typeof Date; - Error: typeof Error; - EvalError: typeof EvalError; - Float32Array: typeof Float32Array; - Float64Array: typeof Float64Array; - Function: typeof Function; - GLOBAL: Global; - Infinity: typeof Infinity; - Int16Array: typeof Int16Array; - Int32Array: typeof Int32Array; - Int8Array: typeof Int8Array; - Intl: typeof Intl; - JSON: typeof JSON; - Map: MapConstructor; - Math: typeof Math; - NaN: typeof NaN; - Number: typeof Number; - Object: typeof Object; - Promise: Function; - RangeError: typeof RangeError; - ReferenceError: typeof ReferenceError; - RegExp: typeof RegExp; - Set: SetConstructor; - String: typeof String; - Symbol: Function; - SyntaxError: typeof SyntaxError; - TypeError: typeof TypeError; - URIError: typeof URIError; - Uint16Array: typeof Uint16Array; - Uint32Array: typeof Uint32Array; - Uint8Array: typeof Uint8Array; - Uint8ClampedArray: Function; - WeakMap: WeakMapConstructor; - WeakSet: WeakSetConstructor; - clearImmediate: (immediateId: any) => void; - clearInterval: (intervalId: NodeJS.Timer) => void; - clearTimeout: (timeoutId: NodeJS.Timer) => void; - console: typeof console; - decodeURI: typeof decodeURI; - decodeURIComponent: typeof decodeURIComponent; - encodeURI: typeof encodeURI; - encodeURIComponent: typeof encodeURIComponent; - escape: (str: string) => string; - eval: typeof eval; - global: Global; - isFinite: typeof isFinite; - isNaN: typeof isNaN; - parseFloat: typeof parseFloat; - parseInt: typeof parseInt; - process: Process; - root: Global; - setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; - setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - undefined: typeof undefined; - unescape: (str: string) => string; - gc: () => void; - v8debug?: any; - } - - export interface Timer { - ref(): void; - unref(): void; - } -} - -/** - * @deprecated - */ -interface NodeBuffer extends Uint8Array { - write(string: string, offset?: number, length?: number, encoding?: string): number; - toString(encoding?: string, start?: number, end?: number): string; - toJSON(): { type: 'Buffer', data: any[] }; - equals(otherBuffer: Buffer): boolean; - compare(otherBuffer: Buffer): number; - copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; - slice(start?: number, end?: number): Buffer; - writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readUInt8(offset: number, noAssert?: boolean): number; - readUInt16LE(offset: number, noAssert?: boolean): number; - readUInt16BE(offset: number, noAssert?: boolean): number; - readUInt32LE(offset: number, noAssert?: boolean): number; - readUInt32BE(offset: number, noAssert?: boolean): number; - readInt8(offset: number, noAssert?: boolean): number; - readInt16LE(offset: number, noAssert?: boolean): number; - readInt16BE(offset: number, noAssert?: boolean): number; - readInt32LE(offset: number, noAssert?: boolean): number; - readInt32BE(offset: number, noAssert?: boolean): number; - readFloatLE(offset: number, noAssert?: boolean): number; - readFloatBE(offset: number, noAssert?: boolean): number; - readDoubleLE(offset: number, noAssert?: boolean): number; - readDoubleBE(offset: number, noAssert?: boolean): number; - writeUInt8(value: number, offset: number, noAssert?: boolean): number; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeInt8(value: number, offset: number, noAssert?: boolean): number; - writeInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeFloatLE(value: number, offset: number, noAssert?: boolean): number; - writeFloatBE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; - fill(value: any, offset?: number, end?: number): this; - // TODO: encoding param - indexOf(value: string | number | Buffer, byteOffset?: number): number; - // TODO: entries - // TODO: includes - // TODO: keys - // TODO: values -} - -/************************************************ -* * -* MODULES * -* * -************************************************/ -declare module "buffer" { - export var INSPECT_MAX_BYTES: number; - var BuffType: typeof Buffer; - var SlowBuffType: typeof SlowBuffer; - export { BuffType as Buffer, SlowBuffType as SlowBuffer }; -} - -declare module "querystring" { - export interface StringifyOptions { - encodeURIComponent?: Function; - } - - export interface ParseOptions { - maxKeys?: number; - decodeURIComponent?: Function; - } - - export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; - export function escape(str: string): string; - export function unescape(str: string): string; -} - -declare module "events" { - export class EventEmitter implements NodeJS.EventEmitter { - static EventEmitter: EventEmitter; - static listenerCount(emitter: EventEmitter, event: string): number; // deprecated - static defaultMaxListeners: number; - - addListener(event: string, listener: Function): this; - on(event: string, listener: Function): this; - once(event: string, listener: Function): this; - removeListener(event: string, listener: Function): this; - removeAllListeners(event?: string): this; - setMaxListeners(n: number): this; - getMaxListeners(): number; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - listenerCount(type: string): number; - } -} - -declare module "http" { - import * as events from "events"; - import * as net from "net"; - import * as stream from "stream"; - - export interface RequestOptions { - protocol?: string; - host?: string; - hostname?: string; - family?: number; - port?: number; - localAddress?: string; - socketPath?: string; - method?: string; - path?: string; - headers?: { [key: string]: any }; - auth?: string; - agent?: Agent | boolean; - } - - export interface Server extends net.Server { - setTimeout(msecs: number, callback: Function): void; - maxHeadersCount: number; - timeout: number; - } - /** - * @deprecated Use IncomingMessage - */ - export interface ServerRequest extends IncomingMessage { - connection: net.Socket; - } - export interface ServerResponse extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - writeContinue(): void; - writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; - writeHead(statusCode: number, headers?: any): void; - statusCode: number; - statusMessage: string; - headersSent: boolean; - setHeader(name: string, value: string | string[]): void; - sendDate: boolean; - getHeader(name: string): string; - removeHeader(name: string): void; - write(chunk: any, encoding?: string): any; - addTrailers(headers: any): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface ClientRequest extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - write(chunk: any, encoding?: string): void; - abort(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; - - setHeader(name: string, value: string | string[]): void; - getHeader(name: string): string; - removeHeader(name: string): void; - addTrailers(headers: any): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface IncomingMessage extends events.EventEmitter, stream.Readable { - httpVersion: string; - headers: any; - rawHeaders: string[]; - trailers: any; - rawTrailers: any; - setTimeout(msecs: number, callback: Function): NodeJS.Timer; - /** - * Only valid for request obtained from http.Server. - */ - method?: string; - /** - * Only valid for request obtained from http.Server. - */ - url?: string; - /** - * Only valid for response obtained from http.ClientRequest. - */ - statusCode?: number; - /** - * Only valid for response obtained from http.ClientRequest. - */ - statusMessage?: string; - socket: net.Socket; - destroy(error?: Error): void; - } - /** - * @deprecated Use IncomingMessage - */ - export interface ClientResponse extends IncomingMessage { } - - export interface AgentOptions { - /** - * Keep sockets around in a pool to be used by other requests in the future. Default = false - */ - keepAlive?: boolean; - /** - * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. - * Only relevant if keepAlive is set to true. - */ - keepAliveMsecs?: number; - /** - * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity - */ - maxSockets?: number; - /** - * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. - */ - maxFreeSockets?: number; - } - - export class Agent { - maxSockets: number; - sockets: any; - requests: any; - - constructor(opts?: AgentOptions); - - /** - * Destroy any sockets that are currently in use by the agent. - * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, - * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, - * sockets may hang open for quite a long time before the server terminates them. - */ - destroy(): void; - } - - export var METHODS: string[]; - - export var STATUS_CODES: { - [errorCode: number]: string; - [errorCode: string]: string; - }; - export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; - export function createClient(port?: number, host?: string): any; - export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; - export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; - export var globalAgent: Agent; -} - -declare module "cluster" { - import * as child from "child_process"; - import * as events from "events"; - - export interface ClusterSettings { - exec?: string; - args?: string[]; - silent?: boolean; - } - - export interface Address { - address: string; - port: number; - addressType: string; - } - - export class Worker extends events.EventEmitter { - id: string; - process: child.ChildProcess; - suicide: boolean; - send(message: any, sendHandle?: any): void; - kill(signal?: string): void; - destroy(signal?: string): void; - disconnect(): void; - isConnected(): boolean; - isDead(): boolean; - } - - export var settings: ClusterSettings; - export var isMaster: boolean; - export var isWorker: boolean; - export function setupMaster(settings?: ClusterSettings): void; - export function fork(env?: any): Worker; - export function disconnect(callback?: Function): void; - export var worker: Worker; - export var workers: { - [index: string]: Worker - }; - - // Event emitter - export function addListener(event: string, listener: Function): void; - export function on(event: "disconnect", listener: (worker: Worker) => void): void; - export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): void; - export function on(event: "fork", listener: (worker: Worker) => void): void; - export function on(event: "listening", listener: (worker: Worker, address: any) => void): void; - export function on(event: "message", listener: (worker: Worker, message: any) => void): void; - export function on(event: "online", listener: (worker: Worker) => void): void; - export function on(event: "setup", listener: (settings: any) => void): void; - export function on(event: string, listener: Function): any; - export function once(event: string, listener: Function): void; - export function removeListener(event: string, listener: Function): void; - export function removeAllListeners(event?: string): void; - export function setMaxListeners(n: number): void; - export function listeners(event: string): Function[]; - export function emit(event: string, ...args: any[]): boolean; -} - -declare module "zlib" { - import * as stream from "stream"; - export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } - - export interface Gzip extends stream.Transform { } - export interface Gunzip extends stream.Transform { } - export interface Deflate extends stream.Transform { } - export interface Inflate extends stream.Transform { } - export interface DeflateRaw extends stream.Transform { } - export interface InflateRaw extends stream.Transform { } - export interface Unzip extends stream.Transform { } - - export function createGzip(options?: ZlibOptions): Gzip; - export function createGunzip(options?: ZlibOptions): Gunzip; - export function createDeflate(options?: ZlibOptions): Deflate; - export function createInflate(options?: ZlibOptions): Inflate; - export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; - export function createInflateRaw(options?: ZlibOptions): InflateRaw; - export function createUnzip(options?: ZlibOptions): Unzip; - - export function deflate(buf: Buffer, callback: (error: Error, result: any) => void): void; - export function deflateSync(buf: Buffer, options?: ZlibOptions): any; - export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; - export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; - export function gzip(buf: Buffer, callback: (error: Error, result: any) => void): void; - export function gzipSync(buf: Buffer, options?: ZlibOptions): any; - export function gunzip(buf: Buffer, callback: (error: Error, result: any) => void): void; - export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; - export function inflate(buf: Buffer, callback: (error: Error, result: any) => void): void; - export function inflateSync(buf: Buffer, options?: ZlibOptions): any; - export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; - export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; - export function unzip(buf: Buffer, callback: (error: Error, result: any) => void): void; - export function unzipSync(buf: Buffer, options?: ZlibOptions): any; - - // Constants - export var Z_NO_FLUSH: number; - export var Z_PARTIAL_FLUSH: number; - export var Z_SYNC_FLUSH: number; - export var Z_FULL_FLUSH: number; - export var Z_FINISH: number; - export var Z_BLOCK: number; - export var Z_TREES: number; - export var Z_OK: number; - export var Z_STREAM_END: number; - export var Z_NEED_DICT: number; - export var Z_ERRNO: number; - export var Z_STREAM_ERROR: number; - export var Z_DATA_ERROR: number; - export var Z_MEM_ERROR: number; - export var Z_BUF_ERROR: number; - export var Z_VERSION_ERROR: number; - export var Z_NO_COMPRESSION: number; - export var Z_BEST_SPEED: number; - export var Z_BEST_COMPRESSION: number; - export var Z_DEFAULT_COMPRESSION: number; - export var Z_FILTERED: number; - export var Z_HUFFMAN_ONLY: number; - export var Z_RLE: number; - export var Z_FIXED: number; - export var Z_DEFAULT_STRATEGY: number; - export var Z_BINARY: number; - export var Z_TEXT: number; - export var Z_ASCII: number; - export var Z_UNKNOWN: number; - export var Z_DEFLATED: number; - export var Z_NULL: number; -} - -declare module "os" { - export interface CpuInfo { - model: string; - speed: number; - times: { - user: number; - nice: number; - sys: number; - idle: number; - irq: number; - }; - } - - export interface NetworkInterfaceInfo { - address: string; - netmask: string; - family: string; - mac: string; - internal: boolean; - } - - export function tmpdir(): string; - export function homedir(): string; - export function endianness(): string; - export function hostname(): string; - export function type(): string; - export function platform(): string; - export function arch(): string; - export function release(): string; - export function uptime(): number; - export function loadavg(): number[]; - export function totalmem(): number; - export function freemem(): number; - export function cpus(): CpuInfo[]; - export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; - export var EOL: string; -} - -declare module "https" { - import * as tls from "tls"; - import * as events from "events"; - import * as http from "http"; - - export interface ServerOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - crl?: any; - ciphers?: string; - honorCipherOrder?: boolean; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; - SNICallback?: (servername: string) => any; - } - - export interface RequestOptions extends http.RequestOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - ciphers?: string; - rejectUnauthorized?: boolean; - secureProtocol?: string; - } - - export interface Agent extends http.Agent { } - - export interface AgentOptions extends http.AgentOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - ciphers?: string; - rejectUnauthorized?: boolean; - secureProtocol?: string; - maxCachedSessions?: number; - } - - export var Agent: { - new (options?: AgentOptions): Agent; - }; - export interface Server extends tls.Server { } - export function createServer(options: ServerOptions, requestListener?: Function): Server; - export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; - export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; - export var globalAgent: Agent; -} - -declare module "punycode" { - export function decode(string: string): string; - export function encode(string: string): string; - export function toUnicode(domain: string): string; - export function toASCII(domain: string): string; - export var ucs2: ucs2; - interface ucs2 { - decode(string: string): number[]; - encode(codePoints: number[]): string; - } - export var version: any; -} - -declare module "repl" { - import * as stream from "stream"; - import * as events from "events"; - - export interface ReplOptions { - prompt?: string; - input?: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - terminal?: boolean; - eval?: Function; - useColors?: boolean; - useGlobal?: boolean; - ignoreUndefined?: boolean; - writer?: Function; - } - export function start(options: ReplOptions): events.EventEmitter; -} - -declare module "readline" { - import * as events from "events"; - import * as stream from "stream"; - - export interface Key { - sequence?: string; - name?: string; - ctrl?: boolean; - meta?: boolean; - shift?: boolean; - } - - export interface ReadLine extends events.EventEmitter { - setPrompt(prompt: string): void; - prompt(preserveCursor?: boolean): void; - question(query: string, callback: (answer: string) => void): void; - pause(): ReadLine; - resume(): ReadLine; - close(): void; - write(data: string | Buffer, key?: Key): void; - } - - export interface Completer { - (line: string): CompleterResult; - (line: string, callback: (err: any, result: CompleterResult) => void): any; - } - - export interface CompleterResult { - completions: string[]; - line: string; - } - - export interface ReadLineOptions { - input: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - completer?: Completer; - terminal?: boolean; - historySize?: number; - } - - export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer, terminal?: boolean): ReadLine; - export function createInterface(options: ReadLineOptions): ReadLine; - - export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; - export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; - export function clearLine(stream: NodeJS.WritableStream, dir: number): void; - export function clearScreenDown(stream: NodeJS.WritableStream): void; -} - -declare module "vm" { - export interface Context { } - export interface ScriptOptions { - filename?: string; - lineOffset?: number; - columnOffset?: number; - displayErrors?: boolean; - timeout?: number; - cachedData?: Buffer; - produceCachedData?: boolean; - } - export interface RunningScriptOptions { - filename?: string; - lineOffset?: number; - columnOffset?: number; - displayErrors?: boolean; - timeout?: number; - } - export class Script { - constructor(code: string, options?: ScriptOptions); - runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; - runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; - runInThisContext(options?: RunningScriptOptions): any; - } - export function createContext(sandbox?: Context): Context; - export function isContext(sandbox: Context): boolean; - export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; - export function runInDebugContext(code: string): any; - export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; - export function runInThisContext(code: string, options?: RunningScriptOptions): any; -} - -declare module "child_process" { - import * as events from "events"; - import * as stream from "stream"; - - export interface ChildProcess extends events.EventEmitter { - stdin: stream.Writable; - stdout: stream.Readable; - stderr: stream.Readable; - stdio: [stream.Writable, stream.Readable, stream.Readable]; - pid: number; - kill(signal?: string): void; - send(message: any, sendHandle?: any): void; - connected: boolean; - disconnect(): void; - unref(): void; - } - - export interface SpawnOptions { - cwd?: string; - env?: any; - stdio?: any; - detached?: boolean; - uid?: number; - gid?: number; - shell?: boolean | string; - } - export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; - - export interface ExecOptions { - cwd?: string; - env?: any; - shell?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - uid?: number; - gid?: number; - } - export interface ExecOptionsWithStringEncoding extends ExecOptions { - encoding: BufferEncoding; - } - export interface ExecOptionsWithBufferEncoding extends ExecOptions { - encoding: string; // specify `null`. - } - export function exec(command: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function exec(command: string, options: ExecOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - // usage. child_process.exec("tsc", {encoding: null as string}, (err, stdout, stderr) => {}); - export function exec(command: string, options: ExecOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - export function exec(command: string, options: ExecOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - - export interface ExecFileOptions { - cwd?: string; - env?: any; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - uid?: number; - gid?: number; - } - export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { - encoding: BufferEncoding; - } - export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { - encoding: string; // specify `null`. - } - export function execFile(file: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - // usage. child_process.execFile("file.sh", {encoding: null as string}, (err, stdout, stderr) => {}); - export function execFile(file: string, options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - export function execFile(file: string, options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, args?: string[], callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - // usage. child_process.execFile("file.sh", ["foo"], {encoding: null as string}, (err, stdout, stderr) => {}); - export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; - export function execFile(file: string, args?: string[], options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; - - export interface ForkOptions { - cwd?: string; - env?: any; - execPath?: string; - execArgv?: string[]; - silent?: boolean; - uid?: number; - gid?: number; - } - export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; - - export interface SpawnSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - shell?: boolean | string; - } - export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { - encoding: BufferEncoding; - } - export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { - encoding: string; // specify `null`. - } - export interface SpawnSyncReturns { - pid: number; - output: string[]; - stdout: T; - stderr: T; - status: number; - signal: string; - error: Error; - } - export function spawnSync(command: string): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; - export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; - export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; - - export interface ExecSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - shell?: string; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - } - export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { - encoding: BufferEncoding; - } - export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { - encoding: string; // specify `null`. - } - export function execSync(command: string): Buffer; - export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; - export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; - export function execSync(command: string, options?: ExecSyncOptions): Buffer; - - export interface ExecFileSyncOptions { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - killSignal?: string; - maxBuffer?: number; - encoding?: string; - } - export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { - encoding: BufferEncoding; - } - export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { - encoding: string; // specify `null`. - } - export function execFileSync(command: string): Buffer; - export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; - export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; - export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; - export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; -} - -declare module "url" { - export interface Url { - href?: string; - protocol?: string; - auth?: string; - hostname?: string; - port?: string; - host?: string; - pathname?: string; - search?: string; - query?: string | any; - slashes?: boolean; - hash?: string; - path?: string; - } - - export function parse(urlStr: string, parseQueryString?: boolean, slashesDenoteHost?: boolean): Url; - export function format(url: Url): string; - export function resolve(from: string, to: string): string; -} - -declare module "dns" { - export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) => void): string; - export function lookup(domain: string, callback: (err: Error, address: string, family: number) => void): string; - export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolve(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolve4(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolve6(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; - export function reverse(ip: string, callback: (err: Error, domains: string[]) => void): string[]; -} - -declare module "net" { - import * as stream from "stream"; - import * as events from "events"; - - export interface Socket extends stream.Duplex { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - connect(port: number, host?: string, connectionListener?: Function): void; - connect(path: string, connectionListener?: Function): void; - bufferSize: number; - setEncoding(encoding?: string): void; - write(data: any, encoding?: string, callback?: Function): void; - destroy(): void; - pause(): void; - resume(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setKeepAlive(enable?: boolean, initialDelay?: number): void; - address(): { port: number; family: string; address: string; }; - unref(): void; - ref(): void; - - remoteAddress: string; - remoteFamily: string; - remotePort: number; - localAddress: string; - localPort: number; - bytesRead: number; - bytesWritten: number; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - - export var Socket: { - new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; - }; - - export interface ListenOptions { - port?: number; - host?: string; - backlog?: number; - path?: string; - exclusive?: boolean; - } - - export interface Server extends events.EventEmitter { - listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function): Server; - listen(port: number, hostname?: string, listeningListener?: Function): Server; - listen(port: number, backlog?: number, listeningListener?: Function): Server; - listen(port: number, listeningListener?: Function): Server; - listen(path: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(handle: any, backlog?: number, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - listen(options: ListenOptions, listeningListener?: Function): Server; - close(callback?: Function): Server; - address(): { port: number; family: string; address: string; }; - getConnections(cb: (error: Error, count: number) => void): void; - ref(): Server; - unref(): Server; - maxConnections: number; - connections: number; - - /** - * events.EventEmitter - * 1. close - * 2. connection - * 3. error - * 4. listening - */ - addListener(event: string, listener: Function): this; - addListener(event: "close", listener: () => void): this; - addListener(event: "connection", listener: (socket: Socket) => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "listening", listener: () => void): this; - - emit(event: string, ...args: any[]): boolean; - emit(event: "close"): boolean; - emit(event: "connection", socket: Socket): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "listening"): boolean; - - on(event: string, listener: Function): this; - on(event: "close", listener: () => void): this; - on(event: "connection", listener: (socket: Socket) => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "listening", listener: () => void): this; - - once(event: string, listener: Function): this; - once(event: "close", listener: () => void): this; - once(event: "connection", listener: (socket: Socket) => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "listening", listener: () => void): this; - - prependListener(event: string, listener: Function): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "connection", listener: (socket: Socket) => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "listening", listener: () => void): this; - - prependOnceListener(event: string, listener: Function): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "connection", listener: (socket: Socket) => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "listening", listener: () => void): this; - } - export function createServer(connectionListener?: (socket: Socket) => void): Server; - export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) => void): Server; - export function connect(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function connect(port: number, host?: string, connectionListener?: Function): Socket; - export function connect(path: string, connectionListener?: Function): Socket; - export function createConnection(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; - export function createConnection(path: string, connectionListener?: Function): Socket; - export function isIP(input: string): number; - export function isIPv4(input: string): boolean; - export function isIPv6(input: string): boolean; -} - -declare module "dgram" { - import * as events from "events"; - - interface RemoteInfo { - address: string; - port: number; - size: number; - } - - interface AddressInfo { - address: string; - family: string; - port: number; - } - - export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; - - interface Socket extends events.EventEmitter { - send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; - bind(port: number, address?: string, callback?: () => void): void; - close(): void; - address(): AddressInfo; - setBroadcast(flag: boolean): void; - setMulticastTTL(ttl: number): void; - setMulticastLoopback(flag: boolean): void; - addMembership(multicastAddress: string, multicastInterface?: string): void; - dropMembership(multicastAddress: string, multicastInterface?: string): void; - } -} - -declare module "fs" { - import * as stream from "stream"; - import * as events from "events"; - - interface Stats { - isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; - } - - interface FSWatcher extends events.EventEmitter { - close(): void; - } - - export interface ReadStream extends stream.Readable { - close(): void; - } - export interface WriteStream extends stream.Writable { - close(): void; - bytesWritten: number; - } - - /** - * Asynchronous rename. - * @param oldPath - * @param newPath - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /** - * Synchronous rename - * @param oldPath - * @param newPath - */ - export function renameSync(oldPath: string, newPath: string): void; - export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncateSync(path: string, len?: number): void; - export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncateSync(fd: number, len?: number): void; - export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chownSync(path: string, uid: number, gid: number): void; - export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchownSync(fd: number, uid: number, gid: number): void; - export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchownSync(path: string, uid: number, gid: number): void; - export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmodSync(path: string, mode: number): void; - export function chmodSync(path: string, mode: string): void; - export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmodSync(fd: number, mode: number): void; - export function fchmodSync(fd: number, mode: string): void; - export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmodSync(path: string, mode: number): void; - export function lchmodSync(path: string, mode: string): void; - export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function statSync(path: string): Stats; - export function lstatSync(path: string): Stats; - export function fstatSync(fd: number): Stats; - export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function linkSync(srcpath: string, dstpath: string): void; - export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; - export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; - export function readlinkSync(path: string): string; - export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; - export function realpath(path: string, cache: { [path: string]: string }, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; - export function realpathSync(path: string, cache?: { [path: string]: string }): string; - /* - * Asynchronous unlink - deletes the file specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous unlink - deletes the file specified in {path} - * - * @param path - */ - export function unlinkSync(path: string): void; - /* - * Asynchronous rmdir - removes the directory specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous rmdir - removes the directory specified in {path} - * - * @param path - */ - export function rmdirSync(path: string): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdirSync(path: string, mode?: number): void; - /* - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdirSync(path: string, mode?: string): void; - /* - * Asynchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * - * @param prefix - * @param callback The created folder path is passed as a string to the callback's second parameter. - */ - export function mkdtemp(prefix: string, callback?: (err: NodeJS.ErrnoException, folder: string) => void): void; - /* - * Synchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. - * - * @param prefix - * @returns Returns the created folder path. - */ - export function mkdtempSync(prefix: string): string; - export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; - export function readdirSync(path: string): string[]; - export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function closeSync(fd: number): void; - export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function openSync(path: string, flags: string, mode?: number): number; - export function openSync(path: string, flags: string, mode?: string): number; - export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimesSync(path: string, atime: number, mtime: number): void; - export function utimesSync(path: string, atime: Date, mtime: Date): void; - export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimesSync(fd: number, atime: number, mtime: number): void; - export function futimesSync(fd: number, atime: Date, mtime: Date): void; - export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fsyncSync(fd: number): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number; - export function writeSync(fd: number, data: any, position?: number, enconding?: string): number; - export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; - export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding - */ - export function readFileSync(filename: string, encoding: string): string; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. - */ - export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. - */ - export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; - export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; - export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; - export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; - export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; - export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; - export function exists(path: string, callback?: (exists: boolean) => void): void; - export function existsSync(path: string): boolean; - /** Constant for fs.access(). File is visible to the calling process. */ - export var F_OK: number; - /** Constant for fs.access(). File can be read by the calling process. */ - export var R_OK: number; - /** Constant for fs.access(). File can be written by the calling process. */ - export var W_OK: number; - /** Constant for fs.access(). File can be executed by the calling process. */ - export var X_OK: number; - /** Tests a user's permissions for the file specified by path. */ - export function access(path: string, callback: (err: NodeJS.ErrnoException) => void): void; - export function access(path: string, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; - /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ - export function accessSync(path: string, mode?: number): void; - export function createReadStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - autoClose?: boolean; - }): ReadStream; - export function createWriteStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - }): WriteStream; -} - -declare module "path" { - - /** - * A parsed path object generated by path.parse() or consumed by path.format(). - */ - export interface ParsedPath { - /** - * The root of the path such as '/' or 'c:\' - */ - root: string; - /** - * The full directory path such as '/home/user/dir' or 'c:\path\dir' - */ - dir: string; - /** - * The file name including extension (if any) such as 'index.html' - */ - base: string; - /** - * The file extension (if any) such as '.html' - */ - ext: string; - /** - * The file name without extension (if any) such as 'index' - */ - name: string; - } - - /** - * Normalize a string path, reducing '..' and '.' parts. - * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. - * - * @param p string path to normalize. - */ - export function normalize(p: string): string; - /** - * Join all arguments together and normalize the resulting path. - * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. - * - * @param paths string paths to join. - */ - export function join(...paths: any[]): string; - /** - * Join all arguments together and normalize the resulting path. - * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. - * - * @param paths string paths to join. - */ - export function join(...paths: string[]): string; - /** - * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. - * - * Starting from leftmost {from} paramter, resolves {to} to an absolute path. - * - * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. - * - * @param pathSegments string paths to join. Non-string arguments are ignored. - */ - export function resolve(...pathSegments: any[]): string; - /** - * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. - * - * @param path path to test. - */ - export function isAbsolute(path: string): boolean; - /** - * Solve the relative path from {from} to {to}. - * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. - * - * @param from - * @param to - */ - export function relative(from: string, to: string): string; - /** - * Return the directory name of a path. Similar to the Unix dirname command. - * - * @param p the path to evaluate. - */ - export function dirname(p: string): string; - /** - * Return the last portion of a path. Similar to the Unix basename command. - * Often used to extract the file name from a fully qualified path. - * - * @param p the path to evaluate. - * @param ext optionally, an extension to remove from the result. - */ - export function basename(p: string, ext?: string): string; - /** - * Return the extension of the path, from the last '.' to end of string in the last portion of the path. - * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string - * - * @param p the path to evaluate. - */ - export function extname(p: string): string; - /** - * The platform-specific file separator. '\\' or '/'. - */ - export var sep: string; - /** - * The platform-specific file delimiter. ';' or ':'. - */ - export var delimiter: string; - /** - * Returns an object from a path string - the opposite of format(). - * - * @param pathString path to evaluate. - */ - export function parse(pathString: string): ParsedPath; - /** - * Returns a path string from an object - the opposite of parse(). - * - * @param pathString path to evaluate. - */ - export function format(pathObject: ParsedPath): string; - - export module posix { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } - - export module win32 { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } -} - -declare module "string_decoder" { - export interface NodeStringDecoder { - write(buffer: Buffer): string; - end(): string; - } - export var StringDecoder: { - new (encoding?: string): NodeStringDecoder; - }; -} - -declare module "tls" { - import * as crypto from "crypto"; - import * as net from "net"; - import * as stream from "stream"; - - var CLIENT_RENEG_LIMIT: number; - var CLIENT_RENEG_WINDOW: number; - - export interface TlsOptions { - host?: string; - port?: number; - pfx?: any; //string or buffer - key?: any; //string or buffer - passphrase?: string; - cert?: any; - ca?: any; //string or buffer - crl?: any; //string or string array - ciphers?: string; - honorCipherOrder?: any; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; //array or Buffer; - SNICallback?: (servername: string) => any; - } - - export interface ConnectionOptions { - host?: string; - port?: number; - socket?: net.Socket; - pfx?: string | Buffer - key?: string | Buffer - passphrase?: string; - cert?: string | Buffer - ca?: (string | Buffer)[]; - rejectUnauthorized?: boolean; - NPNProtocols?: (string | Buffer)[]; - servername?: string; - } - - export interface Server extends net.Server { - close(): Server; - address(): { port: number; family: string; address: string; }; - addContext(hostName: string, credentials: { - key: string; - cert: string; - ca: string; - }): void; - maxConnections: number; - connections: number; - } - - export interface ClearTextStream extends stream.Duplex { - authorized: boolean; - authorizationError: Error; - getPeerCertificate(): any; - getCipher: { - name: string; - version: string; - }; - address: { - port: number; - family: string; - address: string; - }; - remoteAddress: string; - remotePort: number; - } - - export interface SecurePair { - encrypted: any; - cleartext: any; - } - - export interface SecureContextOptions { - pfx?: string | Buffer; - key?: string | Buffer; - passphrase?: string; - cert?: string | Buffer; - ca?: string | Buffer; - crl?: string | string[] - ciphers?: string; - honorCipherOrder?: boolean; - } - - export interface SecureContext { - context: any; - } - - export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) => void): Server; - export function connect(options: TlsOptions, secureConnectionListener?: () => void): ClearTextStream; - export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; - export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; - export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; - export function createSecureContext(details: SecureContextOptions): SecureContext; -} - -declare module "crypto" { - export interface CredentialDetails { - pfx: string; - key: string; - passphrase: string; - cert: string; - ca: string | string[]; - crl: string | string[]; - ciphers: string; - } - export interface Credentials { context?: any; } - export function createCredentials(details: CredentialDetails): Credentials; - export function createHash(algorithm: string): Hash; - export function createHmac(algorithm: string, key: string): Hmac; - export function createHmac(algorithm: string, key: Buffer): Hmac; - export interface Hash { - update(data: any, input_encoding?: string): Hash; - digest(encoding: 'buffer'): Buffer; - digest(encoding: string): any; - digest(): Buffer; - } - export interface Hmac extends NodeJS.ReadWriteStream { - update(data: any, input_encoding?: string): Hmac; - digest(encoding: 'buffer'): Buffer; - digest(encoding: string): any; - digest(): Buffer; - } - export function createCipher(algorithm: string, password: any): Cipher; - export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; - export interface Cipher extends NodeJS.ReadWriteStream { - update(data: Buffer): Buffer; - update(data: string, input_encoding: "utf8" | "ascii" | "binary"): Buffer; - update(data: Buffer, input_encoding: any, output_encoding: "binary" | "base64" | "hex"): string; - update(data: string, input_encoding: "utf8" | "ascii" | "binary", output_encoding: "binary" | "base64" | "hex"): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding: boolean): void; - getAuthTag(): Buffer; - } - export function createDecipher(algorithm: string, password: any): Decipher; - export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; - export interface Decipher extends NodeJS.ReadWriteStream { - update(data: Buffer): Buffer; - update(data: string, input_encoding: "binary" | "base64" | "hex"): Buffer; - update(data: Buffer, input_encoding: any, output_encoding: "utf8" | "ascii" | "binary"): string; - update(data: string, input_encoding: "binary" | "base64" | "hex", output_encoding: "utf8" | "ascii" | "binary"): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding: boolean): void; - setAuthTag(tag: Buffer): void; - } - export function createSign(algorithm: string): Signer; - export interface Signer extends NodeJS.WritableStream { - update(data: any): void; - sign(private_key: string, output_format: string): string; - } - export function createVerify(algorith: string): Verify; - export interface Verify extends NodeJS.WritableStream { - update(data: any): void; - verify(object: string, signature: string, signature_format?: string): boolean; - } - export function createDiffieHellman(prime_length: number): DiffieHellman; - export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; - export interface DiffieHellman { - generateKeys(encoding?: string): string; - computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; - getPrime(encoding?: string): string; - getGenerator(encoding: string): string; - getPublicKey(encoding?: string): string; - getPrivateKey(encoding?: string): string; - setPublicKey(public_key: string, encoding?: string): void; - setPrivateKey(public_key: string, encoding?: string): void; - } - export function getDiffieHellman(group_name: string): DiffieHellman; - export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number): Buffer; - export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; - export function randomBytes(size: number): Buffer; - export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; - export function pseudoRandomBytes(size: number): Buffer; - export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; - export interface RsaPublicKey { - key: string; - padding?: any; - } - export interface RsaPrivateKey { - key: string; - passphrase?: string, - padding?: any; - } - export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer - export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer -} - -declare module "stream" { - import * as events from "events"; - - export class Stream extends events.EventEmitter { - pipe(destination: T, options?: { end?: boolean; }): T; - } - - export interface ReadableOptions { - highWaterMark?: number; - encoding?: string; - objectMode?: boolean; - } - - export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { - readable: boolean; - constructor(opts?: ReadableOptions); - protected _read(size: number): void; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: any): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - } - - export interface WritableOptions { - highWaterMark?: number; - decodeStrings?: boolean; - objectMode?: boolean; - } - - export class Writable extends events.EventEmitter implements NodeJS.WritableStream { - writable: boolean; - constructor(opts?: WritableOptions); - protected _write(chunk: any, encoding: string, callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - } - - export interface DuplexOptions extends ReadableOptions, WritableOptions { - allowHalfOpen?: boolean; - } - - // Note: Duplex extends both Readable and Writable. - export class Duplex extends Readable implements NodeJS.ReadWriteStream { - writable: boolean; - constructor(opts?: DuplexOptions); - protected _write(chunk: any, encoding: string, callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - } - - export interface TransformOptions extends ReadableOptions, WritableOptions { } - - // Note: Transform lacks the _read and _write methods of Readable/Writable. - export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { - readable: boolean; - writable: boolean; - constructor(opts?: TransformOptions); - protected _transform(chunk: any, encoding: string, callback: Function): void; - protected _flush(callback: Function): void; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: any): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - } - - export class PassThrough extends Transform { } -} - -declare module "util" { - export interface InspectOptions { - showHidden?: boolean; - depth?: number; - colors?: boolean; - customInspect?: boolean; - } - - export function format(format: any, ...param: any[]): string; - export function debug(string: string): void; - export function error(...param: any[]): void; - export function puts(...param: any[]): void; - export function print(...param: any[]): void; - export function log(string: string): void; - export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; - export function inspect(object: any, options: InspectOptions): string; - export function isArray(object: any): boolean; - export function isRegExp(object: any): boolean; - export function isDate(object: any): boolean; - export function isError(object: any): boolean; - export function inherits(constructor: any, superConstructor: any): void; - export function debuglog(key: string): (msg: string, ...param: any[]) => void; -} - -declare module "assert" { - function internal(value: any, message?: string): void; - namespace internal { - export class AssertionError implements Error { - name: string; - message: string; - actual: any; - expected: any; - operator: string; - generatedMessage: boolean; - - constructor(options?: { - message?: string; actual?: any; expected?: any; - operator?: string; stackStartFunction?: Function - }); - } - - export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; - export function ok(value: any, message?: string): void; - export function equal(actual: any, expected: any, message?: string): void; - export function notEqual(actual: any, expected: any, message?: string): void; - export function deepEqual(actual: any, expected: any, message?: string): void; - export function notDeepEqual(acutal: any, expected: any, message?: string): void; - export function strictEqual(actual: any, expected: any, message?: string): void; - export function notStrictEqual(actual: any, expected: any, message?: string): void; - export function deepStrictEqual(actual: any, expected: any, message?: string): void; - export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; - export var throws: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export var doesNotThrow: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export function ifError(value: any): void; - } - - export = internal; -} - -declare module "tty" { - import * as net from "net"; - - export function isatty(fd: number): boolean; - export interface ReadStream extends net.Socket { - isRaw: boolean; - setRawMode(mode: boolean): void; - isTTY: boolean; - } - export interface WriteStream extends net.Socket { - columns: number; - rows: number; - isTTY: boolean; - } -} - -declare module "domain" { - import * as events from "events"; - - export class Domain extends events.EventEmitter implements NodeJS.Domain { - run(fn: Function): void; - add(emitter: events.EventEmitter): void; - remove(emitter: events.EventEmitter): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - } - - export function create(): Domain; -} - -declare module "constants" { - export var E2BIG: number; - export var EACCES: number; - export var EADDRINUSE: number; - export var EADDRNOTAVAIL: number; - export var EAFNOSUPPORT: number; - export var EAGAIN: number; - export var EALREADY: number; - export var EBADF: number; - export var EBADMSG: number; - export var EBUSY: number; - export var ECANCELED: number; - export var ECHILD: number; - export var ECONNABORTED: number; - export var ECONNREFUSED: number; - export var ECONNRESET: number; - export var EDEADLK: number; - export var EDESTADDRREQ: number; - export var EDOM: number; - export var EEXIST: number; - export var EFAULT: number; - export var EFBIG: number; - export var EHOSTUNREACH: number; - export var EIDRM: number; - export var EILSEQ: number; - export var EINPROGRESS: number; - export var EINTR: number; - export var EINVAL: number; - export var EIO: number; - export var EISCONN: number; - export var EISDIR: number; - export var ELOOP: number; - export var EMFILE: number; - export var EMLINK: number; - export var EMSGSIZE: number; - export var ENAMETOOLONG: number; - export var ENETDOWN: number; - export var ENETRESET: number; - export var ENETUNREACH: number; - export var ENFILE: number; - export var ENOBUFS: number; - export var ENODATA: number; - export var ENODEV: number; - export var ENOENT: number; - export var ENOEXEC: number; - export var ENOLCK: number; - export var ENOLINK: number; - export var ENOMEM: number; - export var ENOMSG: number; - export var ENOPROTOOPT: number; - export var ENOSPC: number; - export var ENOSR: number; - export var ENOSTR: number; - export var ENOSYS: number; - export var ENOTCONN: number; - export var ENOTDIR: number; - export var ENOTEMPTY: number; - export var ENOTSOCK: number; - export var ENOTSUP: number; - export var ENOTTY: number; - export var ENXIO: number; - export var EOPNOTSUPP: number; - export var EOVERFLOW: number; - export var EPERM: number; - export var EPIPE: number; - export var EPROTO: number; - export var EPROTONOSUPPORT: number; - export var EPROTOTYPE: number; - export var ERANGE: number; - export var EROFS: number; - export var ESPIPE: number; - export var ESRCH: number; - export var ETIME: number; - export var ETIMEDOUT: number; - export var ETXTBSY: number; - export var EWOULDBLOCK: number; - export var EXDEV: number; - export var WSAEINTR: number; - export var WSAEBADF: number; - export var WSAEACCES: number; - export var WSAEFAULT: number; - export var WSAEINVAL: number; - export var WSAEMFILE: number; - export var WSAEWOULDBLOCK: number; - export var WSAEINPROGRESS: number; - export var WSAEALREADY: number; - export var WSAENOTSOCK: number; - export var WSAEDESTADDRREQ: number; - export var WSAEMSGSIZE: number; - export var WSAEPROTOTYPE: number; - export var WSAENOPROTOOPT: number; - export var WSAEPROTONOSUPPORT: number; - export var WSAESOCKTNOSUPPORT: number; - export var WSAEOPNOTSUPP: number; - export var WSAEPFNOSUPPORT: number; - export var WSAEAFNOSUPPORT: number; - export var WSAEADDRINUSE: number; - export var WSAEADDRNOTAVAIL: number; - export var WSAENETDOWN: number; - export var WSAENETUNREACH: number; - export var WSAENETRESET: number; - export var WSAECONNABORTED: number; - export var WSAECONNRESET: number; - export var WSAENOBUFS: number; - export var WSAEISCONN: number; - export var WSAENOTCONN: number; - export var WSAESHUTDOWN: number; - export var WSAETOOMANYREFS: number; - export var WSAETIMEDOUT: number; - export var WSAECONNREFUSED: number; - export var WSAELOOP: number; - export var WSAENAMETOOLONG: number; - export var WSAEHOSTDOWN: number; - export var WSAEHOSTUNREACH: number; - export var WSAENOTEMPTY: number; - export var WSAEPROCLIM: number; - export var WSAEUSERS: number; - export var WSAEDQUOT: number; - export var WSAESTALE: number; - export var WSAEREMOTE: number; - export var WSASYSNOTREADY: number; - export var WSAVERNOTSUPPORTED: number; - export var WSANOTINITIALISED: number; - export var WSAEDISCON: number; - export var WSAENOMORE: number; - export var WSAECANCELLED: number; - export var WSAEINVALIDPROCTABLE: number; - export var WSAEINVALIDPROVIDER: number; - export var WSAEPROVIDERFAILEDINIT: number; - export var WSASYSCALLFAILURE: number; - export var WSASERVICE_NOT_FOUND: number; - export var WSATYPE_NOT_FOUND: number; - export var WSA_E_NO_MORE: number; - export var WSA_E_CANCELLED: number; - export var WSAEREFUSED: number; - export var SIGHUP: number; - export var SIGINT: number; - export var SIGILL: number; - export var SIGABRT: number; - export var SIGFPE: number; - export var SIGKILL: number; - export var SIGSEGV: number; - export var SIGTERM: number; - export var SIGBREAK: number; - export var SIGWINCH: number; - export var SSL_OP_ALL: number; - export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; - export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; - export var SSL_OP_CISCO_ANYCONNECT: number; - export var SSL_OP_COOKIE_EXCHANGE: number; - export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; - export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; - export var SSL_OP_EPHEMERAL_RSA: number; - export var SSL_OP_LEGACY_SERVER_CONNECT: number; - export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; - export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; - export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; - export var SSL_OP_NETSCAPE_CA_DN_BUG: number; - export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; - export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NO_COMPRESSION: number; - export var SSL_OP_NO_QUERY_MTU: number; - export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; - export var SSL_OP_NO_SSLv2: number; - export var SSL_OP_NO_SSLv3: number; - export var SSL_OP_NO_TICKET: number; - export var SSL_OP_NO_TLSv1: number; - export var SSL_OP_NO_TLSv1_1: number; - export var SSL_OP_NO_TLSv1_2: number; - export var SSL_OP_PKCS1_CHECK_1: number; - export var SSL_OP_PKCS1_CHECK_2: number; - export var SSL_OP_SINGLE_DH_USE: number; - export var SSL_OP_SINGLE_ECDH_USE: number; - export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; - export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; - export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; - export var SSL_OP_TLS_D5_BUG: number; - export var SSL_OP_TLS_ROLLBACK_BUG: number; - export var ENGINE_METHOD_DSA: number; - export var ENGINE_METHOD_DH: number; - export var ENGINE_METHOD_RAND: number; - export var ENGINE_METHOD_ECDH: number; - export var ENGINE_METHOD_ECDSA: number; - export var ENGINE_METHOD_CIPHERS: number; - export var ENGINE_METHOD_DIGESTS: number; - export var ENGINE_METHOD_STORE: number; - export var ENGINE_METHOD_PKEY_METHS: number; - export var ENGINE_METHOD_PKEY_ASN1_METHS: number; - export var ENGINE_METHOD_ALL: number; - export var ENGINE_METHOD_NONE: number; - export var DH_CHECK_P_NOT_SAFE_PRIME: number; - export var DH_CHECK_P_NOT_PRIME: number; - export var DH_UNABLE_TO_CHECK_GENERATOR: number; - export var DH_NOT_SUITABLE_GENERATOR: number; - export var NPN_ENABLED: number; - export var RSA_PKCS1_PADDING: number; - export var RSA_SSLV23_PADDING: number; - export var RSA_NO_PADDING: number; - export var RSA_PKCS1_OAEP_PADDING: number; - export var RSA_X931_PADDING: number; - export var RSA_PKCS1_PSS_PADDING: number; - export var POINT_CONVERSION_COMPRESSED: number; - export var POINT_CONVERSION_UNCOMPRESSED: number; - export var POINT_CONVERSION_HYBRID: number; - export var O_RDONLY: number; - export var O_WRONLY: number; - export var O_RDWR: number; - export var S_IFMT: number; - export var S_IFREG: number; - export var S_IFDIR: number; - export var S_IFCHR: number; - export var S_IFLNK: number; - export var O_CREAT: number; - export var O_EXCL: number; - export var O_TRUNC: number; - export var O_APPEND: number; - export var F_OK: number; - export var R_OK: number; - export var W_OK: number; - export var X_OK: number; - export var UV_UDP_REUSEADDR: number; - export var EDQUOT: number; - export var EMULTIHOP: number; - export var ESTALE: number; - export var O_DIRECT: number; - export var O_DIRECTORY: number; - export var O_NOCTTY: number; - export var O_NOFOLLOW: number; - export var O_NONBLOCK: number; - export var O_SYNC: number; - export var SIGALRM: number; - export var SIGBUS: number; - export var SIGCHLD: number; - export var SIGCONT: number; - export var SIGIO: number; - export var SIGIOT: number; - export var SIGPIPE: number; - export var SIGPOLL: number; - export var SIGPROF: number; - export var SIGPWR: number; - export var SIGQUIT: number; - export var SIGSTKFLT: number; - export var SIGSTOP: number; - export var SIGSYS: number; - export var SIGTRAP: number; - export var SIGTSTP: number; - export var SIGTTIN: number; - export var SIGTTOU: number; - export var SIGUNUSED: number; - export var SIGURG: number; - export var SIGUSR1: number; - export var SIGUSR2: number; - export var SIGVTALRM: number; - export var SIGXCPU: number; - export var SIGXFSZ: number; - export var S_IFBLK: number; - export var S_IFIFO: number; - export var S_IFSOCK: number; - export var S_IRGRP: number; - export var S_IROTH: number; - export var S_IRUSR: number; - export var S_IRWXG: number; - export var S_IRWXO: number; - export var S_IRWXU: number; - export var S_IWGRP: number; - export var S_IWOTH: number; - export var S_IWUSR: number; - export var S_IXGRP: number; - export var S_IXOTH: number; - export var S_IXUSR: number; - export var defaultCipherList: string; - export var defaultCoreCipherList: string; -} - -declare module "process" { - export = process; -} - -declare module "console" { - export = console; -} diff --git a/lib/definitions/osenv.d.ts b/lib/definitions/osenv.d.ts new file mode 100644 index 0000000000..0fc84a829b --- /dev/null +++ b/lib/definitions/osenv.d.ts @@ -0,0 +1,4 @@ +declare module "osenv" { + function home(): string; + function shell(): string; +} \ No newline at end of file diff --git a/lib/definitions/unzip.d.ts b/lib/definitions/unzip.d.ts new file mode 100644 index 0000000000..de6f8bb632 --- /dev/null +++ b/lib/definitions/unzip.d.ts @@ -0,0 +1,3 @@ +declare module "unzip" { + export function Extract(options: { path: string }): NodeJS.WritableStream; +} \ No newline at end of file diff --git a/lib/doctor.ts b/lib/doctor.ts new file mode 100644 index 0000000000..552f866d45 --- /dev/null +++ b/lib/doctor.ts @@ -0,0 +1,163 @@ +import { Constants } from "./constants"; +import { SysInfo } from "./sys-info"; +import { EOL } from "os"; +import { HostInfo } from "./host-info"; +import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; +import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local-build-requirements"; +import { Helpers } from "./helpers"; +import * as semver from "semver"; + +export class Doctor { + private static MIN_SUPPORTED_POD_VERSION = "0.38.2"; + + constructor(private sysInfo: SysInfo, + private hostInfo: HostInfo, + private androidLocalBuildRequirements: AndroidLocalBuildRequirements, + private iosLocalBuildRequirements: IosLocalBuildRequirements, + private helpers: Helpers) { } + + public async canExecuteLocalBuild(platform: string): Promise { + this.validatePlatform(platform); + + if (platform.toLocaleLowerCase() === Constants.ANDROID_PLATFORM_NAME.toLocaleLowerCase()) { + return await this.androidLocalBuildRequirements.checkRequirements(); + } else if (platform.toLocaleLowerCase() === Constants.IOS_PLATFORM_NAME.toLocaleLowerCase()) { + return await this.iosLocalBuildRequirements.checkRequirements(); + } + + return false; + } + + public async getWarnings(): Promise { + const result: IWarning[] = []; + const sysInfoData = await this.sysInfo.getSysInfo(); + + if (!sysInfoData.adbVer) { + result.push({ + warning: "WARNING: adb from the Android SDK is not installed or is not configured properly. ", + additionalInformation: "For Android-related operations, the AppBuilder CLI will use a built-in version of adb." + EOL + + "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL + + "Android devices, verify that you have installed the latest Android SDK and" + EOL + + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL + }); + } + + if (!sysInfoData.androidInstalled) { + result.push({ + warning: "WARNING: The Android SDK is not installed or is not configured properly.", + additionalInformation: "You will not be able to run your apps in the native emulator. To be able to run apps" + EOL + + "in the native Android emulator, verify that you have installed the latest Android SDK " + EOL + + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL + }); + } + + if (this.hostInfo.isDarwin) { + if (!sysInfoData.xcodeVer) { + result.push({ + warning: "WARNING: Xcode is not installed or is not configured properly.", + additionalInformation: "You will not be able to build your projects for iOS or run them in the iOS Simulator." + EOL + + "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + EOL + }); + } + + if (!sysInfoData.xcodeprojGemLocation) { + result.push({ + warning: "WARNING: xcodeproj gem is not installed or is not configured properly.", + additionalInformation: "You will not be able to build your projects for iOS." + EOL + + "To be able to build for iOS and run apps in the native emulator, verify that you have installed xcodeproj." + EOL + }); + } + + if (!sysInfoData.cocoapodVer) { + result.push({ + warning: "WARNING: CocoaPods is not installed or is not configured properly.", + additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL + + "To be able to build such projects, verify that you have installed CocoaPods." + }); + } + + if (sysInfoData.xcodeVer && sysInfoData.cocoapodVer) { + let isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly(); + if (!isCocoaPodsWorkingCorrectly) { + result.push({ + warning: "WARNING: There was a problem with CocoaPods", + additionalInformation: "Verify that CocoaPods are configured properly." + }); + } + } + + if (sysInfoData.cocoapodVer && semver.valid(sysInfoData.cocoapodVer) && semver.lt(sysInfoData.cocoapodVer, Doctor.MIN_SUPPORTED_POD_VERSION)) { + result.push({ + warning: `WARNING: Your current CocoaPods version is earlier than ${Doctor.MIN_SUPPORTED_POD_VERSION}.`, + additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL + + `To be able to build such projects, verify that you have at least ${Doctor.MIN_SUPPORTED_POD_VERSION} version installed.` + }); + } + + if (!sysInfoData.monoVer || semver.lt(sysInfoData.monoVer, "3.12.0")) { + result.push({ + warning: "WARNING: Mono 3.12 or later is not installed or not configured properly.", + additionalInformation: "You will not be able to work with Android devices in the device simulator or debug on connected Android devices." + EOL + + "To be able to work with Android in the device simulator and debug on connected Android devices," + EOL + + "download and install Mono 3.12 or later from http://www.mono-project.com/download/" + EOL + }); + } + } else { + result.push({ + warning: "NOTE: You can develop for iOS only on Mac OS X systems.", + additionalInformation: "To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL + }); + } + + if (!sysInfoData.itunesInstalled) { + result.push({ + warning: "WARNING: iTunes is not installed.", + additionalInformation: "You will not be able to work with iOS devices via cable connection." + EOL + + "To be able to work with connected iOS devices," + EOL + + "download and install iTunes from http://www.apple.com" + EOL + }); + } + + if (!sysInfoData.javaVer) { + result.push({ + warning: "WARNING: The Java Development Kit (JDK) is not installed or is not configured properly.", + additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL + + "to perform some Android-related operations. To ensure that you can develop and" + EOL + + "test your apps for Android, verify that you have installed the JDK as" + EOL + + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)" + EOL + + "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + EOL + }); + } + + if (!sysInfoData.gitVer) { + result.push({ + warning: "WARNING: Git is not installed or not configured properly.", + additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL + + "To be able to work with Screen Builder projects, download and install Git as described" + EOL + + "in https://git-scm.com/downloads and add the git executable to your PATH." + EOL + }); + } + + return result; + } + + private isPlatformSupported(platform: string): boolean { + return Constants.SUPPORTED_PLATFORMS.reduce((prevValue, currentValue) => { + if (!prevValue) { + return currentValue.toLocaleLowerCase() === platform.toLocaleLowerCase(); + } else { + return prevValue; + } + }, false); + } + + private validatePlatform(platform: string): void { + if (!platform) { + throw new Error("You must specify a platform."); + } + + if (!this.isPlatformSupported(platform)) { + throw new Error(`Platform ${platform} is not supported. The supported platforms are: ${Constants.SUPPORTED_PLATFORMS.join(", ")}`); + } + } +} diff --git a/lib/helpers.ts b/lib/helpers.ts new file mode 100644 index 0000000000..3ded21a66e --- /dev/null +++ b/lib/helpers.ts @@ -0,0 +1,27 @@ +import { platform } from "os"; + +export class Helpers { + public quoteString(value: string): string { + if (!value) { + return value; + } + + return (platform() === "win32") ? this.cmdQuote(value) : this.bashQuote(value); + } + + private bashQuote(s: string): string { + if (s[0] === "'" && s[s.length - 1] === "'") { + return s; + } + // replace ' with '"'"' and wrap in '' + return "'" + s.replace(/'/g, '\'"\'"\'') + "'"; + } + + private cmdQuote(s: string): string { + if (s[0] === '"' && s[s.length - 1] === '"') { + return s; + } + // replace " with \" and wrap in "" + return '"' + s.replace(/"/g, '\\"') + '"'; + } +} diff --git a/lib/host-info.ts b/lib/host-info.ts new file mode 100644 index 0000000000..ff08a7022f --- /dev/null +++ b/lib/host-info.ts @@ -0,0 +1,43 @@ +import { WinReg } from "./winreg"; + +export class HostInfo { + private static WIN32_NAME = "win32"; + private static PROCESSOR_ARCHITEW6432 = "PROCESSOR_ARCHITEW6432"; + private static DARWIN_OS_NAME = "darwin"; + private static LINUX_OS_NAME = "linux"; + private static DOT_NET_REGISTRY_PATH = "\\Software\\Microsoft\\NET Framework Setup\\NDP\\v4\\Client"; + + constructor(private winreg: WinReg) { } + + public get isWindows(): boolean { + return process.platform === HostInfo.WIN32_NAME; + } + + public get isWindows64(): boolean { + return this.isWindows && (this.isNode64Bit || process.env.hasOwnProperty(HostInfo.PROCESSOR_ARCHITEW6432)); + } + + public get isWindows32() { + return this.isWindows && !this.isWindows64; + } + + public get isDarwin(): boolean { + return process.platform === HostInfo.DARWIN_OS_NAME; + } + + public get isLinux(): boolean { + return process.platform === HostInfo.LINUX_OS_NAME; + } + + public get isNode64Bit(): boolean { + return process.arch === "x64"; + } + + public dotNetVersion(): Promise { + if (this.isWindows) { + return this.winreg.getRegistryValue("Version", this.winreg.registryKeys.HKLM, HostInfo.DOT_NET_REGISTRY_PATH); + } else { + return Promise.resolve(null); + } + } +} diff --git a/lib/index.ts b/lib/index.ts index dbac53f416..3d23ca3a67 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,18 +1,25 @@ import { ChildProcess } from "./wrappers/child-process"; +import { FileSystem } from "./wrappers/file-system"; import { SysInfo } from "./sys-info"; +import { HostInfo } from "./host-info"; +import { WinReg } from "./winreg"; +import { Helpers } from "./helpers"; +import { Doctor } from "./doctor"; +import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; +import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local-build-requirements"; const childProcess = new ChildProcess(); -const sysInfo = new SysInfo(childProcess); +const winreg = new WinReg(); +const hostInfo = new HostInfo(winreg); +const fileSystem = new FileSystem(); +const helpers = new Helpers(); +const sysInfo = new SysInfo(childProcess, hostInfo, fileSystem, winreg, helpers); -const getJavaVersion = (): Promise => { - return sysInfo.getJavaVersion(); -}; - -const getJavaCompilerVersion = (): Promise => { - return sysInfo.getJavaCompilerVersion(); -}; +const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(sysInfo); +const iosLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); +const doctor = new Doctor(sysInfo, hostInfo, androidLocalBuildRequirements, iosLocalBuildRequirements, helpers); export { - getJavaVersion, - getJavaCompilerVersion + sysInfo, + doctor }; diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts new file mode 100644 index 0000000000..54acb50443 --- /dev/null +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -0,0 +1,16 @@ +import { SysInfo } from "../sys-info"; + +export class AndroidLocalBuildRequirements { + constructor(private sysInfo: SysInfo) { } + + public async checkRequirements(): Promise { + if (!await this.sysInfo.isAndroidInstalled() || + !await this.sysInfo.getJavaCompilerVersion() || + !await this.sysInfo.getJavaVersion() || + !await this.sysInfo.getAdbVersion()) { + return false; + } + + return true; + } +} diff --git a/lib/local-build-requirements/ios-local-build-requirements.ts b/lib/local-build-requirements/ios-local-build-requirements.ts new file mode 100644 index 0000000000..93acdf3a24 --- /dev/null +++ b/lib/local-build-requirements/ios-local-build-requirements.ts @@ -0,0 +1,17 @@ +import { SysInfo } from "../sys-info"; +import { HostInfo } from "../host-info"; + +export class IosLocalBuildRequirements { + constructor(private sysInfo: SysInfo, + private hostInfo: HostInfo) { } + + public async checkRequirements(): Promise { + if (!this.hostInfo.isDarwin || + !await this.sysInfo.getXCodeVersion() || + !await this.sysInfo.getXCodeProjGemLocation()) { + return false; + } + + return true; + } +} diff --git a/lib/sys-info.ts b/lib/sys-info.ts index dd42a8bd85..e732af6b4a 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -1,22 +1,58 @@ import { ChildProcess } from "./wrappers/child-process"; +import { FileSystem } from "./wrappers/file-system"; +import { HostInfo } from "./host-info"; +import { ExecOptions } from "child_process"; +import { WinReg } from "./winreg"; +import { Helpers } from "./helpers"; +import { platform } from "os"; import * as path from "path"; +import * as osenv from "osenv"; +import * as temp from "temp"; export class SysInfo { // Different java has different format for `java -version` command. private static JAVA_VERSION_REGEXP = /(?:openjdk|java) version \"((?:\d+\.)+(?:\d+))/i; private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im; + private static XCODE_VERSION_REGEXP = /Xcode (.*)/; + private static VERSION_REGEXP = /(\d{1,})\.(\d{1,})\.*([\w-]{0,})/m; + private static GIT_VERSION_REGEXP = /^git version (.*)/; + private static GRADLE_VERSION_REGEXP = /Gradle (.*)/i; + + private monoVerRegExp = /version (\d+[.]\d+[.]\d+) /gm; private javaVerCache: string; private javaCompilerVerCache: string; + private xCodeVerCache: string; + private npmVerCache: string; + private nodeGypVerCache: string; + private xCodeprojGemLocationCache: string; + private iTunesInstalledCache: boolean = null; + private cocoapodVerCache: string; + private osCache: string; + private adbVerCache: string; + private androidInstalledCache: boolean = null; + private monoVerCache: string; + private gitVerCache: string; + private gradleVerCache: string; + private sysInfoCache: ISysInfoData; + private isCocoaPodsWorkingCorrectlyCache: boolean = null; - constructor(private childProcess: ChildProcess) { } + constructor(private childProcess: ChildProcess, + private hostInfo: HostInfo, + private fileSystem: FileSystem, + private winreg: WinReg, + private helpers: Helpers) { } public async getJavaVersion(): Promise { if (!this.javaVerCache) { - const spawnResult = await this.childProcess.spawnFromEvent("java", ["-version"], "exit", { ignoreError: true }); - const matches = spawnResult && SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr); - this.javaVerCache = matches && matches[1]; + try { + const spawnResult = await this.childProcess.spawnFromEvent("java", ["-version"], "exit"); + const matches = spawnResult && SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr); + this.javaVerCache = matches && matches[1]; + } catch (err) { + this.javaVerCache = null; + } } return this.javaVerCache; @@ -37,4 +73,257 @@ export class SysInfo { return this.javaCompilerVerCache; } + + public async getXCodeVersion(): Promise { + if (!this.xCodeVerCache && this.hostInfo.isDarwin) { + const output = await this.execCommand("xcodebuild -version"); + const xcodeVersionMatch = output && output.match(SysInfo.XCODE_VERSION_REGEXP); + + if (xcodeVersionMatch) { + this.xCodeVerCache = this.getVersionFromString(output); + } + } + + return this.xCodeVerCache; + } + + public async getNodeVersion(): Promise { + return this.getVersionFromString(process.version); + } + + public async getNpmVersion(): Promise { + if (!this.npmVerCache) { + const output = await this.execCommand("npm -v"); + this.npmVerCache = output ? output.split("\n")[0] : null; + } + + return this.npmVerCache; + } + + public async getNodeGypVersion(): Promise { + if (!this.nodeGypVerCache) { + const output = await this.execCommand("node-gyp -v"); + this.nodeGypVerCache = output ? this.getVersionFromString(output) : null; + } + + return this.nodeGypVerCache; + } + + public async getXCodeProjGemLocation(): Promise { + if (!this.xCodeprojGemLocationCache && this.hostInfo.isDarwin) { + const output = await this.execCommand("gem which xcodeproj"); + this.xCodeprojGemLocationCache = output ? output.trim() : null; + } + + return this.xCodeprojGemLocationCache; + } + + public async isITunesInstalled(): Promise { + if (this.iTunesInstalledCache === null && !this.hostInfo.isLinux) { + let coreFoundationDir: string; + let mobileDeviceDir: string; + + if (this.hostInfo.isWindows) { + const commonProgramFiles = this.hostInfo.isWindows64 ? process.env["CommonProgramFiles(x86)"] : process.env.CommonProgramFiles; + coreFoundationDir = path.join(commonProgramFiles, "Apple", "Apple Application Support"); + mobileDeviceDir = path.join(commonProgramFiles, "Apple", "Mobile Device Support"); + } else if (this.hostInfo.isDarwin) { + coreFoundationDir = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"; + mobileDeviceDir = "/System/Library/PrivateFrameworks/MobileDevice.framework/MobileDevice"; + } + + this.iTunesInstalledCache = await this.fileSystem.exists(coreFoundationDir) && await this.fileSystem.exists(mobileDeviceDir); + } + + return !!this.iTunesInstalledCache; + } + + public async getCocoapodVersion(): Promise { + if (!this.cocoapodVerCache && this.hostInfo.isDarwin) { + if (this.hostInfo.isDarwin) { + const output = await this.execCommand("pod --version"); + // Output of pod --version could contain some warnings. Find the version in it. + const cocoapodVersionMatch = output && output.match(SysInfo.VERSION_REGEXP); + if (cocoapodVersionMatch && cocoapodVersionMatch[0]) { + this.cocoapodVerCache = cocoapodVersionMatch[0].trim(); + } + } + } + + return this.cocoapodVerCache; + } + + public async getOs(): Promise { + if (!this.osCache) { + this.osCache = await (this.hostInfo.isWindows ? this.winVer() : this.unixVer()); + } + + return this.osCache; + } + + public async getAdbVersion(): Promise { + if (!this.adbVerCache) { + const output = await this.execCommand("adb version"); + this.adbVerCache = output ? this.getVersionFromString(output) : null; + } + + return this.adbVerCache; + } + + // `android -h` returns exit code 1 on successful invocation (Mac OS X for now, possibly Linux). + public async isAndroidInstalled(): Promise { + if (this.androidInstalledCache === null) { + let pathToAndroid = "android"; + if (this.hostInfo.isWindows) { + pathToAndroid = `${pathToAndroid}.bat`; + } + + try { + const output = await this.childProcess.spawnFromEvent(pathToAndroid, ["-h"], "close"); + if (output) { + output.stdout = output.stdout || ''; + this.androidInstalledCache = output.stdout.indexOf("android") >= 0; + } + } catch (err) { + this.androidInstalledCache = null; + } + } + + return !!this.androidInstalledCache; + } + + public async getMonoVersion(): Promise { + if (!this.monoVerCache) { + const output = await this.execCommand("mono --version"); + const match = this.monoVerRegExp.exec(output); + this.monoVerCache = match ? match[1] : null; + } + + return this.monoVerCache; + } + + public async getGitVersion(): Promise { + if (!this.gitVerCache) { + const output = await this.execCommand("git --version"); + const matches = SysInfo.GIT_VERSION_REGEXP.exec(output); + this.gitVerCache = matches && matches[1]; + } + + return this.gitVerCache; + } + + public async getGradleVersion(): Promise { + if (!this.gradleVerCache) { + const output = await this.execCommand("gradle -v"); + const matches = SysInfo.GRADLE_VERSION_REGEXP.exec(output); + + this.gradleVerCache = matches && matches[1]; + } + + return this.gradleVerCache; + } + + public async getSysInfo(): Promise { + if (!this.sysInfoCache) { + const result: ISysInfoData = Object.create(null); + + // os stuff + result.platform = platform(); + result.shell = osenv.shell(); + result.os = await this.getOs(); + + // node stuff + result.procArch = process.arch; + result.nodeVer = await this.getNodeVersion(); + result.npmVer = await this.getNpmVersion(); + result.nodeGypVer = await this.getNodeGypVersion(); + + result.dotNetVer = await this.hostInfo.dotNetVersion(); + result.javaVer = await this.getJavaVersion(); + result.javacVersion = await this.getJavaCompilerVersion(); + result.xcodeVer = await this.getXCodeVersion(); + result.xcodeprojGemLocation = await this.getXCodeProjGemLocation(); + result.itunesInstalled = await this.isITunesInstalled(); + result.cocoapodVer = await this.getCocoapodVersion(); + result.adbVer = await this.getAdbVersion(); + result.androidInstalled = await this.isAndroidInstalled(); + result.monoVer = await this.getMonoVersion(); + result.gitVer = await this.getGitVersion(); + result.gradleVer = await this.getGradleVersion(); + result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); + + this.sysInfoCache = result; + } + + return this.sysInfoCache; + } + + public async isCocoaPodsWorkingCorrectly(): Promise { + if (this.isCocoaPodsWorkingCorrectlyCache === null && this.hostInfo.isDarwin) { + temp.track(); + const tempDirectory = temp.mkdirSync("nativescript-check-cocoapods"); + const pathToXCodeProjectZip = path.join(__dirname, "..", "resources", "cocoapods-verification", "cocoapods.zip"); + + await this.fileSystem.extractZip(pathToXCodeProjectZip, tempDirectory); + + const xcodeProjectDir = path.join(tempDirectory, "cocoapods"); + + try { + let spawnResult = await this.childProcess.spawnFromEvent("pod", ["install"], "exit", { spawnOptions: { cwd: xcodeProjectDir } }); + if (spawnResult.exitCode) { + this.isCocoaPodsWorkingCorrectlyCache = false; + } else { + this.isCocoaPodsWorkingCorrectlyCache = await this.fileSystem.exists(path.join(xcodeProjectDir, "cocoapods.xcworkspace")); + } + } catch (err) { + this.isCocoaPodsWorkingCorrectlyCache = null; + } + } + + return !!this.isCocoaPodsWorkingCorrectlyCache; + } + + private async exec(cmd: string, execOptions?: ExecOptions): Promise { + if (cmd) { + try { + return await this.childProcess.exec(cmd, execOptions); + } catch (err) { + return null; + } + } + + return null; + } + + private async execCommand(cmd: string, execOptions?: ExecOptions): Promise { + const output = await this.exec(cmd, execOptions); + return output && output.stdout; + } + + private getVersionFromString(versionString: string): string { + const matches = versionString.match(SysInfo.VERSION_REGEXP); + if (matches) { + return `${matches[1]}.${matches[2]}.${matches[3] || 0}`; + } + + return null; + } + + private async winVer(): Promise { + let productName: string; + let currentVersion: string; + let currentBuild: string; + const hive = this.winreg.registryKeys.HKLM; + const key = "\\Software\\Microsoft\\Windows NT\\CurrentVersion"; + + productName = await this.winreg.getRegistryValue("ProductName", hive, key); + currentVersion = await this.winreg.getRegistryValue("CurrentVersion", hive, key); + currentBuild = await this.winreg.getRegistryValue("CurrentBuild", hive, key); + + return `${productName} ${currentVersion}.${currentBuild}`; + } + + private unixVer(): Promise { + return this.execCommand("uname -a"); + } } diff --git a/lib/winreg.ts b/lib/winreg.ts new file mode 100644 index 0000000000..3c46428cc7 --- /dev/null +++ b/lib/winreg.ts @@ -0,0 +1,41 @@ +import * as Registry from "winreg"; + +export class WinReg { + public registryKeys: IHiveIds = { + HKLM: { registry: Registry.HKLM }, + HKCU: { registry: Registry.HKCU }, + HKCR: { registry: Registry.HKCR }, + HKCC: { registry: Registry.HKCC }, + HKU: { registry: Registry.HKU } + }; + + public getRegistryItem(valueName: string, hive?: IHiveId, key?: string, host?: string): Promise { + return new Promise((resolve, reject) => { + const regKey = new Registry({ + hive: (hive && hive.registry) ? hive.registry : null, + key: key, + host: host + }); + + regKey.get(valueName, (err: Error, value: Registry.RegistryItem) => { + if (err) { + reject(err); + } else { + resolve(value); + } + }); + }); + } + + public getRegistryValue(valueName: string, hive?: IHiveId, key?: string, host?: string): Promise { + return new Promise((resolve, reject) => { + return this.getRegistryItem(valueName, hive, key, host) + .then((data) => { + resolve(data.value); + }) + .catch(() => { + resolve(null); + }); + }); + } +} diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts new file mode 100644 index 0000000000..922961e197 --- /dev/null +++ b/lib/wrappers/file-system.ts @@ -0,0 +1,18 @@ +import * as fs from "fs"; +import { Extract } from "unzip"; + +export class FileSystem { + public exists(path: string): Promise { + return new Promise((resolve) => { + fs.exists(path, resolve); + }); + } + + public extractZip(pathToZip: string, outputDir: string): Promise { + return new Promise((resolve, reject) => { + const stream = fs.createReadStream(pathToZip).pipe(Extract({ path: outputDir })); + stream.on("close", resolve); + stream.on("error", reject); + }); + } +} diff --git a/package.json b/package.json index aa60c38612..db396e39ad 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,9 @@ "homepage": "https://github.com/NativeScript/nativescript-doctor#readme", "devDependencies": { "@types/mocha": "2.2.32", + "@types/semver": "5.3.30", + "@types/temp": "0.8.29", + "@types/winreg": "1.2.30", "grunt": "1.0.1", "grunt-contrib-clean": "1.0.0", "grunt-contrib-watch": "1.0.0", @@ -36,5 +39,12 @@ "tslint": "3.15.1", "typescript": "2.0.3" }, - "dependencies": {} + "dependencies": { + "bluebird": "3.4.6", + "osenv": "0.1.3", + "semver": "5.3.0", + "temp": "0.8.3", + "unzip": "0.1.11", + "winreg": "1.2.2" + } } diff --git a/resources/cocoapods-verification/cocoapods.zip b/resources/cocoapods-verification/cocoapods.zip new file mode 100644 index 0000000000000000000000000000000000000000..2a6bad6635fa96942b4b8ec57385773516cbbb5e GIT binary patch literal 16919 zcmcJ01z40@*EZeVAuZjFbazTi$I#s%jnW9x9ZENYG$P#%N(hK_mvsJc&Oy;r@B4k< zKXW}Z56t!4>)vbaSZnRI6=lF7;6UzP9AQRMzuo-t0SAHtVq|M%YhY(!;9zz<72ONOKdq^&~8t3 zQ(tgJLHdHq0Do&y@m1cUrqp=A8;FcAKSh~y*J=#D{k!R?J8<8Y>uKG) z8$BID87(c1^&j#97{?$OgA`txz!gnkNvpZwm0o{YWRN9sX zXGXd7QK(qZt8;_9dJEHmOed`M4pT_fq30Owc>*6tT`ymB+1Hq)+#EHG7bufkTm4(2 z!Ll$QVxh(|)2l0{1Vx8-JyhTpRL`j_3*wUjVn_?raP~BzLQQ^3pDRmbeTR^_o-jaN ztUU^JMl9I&8zC!GEL#O`4Rg@j`+hrH8-#kjGox)>;SQpl%c%mY);%XKHo;ELLKl4E zY04RMc51qLaP}U2uJL~D;bmbAbFKBfRPQOFe0IK;p@tkrV^LPeXNZb097 zml5@`;A~>juk!9bk^8t#Et3PjsQPpX-Mu*6IAqxXmE4{8HMk*S#!|s2<=ufCA%1PT zIP<5lJ&1>O){+M(S(=);2qZCy(L6O?q@ds=Tiwx(m~TAA*W7q%4vU|*lJdaQE*-ov z)*g5CMQq6wC5<-dkGrNtN)?x)dN-F=Z&YQXan2w4)C34F6UJgxx2J(%ftltLP>A-Z z)e=G8CIgX{zrv1j&9pZ;{Tk$h5g9S7*Q<#^D?g%o92bay7`axrl&>B#tW4d{kRPFQ zRfiB5YH=Lbo1f(}Wj!9xY}D1+H$-PWrg0sEp_&BwqKd_aa>SVE zTyg25LaFnSqP6n{6({$|XS?usw#-o!k+-|GBL(=wkx2H-ME5tgWN;8rQJtwd3kF~t8s^gHGqG{^W=6r8JqJt;g(+-eE($~F~X1$pgzG|L=N?2bHVzEs zO_t45-$6#T0BVcfwM^R4By15Yp40MclhAGC0tz7n@$Xoksatl@$$w}mydP3 zyShwQ1&CyXu|L&k;d6)C;hn7Npg72-QCmT6COR>?%>c+ota8-Ef{qDwS#n=AZ+d-EK`^I?8}(` zugY!l^Ko{#b>pE_F_hDx7O3ExKzdDz*O>jY6+mNX0ozKD#5hm*)~-xr;rb8w^5$Q* zhwz=!%GM_@y6E5%!hDVk3wz`Wsatd=q02gY@Y!V6l%pAT1o%#A2jG&lFlnjYy(U)0 zTb4j`?8SAYv@scTkICxT=vQoZg)_o8W}R@R*ixE*9-ewiIGjhhny{KN$S}zG#8(Ut zKJjGBAOl&fPZ0TXRS2iY>1)ssGMi*LlRTEv+9+2b%wjgU*++Q#W7Sk<<5yNdU19dk ziHK#(y4c?(JSzp1SKjS-v!guMWk8?CfK8-He)XbUvGN`tyBe0}sVrOok8O4Mqw0X($=5YVYqjR^ zr94(D&ps|^*TcU}UU(lT%=gK(m}9wmLVmH>Tp)(EBHm+K*$Z+`7zlU#1~$xGTh;hO zITWL1oW3+RMsj%b(I-=2|5L;ov1HSC^p0Xl+Ep%PlGXqzO~jx|_cf8or7>>~`^0A1 ziekc@6iH13h9%igHyrW#ErFMV*x6o==#H!qoUKyP-6?c2jfg=+nA{l8nZxGUa-KMA z?h)ywAFORUIq_n!EpxU!b&^9DhoPWsTAWiLGsS|Url^w4mzjHHMJp;1njbS9r~>bAL1jPp<5ZKkxSy8>V-tAQkWNnm6+#a zQ6NU&?5I_D)P|Dvr_BsM#judim%3`uDgRj93R)Ab(FYoVlwWg1ERq|uTx{YU)8Fb@ zc^Ewu!jS&~&L}2PvU!xfLheNfiN?g%d%dx-RPq9Uj>n_h^aey$2EoDRu*r1#Nsz;I z8s4XNm*Yi#n5gh>{lrb2_5z;y#8DK%G^Av1acXDuZ8%AY-|A1pLF~6DJZSWXBL}LZ4(}1PoEghror6X2xNwG-{N1! zUO8$#jlm!$8zJE6xmEdFvq8MEQV&e7+H$x~XwFDn* zDMkm6OWNw6tPVj+5{lepN{Wt!WJ!`6O+H4DJ~xB#2rXprVx4duMwGz?Si>ldAU;)B zjTyqn@nd{!oXkzZf=89ynz>R)EH_dCReJI zJRp#U!;ez1@G8vbUJwnMfds9q`DrtYzw&d?a-w5g=7iOS`(#Ukhi@(G)w?kg3EY2c zb$JsPL0E<#6sgN1klHzf{9f9An3z0CaG7^~g=a_2z@?PL8n7Vo$y?;p;LwHwxk?8n=5m}NQEP6r7`=Z!hO=(3fjQ{3(d<_Q&O(Y4Xl5{UM3{=mJ@OeN*1 z1%)qkDp61u5^!(W4YB)^0uqgg-4n5JskFmBUK}c|H@rnihBL}}+2ejf2qv!h4X@>3 z=UU1BYl3xVFT`g&t(b|tMmE*yoE`OZ(OJNPtfzFMH@VbonRoXNZ>KoYL z#FZL9e+{Z5I<8OM4FVWT-uBSSItjBve%#dbXU*PFEFY-FcRELLt3Ev+chfse+qgpB zxGYo5OLhj*hE<0JAH<1WbpqEr7kG4aOVMj`1zSG%s%&%EZqiFHpMS`4X3#N_Ur(z% zjOp!^_FU{Bv@<&Ln0PT-t>(9T^}g@KVd3~d#l=vI-=hS*&uVs1Xr+q^0iExP#lX3* z@iQl~`g6wTKDQ1kG|Zgj6*~hA2nhV+hfdC~4lB!l?3lP2x!O8dI@%c+0lr6zJO3Jt zNdJ%Ujcje405(pJxBk(0p~ePI26tZ3oy>c=l@(>(14>jf^fZJ0LzSv5JVfi;Uj*dfMV1_nu4`Q@jIzSQdFsvwr-;2~4BfR${hoLs+2!Kj#w zR1Gjy<<#UDlepB3)C`TNjHkuwplp0qnN$Msg-S$)=w@O3Gk81GjetWINUY&FZKMpDC%FFRn`BkC_^g)BTHik15;a@Tdm(SF#b+q z?oU4MuM`~rzfrhVhtzF{a4@;;d&*7*PJllcI^Nyi^@;gga`yzQG~GRwRgVQuIQnEp ziy19ZLA9P$@9@wlP6L%`bj+wxMh}(1%$1|x`364{6jb6sMTN+Q)Kulb78Gq(GR4rI zRB4}8GL5x&)fP{@I7ogcl$ddInXIth$G4j9xcg+)d+3DUBBe21kcobq4kZ%>oFyv2 z|60(eSlSHr5;U@`f~G~CN6ro!{39&Ghv$VshzXPsUUC$~VVt|njo{MrzR;{1#IPPh zwrk*CSwxRT;If4&mfFmy{FoKtYFad?0vz&vrE#EDnP5{Dp>@rC#rK5JA@q@EK)>mO z(!G5Cm46Zh-vFH#EF}wbS|57r1z$NfQY#4;!ceQd8>+5p-D7P`mn52M z%wqrg8A}{nl*y>DNwhmek0&sgj;yZ-4j9iX`swx25-RW|uY5Z3MURj}Ft5a`X!IrW z1334%)W>-}PY#gk1o_D_Vi>yxx&?X^mcA^R9>AZ)UCJBfhxZl);^n7tn<0Ck%Vl4g zaS!BOtq;75!WuE;PJZ%p4tYRPzwYgGfg_VGPrWTt{p-4|(*+iFH=o zb!7Gs*CUEBt7{$h9L_7QNlIai_0aJg@(TKj@+#U}jB&(gq->q@Q0tuFs);nKVrr8Q zoJKJK%1{V7*Pa|eJ@#_SZ-2}7c|9%qjIKKIFx0bQl8!_UCSO#*>EliwL|9ER^C?L8 zfUp>7Q{xxSe#yT6A$r2-7_}|7#2{?U$ZuzP(8=01S>3BPHYj)j z23=~ksAx3-h+Ff%Tx(#Qg6gqv!Q#5J;6CP0AhH>y zdgH8MlxDkv@}Wq`4$q_9kNKLrg>hW0F}}e9-YY`r!_X$+Xp0SDtudP_tCFdR%hJwU zNY_DLUP#_S&BjF6!P~>dz`@4DM%>$8-rL(m&2MbDtP-@xD<~pVd??(+z>VN@u4!n{ z6q}RL2ILMg568s5g`H@%(#|(`OP%Yle$oof%9{Wlpli2wRlr-(Pfr|2&z*>Uj>iZ5Mm|`;lV%ySxY&lHMXnqgSXfhmu+q@2L;XbFF?!{$xL4Sn;Vk~2_!29U)s zRP6+cJG~RbsS`uZ6Ppk}2`Xsxc~7)>^y_DiWL(Yp*MxeD+0mqbT(T%e-w@WMK7rpR zW>K@NUnUl6yCbbcx)hJ^_*Drf3g#U^Ea9K#vRuF6$Uw+6=nU0O}? zM&lyO#AfRCaM<)V3F>N4O+6$bq%y5lN59%+pe89oSYaH4Z6yj7jFZ|dWMqg~EqoK!h^}Y7z=7_HGVJ&veJyM6lQ)pE>K3ng_VIU zyTCmv2npP&v#a{mY}5WU{7=tuud$f-;E>js?BH}Gi&eA*pK91a4T=qpxIcO!HJaoO zJ)<=b)(DSX0Rmr9yEx+sLL`BCD0mtxG_GHfnUbxH`sos^DSY%1Lc(yM*qfDTBcBVSSYOO!L$Ro$LXC?lcspI1oVj!>NN<$5DT<93M zkPBWXOD#IsRttIhp)ZW>Hhif5jGHaYERX8r5Hikkr)UO^Ptx^0IsuXym9`Fy!dfZ1X3>mRlK4D28aicY?ml863KI(eO z!~wo84uKfFhd9+2-5!nGo~6Frg$Gv_P70OUBqPfhr@jJdb)NKCGhBwr9IOp4s~giP zZpa4BVp^H9G#)j;9|ha>rQ%!1Mh*VQ#)fF9ucd|iyHPuVmfiI)03DSYryZp0Yb@*r znjMo$@&NEst*>c$!FX`1-1v8jb_UryN z1fq5Yu(b{-`x`#)V>~fLZeb#Ud>aQ-UXsf0)U{V~E5KLV=mwT8D^a;)`sa(iIgkt} zMUEurO0MyA6f)hjR$GL?*cq9fBBU2@+FF$e4%uMBbJ*EFjyo?Aq%a4Arf##TC>R_~ z3b3@ilUtARz{%C!2R;|E$I@$D)U-95;yV7BPMq>QZ@pR_AOQ%!~tq&_e<-gV4Sg= zg0`Us(yLTh)de)QpssFvH2}QQLfR7KL4sx1`-n!Wz-b|4b3aAE9hB8&Xvr;(KUECi0cq)ea`NX+9Z{mxeGXYB z(?~-)KRZdd$GT)CCWXrrWW5yLUEhI`j;(x(#UQ4GvD-Ufpz!3$8S0$a966Ejf||qY zMu|B}qIs`cgoMS=k|nYO=Cc=`p|tx#o-h*zPd`!_NW;7+?DE*ilh)C;a75!N5B4NQ zP(k%Zars7mChqhNvrhC{tf^DgO`xe`S-~X=jUnX?2FXN}F8z&fI%3&OS<=xq)`V9s%8r6JO7yve+BmdU8?7{! zdaST=1tQV5h7#1k&Q{RMu=b3<7IPDKE72mf`x`u@_b-vclUakY<~e2vo7|jMvi1Wg zBrmvSf`+r4a8meEALWrz8zEAB7{Y#pY4CzP%LDikJ|cZZ@cF8Vx`Tn5V)SInWjd6L z-(>*I3DBql9XU0R+zG)^QQG#cQBus;cmBO*;erJL%oGDq$W9+Mpj=_Pk=O=F{SK-PQ znd=oGb_IYg9=`mzhTD{Tke$;pr3#GeBo$1^i+bE6GUt!@Xhvl`Vf8T9jd(h=o;=w) zfjoa|8Y-b@g0TyDy`VFu;Py%C953at|CeLKZ! z8c1I(3dmZH#f*5g3yblb?`V71Am=No3yD2^8~7q`aR~f^So@6Ta0|KIs2$8pf8pQ+ zF(~p`l2WM1gb{0*RiO%ecX$yP_c#fc_8D)XMvP=$Ic2X1;pVa7EzB>n%X!9Jh~OK~ z{GCZYE)}(3g|UnRM?+adqrW-ASH@I^9)!hwgF67mzyn7e9DuB$4x>R!YJRo z9c_$icV|x_fE^gZlGjh}*atC{22=$`0F{Br%N}QP2W;+vyvqFAy3}Ry6Wx?Olzo=V z^at(-4NGCmu6+r;6TO_>oIRXD$EMF zwAM@}>Ut_PjHJ-(P+_quL*N^suj&w(^r25e>q6Z_&qCQl146Me^Ds>@S21mA8K@X& z=F~k4YO_zD?UyV(?}!Zbq4ie6i`A5_aqx49a|m-NJMcZAUKUz5SVmp8>~)RXr4>-| zeskGy;J94V+oz2{xf-iYm$!(J8q(mm**n{PwEVP|jUlFQ#i5S0G!efQaWOSD;hQ~c zE%8L_zyg-NtD{UEUyC$Y0dyz?@NzqFF zO5sYuN)c8eRsrGD5_M}u>!;RgRRz_B)dep3E(L_jd}SV5M@bv5?0HQ}I+>-43TmAB zDdXPGl^(es)%B`ZFFZ2Neb3F0gpLf3zHP*8ux>bR)Qs=u3#j-MU#natox?|HjwvW- z!*LrCO!@w{nxWCJ8I%11ZTL zx}qm-D!h!sjJi5MwabS)ch(!uR?JOyPUdR(STR+TSF;~SOwvy4PFq>0SARHG+ZMF; zb9vzse#~K=R4uGkR5Ic5Zmde~*$0k%>ygq4n~|N5{5f9Y&n2I$JePege1W}9z1=m< zSamb%{q{;8`|a3zf=+a4O=+1;h)s^o+fun2)f%}Pt&>`tNSlnE%pLbx&DrPm zUyfM3{F^>_=X)o5*Lr7r1Nk%cGWFhm$rH%*k-iDPj=I*oBEM2N*E{^M?!%dnh$Vt8 zqAtQIf-IsZ5}(zt2uL&+Y-4GIYolqiXoG6=ZetBp4*Vu=sDd*V!HJ&|0Us_Cfs9AQ zQp#z=#BVWUJ!8ph%xlPN!E55#cUrI?y>Gc#)43ZVfXA59EGowm)7qXCp39IcItDT( zsa#hussg~XP1Z+~J)(#-uPVx?!@W=Ui5GC7|cqH@zQPGnR(-u}{M;FD`>F$**~?p|2^gIj>!>Lz5EOO)Bexo{Y@& z&2*(&$a9(|R}P2_bkKGHt4J`FXyn%VF*>^)vOO9v_ZCHv>Ke6>pY&F5xL@D2dcM(KyjW*2n-h z8C*?zbeL3id_MmSXDwpYW<_QNsFv1>vu-Sz;}}?}Iz)kn#P*isiv=*HPteG zK3P3-9K6lRW6C-0-q2xF$+N{dg}xPXtb5FV?0pP&0drw?fpcMf{Ooy}SEyH^S2CZz z#0BXE+6CY7@^Rep#WwP!>vTpn5m3NVz(T-8z`&=?yXCs>%Jib__-2xkr&)-AC8)LK z$)i^cuS#Fpydr$%CZQk^{kG<98QEv%Zl!HA2Resh*Dcq^jZ>yl3GK4l@!HGU*Y-K~ zaU=)GvDG(MxNp1{3a@`FF__=+it@(*0Wl-~rvx$ezotxoq+-8kV(*jRf1h_2`fp(W zE%Ezjaf!c_EXn*|h;uV?G%^EN1AdgE?fz+V;a9;r|F?pF6iD5ZxyvozRbbpx*;doB zoo2%D+ARw{;D_0)RzuGL6V8z?R>_&|dYhvC)b}39cfOJzHCA?LGz+9FZU$*xIW+C85baWbhJ7Go^7|}J{P;R!65TE z5H0jsZ(h)bplo_{HcZ!Ay@n^TB~f=XCfBk5w`0WZLFOY z4;09-T?ZyzG6<2RC3M|tEG44GXUhZQ)42wZlyxG@HFJIN=T~(oq#T=b6MO*e{jzE$ z8XY&y(_xP~#Y#ob5l^51#Mx+;aCM{kMM*D5UckeiRjJKs8{j*NVf5D)EE^ilKBam? zDyCiX#TvIz(J_iVLLb;3t2SycBeXD4AvkWg&xNVvT>C^0zB;|JEsXJTv>~uxGOmDp zkkN9I1nijNh+Dh<_+v>;=%);fqAy3;lJ8`v0_-VSP; z+q$Ov;|vIk7>A#OsFF}27m{Xipc#w+EFzmN(6p+R=XW>v zsKnmTeqLmCeMKPe>MYhYqEV0xO8^y)W>t#@)Kpk2bi)l_XWIyJoqGPvbBXm0tvNxD zdXHf`8aGIARVfNFElV`xN}vBJg6|YQxzl2*H`Js}jnI@5sJb)sv+jsdvl;KNZBR`l zDDsK|D~aAYi$%f?*hkO5V(+{q|Dqp38)mXD9Yo?J=HqJk3PoKz?inopRxKY}Y8|}W z<2Y0^UBIHZpYEDMtvGrG%HZcx)ImJEuc^ffX@>!egk@Ey8Q8Pn0U8kYF~dUIiwB! zxnLCaC(|j~8k?9~{kAFAaI0uA)!(Z{X{G3-73h@|6$WqLblnQnYU+|bs|yf7jB$~t zVKQI`%Hz%$#c*gcEErbX7~@BW25+DKC6-yU{7|(`IMUFFeqG;-La? zbh_p8ebGAjgUFB4$`)N7OU|UWSc!V&&Dc?c6O#72Brd2 z;m)KMAi>taTQ&Y%1MGOK3iX?k9{k&1?k-%EFc&|#mTYcW`i2qT2DCTBhZD$2w zy!-EOA3uKjq2xQ{Td?mh+`m+^tdxkDyt3HcYIj%882X2bb(CgrS34A+6FvKdf;iIS z{qi95WD_*y;+Hs2a>Ki#a2D9xsW`;0c3rW}isVBvX3xC!Tnhx=BkT-|*B0%5-CSk- z(tK*9T1)xm%=8qsBJp@)L;YPE!OYmZq;6qMOB&Up~Wch8=*fgk*=-wfb5^2ZU(P zh{FQFO0(8!FF(~+z%p+dG~NecZO7~tWJnk#E>IHm=cJ*QCe?yVV<=x@O_HgUo77JB z=USBp55k-f&)rP5)F?TUjssg}&89bIp2#PSf5W7#(m@z3L6@n$$4g1wIkBc2BOv+F zqG-9TwOM#Msd+^5hIS$~YiT>5e1u0hMk^w zYS%=40sY$~So2uT?{@v-hIr^m8~@U;@&2-3-;bQTj(vBy!ScZ*^m`e_uQ(+Ch$H0a z2ypu0p#D4D&;I>Ao%`=U;22EJoh$(WyE~S5kbj2#brh5SBTEr0gIk_IXxUS05++Y2LS#!M-yj;-4ZF8RksQ z^EYIjm)V9DfO~{oI0^~t&(T;VPsLetkC?K#^!iS(pil;kO=dQ0aP{yuA) zIHwHFnw0Z7h$DbUA_c98PF4fNdgWA!D1xhs#`($za#4QPLK8fnL25q9Xz^xnp2(&Q zP+dS-rFvV1?dG$(>#6-zPjek&rvx5?E{X;(6>d3W=@A!%X7zlf;7cBkEtO`laionD zf2Ucl3y=X4S>0%(FKR6!t{A+i43!xpUImI{hM>=`bxDVn{Ys9ia|X>(Hte1>DtYA5kpw+&U*C)8UGFTWB=4uK~@+Zv9;Y(d(E4$HSjQH0`>B;-7@i11K==R(PX zq9}5gf6z>~c?-+Lvm(ME+F#lwmHcowqZ@rQwt58$iC|aLbFCw|+`YjMb#r~HtnZ_( ztL=nqP1q3Ux6O_YC*$0ZQ*u`nsA(vl?DcwvMaDuKnpcm=y3d_G&cFC_1|ZU=k+C=& zJn_oWT*J@(1}|NfK#MX^U60q~qoGT0V}niY6**OisKLQEB(Gkr#_3^8dlA)H>?>#z z*v;ri>*B$PNMO#(U_Z!cW}--Gazj+b;+t)t4btP)_)@dnlBh_G-nvw^sWrQeF)NvSM&p2W#$47kYWU2YnJA6799U#pl z-_ah>Ta9qG%GqtuF60>1wdRtqH&M4p{F=v?iMj86?{i+&U0XZV*S@RIqI~p*Q?~Nh zK#9+On}}(s-Z?+HJutxobvF@%f??j4_1?Yye69@P-rW$~7P`Cr;mW9LzAPV76z^b>J{tm+UBAD+7i5@op*P|y7 zakqs?Apa8ghwpgnvBUi41>VJJ5Bc8VKCCIF|B0{lzvBMsfD6p`11=Bg|7ty!2V%B` zppgEJ{=Jw7m7~8k>2CeM3p*b+=}y+eN>1qqvaU3q(8B5_(u`< zvEqFv`!{XVJiyNOgJ=0C&D>-ExBP#0fQNz9M9 c7v_81t0)6`>#&1>5Zu0tZubDxIPU)Xe+UqTG5`Po literal 0 HcmV?d00001 diff --git a/test/sys-info.ts b/test/sys-info.ts index 2b8de8c87c..f5902b680c 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -22,7 +22,7 @@ describe("SysInfo unit tests", () => { } }; - sysInfo = new SysInfo(childProcess); + sysInfo = new SysInfo(childProcess, null, null, null, null); }); describe("Should execute correct commands to check for", () => { diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 3ba593b91c..f939381269 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -1,6 +1,103 @@ declare module NativeScriptDoctor { - export function getJavaVersion(): Promise; - export function getJavaCompilerVersion(): Promise; + export const doctor: IDoctor; + export const sysInfo: ISysInfo; + + export interface ISysInfo { + getJavaVersion(): Promise; + + getJavaCompilerVersion(): Promise; + + getXCodeVersion(): Promise; + + getNodeVersion(): Promise; + + getNodeGypVersion(): Promise; + + getXCodeProjGemLocation(): Promise; + + isITunesInstalled(): Promise; + + getCocoapodVersion(): Promise; + + getOs(): Promise; + + getAdbVersion(): Promise; + + isAndroidInstalled(): Promise; + + getMonoVersion(): Promise; + + getGitVersion(): Promise; + + getGradleVersion(): Promise; + + getSysInfo(): Promise; + + isCocoaPodsWorkingCorrectly(): Promise + } + + export interface IDoctor { + canExecuteLocalBuild(platform: string): Promise; + getWarnings(): Promise; + } + + export interface ISysInfoData { + // os stuff + /** os platform flavour, reported by os.platform */ + platform: string; + /** Full os name, like `uname -a` on unix, registry query on win */ + os: string; + /** .net version, applicable to windows only */ + dotNetVer: string; + /** The command shell in use, usually bash or cmd */ + shell: string; + + // node stuff + /** node.js version, returned by `process.version` */ + nodeVer: string; + /** npm version, returned by `npm -v` */ + npmVer: string; + /** Process architecture, returned by `process.arch` */ + procArch: string; + /** node-gyp version as returned by `node-gyp -v`*/ + nodeGypVer: string; + + // dependencies + /** version of java, as returned by `java -version` */ + javaVer: string; + /** Xcode version string as returned by `xcodebuild -version`. Valid only on Mac */ + xcodeVer: string; + /** Version string of adb, as returned by `adb version` */ + adbVer: string; + /** Whether iTunes is installed on the machine */ + itunesInstalled: boolean; + /** Whether `android` executable can be run */ + androidInstalled: boolean; + /** mono version, relevant on Mac only **/ + monoVer: string; + /** git version string, as returned by `git --version` **/ + gitVer: string; + /** gradle version string as returned by `gradle -v` **/ + gradleVer: string; + /** javac version string as returned by `javac -version` **/ + javacVersion: string; + /** pod version string, as returned by `pod --version` **/ + cocoapodVer: string; + /** xcodeproj gem location, as returned by `which gem xcodeproj` **/ + xcodeprojGemLocation: string; + /** true id CocoaPods can successfully execute pod install **/ + isCocoaPodsWorkingCorrectly: boolean; + } + + /** + * Describes warning returned from nativescript-doctor check. + */ + export interface IWarning { + /** The warning. */ + warning: string; + /** Additional information for the warning. */ + additionalInformation: string; + } } export = NativeScriptDoctor; From d97c0d574d3c9b9038f6ff41d7b884ea68b79dcd Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 4 Nov 2016 11:14:44 +0200 Subject: [PATCH 014/169] Add more unit tests --- test/sys-info.ts | 288 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 274 insertions(+), 14 deletions(-) diff --git a/test/sys-info.ts b/test/sys-info.ts index f5902b680c..b07726c93f 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -4,28 +4,136 @@ import { SysInfo } from "../lib/sys-info"; import { ChildProcess } from "../lib/wrappers/child-process"; const JavaHomeName = "JAVA_HOME"; +const AndroidHomeName = "ANDROID_HOME"; + +interface IChildProcessResultDescription { + result?: any; + shouldThrowError?: boolean; +} + +interface IChildProcessResults { + uname: IChildProcessResultDescription; + npmV: IChildProcessResultDescription; + javaVersion: IChildProcessResultDescription; + javacVersion: IChildProcessResultDescription; + nodeGypVersion: IChildProcessResultDescription; + xCodeVersion: IChildProcessResultDescription; + adbVersion: IChildProcessResultDescription; + androidInstalled: IChildProcessResultDescription; + monoVersion: IChildProcessResultDescription; + gradleVersion: IChildProcessResultDescription; + gitVersion: IChildProcessResultDescription; + podVersion: IChildProcessResultDescription; + pod: IChildProcessResultDescription; +} + +interface IHostInfoMockOptions { + isWindows?: boolean; + dotNetVersion?: string; + isDarwin?: boolean; +} + +interface IFileSystemMockOptions { + existsResult?: boolean; +} + +function createChildProcessResults(childProcessResult: IChildProcessResults): IDictionary { + return { + "uname -a": childProcessResult.uname, + "npm -v": childProcessResult.npmV, + "java": childProcessResult.javaVersion, + '"javac" -version': childProcessResult.javacVersion, + "node-gyp -v": childProcessResult.nodeGypVersion, + "xcodebuild -version": childProcessResult.xCodeVersion, + "pod --version": childProcessResult.podVersion, + "pod": childProcessResult.pod, + 'adb version': childProcessResult.adbVersion, + "'adb' version": childProcessResult.adbVersion, // for Mac and Linux + 'android': childProcessResult.androidInstalled, + 'android.bat': childProcessResult.androidInstalled, // for Windows + "mono --version": childProcessResult.monoVersion, + "git --version": childProcessResult.gitVersion, + "gradle -v": childProcessResult.gradleVersion + }; +} + +function getResultFromChildProcess(childProcessResultDescription: IChildProcessResultDescription, command: string): any { + if (childProcessResultDescription.shouldThrowError) { + throw new Error(`This one throws error. (${command})`); + } + + return childProcessResultDescription.result; +} + +function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: IHostInfoMockOptions, fileSystemOptions?: IFileSystemMockOptions): SysInfo { + hostInfoOptions = hostInfoOptions || {}; + const winreg: any = { + getRegistryValue: (valueName: string, hive?: IHiveId, key?: string, host?: string) => { return { value: "registryKey" }; }, + registryKeys: { + HKLM: "HKLM" + } + }; + const hostInfo: any = { + dotNetVersion: () => Promise.resolve(hostInfoOptions.dotNetVersion), + isDarwin: hostInfoOptions.isDarwin, + isWindows: hostInfoOptions.isWindows, + isLinux: (!hostInfoOptions.isDarwin && !hostInfoOptions.isWindows), + winreg + }; + const childProcessResultDictionary = createChildProcessResults(childProcessResult); + const childProcess = { + exec: async (command: string) => { + return getResultFromChildProcess(childProcessResultDictionary[command], command); + }, + + spawnFromEvent: async (command: string, args: string[], event: string) => { + return getResultFromChildProcess(childProcessResultDictionary[command], command); + } + }; + + const fileSystem: any = { + exists: () => Promise.resolve((fileSystemOptions || {}).existsResult), + extractZip: () => Promise.resolve() + }; + + return new SysInfo(childProcess, hostInfo, fileSystem, winreg, null); +} + +function setStdOut(value: string): { stdout: string } { + return { stdout: value }; +} +function setStdErr(value: string): { stderr: string } { + return { stderr: value }; +} describe("SysInfo unit tests", () => { let sysInfo: SysInfo; - let spawnFromEventCommand: string; - let execCommand: string; beforeEach(() => { - const childProcess: ChildProcess = { - spawnFromEvent: async (command: string, args: string[], event: string) => { - spawnFromEventCommand = `${command} ${args.join(" ")}`; - return { stdout: "", stderr: "" }; - }, - exec: async (command: string) => { - execCommand = command; - return { stdout: "", stderr: "" }; - } - }; - - sysInfo = new SysInfo(childProcess, null, null, null, null); + // We need to mock this because on Mac the tests in which the platform is mocked to Windows in the process there will be no CommonProgramFiles. + process.env.CommonProgramFiles = process.env.CommonProgramFiles || "mocked on mac"; + process.env["CommonProgramFiles(x86)"] = process.env["CommonProgramFiles(x86)"] || "mocked on mac"; }); describe("Should execute correct commands to check for", () => { + let spawnFromEventCommand: string; + let execCommand: string; + + beforeEach(() => { + const childProcess: ChildProcess = { + spawnFromEvent: async (command: string, args: string[], event: string) => { + spawnFromEventCommand = `${command} ${args.join(" ")}`; + return { stdout: "", stderr: "" }; + }, + exec: async (command: string) => { + execCommand = command; + return { stdout: "", stderr: "" }; + } + }; + + sysInfo = new SysInfo(childProcess, null, null, null, null); + }); + it("java version.", async () => { await sysInfo.getJavaVersion(); assert.deepEqual(spawnFromEventCommand, "java -version"); @@ -53,4 +161,156 @@ describe("SysInfo unit tests", () => { assert.deepEqual(execCommand, `"javac" -version`); }); }); + + describe("getSysInfo", () => { + let childProcessResult: IChildProcessResults; + const originalJavaHome = process.env[JavaHomeName]; + const originalAndroidHome = process.env[AndroidHomeName]; + + beforeEach(() => { + childProcessResult = { + uname: { result: setStdOut("name") }, + npmV: { result: setStdOut("2.14.1") }, + javaVersion: { result: setStdErr('java version "1.8.0_60"') }, + javacVersion: { result: setStdErr("javac 1.8.0_60") }, + nodeGypVersion: { result: setStdOut("2.0.0") }, + xCodeVersion: { result: setStdOut("Xcode 6.4.0") }, + adbVersion: { result: setStdOut("Android Debug Bridge version 1.0.32") }, + androidInstalled: { result: setStdOut("android") }, + monoVersion: { result: setStdOut("version 1.0.6 ") }, + gradleVersion: { result: setStdOut("Gradle 2.8") }, + gitVersion: { result: setStdOut("git version 1.9.5") }, + podVersion: { result: setStdOut("0.38.2") }, + pod: { result: setStdOut("success") } + }; + + delete process.env[JavaHomeName]; + delete process.env[AndroidHomeName]; + }); + + afterEach(() => { + process.env[JavaHomeName] = originalJavaHome; + process.env[AndroidHomeName] = originalAndroidHome; + }); + + describe("returns correct results when everything is installed", () => { + let assertCommonValues = (result: ISysInfoData) => { + assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout); + assert.deepEqual(result.javaVer, "1.8.0"); + assert.deepEqual(result.javacVersion, "1.8.0_60"); + assert.deepEqual(result.nodeGypVer, childProcessResult.nodeGypVersion.result.stdout); + assert.deepEqual(result.adbVer, "1.0.32"); + assert.deepEqual(result.androidInstalled, true); + assert.deepEqual(result.monoVer, "1.0.6"); + assert.deepEqual(result.gradleVer, "2.8"); + assert.deepEqual(result.gitVer, "1.9.5"); + }; + + it("on Windows", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assertCommonValues(result); + assert.deepEqual(result.xcodeVer, null); + assert.deepEqual(result.cocoapodVer, null); + }); + + it("on Mac", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assertCommonValues(result); + assert.deepEqual(result.xcodeVer, "6.4.0"); + assert.deepEqual(result.cocoapodVer, childProcessResult.podVersion.result.stdout); + }); + + it("on Linux", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assertCommonValues(result); + assert.deepEqual(result.xcodeVer, null); + assert.deepEqual(result.cocoapodVer, null); + }); + }); + + describe("cocoapods version", () => { + it("is null when cocoapods are not installed", async () => { + // simulate error when pod --version command is executed + childProcessResult.podVersion = { shouldThrowError: true }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.cocoapodVer, null); + }); + + it("is null when OS is not Mac", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.cocoapodVer, null); + }); + + it("is correct when cocoapods output has warning after version output", async () => { + childProcessResult.podVersion = { result: setStdOut("0.38.2\nWARNING:\n") }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.cocoapodVer, "0.38.2"); + }); + + it("is correct when cocoapods output has warnings before version output", async () => { + childProcessResult.podVersion = { result: setStdOut("WARNING\nWARNING2\n0.38.2") }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.cocoapodVer, "0.38.2"); + }); + }); + + describe("returns correct results when exceptions are raised during sysInfo data collection", () => { + beforeEach(() => { + childProcessResult = { + uname: { shouldThrowError: true }, + npmV: { shouldThrowError: true }, + javaVersion: { shouldThrowError: true }, + javacVersion: { shouldThrowError: true }, + nodeGypVersion: { shouldThrowError: true }, + xCodeVersion: { shouldThrowError: true }, + adbVersion: { shouldThrowError: true }, + androidInstalled: { shouldThrowError: true }, + monoVersion: { shouldThrowError: true }, + gradleVersion: { shouldThrowError: true }, + gitVersion: { shouldThrowError: true }, + podVersion: { shouldThrowError: true }, + pod: { shouldThrowError: true } + }; + }); + + describe("when all of calls throw", () => { + let assertAllValuesAreNull = async () => { + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.npmVer, null); + assert.deepEqual(result.javaVer, null); + assert.deepEqual(result.javacVersion, null); + assert.deepEqual(result.nodeGypVer, null); + assert.deepEqual(result.xcodeVer, null); + assert.deepEqual(result.adbVer, null); + assert.deepEqual(result.androidInstalled, false); + assert.deepEqual(result.monoVer, null); + assert.deepEqual(result.gradleVer, null); + assert.deepEqual(result.gitVer, null); + assert.deepEqual(result.cocoapodVer, null); + }; + + it("on Windows", () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); + assertAllValuesAreNull(); + }); + + it("on Mac", () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + assertAllValuesAreNull(); + }); + + it("on Linux", () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1" }); + assertAllValuesAreNull(); + }); + }); + }); + }); }); From 273b5d894a933979bcb46f8760f95bd42cf3ae3c Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Mon, 7 Nov 2016 14:53:02 +0200 Subject: [PATCH 015/169] Fix PR comments --- lib/declarations.d.ts | 58 --------------- lib/definitions/osenv.d.ts | 2 +- lib/definitions/unzip.d.ts | 2 +- lib/doctor.ts | 41 +++-------- lib/index.ts | 6 +- lib/sys-info.ts | 7 +- test/sys-info.ts | 3 +- typings/nativescript-doctor.d.ts | 117 +++++++++++++++++++++++++------ 8 files changed, 117 insertions(+), 119 deletions(-) diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 94ad9c5107..6d0d6e70fb 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -23,54 +23,6 @@ interface ISpawnFromEventOptions { ignoreError?: boolean; } -interface ISysInfoData { - // os stuff - /** os platform flavour, reported by os.platform */ - platform: string; - /** Full os name, like `uname -a` on unix, registry query on win */ - os: string; - /** .net version, applicable to windows only */ - dotNetVer: string; - /** The command shell in use, usually bash or cmd */ - shell: string; - - // node stuff - /** node.js version, returned by `process.version` */ - nodeVer: string; - /** npm version, returned by `npm -v` */ - npmVer: string; - /** Process architecture, returned by `process.arch` */ - procArch: string; - /** node-gyp version as returned by `node-gyp -v`*/ - nodeGypVer: string; - - // dependencies - /** version of java, as returned by `java -version` */ - javaVer: string; - /** Xcode version string as returned by `xcodebuild -version`. Valid only on Mac */ - xcodeVer: string; - /** Version string of adb, as returned by `adb version` */ - adbVer: string; - /** Whether iTunes is installed on the machine */ - itunesInstalled: boolean; - /** Whether `android` executable can be run */ - androidInstalled: boolean; - /** mono version, relevant on Mac only **/ - monoVer: string; - /** git version string, as returned by `git --version` **/ - gitVer: string; - /** gradle version string as returned by `gradle -v` **/ - gradleVer: string; - /** javac version string as returned by `javac -version` **/ - javacVersion: string; - /** pod version string, as returned by `pod --version` **/ - cocoapodVer: string; - /** xcodeproj gem location, as returned by `which gem xcodeproj` **/ - xcodeprojGemLocation: string; - /** true id CocoaPods can successfully execute pod install **/ - isCocoaPodsWorkingCorrectly: boolean; -} - /** * Describes single registry available for search. */ @@ -111,16 +63,6 @@ interface IHiveIds { HKU: IHiveId; } -/** - * Describes warning returned from nativescript-doctor check. - */ -interface IWarning { - /** The warning. */ - warning: string; - /** Additional information for the warning. */ - additionalInformation: string; -} - interface IDictionary { [key: string]: T } diff --git a/lib/definitions/osenv.d.ts b/lib/definitions/osenv.d.ts index 0fc84a829b..e30314a921 100644 --- a/lib/definitions/osenv.d.ts +++ b/lib/definitions/osenv.d.ts @@ -1,4 +1,4 @@ declare module "osenv" { function home(): string; function shell(): string; -} \ No newline at end of file +} diff --git a/lib/definitions/unzip.d.ts b/lib/definitions/unzip.d.ts index de6f8bb632..69a7593340 100644 --- a/lib/definitions/unzip.d.ts +++ b/lib/definitions/unzip.d.ts @@ -1,3 +1,3 @@ declare module "unzip" { export function Extract(options: { path: string }): NodeJS.WritableStream; -} \ No newline at end of file +} diff --git a/lib/doctor.ts b/lib/doctor.ts index 552f866d45..deee31a908 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -5,24 +5,25 @@ import { HostInfo } from "./host-info"; import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local-build-requirements"; import { Helpers } from "./helpers"; +import { IWarning } from "../typings/nativescript-doctor"; import * as semver from "semver"; export class Doctor { private static MIN_SUPPORTED_POD_VERSION = "0.38.2"; - constructor(private sysInfo: SysInfo, + constructor(private androidLocalBuildRequirements: AndroidLocalBuildRequirements, + private helpers: Helpers, private hostInfo: HostInfo, - private androidLocalBuildRequirements: AndroidLocalBuildRequirements, - private iosLocalBuildRequirements: IosLocalBuildRequirements, - private helpers: Helpers) { } + private iOSLocalBuildRequirements: IosLocalBuildRequirements, + private sysInfo: SysInfo) { } public async canExecuteLocalBuild(platform: string): Promise { this.validatePlatform(platform); - if (platform.toLocaleLowerCase() === Constants.ANDROID_PLATFORM_NAME.toLocaleLowerCase()) { + if (platform.toLowerCase() === Constants.ANDROID_PLATFORM_NAME.toLowerCase()) { return await this.androidLocalBuildRequirements.checkRequirements(); - } else if (platform.toLocaleLowerCase() === Constants.IOS_PLATFORM_NAME.toLocaleLowerCase()) { - return await this.iosLocalBuildRequirements.checkRequirements(); + } else if (platform.toLowerCase() === Constants.IOS_PLATFORM_NAME.toLowerCase()) { + return await this.iOSLocalBuildRequirements.checkRequirements(); } return false; @@ -93,15 +94,6 @@ export class Doctor { + `To be able to build such projects, verify that you have at least ${Doctor.MIN_SUPPORTED_POD_VERSION} version installed.` }); } - - if (!sysInfoData.monoVer || semver.lt(sysInfoData.monoVer, "3.12.0")) { - result.push({ - warning: "WARNING: Mono 3.12 or later is not installed or not configured properly.", - additionalInformation: "You will not be able to work with Android devices in the device simulator or debug on connected Android devices." + EOL - + "To be able to work with Android in the device simulator and debug on connected Android devices," + EOL - + "download and install Mono 3.12 or later from http://www.mono-project.com/download/" + EOL - }); - } } else { result.push({ warning: "NOTE: You can develop for iOS only on Mac OS X systems.", @@ -109,15 +101,6 @@ export class Doctor { }); } - if (!sysInfoData.itunesInstalled) { - result.push({ - warning: "WARNING: iTunes is not installed.", - additionalInformation: "You will not be able to work with iOS devices via cable connection." + EOL - + "To be able to work with connected iOS devices," + EOL - + "download and install iTunes from http://www.apple.com" + EOL - }); - } - if (!sysInfoData.javaVer) { result.push({ warning: "WARNING: The Java Development Kit (JDK) is not installed or is not configured properly.", @@ -142,13 +125,7 @@ export class Doctor { } private isPlatformSupported(platform: string): boolean { - return Constants.SUPPORTED_PLATFORMS.reduce((prevValue, currentValue) => { - if (!prevValue) { - return currentValue.toLocaleLowerCase() === platform.toLocaleLowerCase(); - } else { - return prevValue; - } - }, false); + return Constants.SUPPORTED_PLATFORMS.map(pl => pl.toLowerCase()).indexOf(platform.toLowerCase()) !== -1; } private validatePlatform(platform: string): void { diff --git a/lib/index.ts b/lib/index.ts index 3d23ca3a67..dc4b784e48 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -13,11 +13,11 @@ const winreg = new WinReg(); const hostInfo = new HostInfo(winreg); const fileSystem = new FileSystem(); const helpers = new Helpers(); -const sysInfo = new SysInfo(childProcess, hostInfo, fileSystem, winreg, helpers); +const sysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winreg); const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(sysInfo); -const iosLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); -const doctor = new Doctor(sysInfo, hostInfo, androidLocalBuildRequirements, iosLocalBuildRequirements, helpers); +const iOSLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); +const doctor = new Doctor(androidLocalBuildRequirements, helpers, hostInfo, iOSLocalBuildRequirements, sysInfo); export { sysInfo, diff --git a/lib/sys-info.ts b/lib/sys-info.ts index e732af6b4a..5a8e51cdcc 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -5,6 +5,7 @@ import { ExecOptions } from "child_process"; import { WinReg } from "./winreg"; import { Helpers } from "./helpers"; import { platform } from "os"; +import { ISysInfoData } from "../typings/nativescript-doctor"; import * as path from "path"; import * as osenv from "osenv"; import * as temp from "temp"; @@ -39,10 +40,10 @@ export class SysInfo { private isCocoaPodsWorkingCorrectlyCache: boolean = null; constructor(private childProcess: ChildProcess, - private hostInfo: HostInfo, private fileSystem: FileSystem, - private winreg: WinReg, - private helpers: Helpers) { } + private helpers: Helpers, + private hostInfo: HostInfo, + private winreg: WinReg) { } public async getJavaVersion(): Promise { if (!this.javaVerCache) { diff --git a/test/sys-info.ts b/test/sys-info.ts index b07726c93f..da88f53a4b 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -2,6 +2,7 @@ import * as assert from "assert"; import * as path from "path"; import { SysInfo } from "../lib/sys-info"; import { ChildProcess } from "../lib/wrappers/child-process"; +import { ISysInfoData } from "../typings/nativescript-doctor"; const JavaHomeName = "JAVA_HOME"; const AndroidHomeName = "ANDROID_HOME"; @@ -96,7 +97,7 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: extractZip: () => Promise.resolve() }; - return new SysInfo(childProcess, hostInfo, fileSystem, winreg, null); + return new SysInfo(childProcess, fileSystem, null, hostInfo, winreg); } function setStdOut(value: string): { stdout: string } { diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index f939381269..6cfefec0ab 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -43,49 +43,126 @@ declare module NativeScriptDoctor { export interface ISysInfoData { // os stuff - /** os platform flavour, reported by os.platform */ + /** + * Os platform flavour, reported by os.platform. + * @type {string} + */ platform: string; - /** Full os name, like `uname -a` on unix, registry query on win */ + + /** + * Full os name, like `uname -a` on unix, registry query on win. + * @type {string} + */ os: string; - /** .net version, applicable to windows only */ + + /** + * .net version, applicable to windows only. + * @type {string} + */ dotNetVer: string; - /** The command shell in use, usually bash or cmd */ + + /** + * The command shell in use, usually bash or cmd. + * @type {string} + */ shell: string; // node stuff - /** node.js version, returned by `process.version` */ + /** + * node.js version, returned by `process.version`. + * @type {string} + */ nodeVer: string; - /** npm version, returned by `npm -v` */ + + /** + * npm version, returned by `npm -v`. + * @type {string} + */ npmVer: string; - /** Process architecture, returned by `process.arch` */ + + /** + * Process architecture, returned by `process.arch`. + * @type {string} + */ procArch: string; - /** node-gyp version as returned by `node-gyp -v`*/ + + /** + * node-gyp version as returned by `node-gyp -v`. + * @type {string} + */ nodeGypVer: string; // dependencies - /** version of java, as returned by `java -version` */ + /** + * Version of java, as returned by `java -version`. + * @type {string} + */ javaVer: string; - /** Xcode version string as returned by `xcodebuild -version`. Valid only on Mac */ + + /** + * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. + * @type {string} + */ xcodeVer: string; - /** Version string of adb, as returned by `adb version` */ + + /** + * Version string of adb, as returned by `adb version`. + * @type {string} + */ adbVer: string; - /** Whether iTunes is installed on the machine */ + + /** + * Whether iTunes is installed on the machine. + * @type {boolean} + */ itunesInstalled: boolean; - /** Whether `android` executable can be run */ + + /** + * Whether `android` executable can be run. + * @type {boolean} + */ androidInstalled: boolean; - /** mono version, relevant on Mac only **/ + + /** + * mono version, relevant on Mac only. + * @type {string} + */ monoVer: string; - /** git version string, as returned by `git --version` **/ + + /** + * git version string, as returned by `git --version`. + * @type {string} + */ gitVer: string; - /** gradle version string as returned by `gradle -v` **/ + + /** + * gradle version string as returned by `gradle -v`. + * @type {string} + */ gradleVer: string; - /** javac version string as returned by `javac -version` **/ + + /** + * javac version string as returned by `javac -version`. + * @type {string} + */ javacVersion: string; - /** pod version string, as returned by `pod --version` **/ + + /** + * pod version string, as returned by `pod --version`. + * @type {string} + */ cocoapodVer: string; - /** xcodeproj gem location, as returned by `which gem xcodeproj` **/ + + /** + * xcodeproj gem location, as returned by `which gem xcodeproj`. + * @type {string} + */ xcodeprojGemLocation: string; - /** true id CocoaPods can successfully execute pod install **/ + + /** + * true id CocoaPods can successfully execute pod install. + * @type {boolean} + */ isCocoaPodsWorkingCorrectly: boolean; } From 9092cb000499ccafa2f95741908826b6fc600db4 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 14 Dec 2016 14:37:32 +0200 Subject: [PATCH 016/169] Add methods descriptions in the definition file. --- lib/doctor.ts | 6 +- .../ios-local-build-requirements.ts | 4 +- lib/sys-info.ts | 24 ++--- test/sys-info.ts | 16 ++-- typings/nativescript-doctor.d.ts | 92 +++++++++++++++++-- 5 files changed, 111 insertions(+), 31 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index deee31a908..84d6b6c246 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -69,7 +69,7 @@ export class Doctor { }); } - if (!sysInfoData.cocoapodVer) { + if (!sysInfoData.cocoaPodsVer) { result.push({ warning: "WARNING: CocoaPods is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL @@ -77,7 +77,7 @@ export class Doctor { }); } - if (sysInfoData.xcodeVer && sysInfoData.cocoapodVer) { + if (sysInfoData.xcodeVer && sysInfoData.cocoaPodsVer) { let isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly(); if (!isCocoaPodsWorkingCorrectly) { result.push({ @@ -87,7 +87,7 @@ export class Doctor { } } - if (sysInfoData.cocoapodVer && semver.valid(sysInfoData.cocoapodVer) && semver.lt(sysInfoData.cocoapodVer, Doctor.MIN_SUPPORTED_POD_VERSION)) { + if (sysInfoData.cocoaPodsVer && semver.valid(sysInfoData.cocoaPodsVer) && semver.lt(sysInfoData.cocoaPodsVer, Doctor.MIN_SUPPORTED_POD_VERSION)) { result.push({ warning: `WARNING: Your current CocoaPods version is earlier than ${Doctor.MIN_SUPPORTED_POD_VERSION}.`, additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL diff --git a/lib/local-build-requirements/ios-local-build-requirements.ts b/lib/local-build-requirements/ios-local-build-requirements.ts index 93acdf3a24..dc16d08b1c 100644 --- a/lib/local-build-requirements/ios-local-build-requirements.ts +++ b/lib/local-build-requirements/ios-local-build-requirements.ts @@ -7,8 +7,8 @@ export class IosLocalBuildRequirements { public async checkRequirements(): Promise { if (!this.hostInfo.isDarwin || - !await this.sysInfo.getXCodeVersion() || - !await this.sysInfo.getXCodeProjGemLocation()) { + !await this.sysInfo.getXcodeVersion() || + !await this.sysInfo.getXcodeprojGemLocation()) { return false; } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 5a8e51cdcc..b8a22c4576 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -29,7 +29,7 @@ export class SysInfo { private nodeGypVerCache: string; private xCodeprojGemLocationCache: string; private iTunesInstalledCache: boolean = null; - private cocoapodVerCache: string; + private cocoaPodsVerCache: string; private osCache: string; private adbVerCache: string; private androidInstalledCache: boolean = null; @@ -75,7 +75,7 @@ export class SysInfo { return this.javaCompilerVerCache; } - public async getXCodeVersion(): Promise { + public async getXcodeVersion(): Promise { if (!this.xCodeVerCache && this.hostInfo.isDarwin) { const output = await this.execCommand("xcodebuild -version"); const xcodeVersionMatch = output && output.match(SysInfo.XCODE_VERSION_REGEXP); @@ -110,7 +110,7 @@ export class SysInfo { return this.nodeGypVerCache; } - public async getXCodeProjGemLocation(): Promise { + public async getXcodeprojGemLocation(): Promise { if (!this.xCodeprojGemLocationCache && this.hostInfo.isDarwin) { const output = await this.execCommand("gem which xcodeproj"); this.xCodeprojGemLocationCache = output ? output.trim() : null; @@ -139,19 +139,19 @@ export class SysInfo { return !!this.iTunesInstalledCache; } - public async getCocoapodVersion(): Promise { - if (!this.cocoapodVerCache && this.hostInfo.isDarwin) { + public async getCocoaPodsVersion(): Promise { + if (!this.cocoaPodsVerCache && this.hostInfo.isDarwin) { if (this.hostInfo.isDarwin) { const output = await this.execCommand("pod --version"); // Output of pod --version could contain some warnings. Find the version in it. - const cocoapodVersionMatch = output && output.match(SysInfo.VERSION_REGEXP); - if (cocoapodVersionMatch && cocoapodVersionMatch[0]) { - this.cocoapodVerCache = cocoapodVersionMatch[0].trim(); + const cocoaPodsVersionMatch = output && output.match(SysInfo.VERSION_REGEXP); + if (cocoaPodsVersionMatch && cocoaPodsVersionMatch[0]) { + this.cocoaPodsVerCache = cocoaPodsVersionMatch[0].trim(); } } } - return this.cocoapodVerCache; + return this.cocoaPodsVerCache; } public async getOs(): Promise { @@ -242,10 +242,10 @@ export class SysInfo { result.dotNetVer = await this.hostInfo.dotNetVersion(); result.javaVer = await this.getJavaVersion(); result.javacVersion = await this.getJavaCompilerVersion(); - result.xcodeVer = await this.getXCodeVersion(); - result.xcodeprojGemLocation = await this.getXCodeProjGemLocation(); + result.xcodeVer = await this.getXcodeVersion(); + result.xcodeprojGemLocation = await this.getXcodeprojGemLocation(); result.itunesInstalled = await this.isITunesInstalled(); - result.cocoapodVer = await this.getCocoapodVersion(); + result.cocoaPodsVer = await this.getCocoaPodsVersion(); result.adbVer = await this.getAdbVersion(); result.androidInstalled = await this.isAndroidInstalled(); result.monoVer = await this.getMonoVersion(); diff --git a/test/sys-info.ts b/test/sys-info.ts index da88f53a4b..ca78a88ded 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -212,7 +212,7 @@ describe("SysInfo unit tests", () => { let result = await sysInfo.getSysInfo(); assertCommonValues(result); assert.deepEqual(result.xcodeVer, null); - assert.deepEqual(result.cocoapodVer, null); + assert.deepEqual(result.cocoaPodsVer, null); }); it("on Mac", async () => { @@ -220,7 +220,7 @@ describe("SysInfo unit tests", () => { let result = await sysInfo.getSysInfo(); assertCommonValues(result); assert.deepEqual(result.xcodeVer, "6.4.0"); - assert.deepEqual(result.cocoapodVer, childProcessResult.podVersion.result.stdout); + assert.deepEqual(result.cocoaPodsVer, childProcessResult.podVersion.result.stdout); }); it("on Linux", async () => { @@ -228,7 +228,7 @@ describe("SysInfo unit tests", () => { let result = await sysInfo.getSysInfo(); assertCommonValues(result); assert.deepEqual(result.xcodeVer, null); - assert.deepEqual(result.cocoapodVer, null); + assert.deepEqual(result.cocoaPodsVer, null); }); }); @@ -238,27 +238,27 @@ describe("SysInfo unit tests", () => { childProcessResult.podVersion = { shouldThrowError: true }; sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); let result = await sysInfo.getSysInfo(); - assert.deepEqual(result.cocoapodVer, null); + assert.deepEqual(result.cocoaPodsVer, null); }); it("is null when OS is not Mac", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); let result = await sysInfo.getSysInfo(); - assert.deepEqual(result.cocoapodVer, null); + assert.deepEqual(result.cocoaPodsVer, null); }); it("is correct when cocoapods output has warning after version output", async () => { childProcessResult.podVersion = { result: setStdOut("0.38.2\nWARNING:\n") }; sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); let result = await sysInfo.getSysInfo(); - assert.deepEqual(result.cocoapodVer, "0.38.2"); + assert.deepEqual(result.cocoaPodsVer, "0.38.2"); }); it("is correct when cocoapods output has warnings before version output", async () => { childProcessResult.podVersion = { result: setStdOut("WARNING\nWARNING2\n0.38.2") }; sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); let result = await sysInfo.getSysInfo(); - assert.deepEqual(result.cocoapodVer, "0.38.2"); + assert.deepEqual(result.cocoaPodsVer, "0.38.2"); }); }); @@ -294,7 +294,7 @@ describe("SysInfo unit tests", () => { assert.deepEqual(result.monoVer, null); assert.deepEqual(result.gradleVer, null); assert.deepEqual(result.gitVer, null); - assert.deepEqual(result.cocoapodVer, null); + assert.deepEqual(result.cocoaPodsVer, null); }; it("on Windows", () => { diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 6cfefec0ab..c0b80854d0 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -2,42 +2,122 @@ declare module NativeScriptDoctor { export const doctor: IDoctor; export const sysInfo: ISysInfo; + /** + * Describes methods which helps collecting system information. + */ export interface ISysInfo { + /** + * Returns the currently installed Java version. + * @return {Promise} The currently installed Java version. + */ getJavaVersion(): Promise; + /** + * Returns the currently installed Java compiler version. + * @return {Promise} The currently installed Java compiler version. + */ getJavaCompilerVersion(): Promise; - getXCodeVersion(): Promise; + /** + * Returns the currently installed version of Xcode. + * @return {Promise} Returns the currently installed version of Xcode or null if Xcode is not installed or executed on Linux or Windows. + */ + getXcodeVersion(): Promise; + /** + * Returns the currently installed Node.js version. + * @return {Promise} Returns the currently installed Node.js version. + */ getNodeVersion(): Promise; + /** + * Returns the currently installed node-gyp version. + * @return {Promise} Returns the currently installed node-gyp version. If node-gyp is not installed it will return null. + */ getNodeGypVersion(): Promise; - getXCodeProjGemLocation(): Promise; + /** + * Returns the xcodeproj gem location. + * @return {Promise} Returns the xcodeproj gem location. If the the xcodeproj gem is not installed it will return null. + */ + getXcodeprojGemLocation(): Promise; + /** + * Checks if iTunes is installed. + * @return {Promise} Returns true if iTunes is installed. + */ isITunesInstalled(): Promise; - getCocoapodVersion(): Promise; + /** + * Returns the currently installed Cocoapods version. + * @return {Promise} Returns the currently installed Cocoapods version. It will return null if Cocoapods is not installed. + */ + getCocoaPodsVersion(): Promise; + /** + * Returns the os name. + * @return {Promise} Returns the os name. + */ getOs(): Promise; + /** + * Returns the currently installed ADB version. + * @return {Promise} Returns the currently installed ADB version. It will return null if ADB is not installed. + */ getAdbVersion(): Promise; + /** + * Checks if Android is installed. + * @return {Promise} Returns true if Android is installed. + */ isAndroidInstalled(): Promise; + /** + * Returns the currently installed Mono version. + * @return {Promise} Returns the currently installed Mono version. It will return null if Mono is not installed. + */ getMonoVersion(): Promise; + /** + * Returns the currently installed Git version. + * @return {Promise} Returns the currently installed Git version. It will return null if Git is not installed. + */ getGitVersion(): Promise; + /** + * Returns the currently installed Gradle version. + * @return {Promise} Returns the currently installed Gradle version. It will return null if Gradle is not installed. + */ getGradleVersion(): Promise; - getSysInfo(): Promise; + /** + * Checks if CocoaPods is working correctly by trying to install one pod. + * @return {Promise} Returns true if CocoaPods is working correctly. + */ + isCocoaPodsWorkingCorrectly(): Promise; - isCocoaPodsWorkingCorrectly(): Promise + /** + * Returns the whole system information. + * @return {Promise} The system information. + */ + getSysInfo(): Promise; } + /** + * Describes methods which help identifying if the environment can be used for development of {N} apps. + */ export interface IDoctor { + /** + * Checks if a local build can be executed on the current machine. + * @param {string} platform The platform for which to check if local build is possible. + * @return {Promise} true if local build can be executed for the provided platform. + */ canExecuteLocalBuild(platform: string): Promise; + + /** + * Executes all checks for the current environment and returns the warnings from each check. + * @return {Promise} Array of all the warnings from all checks. If there are no warnings will return empty array. + */ getWarnings(): Promise; } @@ -151,7 +231,7 @@ declare module NativeScriptDoctor { * pod version string, as returned by `pod --version`. * @type {string} */ - cocoapodVer: string; + cocoaPodsVer: string; /** * xcodeproj gem location, as returned by `which gem xcodeproj`. From 39c82eb88f11e4c53d3c30e2b7867d20a804d148 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 14 Dec 2016 14:37:50 +0200 Subject: [PATCH 017/169] Update README.md --- README.md | 344 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) diff --git a/README.md b/README.md index 38f352e027..d9554d3f70 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,346 @@ # nativescript-doctor Library that helps identifying if the environment can be used for development of {N} apps. + +# Installation +1. Using npm + ```bash + $ npm install nativescript-doctor --save + ``` + +# Requirements +1. Node.js 4.3.0 or later + +# Usage +* Module `doctor`: + - Usage: + ```TypeScript + import { doctor } from "nativescript-doctor" + + async function main() { + const canExecuteLocalBuildForAndroid = await doctor.canExecuteLocalBuild("Android"); + const canExecuteLocalBuildForIos = await doctor.canExecuteLocalBuild("iOS"); + console.log("Can execute local build for Android: ", canExecuteLocalBuildForAndroid); + console.log("Can execute local build for iOS: ", canExecuteLocalBuildForIos); + } + + main(); + ``` + + - Interfaces: + ```TypeScript + /** + * Describes methods which help identifying if the environment can be used for development of {N} apps. + */ + interface IDoctor { + /** + * Checks if a local build can be executed on the current machine. + * @param {string} platform The platform for which to check if local build is possible. + * @return {Promise} true if local build can be executed for the provided platform. + */ + canExecuteLocalBuild(platform: string): Promise; + + /** + * Executes all checks for the current environment and returns the warnings from each check. + * @return {Promise} Array of all the warnings from all checks. If there are no warnings will return empty array. + */ + getWarnings(): Promise; + } + + /** + * Describes warning returned from nativescript-doctor check. + */ + interface IWarning { + /** The warning. */ + warning: string; + /** Additional information for the warning. */ + additionalInformation: string; + } + ``` + +* Module `sysInfo`: + - Usage: + ```TypeScript + import { sysInfo } from "nativescript-doctor"; + + async function main() { + const javaVersion = await sysInfo.getJavaVersion(); + console.log("java: ", javaVersion); + + const javacVersion = await sysInfo.getJavaCompilerVersion(); + console.log("javac: ", javacVersion); + + const adbVersion = await sysInfo.getAdbVersion(); + console.log("adb: ", adbVersion); + + const cocoaPodsVersion = await sysInfo.getCocoaPodsVersion(); + console.log("cocoapods: ", cocoaPodsVersion); + + const gitVersion = await sysInfo.getGitVersion(); + console.log("git: ", gitVersion); + + const gradleVersion = await sysInfo.getGradleVersion(); + console.log("gradle: ", gradleVersion); + + const monoVersion = await sysInfo.getMonoVersion(); + console.log("mono: ", monoVersion); + + const nodeVersion = await sysInfo.getNodeVersion(); + console.log("node: ", nodeVer); + + const nodeGypVersion = await sysInfo.getNodeGypVersion(); + console.log("node-gyp: ", nodeGypVersion); + + const osName = await sysInfo.getOs(); + console.log("os: ", osName); + + const xcodeprojGemLocation = await sysInfo.getXCodeProjGemLocation(); + console.log("xcodeproj gem location: ", xcodeprojGemLocation); + + const xcodeVersion = await sysInfo.getXCodeVersion(); + console.log("xcode: ", xcodeVersion); + + const isAndroidInstalled = await sysInfo.isAndroidInstalled(); + console.log("is Android installed: ", isAndroidInstalled); + + const isITunesInstalled = await sysInfo.isITunesInstalled(); + console.log("is iTunes installed: ", isITunesInstalled); + + const isCocoaPodsWorkingCorrectly = await sysInfo.isCocoaPodsWorkingCorrectly(); + console.log("is cocoapods working correctly: ", isCocoaPodsWorkingCorrectly); + + const sysInfoData = await sysInfo.getSysInfo(); + console.log("sysInfo: ", sysInfoData); + } + + main(); + + ``` + + - Interfaces: + ```TypeScript + /** + * Describes methods which helps collecting system information. + */ + interface ISysInfo { + /** + * Returns the currently installed Java version. + * @return {Promise} The currently installed Java version. + */ + getJavaVersion(): Promise; + + /** + * Returns the currently installed Java compiler version. + * @return {Promise} The currently installed Java compiler version. + */ + getJavaCompilerVersion(): Promise; + + /** + * Returns the currently installed version of Xcode. + * @return {Promise} Returns the currently installed version of Xcode or null if Xcode is not installed or executed on Linux or Windows. + */ + getXCodeVersion(): Promise; + + /** + * Returns the currently installed Node.js version. + * @return {Promise} Returns the currently installed Node.js version. + */ + getNodeVersion(): Promise; + + /** + * Returns the currently installed node-gyp version. + * @return {Promise} Returns the currently installed node-gyp version. If node-gyp is not installed it will return null. + */ + getNodeGypVersion(): Promise; + + /** + * Returns the xcodeproj gem location. + * @return {Promise} Returns the xcodeproj gem location. If the the xcodeproj gem is not installed it will return null. + */ + getXCodeProjGemLocation(): Promise; + + /** + * Checks if iTunes is installed. + * @return {Promise} Returns true if iTunes is installed. + */ + isITunesInstalled(): Promise; + + /** + * Returns the currently installed Cocoapods version. + * @return {Promise} Returns the currently installed Cocoapods version. It will return null if Cocoapods is not installed. + */ + getCocoaPodsVersion(): Promise; + + /** + * Returns the os name. + * @return {Promise} Returns the os name. + */ + getOs(): Promise; + + /** + * Returns the currently installed ADB version. + * @return {Promise} Returns the currently installed ADB version. It will return null if ADB is not installed. + */ + getAdbVersion(): Promise; + + /** + * Checks if Android is installed. + * @return {Promise} Returns true if Android is installed. + */ + isAndroidInstalled(): Promise; + + /** + * Returns the currently installed Mono version. + * @return {Promise} Returns the currently installed Mono version. It will return null if Mono is not installed. + */ + getMonoVersion(): Promise; + + /** + * Returns the currently installed Git version. + * @return {Promise} Returns the currently installed Git version. It will return null if Git is not installed. + */ + getGitVersion(): Promise; + + /** + * Returns the currently installed Gradle version. + * @return {Promise} Returns the currently installed Gradle version. It will return null if Gradle is not installed. + */ + getGradleVersion(): Promise; + + /** + * Checks if CocoaPods is working correctly by trying to install one pod. + * @return {Promise} Returns true if CocoaPods is working correctly. + */ + isCocoaPodsWorkingCorrectly(): Promise; + + /** + * Returns the whole system information. + * @return {Promise} The system information. + */ + getSysInfo(): Promise; + } + + interface ISysInfoData { + // os stuff + /** + * Os platform flavour, reported by os.platform. + * @type {string} + */ + platform: string; + + /** + * Full os name, like `uname -a` on unix, registry query on win. + * @type {string} + */ + os: string; + + /** + * .net version, applicable to windows only. + * @type {string} + */ + dotNetVer: string; + + /** + * The command shell in use, usually bash or cmd. + * @type {string} + */ + shell: string; + + // node stuff + /** + * node.js version, returned by `process.version`. + * @type {string} + */ + nodeVer: string; + + /** + * npm version, returned by `npm -v`. + * @type {string} + */ + npmVer: string; + + /** + * Process architecture, returned by `process.arch`. + * @type {string} + */ + procArch: string; + + /** + * node-gyp version as returned by `node-gyp -v`. + * @type {string} + */ + nodeGypVer: string; + + // dependencies + /** + * Version of java, as returned by `java -version`. + * @type {string} + */ + javaVer: string; + + /** + * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. + * @type {string} + */ + xcodeVer: string; + + /** + * Version string of adb, as returned by `adb version`. + * @type {string} + */ + adbVer: string; + + /** + * Whether iTunes is installed on the machine. + * @type {boolean} + */ + itunesInstalled: boolean; + + /** + * Whether `android` executable can be run. + * @type {boolean} + */ + androidInstalled: boolean; + + /** + * mono version, relevant on Mac only. + * @type {string} + */ + monoVer: string; + + /** + * git version string, as returned by `git --version`. + * @type {string} + */ + gitVer: string; + + /** + * gradle version string as returned by `gradle -v`. + * @type {string} + */ + gradleVer: string; + + /** + * javac version string as returned by `javac -version`. + * @type {string} + */ + javacVersion: string; + + /** + * pod version string, as returned by `pod --version`. + * @type {string} + */ + cocoaPodsVer: string; + + /** + * xcodeproj gem location, as returned by `which gem xcodeproj`. + * @type {string} + */ + xcodeprojGemLocation: string; + + /** + * true id CocoaPods can successfully execute pod install. + * @type {boolean} + */ + isCocoaPodsWorkingCorrectly: boolean; + } + ``` From c478b716a6c073cff26a180c56bda8db06bb461b Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 20 Jan 2017 18:00:01 +0200 Subject: [PATCH 018/169] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db396e39ad..2cb3f0d88c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.0.1", + "version": "0.1.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 275cac4d83bf4d346372ae689ec0455cf419dd51 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 9 Feb 2017 14:39:52 +0200 Subject: [PATCH 019/169] Add get NativeScript CLI version method to the public API --- lib/sys-info.ts | 11 +++++++++++ test/sys-info.ts | 11 ++++++++--- typings/nativescript-doctor.d.ts | 12 ++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index b8a22c4576..ded29fa6b8 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -38,6 +38,7 @@ export class SysInfo { private gradleVerCache: string; private sysInfoCache: ISysInfoData; private isCocoaPodsWorkingCorrectlyCache: boolean = null; + private nativeScriptCliVersion: string; constructor(private childProcess: ChildProcess, private fileSystem: FileSystem, @@ -252,6 +253,7 @@ export class SysInfo { result.gitVer = await this.getGitVersion(); result.gradleVer = await this.getGradleVersion(); result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); + result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); this.sysInfoCache = result; } @@ -284,6 +286,15 @@ export class SysInfo { return !!this.isCocoaPodsWorkingCorrectlyCache; } + public async getNativeScriptCliVersion(): Promise { + if (!this.nativeScriptCliVersion) { + const output = await this.execCommand("tns --version"); + this.nativeScriptCliVersion = output.trim(); + } + + return this.nativeScriptCliVersion; + } + private async exec(cmd: string, execOptions?: ExecOptions): Promise { if (cmd) { try { diff --git a/test/sys-info.ts b/test/sys-info.ts index ca78a88ded..52c4e896c3 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -26,6 +26,7 @@ interface IChildProcessResults { gitVersion: IChildProcessResultDescription; podVersion: IChildProcessResultDescription; pod: IChildProcessResultDescription; + nativeScriptCliVersion: IChildProcessResultDescription; } interface IHostInfoMockOptions { @@ -54,7 +55,8 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID 'android.bat': childProcessResult.androidInstalled, // for Windows "mono --version": childProcessResult.monoVersion, "git --version": childProcessResult.gitVersion, - "gradle -v": childProcessResult.gradleVersion + "gradle -v": childProcessResult.gradleVersion, + "tns --version": childProcessResult.nativeScriptCliVersion }; } @@ -182,7 +184,8 @@ describe("SysInfo unit tests", () => { gradleVersion: { result: setStdOut("Gradle 2.8") }, gitVersion: { result: setStdOut("git version 1.9.5") }, podVersion: { result: setStdOut("0.38.2") }, - pod: { result: setStdOut("success") } + pod: { result: setStdOut("success") }, + nativeScriptCliVersion: { result: setStdOut("2.5.0") } }; delete process.env[JavaHomeName]; @@ -205,6 +208,7 @@ describe("SysInfo unit tests", () => { assert.deepEqual(result.monoVer, "1.0.6"); assert.deepEqual(result.gradleVer, "2.8"); assert.deepEqual(result.gitVer, "1.9.5"); + assert.deepEqual(result.nativeScriptCliVersion, childProcessResult.nativeScriptCliVersion.result.stdout); }; it("on Windows", async () => { @@ -277,7 +281,8 @@ describe("SysInfo unit tests", () => { gradleVersion: { shouldThrowError: true }, gitVersion: { shouldThrowError: true }, podVersion: { shouldThrowError: true }, - pod: { shouldThrowError: true } + pod: { shouldThrowError: true }, + nativeScriptCliVersion: { shouldThrowError: true } }; }); diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index c0b80854d0..2f6ad426bb 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -96,6 +96,12 @@ declare module NativeScriptDoctor { */ isCocoaPodsWorkingCorrectly(): Promise; + /** + * Returns the version of the globally installed NativeScript CLI. + * @return {Promise} Returns the version of the globally installed NativeScript CLI. + */ + getNativeScriptCliVersion(): Promise; + /** * Returns the whole system information. * @return {Promise} The system information. @@ -244,6 +250,12 @@ declare module NativeScriptDoctor { * @type {boolean} */ isCocoaPodsWorkingCorrectly: boolean; + + /** + * NativeScript CLI version string, as returned by `tns --version`. + * @type {string} + */ + nativeScriptCliVersion: string; } /** From eb07ac1697c16c2d23a831560e43a7b58ac4b03d Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 9 Feb 2017 15:18:29 +0200 Subject: [PATCH 020/169] Change the definition files to enable the user to use the interfaces without importing them --- Gruntfile.js | 8 +- lib/doctor.ts | 5 +- lib/sys-info.ts | 9 +- test/sys-info.ts | 3 +- typings/interfaces.ts | 267 ++++++++++++++++++++++++++++++ typings/nativescript-doctor.d.ts | 273 +------------------------------ 6 files changed, 282 insertions(+), 283 deletions(-) create mode 100644 typings/interfaces.ts diff --git a/Gruntfile.js b/Gruntfile.js index c728798ca4..e3fabf9117 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -4,17 +4,17 @@ module.exports = function (grunt) { options: grunt.file.readJSON("tsconfig.json").compilerOptions, devlib: { - src: ["lib/**/*.ts"], + src: ["lib/**/*.ts", "typings/**/*.ts"], reference: "lib/.d.ts" }, devall: { - src: ["lib/**/*.ts", "test/**/*.ts"], + src: ["lib/**/*.ts", "test/**/*.ts", "typings/**/*.ts"], reference: "lib/.d.ts" }, release_build: { - src: ["lib/**/*.ts", "test/**/*.ts"], + src: ["lib/**/*.ts", "test/**/*.ts", "typings/**/*.ts"], reference: "lib/.d.ts", options: { sourceMap: false, @@ -26,7 +26,7 @@ module.exports = function (grunt) { tslint: { build: { files: { - src: ["lib/**/*.ts", "test/**/*.ts", "!**/*.d.ts"] + src: ["lib/**/*.ts", "test/**/*.ts", "typings/**/*.ts", "!**/*.d.ts"] }, options: { configuration: grunt.file.readJSON("./tslint.json") diff --git a/lib/doctor.ts b/lib/doctor.ts index 84d6b6c246..78ce73fc58 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -5,7 +5,6 @@ import { HostInfo } from "./host-info"; import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local-build-requirements"; import { Helpers } from "./helpers"; -import { IWarning } from "../typings/nativescript-doctor"; import * as semver from "semver"; export class Doctor { @@ -29,8 +28,8 @@ export class Doctor { return false; } - public async getWarnings(): Promise { - const result: IWarning[] = []; + public async getWarnings(): Promise { + const result: NativeScriptDoctor.IWarning[] = []; const sysInfoData = await this.sysInfo.getSysInfo(); if (!sysInfoData.adbVer) { diff --git a/lib/sys-info.ts b/lib/sys-info.ts index ded29fa6b8..e90eaaecea 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -5,7 +5,6 @@ import { ExecOptions } from "child_process"; import { WinReg } from "./winreg"; import { Helpers } from "./helpers"; import { platform } from "os"; -import { ISysInfoData } from "../typings/nativescript-doctor"; import * as path from "path"; import * as osenv from "osenv"; import * as temp from "temp"; @@ -36,7 +35,7 @@ export class SysInfo { private monoVerCache: string; private gitVerCache: string; private gradleVerCache: string; - private sysInfoCache: ISysInfoData; + private sysInfoCache: NativeScriptDoctor.ISysInfoData; private isCocoaPodsWorkingCorrectlyCache: boolean = null; private nativeScriptCliVersion: string; @@ -219,15 +218,15 @@ export class SysInfo { const output = await this.execCommand("gradle -v"); const matches = SysInfo.GRADLE_VERSION_REGEXP.exec(output); - this.gradleVerCache = matches && matches[1]; + this.gradleVerCache = matches && matches[1]; } return this.gradleVerCache; } - public async getSysInfo(): Promise { + public async getSysInfo(): Promise { if (!this.sysInfoCache) { - const result: ISysInfoData = Object.create(null); + const result: NativeScriptDoctor.ISysInfoData = Object.create(null); // os stuff result.platform = platform(); diff --git a/test/sys-info.ts b/test/sys-info.ts index 52c4e896c3..2332dab1f6 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -2,7 +2,6 @@ import * as assert from "assert"; import * as path from "path"; import { SysInfo } from "../lib/sys-info"; import { ChildProcess } from "../lib/wrappers/child-process"; -import { ISysInfoData } from "../typings/nativescript-doctor"; const JavaHomeName = "JAVA_HOME"; const AndroidHomeName = "ANDROID_HOME"; @@ -198,7 +197,7 @@ describe("SysInfo unit tests", () => { }); describe("returns correct results when everything is installed", () => { - let assertCommonValues = (result: ISysInfoData) => { + let assertCommonValues = (result: NativeScriptDoctor.ISysInfoData) => { assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout); assert.deepEqual(result.javaVer, "1.8.0"); assert.deepEqual(result.javacVersion, "1.8.0_60"); diff --git a/typings/interfaces.ts b/typings/interfaces.ts new file mode 100644 index 0000000000..6a21cb1eca --- /dev/null +++ b/typings/interfaces.ts @@ -0,0 +1,267 @@ +declare module NativeScriptDoctor { + /** + * Describes methods which helps collecting system information. + */ + interface ISysInfo { + /** + * Returns the currently installed Java version. + * @return {Promise} The currently installed Java version. + */ + getJavaVersion(): Promise; + + /** + * Returns the currently installed Java compiler version. + * @return {Promise} The currently installed Java compiler version. + */ + getJavaCompilerVersion(): Promise; + + /** + * Returns the currently installed version of Xcode. + * @return {Promise} Returns the currently installed version of Xcode or null if Xcode is not installed or executed on Linux or Windows. + */ + getXcodeVersion(): Promise; + + /** + * Returns the currently installed Node.js version. + * @return {Promise} Returns the currently installed Node.js version. + */ + getNodeVersion(): Promise; + + /** + * Returns the currently installed node-gyp version. + * @return {Promise} Returns the currently installed node-gyp version. If node-gyp is not installed it will return null. + */ + getNodeGypVersion(): Promise; + + /** + * Returns the xcodeproj gem location. + * @return {Promise} Returns the xcodeproj gem location. If the the xcodeproj gem is not installed it will return null. + */ + getXcodeprojGemLocation(): Promise; + + /** + * Checks if iTunes is installed. + * @return {Promise} Returns true if iTunes is installed. + */ + isITunesInstalled(): Promise; + + /** + * Returns the currently installed Cocoapods version. + * @return {Promise} Returns the currently installed Cocoapods version. It will return null if Cocoapods is not installed. + */ + getCocoaPodsVersion(): Promise; + + /** + * Returns the os name. + * @return {Promise} Returns the os name. + */ + getOs(): Promise; + + /** + * Returns the currently installed ADB version. + * @return {Promise} Returns the currently installed ADB version. It will return null if ADB is not installed. + */ + getAdbVersion(): Promise; + + /** + * Checks if Android is installed. + * @return {Promise} Returns true if Android is installed. + */ + isAndroidInstalled(): Promise; + + /** + * Returns the currently installed Mono version. + * @return {Promise} Returns the currently installed Mono version. It will return null if Mono is not installed. + */ + getMonoVersion(): Promise; + + /** + * Returns the currently installed Git version. + * @return {Promise} Returns the currently installed Git version. It will return null if Git is not installed. + */ + getGitVersion(): Promise; + + /** + * Returns the currently installed Gradle version. + * @return {Promise} Returns the currently installed Gradle version. It will return null if Gradle is not installed. + */ + getGradleVersion(): Promise; + + /** + * Checks if CocoaPods is working correctly by trying to install one pod. + * @return {Promise} Returns true if CocoaPods is working correctly. + */ + isCocoaPodsWorkingCorrectly(): Promise; + + /** + * Returns the version of the globally installed NativeScript CLI. + * @return {Promise} Returns the version of the globally installed NativeScript CLI. + */ + getNativeScriptCliVersion(): Promise; + + /** + * Returns the whole system information. + * @return {Promise} The system information. + */ + getSysInfo(): Promise; + } + + /** + * Describes methods which help identifying if the environment can be used for development of {N} apps. + */ + interface IDoctor { + /** + * Checks if a local build can be executed on the current machine. + * @param {string} platform The platform for which to check if local build is possible. + * @return {Promise} true if local build can be executed for the provided platform. + */ + canExecuteLocalBuild(platform: string): Promise; + + /** + * Executes all checks for the current environment and returns the warnings from each check. + * @return {Promise} Array of all the warnings from all checks. If there are no warnings will return empty array. + */ + getWarnings(): Promise; + } + + interface ISysInfoData { + // os stuff + /** + * Os platform flavour, reported by os.platform. + * @type {string} + */ + platform: string; + + /** + * Full os name, like `uname -a` on unix, registry query on win. + * @type {string} + */ + os: string; + + /** + * .net version, applicable to windows only. + * @type {string} + */ + dotNetVer: string; + + /** + * The command shell in use, usually bash or cmd. + * @type {string} + */ + shell: string; + + // node stuff + /** + * node.js version, returned by `process.version`. + * @type {string} + */ + nodeVer: string; + + /** + * npm version, returned by `npm -v`. + * @type {string} + */ + npmVer: string; + + /** + * Process architecture, returned by `process.arch`. + * @type {string} + */ + procArch: string; + + /** + * node-gyp version as returned by `node-gyp -v`. + * @type {string} + */ + nodeGypVer: string; + + // dependencies + /** + * Version of java, as returned by `java -version`. + * @type {string} + */ + javaVer: string; + + /** + * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. + * @type {string} + */ + xcodeVer: string; + + /** + * Version string of adb, as returned by `adb version`. + * @type {string} + */ + adbVer: string; + + /** + * Whether iTunes is installed on the machine. + * @type {boolean} + */ + itunesInstalled: boolean; + + /** + * Whether `android` executable can be run. + * @type {boolean} + */ + androidInstalled: boolean; + + /** + * mono version, relevant on Mac only. + * @type {string} + */ + monoVer: string; + + /** + * git version string, as returned by `git --version`. + * @type {string} + */ + gitVer: string; + + /** + * gradle version string as returned by `gradle -v`. + * @type {string} + */ + gradleVer: string; + + /** + * javac version string as returned by `javac -version`. + * @type {string} + */ + javacVersion: string; + + /** + * pod version string, as returned by `pod --version`. + * @type {string} + */ + cocoaPodsVer: string; + + /** + * xcodeproj gem location, as returned by `which gem xcodeproj`. + * @type {string} + */ + xcodeprojGemLocation: string; + + /** + * true id CocoaPods can successfully execute pod install. + * @type {boolean} + */ + isCocoaPodsWorkingCorrectly: boolean; + + /** + * NativeScript CLI version string, as returned by `tns --version`. + * @type {string} + */ + nativeScriptCliVersion: string; + } + + /** + * Describes warning returned from nativescript-doctor check. + */ + interface IWarning { + /** The warning. */ + warning: string; + /** Additional information for the warning. */ + additionalInformation: string; + } +} diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 2f6ad426bb..5f4e3b9227 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -1,272 +1,7 @@ -declare module NativeScriptDoctor { - export const doctor: IDoctor; - export const sysInfo: ISysInfo; +/// - /** - * Describes methods which helps collecting system information. - */ - export interface ISysInfo { - /** - * Returns the currently installed Java version. - * @return {Promise} The currently installed Java version. - */ - getJavaVersion(): Promise; - /** - * Returns the currently installed Java compiler version. - * @return {Promise} The currently installed Java compiler version. - */ - getJavaCompilerVersion(): Promise; - - /** - * Returns the currently installed version of Xcode. - * @return {Promise} Returns the currently installed version of Xcode or null if Xcode is not installed or executed on Linux or Windows. - */ - getXcodeVersion(): Promise; - - /** - * Returns the currently installed Node.js version. - * @return {Promise} Returns the currently installed Node.js version. - */ - getNodeVersion(): Promise; - - /** - * Returns the currently installed node-gyp version. - * @return {Promise} Returns the currently installed node-gyp version. If node-gyp is not installed it will return null. - */ - getNodeGypVersion(): Promise; - - /** - * Returns the xcodeproj gem location. - * @return {Promise} Returns the xcodeproj gem location. If the the xcodeproj gem is not installed it will return null. - */ - getXcodeprojGemLocation(): Promise; - - /** - * Checks if iTunes is installed. - * @return {Promise} Returns true if iTunes is installed. - */ - isITunesInstalled(): Promise; - - /** - * Returns the currently installed Cocoapods version. - * @return {Promise} Returns the currently installed Cocoapods version. It will return null if Cocoapods is not installed. - */ - getCocoaPodsVersion(): Promise; - - /** - * Returns the os name. - * @return {Promise} Returns the os name. - */ - getOs(): Promise; - - /** - * Returns the currently installed ADB version. - * @return {Promise} Returns the currently installed ADB version. It will return null if ADB is not installed. - */ - getAdbVersion(): Promise; - - /** - * Checks if Android is installed. - * @return {Promise} Returns true if Android is installed. - */ - isAndroidInstalled(): Promise; - - /** - * Returns the currently installed Mono version. - * @return {Promise} Returns the currently installed Mono version. It will return null if Mono is not installed. - */ - getMonoVersion(): Promise; - - /** - * Returns the currently installed Git version. - * @return {Promise} Returns the currently installed Git version. It will return null if Git is not installed. - */ - getGitVersion(): Promise; - - /** - * Returns the currently installed Gradle version. - * @return {Promise} Returns the currently installed Gradle version. It will return null if Gradle is not installed. - */ - getGradleVersion(): Promise; - - /** - * Checks if CocoaPods is working correctly by trying to install one pod. - * @return {Promise} Returns true if CocoaPods is working correctly. - */ - isCocoaPodsWorkingCorrectly(): Promise; - - /** - * Returns the version of the globally installed NativeScript CLI. - * @return {Promise} Returns the version of the globally installed NativeScript CLI. - */ - getNativeScriptCliVersion(): Promise; - - /** - * Returns the whole system information. - * @return {Promise} The system information. - */ - getSysInfo(): Promise; - } - - /** - * Describes methods which help identifying if the environment can be used for development of {N} apps. - */ - export interface IDoctor { - /** - * Checks if a local build can be executed on the current machine. - * @param {string} platform The platform for which to check if local build is possible. - * @return {Promise} true if local build can be executed for the provided platform. - */ - canExecuteLocalBuild(platform: string): Promise; - - /** - * Executes all checks for the current environment and returns the warnings from each check. - * @return {Promise} Array of all the warnings from all checks. If there are no warnings will return empty array. - */ - getWarnings(): Promise; - } - - export interface ISysInfoData { - // os stuff - /** - * Os platform flavour, reported by os.platform. - * @type {string} - */ - platform: string; - - /** - * Full os name, like `uname -a` on unix, registry query on win. - * @type {string} - */ - os: string; - - /** - * .net version, applicable to windows only. - * @type {string} - */ - dotNetVer: string; - - /** - * The command shell in use, usually bash or cmd. - * @type {string} - */ - shell: string; - - // node stuff - /** - * node.js version, returned by `process.version`. - * @type {string} - */ - nodeVer: string; - - /** - * npm version, returned by `npm -v`. - * @type {string} - */ - npmVer: string; - - /** - * Process architecture, returned by `process.arch`. - * @type {string} - */ - procArch: string; - - /** - * node-gyp version as returned by `node-gyp -v`. - * @type {string} - */ - nodeGypVer: string; - - // dependencies - /** - * Version of java, as returned by `java -version`. - * @type {string} - */ - javaVer: string; - - /** - * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. - * @type {string} - */ - xcodeVer: string; - - /** - * Version string of adb, as returned by `adb version`. - * @type {string} - */ - adbVer: string; - - /** - * Whether iTunes is installed on the machine. - * @type {boolean} - */ - itunesInstalled: boolean; - - /** - * Whether `android` executable can be run. - * @type {boolean} - */ - androidInstalled: boolean; - - /** - * mono version, relevant on Mac only. - * @type {string} - */ - monoVer: string; - - /** - * git version string, as returned by `git --version`. - * @type {string} - */ - gitVer: string; - - /** - * gradle version string as returned by `gradle -v`. - * @type {string} - */ - gradleVer: string; - - /** - * javac version string as returned by `javac -version`. - * @type {string} - */ - javacVersion: string; - - /** - * pod version string, as returned by `pod --version`. - * @type {string} - */ - cocoaPodsVer: string; - - /** - * xcodeproj gem location, as returned by `which gem xcodeproj`. - * @type {string} - */ - xcodeprojGemLocation: string; - - /** - * true id CocoaPods can successfully execute pod install. - * @type {boolean} - */ - isCocoaPodsWorkingCorrectly: boolean; - - /** - * NativeScript CLI version string, as returned by `tns --version`. - * @type {string} - */ - nativeScriptCliVersion: string; - } - - /** - * Describes warning returned from nativescript-doctor check. - */ - export interface IWarning { - /** The warning. */ - warning: string; - /** Additional information for the warning. */ - additionalInformation: string; - } +declare module "nativescript-doctor" { + export const doctor: NativeScriptDoctor.IDoctor; + export const sysInfo: NativeScriptDoctor.ISysInfo; } - -export = NativeScriptDoctor; From 010cd279e8ab5b2f22f2c4894c4ad91be76bbe4e Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 9 Feb 2017 15:36:52 +0200 Subject: [PATCH 021/169] Add constants to the public API --- lib/index.ts | 10 ++++++---- lib/sys-info.ts | 10 +++++----- typings/interfaces.ts | 9 +++++++++ typings/nativescript-doctor.d.ts | 1 + 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/index.ts b/lib/index.ts index dc4b784e48..4f8fb95c5c 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -7,13 +7,14 @@ import { Helpers } from "./helpers"; import { Doctor } from "./doctor"; import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local-build-requirements"; +import { Constants as constants } from "./constants"; const childProcess = new ChildProcess(); -const winreg = new WinReg(); -const hostInfo = new HostInfo(winreg); +const winReg = new WinReg(); +const hostInfo = new HostInfo(winReg); const fileSystem = new FileSystem(); const helpers = new Helpers(); -const sysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winreg); +const sysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg); const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(sysInfo); const iOSLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); @@ -21,5 +22,6 @@ const doctor = new Doctor(androidLocalBuildRequirements, helpers, hostInfo, iOSL export { sysInfo, - doctor + doctor, + constants }; diff --git a/lib/sys-info.ts b/lib/sys-info.ts index e90eaaecea..89f6d27946 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -43,7 +43,7 @@ export class SysInfo { private fileSystem: FileSystem, private helpers: Helpers, private hostInfo: HostInfo, - private winreg: WinReg) { } + private winReg: WinReg) { } public async getJavaVersion(): Promise { if (!this.javaVerCache) { @@ -324,12 +324,12 @@ export class SysInfo { let productName: string; let currentVersion: string; let currentBuild: string; - const hive = this.winreg.registryKeys.HKLM; + const hive = this.winReg.registryKeys.HKLM; const key = "\\Software\\Microsoft\\Windows NT\\CurrentVersion"; - productName = await this.winreg.getRegistryValue("ProductName", hive, key); - currentVersion = await this.winreg.getRegistryValue("CurrentVersion", hive, key); - currentBuild = await this.winreg.getRegistryValue("CurrentBuild", hive, key); + productName = await this.winReg.getRegistryValue("ProductName", hive, key); + currentVersion = await this.winReg.getRegistryValue("CurrentVersion", hive, key); + currentBuild = await this.winReg.getRegistryValue("CurrentBuild", hive, key); return `${productName} ${currentVersion}.${currentBuild}`; } diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 6a21cb1eca..4f6487afc3 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -264,4 +264,13 @@ declare module NativeScriptDoctor { /** Additional information for the warning. */ additionalInformation: string; } + + /** + * Describes the constants used in the module. + */ + interface IConstants { + ANDROID_PLATFORM_NAME: string; + IOS_PLATFORM_NAME: string; + SUPPORTED_PLATFORMS: string[]; + } } diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 5f4e3b9227..2f3cd656e4 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -4,4 +4,5 @@ declare module "nativescript-doctor" { export const doctor: NativeScriptDoctor.IDoctor; export const sysInfo: NativeScriptDoctor.ISysInfo; + export const constants: NativeScriptDoctor.IConstants; } From 5ec1b6633cac623bc4fc4e533574ea42d7004b06 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 9 Feb 2017 17:36:54 +0200 Subject: [PATCH 022/169] Add platforms to the warnings and update the doctor checks --- lib/doctor.ts | 42 ++++++++++++++++++++++++---------- lib/sys-info.ts | 51 +++++++++++++++++++++++++++++++++++++----- typings/interfaces.ts | 52 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 125 insertions(+), 20 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 78ce73fc58..0c5c39a8e9 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -7,7 +7,7 @@ import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local- import { Helpers } from "./helpers"; import * as semver from "semver"; -export class Doctor { +export class Doctor implements NativeScriptDoctor.IDoctor { private static MIN_SUPPORTED_POD_VERSION = "0.38.2"; constructor(private androidLocalBuildRequirements: AndroidLocalBuildRequirements, @@ -38,7 +38,8 @@ export class Doctor { additionalInformation: "For Android-related operations, the AppBuilder CLI will use a built-in version of adb." + EOL + "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL + "Android devices, verify that you have installed the latest Android SDK and" + EOL - + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL + + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, + platforms: [Constants.ANDROID_PLATFORM_NAME] }); } @@ -47,7 +48,8 @@ export class Doctor { warning: "WARNING: The Android SDK is not installed or is not configured properly.", additionalInformation: "You will not be able to run your apps in the native emulator. To be able to run apps" + EOL + "in the native Android emulator, verify that you have installed the latest Android SDK " + EOL - + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL + + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, + platforms: [Constants.ANDROID_PLATFORM_NAME] }); } @@ -56,7 +58,8 @@ export class Doctor { result.push({ warning: "WARNING: Xcode is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS or run them in the iOS Simulator." + EOL - + "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + EOL + + "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + EOL, + platforms: [Constants.IOS_PLATFORM_NAME] }); } @@ -64,7 +67,8 @@ export class Doctor { result.push({ warning: "WARNING: xcodeproj gem is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS." + EOL - + "To be able to build for iOS and run apps in the native emulator, verify that you have installed xcodeproj." + EOL + + "To be able to build for iOS and run apps in the native emulator, verify that you have installed xcodeproj." + EOL, + platforms: [Constants.IOS_PLATFORM_NAME] }); } @@ -72,7 +76,16 @@ export class Doctor { result.push({ warning: "WARNING: CocoaPods is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL - + "To be able to build such projects, verify that you have installed CocoaPods." + + "To be able to build such projects, verify that you have installed CocoaPods.", + platforms: [Constants.IOS_PLATFORM_NAME] + }); + } + + if (sysInfoData.cocoaPodsVer && sysInfoData.isCocoaPodsUpdateRequired) { + result.push({ + warning: "WARNING: CocoaPods update required.", + additionalInformation: `You are using CocoaPods version ${sysInfoData.cocoaPodsVer} which does not support Xcode ${sysInfoData.xcodeVer} yet.${EOL}${EOL}You can update your cocoapods by running $sudo gem install cocoapods from a terminal.${EOL}${EOL}In order for the NativeScript CLI to be able to work correctly with this setup you need to install xcproj command line tool and add it to your PATH.Xcproj can be installed with homebrew by running $ brew install xcproj from the terminal`, + platforms: [Constants.IOS_PLATFORM_NAME] }); } @@ -81,7 +94,8 @@ export class Doctor { if (!isCocoaPodsWorkingCorrectly) { result.push({ warning: "WARNING: There was a problem with CocoaPods", - additionalInformation: "Verify that CocoaPods are configured properly." + additionalInformation: "Verify that CocoaPods are configured properly.", + platforms: [Constants.IOS_PLATFORM_NAME] }); } } @@ -90,13 +104,15 @@ export class Doctor { result.push({ warning: `WARNING: Your current CocoaPods version is earlier than ${Doctor.MIN_SUPPORTED_POD_VERSION}.`, additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL - + `To be able to build such projects, verify that you have at least ${Doctor.MIN_SUPPORTED_POD_VERSION} version installed.` + + `To be able to build such projects, verify that you have at least ${Doctor.MIN_SUPPORTED_POD_VERSION} version installed.`, + platforms: [Constants.IOS_PLATFORM_NAME] }); } } else { result.push({ warning: "NOTE: You can develop for iOS only on Mac OS X systems.", - additionalInformation: "To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL + additionalInformation: "To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL, + platforms: [Constants.IOS_PLATFORM_NAME] }); } @@ -107,7 +123,8 @@ export class Doctor { + "to perform some Android-related operations. To ensure that you can develop and" + EOL + "test your apps for Android, verify that you have installed the JDK as" + EOL + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)" + EOL - + "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + EOL + + "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + EOL, + platforms: [Constants.ANDROID_PLATFORM_NAME] }); } @@ -116,7 +133,8 @@ export class Doctor { warning: "WARNING: Git is not installed or not configured properly.", additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL + "To be able to work with Screen Builder projects, download and install Git as described" + EOL - + "in https://git-scm.com/downloads and add the git executable to your PATH." + EOL + + "in https://git-scm.com/downloads and add the git executable to your PATH." + EOL, + platforms: Constants.SUPPORTED_PLATFORMS }); } @@ -133,7 +151,7 @@ export class Doctor { } if (!this.isPlatformSupported(platform)) { - throw new Error(`Platform ${platform} is not supported. The supported platforms are: ${Constants.SUPPORTED_PLATFORMS.join(", ")}`); + throw new Error(`Platform ${platform} is not supported.The supported platforms are: ${Constants.SUPPORTED_PLATFORMS.join(", ")} `); } } } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 89f6d27946..025f437fbe 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -8,8 +8,9 @@ import { platform } from "os"; import * as path from "path"; import * as osenv from "osenv"; import * as temp from "temp"; +import * as semver from "semver"; -export class SysInfo { +export class SysInfo implements NativeScriptDoctor.ISysInfo { // Different java has different format for `java -version` command. private static JAVA_VERSION_REGEXP = /(?:openjdk|java) version \"((?:\d+\.)+(?:\d+))/i; @@ -37,7 +38,9 @@ export class SysInfo { private gradleVerCache: string; private sysInfoCache: NativeScriptDoctor.ISysInfoData; private isCocoaPodsWorkingCorrectlyCache: boolean = null; - private nativeScriptCliVersion: string; + private nativeScriptCliVersionCache: string; + private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; + private isCocoaPodsUpdateRequiredCache: boolean = null; constructor(private childProcess: ChildProcess, private fileSystem: FileSystem, @@ -218,7 +221,7 @@ export class SysInfo { const output = await this.execCommand("gradle -v"); const matches = SysInfo.GRADLE_VERSION_REGEXP.exec(output); - this.gradleVerCache = matches && matches[1]; + this.gradleVerCache = matches && matches[1]; } return this.gradleVerCache; @@ -253,6 +256,7 @@ export class SysInfo { result.gradleVer = await this.getGradleVersion(); result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); + result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); this.sysInfoCache = result; } @@ -286,12 +290,47 @@ export class SysInfo { } public async getNativeScriptCliVersion(): Promise { - if (!this.nativeScriptCliVersion) { + if (!this.nativeScriptCliVersionCache) { const output = await this.execCommand("tns --version"); - this.nativeScriptCliVersion = output.trim(); + this.nativeScriptCliVersionCache = output ? output.trim() : output; } - return this.nativeScriptCliVersion; + return this.nativeScriptCliVersionCache; + } + + public async getXcprojInfo(): Promise { + if (!this.xcprojInfoCache) { + const cocoaPodsVersion = await this.getCocoaPodsVersion(); + const xcodeVersion = await this.getXcodeVersion(); + + // CocoaPods with version lower than 1.0.0 don't support Xcode 7.3 yet + // https://github.com/CocoaPods/CocoaPods/issues/2530#issuecomment-210470123 + // as a result of this all .pbxprojects touched by CocoaPods get converted to XML plist format + const shouldUseXcproj = cocoaPodsVersion && !!(semver.lt(cocoaPodsVersion, "1.0.0") && semver.gte(xcodeVersion, "7.3.0")); + let xcprojAvailable: boolean; + + if (shouldUseXcproj) { + // If that's the case we can use xcproj gem to convert them back to ASCII plist format + xcprojAvailable = !!(await this.exec("xcproj --version")) + } + + this.xcprojInfoCache = { shouldUseXcproj, xcprojAvailable }; + } + + return this.xcprojInfoCache; + } + + public async isCocoaPodsUpdateRequired(): Promise { + if (this.isCocoaPodsUpdateRequiredCache === null) { + let xcprojInfo = await this.getXcprojInfo(); + if (xcprojInfo.shouldUseXcproj && !xcprojInfo.xcprojAvailable) { + this.isCocoaPodsUpdateRequiredCache = true; + } else { + this.isCocoaPodsUpdateRequiredCache = false; + } + } + + return this.isCocoaPodsUpdateRequiredCache; } private async exec(cmd: string, execOptions?: ExecOptions): Promise { diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 4f6487afc3..2992c30b4f 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -99,6 +99,18 @@ declare module NativeScriptDoctor { */ getNativeScriptCliVersion(): Promise; + /** + * Checks if xcproj is required to build projects and if it is installed. + * @return {Promise} Returns the collected information aboud xcproj. + */ + getXcprojInfo(): Promise; + + /** + * Checks if the current version of CocoaPods is compatible with the installed Xcode. + * @return {boolean} true if an update us require. + */ + isCocoaPodsUpdateRequired(): Promise; + /** * Returns the whole system information. * @return {Promise} The system information. @@ -253,16 +265,52 @@ declare module NativeScriptDoctor { * @type {string} */ nativeScriptCliVersion: string; + + /** + * Information about xcproj. + * @type {string} + */ + xcprojInfo: IXcprojInfo + + /** + * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. + */ + isCocoaPodsUpdateRequired: boolean; } /** * Describes warning returned from nativescript-doctor check. */ interface IWarning { - /** The warning. */ + /** The warning. + * @type {string} + */ warning: string; - /** Additional information for the warning. */ + + /** Additional information for the warning. + * @type {string} + */ additionalInformation: string; + + /** The platforms which are affected by this warning. + * @type {string[]} + */ + platforms: string[]; + } + + /** + * Describes information about xcproj brew formula. + */ + interface IXcprojInfo { + /** + * Determines whether the system needs xcproj to execute ios builds sucessfully. + */ + shouldUseXcproj: boolean; + + /** + * Determines whether xcproj can be called from the command line. + */ + xcprojAvailable: boolean; } /** From 47e9949b748ff92278faaefdb11a63d65c7d6ce0 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Mon, 13 Feb 2017 18:56:23 +0200 Subject: [PATCH 023/169] Update README.md Update the README.md and bump the version to 0.2.0 Added new functionalities to the public API: - constants module - getNativeScriptCliVersion method - getXcprojInfo method - isCocoaPodsUpdateRequired method - platforms property in the IWarning interface --- README.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d9554d3f70..693c6968d6 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,20 @@ Library that helps identifying if the environment can be used for development of * Describes warning returned from nativescript-doctor check. */ interface IWarning { - /** The warning. */ + /** The warning. + * @type {string} + */ warning: string; - /** Additional information for the warning. */ + + /** Additional information for the warning. + * @type {string} + */ additionalInformation: string; + + /** The platforms which are affected by this warning. + * @type {string[]} + */ + platforms: string[]; } ``` @@ -108,6 +118,15 @@ Library that helps identifying if the environment can be used for development of const isCocoaPodsWorkingCorrectly = await sysInfo.isCocoaPodsWorkingCorrectly(); console.log("is cocoapods working correctly: ", isCocoaPodsWorkingCorrectly); + const nativeScriptCliVersion = await sysInfo.getNativeScriptCliVersion(); + console.log("{N} CLI version: ", nativeScriptCliVersion); + + const xcprojInfo = await sysInfo.getXcprojInfo(); + console.log("xcproj info: ", xcprojInfo); + + const isCocoaPodsUpdateRequired = await sysInfo.isCocoaPodsUpdateRequired(); + console.log("is CocoaPods update required: ", isCocoaPodsUpdateRequired); + const sysInfoData = await sysInfo.getSysInfo(); console.log("sysInfo: ", sysInfoData); } @@ -115,7 +134,7 @@ Library that helps identifying if the environment can be used for development of main(); ``` - + - Interfaces: ```TypeScript /** @@ -138,7 +157,7 @@ Library that helps identifying if the environment can be used for development of * Returns the currently installed version of Xcode. * @return {Promise} Returns the currently installed version of Xcode or null if Xcode is not installed or executed on Linux or Windows. */ - getXCodeVersion(): Promise; + getXcodeVersion(): Promise; /** * Returns the currently installed Node.js version. @@ -156,7 +175,7 @@ Library that helps identifying if the environment can be used for development of * Returns the xcodeproj gem location. * @return {Promise} Returns the xcodeproj gem location. If the the xcodeproj gem is not installed it will return null. */ - getXCodeProjGemLocation(): Promise; + getXcodeprojGemLocation(): Promise; /** * Checks if iTunes is installed. @@ -212,6 +231,24 @@ Library that helps identifying if the environment can be used for development of */ isCocoaPodsWorkingCorrectly(): Promise; + /** + * Returns the version of the globally installed NativeScript CLI. + * @return {Promise} Returns the version of the globally installed NativeScript CLI. + */ + getNativeScriptCliVersion(): Promise; + + /** + * Checks if xcproj is required to build projects and if it is installed. + * @return {Promise} Returns the collected information aboud xcproj. + */ + getXcprojInfo(): Promise; + + /** + * Checks if the current version of CocoaPods is compatible with the installed Xcode. + * @return {boolean} true if an update us require. + */ + isCocoaPodsUpdateRequired(): Promise; + /** * Returns the whole system information. * @return {Promise} The system information. @@ -342,5 +379,63 @@ Library that helps identifying if the environment can be used for development of * @type {boolean} */ isCocoaPodsWorkingCorrectly: boolean; + + /** + * NativeScript CLI version string, as returned by `tns --version`. + * @type {string} + */ + nativeScriptCliVersion: string; + + /** + * Information about xcproj. + * @type {string} + */ + xcprojInfo: IXcprojInfo + + /** + * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. + */ + isCocoaPodsUpdateRequired: boolean; + } + + /** + * Describes information about xcproj brew formula. + */ + interface IXcprojInfo { + /** + * Determines whether the system needs xcproj to execute ios builds sucessfully. + */ + shouldUseXcproj: boolean; + + /** + * Determines whether xcproj can be called from the command line. + */ + xcprojAvailable: boolean; + } + ``` + +* Module `constants`: + - Usage: + ```TypeScript + import { constants } from "nativescript-doctor" + + function main() { + for(let constantName in constants) { + console.log(`${constantName}: ${constants[constantName]}`); + } + } + + main(); + ``` + + - Interfaces: + ```TypeScript + /** + * Describes the constants used in the module. + */ + interface IConstants { + ANDROID_PLATFORM_NAME: string; + IOS_PLATFORM_NAME: string; + SUPPORTED_PLATFORMS: string[]; } ``` diff --git a/package.json b/package.json index 2cb3f0d88c..3c39d2da1c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.1.0", + "version": "0.2.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From ee2da50cf0fb0e21fa9f3791fa4c27eb16677856 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Tue, 14 Feb 2017 13:15:35 +0200 Subject: [PATCH 024/169] Fix PR comments --- README.md | 9 ++++++--- typings/interfaces.ts | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 693c6968d6..7b3ad36ebd 100644 --- a/README.md +++ b/README.md @@ -50,17 +50,20 @@ Library that helps identifying if the environment can be used for development of * Describes warning returned from nativescript-doctor check. */ interface IWarning { - /** The warning. + /** + * The warning. * @type {string} */ warning: string; - /** Additional information for the warning. + /** + * Additional information for the warning. * @type {string} */ additionalInformation: string; - /** The platforms which are affected by this warning. + /** + * The platforms which are affected by this warning. * @type {string[]} */ platforms: string[]; diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 2992c30b4f..6675ea6624 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -282,17 +282,20 @@ declare module NativeScriptDoctor { * Describes warning returned from nativescript-doctor check. */ interface IWarning { - /** The warning. + /** + * The warning. * @type {string} */ warning: string; - /** Additional information for the warning. + /** + * Additional information for the warning. * @type {string} */ additionalInformation: string; - /** The platforms which are affected by this warning. + /** + * The platforms which are affected by this warning. * @type {string[]} */ platforms: string[]; From eb59e7356b5f605b39ec07018a3bdaada8fb21aa Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 8 Mar 2017 19:36:56 +0200 Subject: [PATCH 025/169] Fix check for android on mac --- lib/sys-info.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 025f437fbe..f0964df25a 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -183,7 +183,8 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { } try { - const output = await this.childProcess.spawnFromEvent(pathToAndroid, ["-h"], "close"); + // On mac android -h returns exit code 1. That's why we need to ignore the error. + const output = await this.childProcess.spawnFromEvent(pathToAndroid, ["-h"], "close", { ignoreError: true }); if (output) { output.stdout = output.stdout || ''; this.androidInstalledCache = output.stdout.indexOf("android") >= 0; From 64a088ce4fcd3c0a311e400db185b36b6ba384c7 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 8 Mar 2017 19:37:50 +0200 Subject: [PATCH 026/169] Bump version to 0.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3c39d2da1c..24c7d7b0a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.2.0", + "version": "0.2.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 42d369ddfa758b62efe6d69d1614b4790980db0c Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 24 Feb 2017 13:25:19 +0200 Subject: [PATCH 027/169] Add method to control the sys info cache --- lib/doctor.ts | 3 +- lib/helpers.ts | 11 + lib/index.ts | 11 +- .../android-local-build-requirements.ts | 4 +- .../ios-local-build-requirements.ts | 3 +- lib/sys-info.ts | 275 +++++++++--------- test/sys-info.ts | 6 +- typings/interfaces.ts | 9 +- typings/nativescript-doctor.d.ts | 1 + 9 files changed, 171 insertions(+), 152 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 0c5c39a8e9..966bd29f1e 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -1,5 +1,4 @@ import { Constants } from "./constants"; -import { SysInfo } from "./sys-info"; import { EOL } from "os"; import { HostInfo } from "./host-info"; import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; @@ -14,7 +13,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { private helpers: Helpers, private hostInfo: HostInfo, private iOSLocalBuildRequirements: IosLocalBuildRequirements, - private sysInfo: SysInfo) { } + private sysInfo: NativeScriptDoctor.ISysInfo) { } public async canExecuteLocalBuild(platform: string): Promise { this.validatePlatform(platform); diff --git a/lib/helpers.ts b/lib/helpers.ts index 3ded21a66e..87c70200e5 100644 --- a/lib/helpers.ts +++ b/lib/helpers.ts @@ -1,6 +1,17 @@ import { platform } from "os"; export class Helpers { + public getPropertyName(method: Function): string { + if (method) { + let match = method.toString().match(/(?:return\s+?.*\.(.+);)|(?:=>\s*?.*\.(.+)\b)/); + if (match) { + return (match[1] || match[2]).trim(); + } + } + + return null; + } + public quoteString(value: string): string { if (!value) { return value; diff --git a/lib/index.ts b/lib/index.ts index 4f8fb95c5c..a55997f508 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -14,14 +14,19 @@ const winReg = new WinReg(); const hostInfo = new HostInfo(winReg); const fileSystem = new FileSystem(); const helpers = new Helpers(); -const sysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg); + +const sysInfo: NativeScriptDoctor.ISysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg); const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(sysInfo); const iOSLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); -const doctor = new Doctor(androidLocalBuildRequirements, helpers, hostInfo, iOSLocalBuildRequirements, sysInfo); + +const doctor: NativeScriptDoctor.IDoctor = new Doctor(androidLocalBuildRequirements, helpers, hostInfo, iOSLocalBuildRequirements, sysInfo); + +const setShouldCacheSysInfo = sysInfo.setShouldCacheSysInfo.bind(sysInfo); export { sysInfo, doctor, - constants + constants, + setShouldCacheSysInfo }; diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index 54acb50443..37127fe691 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -1,7 +1,5 @@ -import { SysInfo } from "../sys-info"; - export class AndroidLocalBuildRequirements { - constructor(private sysInfo: SysInfo) { } + constructor(private sysInfo: NativeScriptDoctor.ISysInfo) { } public async checkRequirements(): Promise { if (!await this.sysInfo.isAndroidInstalled() || diff --git a/lib/local-build-requirements/ios-local-build-requirements.ts b/lib/local-build-requirements/ios-local-build-requirements.ts index dc16d08b1c..6db76da6ac 100644 --- a/lib/local-build-requirements/ios-local-build-requirements.ts +++ b/lib/local-build-requirements/ios-local-build-requirements.ts @@ -1,8 +1,7 @@ -import { SysInfo } from "../sys-info"; import { HostInfo } from "../host-info"; export class IosLocalBuildRequirements { - constructor(private sysInfo: SysInfo, + constructor(private sysInfo: NativeScriptDoctor.ISysInfo, private hostInfo: HostInfo) { } public async checkRequirements(): Promise { diff --git a/lib/sys-info.ts b/lib/sys-info.ts index f0964df25a..d8a74225a3 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -41,6 +41,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private nativeScriptCliVersionCache: string; private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; private isCocoaPodsUpdateRequiredCache: boolean = null; + private shouldCache: boolean = true; constructor(private childProcess: ChildProcess, private fileSystem: FileSystem, @@ -48,82 +49,76 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private hostInfo: HostInfo, private winReg: WinReg) { } - public async getJavaVersion(): Promise { - if (!this.javaVerCache) { + public getJavaVersion(): Promise { + return this.getValueForProperty(() => this.javaVerCache, async (): Promise => { try { const spawnResult = await this.childProcess.spawnFromEvent("java", ["-version"], "exit"); const matches = spawnResult && SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr); - this.javaVerCache = matches && matches[1]; + return matches && matches[1]; } catch (err) { - this.javaVerCache = null; + return null; } - } - - return this.javaVerCache; + }); } - public async getJavaCompilerVersion(): Promise { - if (!this.javaCompilerVerCache) { + public getJavaCompilerVersion(): Promise { + return this.getValueForProperty(() => this.javaCompilerVerCache, async (): Promise => { const javaCompileExecutableName = "javac"; const javaHome = process.env.JAVA_HOME; const pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName; try { const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`); - this.javaCompilerVerCache = SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1]; + return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1]; } catch (err) { - this.javaCompilerVerCache = null; + return null; } - } - - return this.javaCompilerVerCache; + }); } - public async getXcodeVersion(): Promise { - if (!this.xCodeVerCache && this.hostInfo.isDarwin) { - const output = await this.execCommand("xcodebuild -version"); - const xcodeVersionMatch = output && output.match(SysInfo.XCODE_VERSION_REGEXP); + public getXcodeVersion(): Promise { + return this.getValueForProperty(() => this.xCodeVerCache, async (): Promise => { + if (this.hostInfo.isDarwin) { + const output = await this.execCommand("xcodebuild -version"); + const xcodeVersionMatch = output && output.match(SysInfo.XCODE_VERSION_REGEXP); - if (xcodeVersionMatch) { - this.xCodeVerCache = this.getVersionFromString(output); + if (xcodeVersionMatch) { + return this.getVersionFromString(output); + } } - } - - return this.xCodeVerCache; + }); } public async getNodeVersion(): Promise { return this.getVersionFromString(process.version); } - public async getNpmVersion(): Promise { - if (!this.npmVerCache) { + public getNpmVersion(): Promise { + return this.getValueForProperty(() => this.npmVerCache, async (): Promise => { const output = await this.execCommand("npm -v"); - this.npmVerCache = output ? output.split("\n")[0] : null; - } - - return this.npmVerCache; + return output ? output.split("\n")[0] : null; + }); } - public async getNodeGypVersion(): Promise { - if (!this.nodeGypVerCache) { + public getNodeGypVersion(): Promise { + return this.getValueForProperty(() => this.nodeGypVerCache, async (): Promise => { const output = await this.execCommand("node-gyp -v"); - this.nodeGypVerCache = output ? this.getVersionFromString(output) : null; - } - - return this.nodeGypVerCache; + return output ? this.getVersionFromString(output) : null; + }); } - public async getXcodeprojGemLocation(): Promise { - if (!this.xCodeprojGemLocationCache && this.hostInfo.isDarwin) { + public getXcodeprojGemLocation(): Promise { + return this.getValueForProperty(() => this.xCodeprojGemLocationCache, async (): Promise => { const output = await this.execCommand("gem which xcodeproj"); - this.xCodeprojGemLocationCache = output ? output.trim() : null; - } - - return this.xCodeprojGemLocationCache; + return output ? output.trim() : null; + }); } - public async isITunesInstalled(): Promise { - if (this.iTunesInstalledCache === null && !this.hostInfo.isLinux) { + public isITunesInstalled(): Promise { + return this.getValueForProperty(() => this.iTunesInstalledCache, async (): Promise => { + if (this.hostInfo.isLinux) { + return false; + } + let coreFoundationDir: string; let mobileDeviceDir: string; @@ -136,47 +131,41 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { mobileDeviceDir = "/System/Library/PrivateFrameworks/MobileDevice.framework/MobileDevice"; } - this.iTunesInstalledCache = await this.fileSystem.exists(coreFoundationDir) && await this.fileSystem.exists(mobileDeviceDir); - } - - return !!this.iTunesInstalledCache; + return await this.fileSystem.exists(coreFoundationDir) && await this.fileSystem.exists(mobileDeviceDir); + }); } - public async getCocoaPodsVersion(): Promise { - if (!this.cocoaPodsVerCache && this.hostInfo.isDarwin) { + public getCocoaPodsVersion(): Promise { + return this.getValueForProperty(() => this.cocoaPodsVerCache, async (): Promise => { if (this.hostInfo.isDarwin) { - const output = await this.execCommand("pod --version"); - // Output of pod --version could contain some warnings. Find the version in it. - const cocoaPodsVersionMatch = output && output.match(SysInfo.VERSION_REGEXP); - if (cocoaPodsVersionMatch && cocoaPodsVersionMatch[0]) { - this.cocoaPodsVerCache = cocoaPodsVersionMatch[0].trim(); + if (this.hostInfo.isDarwin) { + const output = await this.execCommand("pod --version"); + // Output of pod --version could contain some warnings. Find the version in it. + const cocoaPodsVersionMatch = output && output.match(SysInfo.VERSION_REGEXP); + if (cocoaPodsVersionMatch && cocoaPodsVersionMatch[0]) { + return cocoaPodsVersionMatch[0].trim(); + } } } - } - - return this.cocoaPodsVerCache; + }); } - public async getOs(): Promise { - if (!this.osCache) { - this.osCache = await (this.hostInfo.isWindows ? this.winVer() : this.unixVer()); - } - - return this.osCache; + public getOs(): Promise { + return this.getValueForProperty(() => this.osCache, async (): Promise => { + return await (this.hostInfo.isWindows ? this.winVer() : this.unixVer()); + }); } - public async getAdbVersion(): Promise { - if (!this.adbVerCache) { + public getAdbVersion(): Promise { + return this.getValueForProperty(() => this.adbVerCache, async (): Promise => { const output = await this.execCommand("adb version"); - this.adbVerCache = output ? this.getVersionFromString(output) : null; - } - - return this.adbVerCache; + return output ? this.getVersionFromString(output) : null; + }); } // `android -h` returns exit code 1 on successful invocation (Mac OS X for now, possibly Linux). - public async isAndroidInstalled(): Promise { - if (this.androidInstalledCache === null) { + public isAndroidInstalled(): Promise { + return this.getValueForProperty(() => this.androidInstalledCache, async (): Promise => { let pathToAndroid = "android"; if (this.hostInfo.isWindows) { pathToAndroid = `${pathToAndroid}.bat`; @@ -187,49 +176,42 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { const output = await this.childProcess.spawnFromEvent(pathToAndroid, ["-h"], "close", { ignoreError: true }); if (output) { output.stdout = output.stdout || ''; - this.androidInstalledCache = output.stdout.indexOf("android") >= 0; + return output.stdout.indexOf("android") >= 0; } } catch (err) { - this.androidInstalledCache = null; + return null; } - } - - return !!this.androidInstalledCache; + }); } - public async getMonoVersion(): Promise { - if (!this.monoVerCache) { + public getMonoVersion(): Promise { + return this.getValueForProperty(() => this.monoVerCache, async (): Promise => { const output = await this.execCommand("mono --version"); const match = this.monoVerRegExp.exec(output); - this.monoVerCache = match ? match[1] : null; - } - - return this.monoVerCache; + return match ? match[1] : null; + }); } - public async getGitVersion(): Promise { - if (!this.gitVerCache) { + public getGitVersion(): Promise { + return this.getValueForProperty(() => this.gitVerCache, async (): Promise => { const output = await this.execCommand("git --version"); const matches = SysInfo.GIT_VERSION_REGEXP.exec(output); - this.gitVerCache = matches && matches[1]; - } + return matches && matches[1]; - return this.gitVerCache; + }); } - public async getGradleVersion(): Promise { - if (!this.gradleVerCache) { + public getGradleVersion(): Promise { + return this.getValueForProperty(() => this.gradleVerCache, async (): Promise => { const output = await this.execCommand("gradle -v"); const matches = SysInfo.GRADLE_VERSION_REGEXP.exec(output); - this.gradleVerCache = matches && matches[1]; - } - - return this.gradleVerCache; + return matches && matches[1]; + }); } - public async getSysInfo(): Promise { - if (!this.sysInfoCache) { + public getSysInfo(): Promise { + return this.getValueForProperty(() => this.sysInfoCache, async (): Promise => { const result: NativeScriptDoctor.ISysInfoData = Object.create(null); // os stuff @@ -259,48 +241,46 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); - this.sysInfoCache = result; - } - - return this.sysInfoCache; + return result; + }); } - public async isCocoaPodsWorkingCorrectly(): Promise { - if (this.isCocoaPodsWorkingCorrectlyCache === null && this.hostInfo.isDarwin) { - temp.track(); - const tempDirectory = temp.mkdirSync("nativescript-check-cocoapods"); - const pathToXCodeProjectZip = path.join(__dirname, "..", "resources", "cocoapods-verification", "cocoapods.zip"); - - await this.fileSystem.extractZip(pathToXCodeProjectZip, tempDirectory); - - const xcodeProjectDir = path.join(tempDirectory, "cocoapods"); - - try { - let spawnResult = await this.childProcess.spawnFromEvent("pod", ["install"], "exit", { spawnOptions: { cwd: xcodeProjectDir } }); - if (spawnResult.exitCode) { - this.isCocoaPodsWorkingCorrectlyCache = false; - } else { - this.isCocoaPodsWorkingCorrectlyCache = await this.fileSystem.exists(path.join(xcodeProjectDir, "cocoapods.xcworkspace")); + public isCocoaPodsWorkingCorrectly(): Promise { + return this.getValueForProperty(() => this.isCocoaPodsWorkingCorrectlyCache, async (): Promise => { + if (this.hostInfo.isDarwin) { + temp.track(); + const tempDirectory = temp.mkdirSync("nativescript-check-cocoapods"); + const pathToXCodeProjectZip = path.join(__dirname, "..", "resources", "cocoapods-verification", "cocoapods.zip"); + + await this.fileSystem.extractZip(pathToXCodeProjectZip, tempDirectory); + + const xcodeProjectDir = path.join(tempDirectory, "cocoapods"); + + try { + let spawnResult = await this.childProcess.spawnFromEvent("pod", ["install"], "exit", { spawnOptions: { cwd: xcodeProjectDir } }); + if (spawnResult.exitCode) { + return false; + } else { + return await this.fileSystem.exists(path.join(xcodeProjectDir, "cocoapods.xcworkspace")); + } + } catch (err) { + return null; } - } catch (err) { - this.isCocoaPodsWorkingCorrectlyCache = null; + } else { + return false; } - } - - return !!this.isCocoaPodsWorkingCorrectlyCache; + }); } - public async getNativeScriptCliVersion(): Promise { - if (!this.nativeScriptCliVersionCache) { + public getNativeScriptCliVersion(): Promise { + return this.getValueForProperty(() => this.nativeScriptCliVersionCache, async (): Promise => { const output = await this.execCommand("tns --version"); - this.nativeScriptCliVersionCache = output ? output.trim() : output; - } - - return this.nativeScriptCliVersionCache; + return output ? output.trim() : output; + }); } - public async getXcprojInfo(): Promise { - if (!this.xcprojInfoCache) { + public getXcprojInfo(): Promise { + return this.getValueForProperty(() => this.xcprojInfoCache, async (): Promise => { const cocoaPodsVersion = await this.getCocoaPodsVersion(); const xcodeVersion = await this.getXcodeVersion(); @@ -312,26 +292,43 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { if (shouldUseXcproj) { // If that's the case we can use xcproj gem to convert them back to ASCII plist format - xcprojAvailable = !!(await this.exec("xcproj --version")) + xcprojAvailable = !!(await this.exec("xcproj --version")); } - this.xcprojInfoCache = { shouldUseXcproj, xcprojAvailable }; - } - - return this.xcprojInfoCache; + return { shouldUseXcproj, xcprojAvailable }; + }); } - public async isCocoaPodsUpdateRequired(): Promise { - if (this.isCocoaPodsUpdateRequiredCache === null) { + public isCocoaPodsUpdateRequired(): Promise { + return this.getValueForProperty(() => this.isCocoaPodsUpdateRequiredCache, async (): Promise => { let xcprojInfo = await this.getXcprojInfo(); if (xcprojInfo.shouldUseXcproj && !xcprojInfo.xcprojAvailable) { - this.isCocoaPodsUpdateRequiredCache = true; + return true; } else { - this.isCocoaPodsUpdateRequiredCache = false; + return false; } - } + }); + } + + public setShouldCacheSysInfo(shouldCache: boolean): void { + this.shouldCache = shouldCache; + } + + private async getValueForProperty(property: Function, getValueMethod: () => Promise): Promise { + if (this.shouldCache) { + const propertyName = this.helpers.getPropertyName(property); + const cachedValue: T = (this)[propertyName]; - return this.isCocoaPodsUpdateRequiredCache; + if (cachedValue === undefined || cachedValue === null) { + const result = await getValueMethod(); + (this)[propertyName] = result; + return result; + } else { + return cachedValue; + } + } else { + return await getValueMethod(); + } } private async exec(cmd: string, execOptions?: ExecOptions): Promise { diff --git a/test/sys-info.ts b/test/sys-info.ts index 2332dab1f6..63663c263f 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -1,10 +1,12 @@ import * as assert from "assert"; import * as path from "path"; import { SysInfo } from "../lib/sys-info"; +import { Helpers } from "../lib/helpers"; import { ChildProcess } from "../lib/wrappers/child-process"; const JavaHomeName = "JAVA_HOME"; const AndroidHomeName = "ANDROID_HOME"; +const helpers = new Helpers(); interface IChildProcessResultDescription { result?: any; @@ -98,7 +100,7 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: extractZip: () => Promise.resolve() }; - return new SysInfo(childProcess, fileSystem, null, hostInfo, winreg); + return new SysInfo(childProcess, fileSystem, helpers, hostInfo, winreg); } function setStdOut(value: string): { stdout: string } { @@ -133,7 +135,7 @@ describe("SysInfo unit tests", () => { } }; - sysInfo = new SysInfo(childProcess, null, null, null, null); + sysInfo = new SysInfo(childProcess, null, helpers, null, null); }); it("java version.", async () => { diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 6675ea6624..07691e8a0a 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -116,6 +116,13 @@ declare module NativeScriptDoctor { * @return {Promise} The system information. */ getSysInfo(): Promise; + + /** + * If set to true each method will cache it's result. The default value is true. + * @param {boolean} shouldCache The cache switch. + * @return {void} + */ + setShouldCacheSysInfo(shouldCache: boolean): void; } /** @@ -270,7 +277,7 @@ declare module NativeScriptDoctor { * Information about xcproj. * @type {string} */ - xcprojInfo: IXcprojInfo + xcprojInfo: IXcprojInfo; /** * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 2f3cd656e4..38c16db16d 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -5,4 +5,5 @@ declare module "nativescript-doctor" { export const doctor: NativeScriptDoctor.IDoctor; export const sysInfo: NativeScriptDoctor.ISysInfo; export const constants: NativeScriptDoctor.IConstants; + export const setShouldCacheSysInfo: (shouldCache: boolean) => void; } From 0d996a91e73b4ab363e677ffa3a2b20de027f1a5 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Fri, 24 Feb 2017 13:30:40 +0200 Subject: [PATCH 028/169] Update README.md --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7b3ad36ebd..eb1f2e6fbe 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,12 @@ Library that helps identifying if the environment can be used for development of * Module `sysInfo`: - Usage: ```TypeScript - import { sysInfo } from "nativescript-doctor"; + import { sysInfo, setShouldCacheSysInfo } from "nativescript-doctor"; async function main() { + // The default value is true. If set to false the result of each check for each element + // of the sys info will not be cached. + setShouldCacheSysInfo(false); const javaVersion = await sysInfo.getJavaVersion(); console.log("java: ", javaVersion); @@ -257,6 +260,13 @@ Library that helps identifying if the environment can be used for development of * @return {Promise} The system information. */ getSysInfo(): Promise; + + /** + * If set to true each method will cache it's result. The default value is true. + * @param {boolean} shouldCache The cache switch. + * @return {void} + */ + setShouldCacheSysInfo(shouldCache: boolean): void; } interface ISysInfoData { @@ -393,7 +403,7 @@ Library that helps identifying if the environment can be used for development of * Information about xcproj. * @type {string} */ - xcprojInfo: IXcprojInfo + xcprojInfo: IXcprojInfo; /** * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. From 5f3c4e7cdd0f64644558694f60ecf1a4d158d554 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 15 Mar 2017 14:46:13 +0200 Subject: [PATCH 029/169] Add AndroidToolsInfo --- lib/android-tools-info.ts | 267 ++++++++++++++++++ .../android-local-build-requirements.ts | 3 +- lib/wrappers/child-process.ts | 12 + lib/wrappers/file-system.ts | 10 +- typings/interfaces.ts | 61 ++++ 5 files changed, 347 insertions(+), 6 deletions(-) create mode 100644 lib/android-tools-info.ts diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts new file mode 100644 index 0000000000..f9e9988c61 --- /dev/null +++ b/lib/android-tools-info.ts @@ -0,0 +1,267 @@ +import * as path from "path"; +import * as semver from "semver"; +import { EOL } from "os"; +import { ChildProcess } from "./wrappers/child-process"; +import { FileSystem } from "./wrappers/file-system"; +import { HostInfo } from "./host-info"; + +export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { + private static ANDROID_TARGET_PREFIX = "android"; + private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25"]; + private static MIN_REQUIRED_COMPILE_TARGET = 22; + private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; + private static VERSION_REGEX = /((\d+\.){2}\d+)/; + private static MIN_JAVA_VERSION = "1.8.0"; + + private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; + private androidHome = process.env["ANDROID_HOME"]; + + constructor(private childProcess: ChildProcess, + private fs: FileSystem, + private hostInfo: HostInfo) { } + + public getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData { + if (!this.toolsInfo) { + const infoData: NativeScriptDoctor.IAndroidToolsInfoData = Object.create(null); + infoData.androidHomeEnvVar = this.androidHome; + infoData.compileSdkVersion = this.getCompileSdk(); + infoData.buildToolsVersion = this.getBuildToolsVersion(); + infoData.supportRepositoryVersion = this.getAndroidSupportRepositoryVersion(); + + this.toolsInfo = infoData; + } + + return this.toolsInfo; + } + + public validateInfo(): string[] { + const errors: string[] = []; + const toolsInfoData = this.getToolsInfo(); + const isAndroidHomeValid = this.validateAndroidHomeEnvVariable(); + if (!toolsInfoData.compileSdkVersion) { + errors.push(`Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later.`, + `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage your Android SDK versions.`); + } + + if (!toolsInfoData.buildToolsVersion) { + const buildToolsRange = this.getBuildToolsRange(); + const versionRangeMatches = buildToolsRange.match(/^.*?([\d\.]+)\s+.*?([\d\.]+)$/); + let message = `You can install any version in the following range: '${buildToolsRange}'.`; + + // Improve message in case buildToolsRange is something like: ">=22.0.0 <=22.0.0" - same numbers on both sides + if (versionRangeMatches && versionRangeMatches[1] && versionRangeMatches[2] && versionRangeMatches[1] === versionRangeMatches[2]) { + message = `You have to install version ${versionRangeMatches[1]}.`; + } + + let invalidBuildToolsAdditionalMsg = `Run \`\$ ${this.getPathToSdkManagementTool()}\` from your command-line to install required \`Android Build Tools\`.`; + if (!isAndroidHomeValid) { + invalidBuildToolsAdditionalMsg += ' In case you already have them installed, make sure `ANDROID_HOME` environment variable is set correctly.'; + } + + errors.push("You need to have the Android SDK Build-tools installed on your system. " + message, invalidBuildToolsAdditionalMsg); + } + + if (!toolsInfoData.supportRepositoryVersion) { + let invalidSupportLibAdditionalMsg = `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage the Android Support Repository.`; + if (!isAndroidHomeValid) { + invalidSupportLibAdditionalMsg += ' In case you already have it installed, make sure `ANDROID_HOME` environment variable is set correctly.'; + } + errors.push(`You need to have Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later and the latest Android Support Repository installed on your system.`, invalidSupportLibAdditionalMsg); + } + + return errors; + } + + public validateJavacVersion(installedJavaVersion: string): string[] { + const errors: string[] = []; + + let additionalMessage = "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + + " described in " + this.getSystemRequirementsLink(); + let matchingVersion = (installedJavaVersion || "").match(AndroidToolsInfo.VERSION_REGEX); + if (matchingVersion && matchingVersion[1]) { + if (semver.lt(matchingVersion[1], AndroidToolsInfo.MIN_JAVA_VERSION)) { + errors.push(`Javac version ${installedJavaVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`, additionalMessage); + } + } else { + errors.push("Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable.", additionalMessage); + } + + return errors; + } + + public async getPathToAdbFromAndroidHome(): Promise { + if (this.androidHome) { + let pathToAdb = path.join(this.androidHome, "platform-tools", "adb"); + try { + await this.childProcess.execFile(pathToAdb, ["help"]); + return pathToAdb; + } catch (err) { + return null; + } + } + + return null; + } + + public validateAndroidHomeEnvVariable(): string[] { + const errors: string[] = []; + const expectedDirectoriesInAndroidHome = ["build-tools", "tools", "platform-tools", "extras"]; + + if (!this.androidHome || !this.fs.exists(this.androidHome)) { + errors.push("The ANDROID_HOME environment variable is not set or it points to a non-existent directory. You will not be able to perform any build-related operations for Android.", + "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory."); + } else if (expectedDirectoriesInAndroidHome.map(dir => this.fs.exists(path.join(this.androidHome, dir))).length === 0) { + errors.push("The ANDROID_HOME environment variable points to incorrect directory. You will not be able to perform any build-related operations for Android.", + "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory, " + + "where you will find `tools` and `platform-tools` directories."); + } + + return errors; + } + + private getPathToSdkManagementTool(): string { + const sdkmanagerName = "sdkmanager"; + let sdkManagementToolPath = sdkmanagerName; + + const isAndroidHomeValid = this.validateAndroidHomeEnvVariable(); + + if (isAndroidHomeValid) { + // In case ANDROID_HOME is correct, check if sdkmanager exists and if not it means the SDK has not been updated. + // In this case user shoud use `android` from the command-line instead of sdkmanager. + const pathToSdkmanager = path.join(this.androidHome, "tools", "bin", sdkmanagerName); + const pathToAndroidExecutable = path.join(this.androidHome, "tools", "android"); + const pathToExecutable = this.fs.exists(pathToSdkmanager) ? pathToSdkmanager : pathToAndroidExecutable; + + sdkManagementToolPath = pathToExecutable.replace(this.androidHome, this.hostInfo.isWindows ? "%ANDROID_HOME%" : "$ANDROID_HOME"); + } + + return sdkManagementToolPath; + } + + private getCompileSdk(): number { + let latestValidAndroidTarget = this.getLatestValidAndroidTarget(); + if (latestValidAndroidTarget) { + let integerVersion = this.parseAndroidSdkString(latestValidAndroidTarget); + + if (integerVersion && integerVersion >= AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET) { + return integerVersion; + } + } + } + + private getMatchingDir(pathToDir: string, versionRange: string): string { + let selectedVersion: string; + if (this.fs.exists(pathToDir)) { + let subDirs = this.fs.readDirectory(pathToDir); + + let subDirsVersions = subDirs + .map(dirName => { + let dirNameGroups = dirName.match(AndroidToolsInfo.VERSION_REGEX); + if (dirNameGroups) { + return dirNameGroups[1]; + } + + return null; + }) + .filter(dirName => !!dirName); + + let version = semver.maxSatisfying(subDirsVersions, versionRange); + if (version) { + selectedVersion = subDirs.find(dir => dir.indexOf(version) !== -1); + } + } + + return selectedVersion; + } + + private getBuildToolsRange(): string { + return `${AndroidToolsInfo.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion()}`; + } + + private getBuildToolsVersion(): string { + let buildToolsVersion: string; + if (this.androidHome) { + let pathToBuildTools = path.join(this.androidHome, "build-tools"); + let buildToolsRange = this.getBuildToolsRange(); + buildToolsVersion = this.getMatchingDir(pathToBuildTools, buildToolsRange); + } + + return buildToolsVersion; + } + + private getAppCompatRange(): string { + let compileSdkVersion = this.getCompileSdk(); + let requiredAppCompatRange: string; + if (compileSdkVersion) { + requiredAppCompatRange = `>=${compileSdkVersion} <${compileSdkVersion + 1}`; + } + + return requiredAppCompatRange; + } + + private getAndroidSupportRepositoryVersion(): string { + let selectedAppCompatVersion: string; + const requiredAppCompatRange = this.getAppCompatRange(); + if (this.androidHome && requiredAppCompatRange) { + const pathToAppCompat = path.join(this.androidHome, "extras", "android", "m2repository", "com", "android", "support", "appcompat-v7"); + selectedAppCompatVersion = this.getMatchingDir(pathToAppCompat, requiredAppCompatRange); + } + + return selectedAppCompatVersion; + } + + private getLatestValidAndroidTarget(): string { + const installedTargets = this.getInstalledTargets(); + let latestValidAndroidTarget: string; + const sortedAndroidToolsInfo = AndroidToolsInfo.SUPPORTED_TARGETS.sort(); + + sortedAndroidToolsInfo.forEach(s => { + if (installedTargets.includes(s)) { + latestValidAndroidTarget = s; + } + }); + + return latestValidAndroidTarget; + } + + private parseAndroidSdkString(androidSdkString: string): number { + return parseInt(androidSdkString.replace(`${AndroidToolsInfo.ANDROID_TARGET_PREFIX}-`, "")); + } + + private getInstalledTargets(): string[] { + try { + const pathToInstalledTargets = path.join(this.androidHome, "platforms"); + if (!this.fs.exists(pathToInstalledTargets)) { + throw new Error("No Android Targets installed."); + } + + return this.fs.readDirectory(pathToInstalledTargets); + } catch (err) { + return []; + } + } + + private getMaxSupportedVersion(): number { + return this.parseAndroidSdkString(AndroidToolsInfo.SUPPORTED_TARGETS.sort()[AndroidToolsInfo.SUPPORTED_TARGETS.length - 1]); + } + + private getSystemRequirementsLink(): string { + let linkToSystemRequirements: string; + switch (process.platform) { + case "linux": + linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-linux.html#system-requirements"; + break; + case "win32": + linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-win.html#system-requirements"; + break; + case "darwin": + linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-os-x.html#system-requirements"; + break; + default: + linkToSystemRequirements = ""; + } + + return linkToSystemRequirements; + } +} diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index 37127fe691..36bf546a0d 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -2,8 +2,7 @@ export class AndroidLocalBuildRequirements { constructor(private sysInfo: NativeScriptDoctor.ISysInfo) { } public async checkRequirements(): Promise { - if (!await this.sysInfo.isAndroidInstalled() || - !await this.sysInfo.getJavaCompilerVersion() || + if (!await this.sysInfo.getJavaCompilerVersion() || !await this.sysInfo.getJavaVersion() || !await this.sysInfo.getAdbVersion()) { return false; diff --git a/lib/wrappers/child-process.ts b/lib/wrappers/child-process.ts index 15b7321187..dc0783a627 100644 --- a/lib/wrappers/child-process.ts +++ b/lib/wrappers/child-process.ts @@ -75,4 +75,16 @@ export class ChildProcess { }); }); } + + public execFile(command: string, args: string[]): Promise { + return new Promise((resolve, reject) => { + childProcess.execFile(command, args, (error: any, stdout: NodeBuffer) => { + if (error) { + reject(error); + } else { + resolve(stdout); + } + }); + }); + } } diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 922961e197..c46bc23969 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -2,10 +2,8 @@ import * as fs from "fs"; import { Extract } from "unzip"; export class FileSystem { - public exists(path: string): Promise { - return new Promise((resolve) => { - fs.exists(path, resolve); - }); + public exists(path: string): boolean { + return fs.existsSync(path); } public extractZip(pathToZip: string, outputDir: string): Promise { @@ -15,4 +13,8 @@ export class FileSystem { stream.on("error", reject); }); } + + public readDirectory(path: string): string[] { + return fs.readdirSync(path); + } } diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 07691e8a0a..157fea0b89 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -331,4 +331,65 @@ declare module NativeScriptDoctor { IOS_PLATFORM_NAME: string; SUPPORTED_PLATFORMS: string[]; } + + /** + * Describes methods for getting and validating Android tools. + */ + interface IAndroidToolsInfo { + /** + * Returns the Android tools info. + * @return {NativeScriptDoctor.IAndroidToolsInfoData} returns the Android tools info. + */ + getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData; + + /** + * Checks if the Android tools are valid. + * @return {string[]} An array of errors from the validation checks. If there are no errors will return []. + */ + validateInfo(): string[]; + + /** + * Checks if the current javac version is valid. + * @param {string} installedJavaVersion The version of javac to check. + * @return {string[]} An array of errors from the validation checks. If there are no errors will return []. + */ + validateJavacVersion(installedJavaVersion: string): string[]; + + /** + * Returns the path to the adb which is located in ANDROID_HOME. + * @return {Promise} Path to the adb which is located in ANDROID_HOME. + */ + getPathToAdbFromAndroidHome(): Promise; + + /** + * Checks if the ANDROID_HOME variable is set to the correct folder. + * @return {string[]} An array of errors from the validation checks. If there are no errors will return []. + */ + validateAndroidHomeEnvVariable(): string[]; + } + + /** + * Describes information about installed Android tools and SDKs. + */ + interface IAndroidToolsInfoData { + /** + * The value of ANDROID_HOME environment variable. + */ + androidHomeEnvVar: string; + + /** + * The latest installed version of Android Build Tools that satisfies CLI's requirements. + */ + buildToolsVersion: string; + + /** + * The latest installed version of Android SDK that satisfies CLI's requirements. + */ + compileSdkVersion: number; + + /** + * The latest installed version of Android Support Repository that satisfies CLI's requirements. + */ + supportRepositoryVersion: string; + } } From 9a11aacad9e01841fa2a3b27610f4c724c2d5289 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 15 Mar 2017 16:32:09 +0200 Subject: [PATCH 030/169] Add the new checks for Android SDK Tools --- lib/android-tools-info.ts | 93 ++++++++++++++++++++++++-------- lib/doctor.ts | 38 ++++++++++--- lib/index.ts | 9 ++-- lib/sys-info.ts | 31 ++++++----- test/sys-info.ts | 31 ++++++++++- typings/interfaces.ts | 33 +++++++++--- typings/nativescript-doctor.d.ts | 1 + 7 files changed, 184 insertions(+), 52 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index f9e9988c61..6d7744f5ed 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -1,9 +1,10 @@ -import * as path from "path"; -import * as semver from "semver"; -import { EOL } from "os"; import { ChildProcess } from "./wrappers/child-process"; import { FileSystem } from "./wrappers/file-system"; import { HostInfo } from "./host-info"; +import { Constants } from "./constants"; +import { EOL } from "os"; +import * as semver from "semver"; +import * as path from "path"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static ANDROID_TARGET_PREFIX = "android"; @@ -15,6 +16,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; private androidHome = process.env["ANDROID_HOME"]; + private pathToEmulatorExecutable: string; constructor(private childProcess: ChildProcess, private fs: FileSystem, @@ -34,13 +36,16 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return this.toolsInfo; } - public validateInfo(): string[] { - const errors: string[] = []; + public validateInfo(): NativeScriptDoctor.IWarning[] { + const errors: NativeScriptDoctor.IWarning[] = []; const toolsInfoData = this.getToolsInfo(); const isAndroidHomeValid = this.validateAndroidHomeEnvVariable(); if (!toolsInfoData.compileSdkVersion) { - errors.push(`Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later.`, - `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage your Android SDK versions.`); + errors.push({ + warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later.`, + additionalInformation: `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage your Android SDK versions.`, + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); } if (!toolsInfoData.buildToolsVersion) { @@ -58,7 +63,11 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { invalidBuildToolsAdditionalMsg += ' In case you already have them installed, make sure `ANDROID_HOME` environment variable is set correctly.'; } - errors.push("You need to have the Android SDK Build-tools installed on your system. " + message, invalidBuildToolsAdditionalMsg); + errors.push({ + warning: "You need to have the Android SDK Build-tools installed on your system. " + message, + additionalInformation: invalidBuildToolsAdditionalMsg, + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); } if (!toolsInfoData.supportRepositoryVersion) { @@ -66,14 +75,19 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (!isAndroidHomeValid) { invalidSupportLibAdditionalMsg += ' In case you already have it installed, make sure `ANDROID_HOME` environment variable is set correctly.'; } - errors.push(`You need to have Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later and the latest Android Support Repository installed on your system.`, invalidSupportLibAdditionalMsg); + + errors.push({ + warning: `You need to have Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later and the latest Android Support Repository installed on your system.`, + additionalInformation: invalidSupportLibAdditionalMsg, + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); } return errors; } - public validateJavacVersion(installedJavaVersion: string): string[] { - const errors: string[] = []; + public validateJavacVersion(installedJavaVersion: string): NativeScriptDoctor.IWarning[] { + const errors: NativeScriptDoctor.IWarning[] = []; let additionalMessage = "You will not be able to build your projects for Android." + EOL + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + @@ -81,10 +95,18 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { let matchingVersion = (installedJavaVersion || "").match(AndroidToolsInfo.VERSION_REGEX); if (matchingVersion && matchingVersion[1]) { if (semver.lt(matchingVersion[1], AndroidToolsInfo.MIN_JAVA_VERSION)) { - errors.push(`Javac version ${installedJavaVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`, additionalMessage); + errors.push({ + warning: `Javac version ${installedJavaVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`, + additionalInformation: additionalMessage, + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); } } else { - errors.push("Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable.", additionalMessage); + errors.push({ + warning: "Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable.", + additionalInformation: additionalMessage, + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); } return errors; @@ -104,22 +126,51 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return null; } - public validateAndroidHomeEnvVariable(): string[] { - const errors: string[] = []; + public validateAndroidHomeEnvVariable(): NativeScriptDoctor.IWarning[] { + const errors: NativeScriptDoctor.IWarning[] = []; const expectedDirectoriesInAndroidHome = ["build-tools", "tools", "platform-tools", "extras"]; if (!this.androidHome || !this.fs.exists(this.androidHome)) { - errors.push("The ANDROID_HOME environment variable is not set or it points to a non-existent directory. You will not be able to perform any build-related operations for Android.", - "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory."); + errors.push({ + warning: "The ANDROID_HOME environment variable is not set or it points to a non-existent directory. You will not be able to perform any build-related operations for Android.", + additionalInformation: "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory.", + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); } else if (expectedDirectoriesInAndroidHome.map(dir => this.fs.exists(path.join(this.androidHome, dir))).length === 0) { - errors.push("The ANDROID_HOME environment variable points to incorrect directory. You will not be able to perform any build-related operations for Android.", - "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory, " + - "where you will find `tools` and `platform-tools` directories."); + errors.push({ + warning: "The ANDROID_HOME environment variable points to incorrect directory. You will not be able to perform any build-related operations for Android.", + additionalInformation: "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory, " + + "where you will find `tools` and `platform-tools` directories.", + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); } return errors; } + public getPathToEmulatorExecutable(): string { + if (!this.pathToEmulatorExecutable) { + const emulatorExecutableName = "emulator"; + + this.pathToEmulatorExecutable = emulatorExecutableName; + + if (this.androidHome) { + // Check https://developer.android.com/studio/releases/sdk-tools.html (25.3.0) + // Since this version of SDK tools, the emulator is a separate package. + // However the emulator executable still exists in the "tools" dir. + const pathToEmulatorFromAndroidStudio = path.join(this.androidHome, emulatorExecutableName, emulatorExecutableName); + + if (this.fs.exists(pathToEmulatorFromAndroidStudio)) { + this.pathToEmulatorExecutable = pathToEmulatorFromAndroidStudio; + } else { + this.pathToEmulatorExecutable = path.join(this.androidHome, "tools", emulatorExecutableName); + } + } + } + + return this.pathToEmulatorExecutable; + } + private getPathToSdkManagementTool(): string { const sdkmanagerName = "sdkmanager"; let sdkManagementToolPath = sdkmanagerName; @@ -217,7 +268,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const sortedAndroidToolsInfo = AndroidToolsInfo.SUPPORTED_TARGETS.sort(); sortedAndroidToolsInfo.forEach(s => { - if (installedTargets.includes(s)) { + if (installedTargets.indexOf(s) >= 0) { latestValidAndroidTarget = s; } }); diff --git a/lib/doctor.ts b/lib/doctor.ts index 966bd29f1e..c2bc2ef788 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -13,7 +13,8 @@ export class Doctor implements NativeScriptDoctor.IDoctor { private helpers: Helpers, private hostInfo: HostInfo, private iOSLocalBuildRequirements: IosLocalBuildRequirements, - private sysInfo: NativeScriptDoctor.ISysInfo) { } + private sysInfo: NativeScriptDoctor.ISysInfo, + private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo) { } public async canExecuteLocalBuild(platform: string): Promise { this.validatePlatform(platform); @@ -28,30 +29,47 @@ export class Doctor implements NativeScriptDoctor.IDoctor { } public async getWarnings(): Promise { - const result: NativeScriptDoctor.IWarning[] = []; + let result: NativeScriptDoctor.IWarning[] = []; const sysInfoData = await this.sysInfo.getSysInfo(); + const androidHomeValidationErrors = this.androidToolsInfo.validateAndroidHomeEnvVariable(); + if (androidHomeValidationErrors.length > 0) { + result = result.concat(androidHomeValidationErrors); + } + if (!sysInfoData.adbVer) { result.push({ warning: "WARNING: adb from the Android SDK is not installed or is not configured properly. ", - additionalInformation: "For Android-related operations, the AppBuilder CLI will use a built-in version of adb." + EOL + additionalInformation: "For Android-related operations, the NativeScript CLI will use a built-in version of adb." + EOL + "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL + "Android devices, verify that you have installed the latest Android SDK and" + EOL - + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, + + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL + + this.getPackageManagerTip(), platforms: [Constants.ANDROID_PLATFORM_NAME] }); } - if (!sysInfoData.androidInstalled) { + if (!sysInfoData.isAndroidSdkConfiguredCorrectly) { result.push({ warning: "WARNING: The Android SDK is not installed or is not configured properly.", additionalInformation: "You will not be able to run your apps in the native emulator. To be able to run apps" + EOL + "in the native Android emulator, verify that you have installed the latest Android SDK " + EOL - + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, + + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL + + this.getPackageManagerTip(), platforms: [Constants.ANDROID_PLATFORM_NAME] }); } + const androidToolsInfoValidationErrors = this.androidToolsInfo.validateInfo(); + if (androidToolsInfoValidationErrors.length > 0) { + result = result.concat(androidToolsInfoValidationErrors); + } + + const javacValidationErrors = this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion); + if (javacValidationErrors.length > 0) { + result = result.concat(javacValidationErrors); + } + if (this.hostInfo.isDarwin) { if (!sysInfoData.xcodeVer) { result.push({ @@ -153,4 +171,12 @@ export class Doctor implements NativeScriptDoctor.IDoctor { throw new Error(`Platform ${platform} is not supported.The supported platforms are: ${Constants.SUPPORTED_PLATFORMS.join(", ")} `); } } + + private getPackageManagerTip(): string { + if (this.hostInfo.isWindows) { + return "TIP: To avoid setting up the necessary environment variables, you can use the chocolatey package manager to install the Android SDK and its dependencies." + EOL; + } else if (this.hostInfo.isDarwin) { + return "TIP: To avoid setting up the necessary environment variables, you can use the Homebrew package manager to install the Android SDK and its dependencies." + EOL; + } + } } diff --git a/lib/index.ts b/lib/index.ts index a55997f508..6688b451f7 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -2,6 +2,7 @@ import { ChildProcess } from "./wrappers/child-process"; import { FileSystem } from "./wrappers/file-system"; import { SysInfo } from "./sys-info"; import { HostInfo } from "./host-info"; +import { AndroidToolsInfo } from "./android-tools-info"; import { WinReg } from "./winreg"; import { Helpers } from "./helpers"; import { Doctor } from "./doctor"; @@ -14,13 +15,14 @@ const winReg = new WinReg(); const hostInfo = new HostInfo(winReg); const fileSystem = new FileSystem(); const helpers = new Helpers(); +const androidToolsInfo = new AndroidToolsInfo(childProcess, fileSystem, hostInfo); -const sysInfo: NativeScriptDoctor.ISysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg); +const sysInfo: NativeScriptDoctor.ISysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg, androidToolsInfo); const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(sysInfo); const iOSLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); -const doctor: NativeScriptDoctor.IDoctor = new Doctor(androidLocalBuildRequirements, helpers, hostInfo, iOSLocalBuildRequirements, sysInfo); +const doctor: NativeScriptDoctor.IDoctor = new Doctor(androidLocalBuildRequirements, helpers, hostInfo, iOSLocalBuildRequirements, sysInfo, androidToolsInfo); const setShouldCacheSysInfo = sysInfo.setShouldCacheSysInfo.bind(sysInfo); @@ -28,5 +30,6 @@ export { sysInfo, doctor, constants, - setShouldCacheSysInfo + setShouldCacheSysInfo, + androidToolsInfo }; diff --git a/lib/sys-info.ts b/lib/sys-info.ts index d8a74225a3..2d75172c29 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -42,12 +42,14 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; private isCocoaPodsUpdateRequiredCache: boolean = null; private shouldCache: boolean = true; + private isAndroidSdkConfiguredCorrectlyCache: boolean = null; constructor(private childProcess: ChildProcess, private fileSystem: FileSystem, private helpers: Helpers, private hostInfo: HostInfo, - private winReg: WinReg) { } + private winReg: WinReg, + private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo) { } public getJavaVersion(): Promise { return this.getValueForProperty(() => this.javaVerCache, async (): Promise => { @@ -158,29 +160,31 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getAdbVersion(): Promise { return this.getValueForProperty(() => this.adbVerCache, async (): Promise => { - const output = await this.execCommand("adb version"); + const output = await this.execCommand(`${await this.androidToolsInfo.getPathToAdbFromAndroidHome()} version`); return output ? this.getVersionFromString(output) : null; }); } - // `android -h` returns exit code 1 on successful invocation (Mac OS X for now, possibly Linux). public isAndroidInstalled(): Promise { return this.getValueForProperty(() => this.androidInstalledCache, async (): Promise => { - let pathToAndroid = "android"; - if (this.hostInfo.isWindows) { - pathToAndroid = `${pathToAndroid}.bat`; + try { + const errors = this.androidToolsInfo.validateAndroidHomeEnvVariable(); + return errors.length === 0; + } catch (err) { + return false; } + }); + } + public async isAndroidSdkConfiguredCorrectly(): Promise { + return this.getValueForProperty(() => this.isAndroidSdkConfiguredCorrectlyCache, async (): Promise => { try { - // On mac android -h returns exit code 1. That's why we need to ignore the error. - const output = await this.childProcess.spawnFromEvent(pathToAndroid, ["-h"], "close", { ignoreError: true }); - if (output) { - output.stdout = output.stdout || ''; - return output.stdout.indexOf("android") >= 0; - } + await this.childProcess.execFile(this.androidToolsInfo.getPathToEmulatorExecutable(), ['-help']); } catch (err) { - return null; + return false; } + + return true; }); } @@ -240,6 +244,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); + result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly(); return result; }); diff --git a/test/sys-info.ts b/test/sys-info.ts index 63663c263f..109679d694 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -40,6 +40,27 @@ interface IFileSystemMockOptions { existsResult?: boolean; } +const androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo = { + getPathToAdbFromAndroidHome: async () => { + return "adb"; + }, + getPathToEmulatorExecutable: () => { + return ""; + }, + getToolsInfo: () => { + return Object.create(null); + }, + validateAndroidHomeEnvVariable: () => { + return []; + }, + validateInfo: () => { + return []; + }, + validateJavacVersion: () => { + return []; + } +}; + function createChildProcessResults(childProcessResult: IChildProcessResults): IDictionary { return { "uname -a": childProcessResult.uname, @@ -92,6 +113,9 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: spawnFromEvent: async (command: string, args: string[], event: string) => { return getResultFromChildProcess(childProcessResultDictionary[command], command); + }, + execFile: async () => { + return undefined; } }; @@ -100,7 +124,7 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: extractZip: () => Promise.resolve() }; - return new SysInfo(childProcess, fileSystem, helpers, hostInfo, winreg); + return new SysInfo(childProcess, fileSystem, helpers, hostInfo, winreg, androidToolsInfo); } function setStdOut(value: string): { stdout: string } { @@ -132,10 +156,13 @@ describe("SysInfo unit tests", () => { exec: async (command: string) => { execCommand = command; return { stdout: "", stderr: "" }; + }, + execFile: async () => { + return undefined; } }; - sysInfo = new SysInfo(childProcess, null, helpers, null, null); + sysInfo = new SysInfo(childProcess, null, helpers, null, null, androidToolsInfo); }); it("java version.", async () => { diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 157fea0b89..4047895371 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -107,10 +107,16 @@ declare module NativeScriptDoctor { /** * Checks if the current version of CocoaPods is compatible with the installed Xcode. - * @return {boolean} true if an update us require. + * @return {Promise} true if an update us require. */ isCocoaPodsUpdateRequired(): Promise; + /** + * Checks if the Android SDK Tools are installed and configured correctly. + * @return {Promise} true if the Android SDK Tools are installed and configured correctly. + */ + isAndroidSdkConfiguredCorrectly(): Promise; + /** * Returns the whole system information. * @return {Promise} The system information. @@ -281,8 +287,15 @@ declare module NativeScriptDoctor { /** * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. + * @type {boolean} */ isCocoaPodsUpdateRequired: boolean; + + /** + * true if the Android SDK Tools are installed and configured correctly. + * @type {boolean} + */ + isAndroidSdkConfiguredCorrectly: boolean; } /** @@ -344,16 +357,16 @@ declare module NativeScriptDoctor { /** * Checks if the Android tools are valid. - * @return {string[]} An array of errors from the validation checks. If there are no errors will return []. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateInfo(): string[]; + validateInfo(): NativeScriptDoctor.IWarning[]; /** * Checks if the current javac version is valid. * @param {string} installedJavaVersion The version of javac to check. - * @return {string[]} An array of errors from the validation checks. If there are no errors will return []. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateJavacVersion(installedJavaVersion: string): string[]; + validateJavacVersion(installedJavaVersion: string): NativeScriptDoctor.IWarning[]; /** * Returns the path to the adb which is located in ANDROID_HOME. @@ -363,9 +376,15 @@ declare module NativeScriptDoctor { /** * Checks if the ANDROID_HOME variable is set to the correct folder. - * @return {string[]} An array of errors from the validation checks. If there are no errors will return []. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. + */ + validateAndroidHomeEnvVariable(): NativeScriptDoctor.IWarning[]; + + /** + * Returns the path to the emulator executable. + * @return {string} The path to the emulator executable. */ - validateAndroidHomeEnvVariable(): string[]; + getPathToEmulatorExecutable(): string; } /** diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 38c16db16d..5d73fc99ed 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -5,5 +5,6 @@ declare module "nativescript-doctor" { export const doctor: NativeScriptDoctor.IDoctor; export const sysInfo: NativeScriptDoctor.ISysInfo; export const constants: NativeScriptDoctor.IConstants; + export const androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo; export const setShouldCacheSysInfo: (shouldCache: boolean) => void; } From bb9b7ad0d3ecdcfd6e9a628b9e3f19bbcfc56832 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 15 Mar 2017 17:20:04 +0200 Subject: [PATCH 031/169] Fix emulator check and unit tests --- lib/sys-info.ts | 8 ++------ test/sys-info.ts | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 2d75172c29..03fc9bb10e 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -178,13 +178,9 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public async isAndroidSdkConfiguredCorrectly(): Promise { return this.getValueForProperty(() => this.isAndroidSdkConfiguredCorrectlyCache, async (): Promise => { - try { - await this.childProcess.execFile(this.androidToolsInfo.getPathToEmulatorExecutable(), ['-help']); - } catch (err) { - return false; - } + const output = await this.childProcess.spawnFromEvent(this.androidToolsInfo.getPathToEmulatorExecutable(), ['-help'], "close", { ignoreError: true }); - return true; + return output && output.stdout.indexOf("usage: emulator") >= 0; }); } diff --git a/test/sys-info.ts b/test/sys-info.ts index 109679d694..a5e76df3a0 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -45,18 +45,18 @@ const androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo = { return "adb"; }, getPathToEmulatorExecutable: () => { - return ""; + return "emulator"; }, getToolsInfo: () => { return Object.create(null); }, - validateAndroidHomeEnvVariable: () => { + validateAndroidHomeEnvVariable: (): any[] => { return []; }, - validateInfo: () => { + validateInfo: (): any[] => { return []; }, - validateJavacVersion: () => { + validateJavacVersion: (): any[] => { return []; } }; @@ -78,7 +78,8 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID "mono --version": childProcessResult.monoVersion, "git --version": childProcessResult.gitVersion, "gradle -v": childProcessResult.gradleVersion, - "tns --version": childProcessResult.nativeScriptCliVersion + "tns --version": childProcessResult.nativeScriptCliVersion, + "emulator": { shouldThrowError: false } }; } @@ -110,7 +111,6 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: exec: async (command: string) => { return getResultFromChildProcess(childProcessResultDictionary[command], command); }, - spawnFromEvent: async (command: string, args: string[], event: string) => { return getResultFromChildProcess(childProcessResultDictionary[command], command); }, @@ -239,6 +239,10 @@ describe("SysInfo unit tests", () => { assert.deepEqual(result.nativeScriptCliVersion, childProcessResult.nativeScriptCliVersion.result.stdout); }; + beforeEach(() => { + androidToolsInfo.validateAndroidHomeEnvVariable = (): any[] => []; + }); + it("on Windows", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); let result = await sysInfo.getSysInfo(); @@ -312,6 +316,7 @@ describe("SysInfo unit tests", () => { pod: { shouldThrowError: true }, nativeScriptCliVersion: { shouldThrowError: true } }; + androidToolsInfo.validateAndroidHomeEnvVariable = (): any[] => [1]; }); describe("when all of calls throw", () => { @@ -330,19 +335,19 @@ describe("SysInfo unit tests", () => { assert.deepEqual(result.cocoaPodsVer, null); }; - it("on Windows", () => { + it("on Windows", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); - assertAllValuesAreNull(); + await assertAllValuesAreNull(); }); - it("on Mac", () => { + it("on Mac", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - assertAllValuesAreNull(); + await assertAllValuesAreNull(); }); - it("on Linux", () => { + it("on Linux", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1" }); - assertAllValuesAreNull(); + await assertAllValuesAreNull(); }); }); }); From 946e944eb7193552f4fb10b841708741595b30c8 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Wed, 15 Mar 2017 17:28:58 +0200 Subject: [PATCH 032/169] Update README.md --- README.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/README.md b/README.md index eb1f2e6fbe..e6b933326b 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,12 @@ Library that helps identifying if the environment can be used for development of */ isCocoaPodsUpdateRequired(): Promise; + /** + * Checks if the Android SDK Tools are installed and configured correctly. + * @return {Promise} true if the Android SDK Tools are installed and configured correctly. + */ + isAndroidSdkConfiguredCorrectly(): Promise; + /** * Returns the whole system information. * @return {Promise} The system information. @@ -409,6 +415,12 @@ Library that helps identifying if the environment can be used for development of * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. */ isCocoaPodsUpdateRequired: boolean; + + /** + * true if the Android SDK Tools are installed and configured correctly. + * @type {boolean} + */ + isAndroidSdkConfiguredCorrectly: boolean; } /** @@ -427,6 +439,91 @@ Library that helps identifying if the environment can be used for development of } ``` +* Module `androidToolsInfo`: + - Usage: + ```TypeScript + import { androidToolsInfo } from "nativescript-doctor" + + function main() { + console.log("path to adb from android home: ", await androidToolsInfo.getPathToAdbFromAndroidHome()); + console.log("path to emulator executable: ", androidToolsInfo.getPathToEmulatorExecutable()); + console.log("android tools info: ", androidToolsInfo.getToolsInfo()); + console.log("ANROID_HOME validation errors: ", await androidToolsInfo.validateAndroidHomeEnvVariable()); + console.log("android tools info validation errors: ", await androidToolsInfo.validateInfo()); + console.log("javac validation errors: ", await androidToolsInfo.validateJavacVersion(await sysInfo.getJavaCompilerVersion())); + } + + main(); + ``` + - Interfaces: + /** + * Describes methods for getting and validating Android tools. + */ + interface IAndroidToolsInfo { + /** + * Returns the Android tools info. + * @return {NativeScriptDoctor.IAndroidToolsInfoData} returns the Android tools info. + */ + getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData; + + /** + * Checks if the Android tools are valid. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. + */ + validateInfo(): NativeScriptDoctor.IWarning[]; + + /** + * Checks if the current javac version is valid. + * @param {string} installedJavaVersion The version of javac to check. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. + */ + validateJavacVersion(installedJavaVersion: string): NativeScriptDoctor.IWarning[]; + + /** + * Returns the path to the adb which is located in ANDROID_HOME. + * @return {Promise} Path to the adb which is located in ANDROID_HOME. + */ + getPathToAdbFromAndroidHome(): Promise; + + /** + * Checks if the ANDROID_HOME variable is set to the correct folder. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. + */ + validateAndroidHomeEnvVariable(): NativeScriptDoctor.IWarning[]; + + /** + * Returns the path to the emulator executable. + * @return {string} The path to the emulator executable. + */ + getPathToEmulatorExecutable(): string; + } + + /** + * Describes information about installed Android tools and SDKs. + */ + interface IAndroidToolsInfoData { + /** + * The value of ANDROID_HOME environment variable. + */ + androidHomeEnvVar: string; + + /** + * The latest installed version of Android Build Tools that satisfies CLI's requirements. + */ + buildToolsVersion: string; + + /** + * The latest installed version of Android SDK that satisfies CLI's requirements. + */ + compileSdkVersion: number; + + /** + * The latest installed version of Android Support Repository that satisfies CLI's requirements. + */ + supportRepositoryVersion: string; + } + ``` + * Module `constants`: - Usage: ```TypeScript From 08e6713681198339ec38db021ae0975a45e361e1 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 16 Mar 2017 12:50:52 +0200 Subject: [PATCH 033/169] Fix PR comments --- lib/android-tools-info.ts | 3 ++- lib/doctor.ts | 14 ++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 6d7744f5ed..923e9f40e4 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -159,8 +159,9 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { // Since this version of SDK tools, the emulator is a separate package. // However the emulator executable still exists in the "tools" dir. const pathToEmulatorFromAndroidStudio = path.join(this.androidHome, emulatorExecutableName, emulatorExecutableName); + const realFilePath = this.hostInfo.isWindows ? `${pathToEmulatorFromAndroidStudio}.exe` : pathToEmulatorFromAndroidStudio; - if (this.fs.exists(pathToEmulatorFromAndroidStudio)) { + if (this.fs.exists(realFilePath)) { this.pathToEmulatorExecutable = pathToEmulatorFromAndroidStudio; } else { this.pathToEmulatorExecutable = path.join(this.androidHome, "tools", emulatorExecutableName); diff --git a/lib/doctor.ts b/lib/doctor.ts index c2bc2ef788..6dc426bee4 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -43,8 +43,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { additionalInformation: "For Android-related operations, the NativeScript CLI will use a built-in version of adb." + EOL + "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL + "Android devices, verify that you have installed the latest Android SDK and" + EOL - + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL - + this.getPackageManagerTip(), + + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, platforms: [Constants.ANDROID_PLATFORM_NAME] }); } @@ -54,8 +53,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { warning: "WARNING: The Android SDK is not installed or is not configured properly.", additionalInformation: "You will not be able to run your apps in the native emulator. To be able to run apps" + EOL + "in the native Android emulator, verify that you have installed the latest Android SDK " + EOL - + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL - + this.getPackageManagerTip(), + + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, platforms: [Constants.ANDROID_PLATFORM_NAME] }); } @@ -171,12 +169,4 @@ export class Doctor implements NativeScriptDoctor.IDoctor { throw new Error(`Platform ${platform} is not supported.The supported platforms are: ${Constants.SUPPORTED_PLATFORMS.join(", ")} `); } } - - private getPackageManagerTip(): string { - if (this.hostInfo.isWindows) { - return "TIP: To avoid setting up the necessary environment variables, you can use the chocolatey package manager to install the Android SDK and its dependencies." + EOL; - } else if (this.hostInfo.isDarwin) { - return "TIP: To avoid setting up the necessary environment variables, you can use the Homebrew package manager to install the Android SDK and its dependencies." + EOL; - } - } } From 2a0f6d165d3ca08bca2a844d77a3105c2fbb5d42 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 16 Mar 2017 12:58:13 +0200 Subject: [PATCH 034/169] Fix PR comments --- lib/sys-info.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 03fc9bb10e..ffdaddb67b 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -28,21 +28,21 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private npmVerCache: string; private nodeGypVerCache: string; private xCodeprojGemLocationCache: string; - private iTunesInstalledCache: boolean = null; + private iTunesInstalledCache: boolean; private cocoaPodsVerCache: string; private osCache: string; private adbVerCache: string; - private androidInstalledCache: boolean = null; + private androidInstalledCache: boolean; private monoVerCache: string; private gitVerCache: string; private gradleVerCache: string; private sysInfoCache: NativeScriptDoctor.ISysInfoData; - private isCocoaPodsWorkingCorrectlyCache: boolean = null; + private isCocoaPodsWorkingCorrectlyCache: boolean; private nativeScriptCliVersionCache: string; private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; - private isCocoaPodsUpdateRequiredCache: boolean = null; + private isCocoaPodsUpdateRequiredCache: boolean; private shouldCache: boolean = true; - private isAndroidSdkConfiguredCorrectlyCache: boolean = null; + private isAndroidSdkConfiguredCorrectlyCache: boolean; constructor(private childProcess: ChildProcess, private fileSystem: FileSystem, @@ -320,7 +320,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { const propertyName = this.helpers.getPropertyName(property); const cachedValue: T = (this)[propertyName]; - if (cachedValue === undefined || cachedValue === null) { + if (cachedValue === undefined) { const result = await getValueMethod(); (this)[propertyName] = result; return result; From 358bfd32855c8704d44ba05eda28d430c114eaf0 Mon Sep 17 00:00:00 2001 From: TsvetanMilanov Date: Thu, 16 Mar 2017 12:58:44 +0200 Subject: [PATCH 035/169] Bump version to 0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 24c7d7b0a2..c0f06bb268 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.2.1", + "version": "0.3.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 7eba27aec1345f83ad1a7eac6494c979cee97d5f Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 17 Mar 2017 11:21:00 +0200 Subject: [PATCH 036/169] Fix check isAndroidHomeValid The method that validates ANDROID_HOME returns array with errors, so current `if(isAndroidHomeValid)` checks are always true. Create new method that returns boolean value and use it instead. --- lib/android-tools-info.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 923e9f40e4..93db85c55b 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -39,7 +39,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public validateInfo(): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const toolsInfoData = this.getToolsInfo(); - const isAndroidHomeValid = this.validateAndroidHomeEnvVariable(); + const isAndroidHomeValid = this.isAndroidHomeValid(); if (!toolsInfoData.compileSdkVersion) { errors.push({ warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later.`, @@ -176,7 +176,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const sdkmanagerName = "sdkmanager"; let sdkManagementToolPath = sdkmanagerName; - const isAndroidHomeValid = this.validateAndroidHomeEnvVariable(); + const isAndroidHomeValid = this.isAndroidHomeValid(); if (isAndroidHomeValid) { // In case ANDROID_HOME is correct, check if sdkmanager exists and if not it means the SDK has not been updated. @@ -316,4 +316,9 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return linkToSystemRequirements; } + + private isAndroidHomeValid(): boolean { + const errors = this.validateAndroidHomeEnvVariable(); + return !errors && !errors.length; + } } From 12346e1e2cc30ef6c5976f3cdb521e9e73c2317c Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 17 Mar 2017 11:29:50 +0200 Subject: [PATCH 037/169] Set version to 0.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c0f06bb268..7107a414a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.3.0", + "version": "0.3.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 873efbb45e7f1326ac2ed325fddf77f02555ef85 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 21 Mar 2017 14:33:14 +0200 Subject: [PATCH 038/169] Fix getting information about adb When path to ANDROID_HOME contains spaces, we do not get the path to adb correctly and we return error that adb is not installed. Fix this by using child_process.spawn which handles spaces. Fix incorrect tests which did not consider the `ignoreError` option of spawnFromEvent method. --- lib/sys-info.ts | 4 ++-- test/sys-info.ts | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index ffdaddb67b..2d70a00aca 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -160,8 +160,8 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getAdbVersion(): Promise { return this.getValueForProperty(() => this.adbVerCache, async (): Promise => { - const output = await this.execCommand(`${await this.androidToolsInfo.getPathToAdbFromAndroidHome()} version`); - return output ? this.getVersionFromString(output) : null; + const output = await this.childProcess.spawnFromEvent(await this.androidToolsInfo.getPathToAdbFromAndroidHome(), ["version"], "close", { ignoreError: true }); + return output && output.stdout ? this.getVersionFromString(output.stdout) : null; }); } diff --git a/test/sys-info.ts b/test/sys-info.ts index a5e76df3a0..298fb30d5b 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -71,6 +71,7 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID "xcodebuild -version": childProcessResult.xCodeVersion, "pod --version": childProcessResult.podVersion, "pod": childProcessResult.pod, + 'adb': childProcessResult.adbVersion, 'adb version': childProcessResult.adbVersion, "'adb' version": childProcessResult.adbVersion, // for Mac and Linux 'android': childProcessResult.androidInstalled, @@ -83,9 +84,13 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID }; } -function getResultFromChildProcess(childProcessResultDescription: IChildProcessResultDescription, command: string): any { +function getResultFromChildProcess(childProcessResultDescription: IChildProcessResultDescription, command: string, options?: ISpawnFromEventOptions): any { if (childProcessResultDescription.shouldThrowError) { - throw new Error(`This one throws error. (${command})`); + if (options && options.ignoreError) { + return null; + } else { + throw new Error(`This one throws error. (${command})`); + } } return childProcessResultDescription.result; @@ -111,8 +116,8 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: exec: async (command: string) => { return getResultFromChildProcess(childProcessResultDictionary[command], command); }, - spawnFromEvent: async (command: string, args: string[], event: string) => { - return getResultFromChildProcess(childProcessResultDictionary[command], command); + spawnFromEvent: async (command: string, args: string[], event: string, options: ISpawnFromEventOptions) => { + return getResultFromChildProcess(childProcessResultDictionary[command], command, options); }, execFile: async () => { return undefined; From e575dab40b0d80f36985cc84fbaa2a685a745dff Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 21 Mar 2017 14:39:09 +0200 Subject: [PATCH 039/169] Set version to 0.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7107a414a3..027e8f697f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.3.1", + "version": "0.3.2", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From df42abe6fec18a03a3bcdde65b1bf73cc5995086 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 21 Mar 2017 15:09:26 +0200 Subject: [PATCH 040/169] Fix check for android local builds Fix the check for Android Local Builds to check all required compontents from androidToolsInfo. --- lib/index.ts | 2 +- .../android-local-build-requirements.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/index.ts b/lib/index.ts index 6688b451f7..b67125351e 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -19,7 +19,7 @@ const androidToolsInfo = new AndroidToolsInfo(childProcess, fileSystem, hostInfo const sysInfo: NativeScriptDoctor.ISysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg, androidToolsInfo); -const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(sysInfo); +const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(androidToolsInfo, sysInfo); const iOSLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); const doctor: NativeScriptDoctor.IDoctor = new Doctor(androidLocalBuildRequirements, helpers, hostInfo, iOSLocalBuildRequirements, sysInfo, androidToolsInfo); diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index 36bf546a0d..1fe8aece4a 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -1,8 +1,11 @@ export class AndroidLocalBuildRequirements { - constructor(private sysInfo: NativeScriptDoctor.ISysInfo) { } + constructor(private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo, + private sysInfo: NativeScriptDoctor.ISysInfo) { } public async checkRequirements(): Promise { - if (!await this.sysInfo.getJavaCompilerVersion() || + const androidToolsInfo = await this.androidToolsInfo.validateInfo(); + if (androidToolsInfo.length || + !await this.sysInfo.getJavaCompilerVersion() || !await this.sysInfo.getJavaVersion() || !await this.sysInfo.getAdbVersion()) { return false; From 4a5a67d009d1bf578390bd12154b45f3851815ba Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 21 Mar 2017 15:31:12 +0200 Subject: [PATCH 041/169] Set version to 0.3.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 027e8f697f..b4f193f323 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.3.2", + "version": "0.3.3", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 4269384f43ac0f554b76d73059d2b2807f9b4b1c Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 22 Mar 2017 11:05:55 +0200 Subject: [PATCH 042/169] Fix getting adb version when ANDROID_HOME is not set In case ANDROID_HOME is not set, trying to get adb version leads to error. Fix this by checking the value of pathToAdbFromAndroidHome. In case it is not set, return null. --- lib/sys-info.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 2d70a00aca..1de7310560 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -160,7 +160,12 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getAdbVersion(): Promise { return this.getValueForProperty(() => this.adbVerCache, async (): Promise => { - const output = await this.childProcess.spawnFromEvent(await this.androidToolsInfo.getPathToAdbFromAndroidHome(), ["version"], "close", { ignoreError: true }); + let output: IProcessInfo = null; + const pathToAdbFromAndroidHome = await this.androidToolsInfo.getPathToAdbFromAndroidHome(); + if (pathToAdbFromAndroidHome) { + output = await this.childProcess.spawnFromEvent(pathToAdbFromAndroidHome, ["version"], "close", { ignoreError: true }); + } + return output && output.stdout ? this.getVersionFromString(output.stdout) : null; }); } From a2092753dc6c85791c1a55eaba780fba980f5970 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 22 Mar 2017 11:07:17 +0200 Subject: [PATCH 043/169] Set version to 0.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b4f193f323..a63a5f8e93 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.3.3", + "version": "0.3.4", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From a8b97d026aa36d09fa03c2f5ea4d982d824be89f Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Sun, 26 Mar 2017 22:20:09 +0300 Subject: [PATCH 044/169] Add getting version of nativescript-cloud library Add command to get the version of `nativescript-cloud` library. Fix getting the version of globally installed Node.js - we've been incorrectly using `process.version` instead of spawning `node -v`. --- README.md | 10 ++++++++-- lib/sys-info.ts | 22 +++++++++++++++++++++- test/sys-info.ts | 5 +++++ typings/interfaces.ts | 16 ++++++++++++++-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e6b933326b..e269da2c61 100644 --- a/README.md +++ b/README.md @@ -303,12 +303,12 @@ Library that helps identifying if the environment can be used for development of // node stuff /** - * node.js version, returned by `process.version`. + * node.js version, returned by node -v. * @type {string} */ nodeVer: string; - /** + /** * npm version, returned by `npm -v`. * @type {string} */ @@ -405,6 +405,12 @@ Library that helps identifying if the environment can be used for development of */ nativeScriptCliVersion: string; + /** + * The version of `nativescript-cloud` library, as returned by `tns cloud lib version`. + * @type {string} + */ + nativeScriptCloudVersion: string; + /** * Information about xcproj. * @type {string} diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 1de7310560..8b443e6fbb 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -26,6 +26,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private javaCompilerVerCache: string; private xCodeVerCache: string; private npmVerCache: string; + private nodeVerCache: string; private nodeGypVerCache: string; private xCodeprojGemLocationCache: string; private iTunesInstalledCache: boolean; @@ -39,6 +40,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private sysInfoCache: NativeScriptDoctor.ISysInfoData; private isCocoaPodsWorkingCorrectlyCache: boolean; private nativeScriptCliVersionCache: string; + private nativeScriptCloudVersionCache: string; private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; private isCocoaPodsUpdateRequiredCache: boolean; private shouldCache: boolean = true; @@ -91,7 +93,15 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { } public async getNodeVersion(): Promise { - return this.getVersionFromString(process.version); + return this.getValueForProperty(() => this.nodeVerCache, async (): Promise => { + const output = await this.execCommand("node -v"); + if (output) { + const version = this.getVersionFromString(output); + return version || output; + } + + return null; + }); } public getNpmVersion(): Promise { @@ -243,7 +253,10 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.gitVer = await this.getGitVersion(); result.gradleVer = await this.getGradleVersion(); result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); + result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); + result.nativeScriptCloudVersion = await this.getNativeScriptCloudVersion(); + result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly(); @@ -285,6 +298,13 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } + public getNativeScriptCloudVersion(): Promise { + return this.getValueForProperty(() => this.nativeScriptCloudVersionCache, async (): Promise => { + const output = await this.execCommand("tns cloud lib version"); + return output ? output.trim() : output; + }); + } + public getXcprojInfo(): Promise { return this.getValueForProperty(() => this.xcprojInfoCache, async (): Promise => { const cocoaPodsVersion = await this.getCocoaPodsVersion(); diff --git a/test/sys-info.ts b/test/sys-info.ts index 298fb30d5b..226faaddc5 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -16,6 +16,7 @@ interface IChildProcessResultDescription { interface IChildProcessResults { uname: IChildProcessResultDescription; npmV: IChildProcessResultDescription; + nodeV: IChildProcessResultDescription; javaVersion: IChildProcessResultDescription; javacVersion: IChildProcessResultDescription; nodeGypVersion: IChildProcessResultDescription; @@ -65,6 +66,7 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID return { "uname -a": childProcessResult.uname, "npm -v": childProcessResult.npmV, + "node -v": childProcessResult.nodeV, "java": childProcessResult.javaVersion, '"javac" -version': childProcessResult.javacVersion, "node-gyp -v": childProcessResult.nodeGypVersion, @@ -207,6 +209,7 @@ describe("SysInfo unit tests", () => { childProcessResult = { uname: { result: setStdOut("name") }, npmV: { result: setStdOut("2.14.1") }, + nodeV: { result: setStdOut("v6.0.0") }, javaVersion: { result: setStdErr('java version "1.8.0_60"') }, javacVersion: { result: setStdErr("javac 1.8.0_60") }, nodeGypVersion: { result: setStdOut("2.0.0") }, @@ -233,6 +236,7 @@ describe("SysInfo unit tests", () => { describe("returns correct results when everything is installed", () => { let assertCommonValues = (result: NativeScriptDoctor.ISysInfoData) => { assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout); + assert.deepEqual(result.nodeVer, "6.0.0"); assert.deepEqual(result.javaVer, "1.8.0"); assert.deepEqual(result.javacVersion, "1.8.0_60"); assert.deepEqual(result.nodeGypVer, childProcessResult.nodeGypVersion.result.stdout); @@ -308,6 +312,7 @@ describe("SysInfo unit tests", () => { childProcessResult = { uname: { shouldThrowError: true }, npmV: { shouldThrowError: true }, + nodeV: { shouldThrowError: true }, javaVersion: { shouldThrowError: true }, javacVersion: { shouldThrowError: true }, nodeGypVersion: { shouldThrowError: true }, diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 4047895371..05fc149184 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -99,6 +99,12 @@ declare module NativeScriptDoctor { */ getNativeScriptCliVersion(): Promise; + /** + * Returns the version of the installed `nativescript-cloud` version. + * @return {Promise} Returns the version of the installed `nativescript-cloud` version. + */ + getNativeScriptCloudVersion(): Promise; + /** * Checks if xcproj is required to build projects and if it is installed. * @return {Promise} Returns the collected information aboud xcproj. @@ -177,12 +183,12 @@ declare module NativeScriptDoctor { // node stuff /** - * node.js version, returned by `process.version`. + * node.js version, returned by node -v. * @type {string} */ nodeVer: string; - /** + /** * npm version, returned by `npm -v`. * @type {string} */ @@ -279,6 +285,12 @@ declare module NativeScriptDoctor { */ nativeScriptCliVersion: string; + /** + * The version of `nativescript-cloud` library, as returned by `tns cloud lib version`. + * @type {string} + */ + nativeScriptCloudVersion: string; + /** * Information about xcproj. * @type {string} From b13f45f603860c4e908c2cc7eff2b1ae5e96d4c0 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 28 Mar 2017 00:20:29 +0300 Subject: [PATCH 045/169] Set version to 0.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a63a5f8e93..5259c3f490 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.3.4", + "version": "0.4.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 90107c0f1391d8eac7d55016712d6abb1e9cd7ba Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 28 Mar 2017 00:52:10 +0300 Subject: [PATCH 046/169] Fix getting the version of nativescript-cloud In case `nativescript-cloud` lib is not installed, the spawned tns command fails and prints the result to the stdout. So add parsing of the result and use it only when the stdout is valid version. --- lib/sys-info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 8b443e6fbb..b567ffb667 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -301,7 +301,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getNativeScriptCloudVersion(): Promise { return this.getValueForProperty(() => this.nativeScriptCloudVersionCache, async (): Promise => { const output = await this.execCommand("tns cloud lib version"); - return output ? output.trim() : output; + return output ? this.getVersionFromString(output.trim()) : output; }); } From 30376dd7213385bb2c1a46c49f329b73aa84d666 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 28 Mar 2017 00:54:06 +0300 Subject: [PATCH 047/169] Set version to 0.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5259c3f490..f91aa111c4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.4.0", + "version": "0.4.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From bfeb0041b589dbe8354a12927c69d78225828bee Mon Sep 17 00:00:00 2001 From: Toma Nikolov Date: Mon, 19 Jun 2017 10:10:49 +0300 Subject: [PATCH 048/169] Find the path to the git executable on different platforms. --- lib/helpers.ts | 6 ++-- lib/index.ts | 2 +- lib/sys-info.ts | 65 +++++++++++++++++++++++++++++++++++++++++-- test/sys-info.ts | 39 +++++++++++++++++++------- typings/interfaces.ts | 6 ++++ 5 files changed, 102 insertions(+), 16 deletions(-) diff --git a/lib/helpers.ts b/lib/helpers.ts index 87c70200e5..1515eabbe6 100644 --- a/lib/helpers.ts +++ b/lib/helpers.ts @@ -1,6 +1,8 @@ -import { platform } from "os"; +import { HostInfo } from "./host-info"; export class Helpers { + constructor(private hostInfo: HostInfo) { } + public getPropertyName(method: Function): string { if (method) { let match = method.toString().match(/(?:return\s+?.*\.(.+);)|(?:=>\s*?.*\.(.+)\b)/); @@ -17,7 +19,7 @@ export class Helpers { return value; } - return (platform() === "win32") ? this.cmdQuote(value) : this.bashQuote(value); + return this.hostInfo.isWindows ? this.cmdQuote(value) : this.bashQuote(value); } private bashQuote(s: string): string { diff --git a/lib/index.ts b/lib/index.ts index b67125351e..04cebe5196 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -14,7 +14,7 @@ const childProcess = new ChildProcess(); const winReg = new WinReg(); const hostInfo = new HostInfo(winReg); const fileSystem = new FileSystem(); -const helpers = new Helpers(); +const helpers = new Helpers(hostInfo); const androidToolsInfo = new AndroidToolsInfo(childProcess, fileSystem, hostInfo); const sysInfo: NativeScriptDoctor.ISysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg, androidToolsInfo); diff --git a/lib/sys-info.ts b/lib/sys-info.ts index b567ffb667..d232060e14 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -193,7 +193,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public async isAndroidSdkConfiguredCorrectly(): Promise { return this.getValueForProperty(() => this.isAndroidSdkConfiguredCorrectlyCache, async (): Promise => { - const output = await this.childProcess.spawnFromEvent(this.androidToolsInfo.getPathToEmulatorExecutable(), ['-help'], "close", { ignoreError: true }); + const output = await this.childProcess.spawnFromEvent(this.androidToolsInfo.getPathToEmulatorExecutable(), ["-help"], "close", { ignoreError: true }); return output && output.stdout.indexOf("usage: emulator") >= 0; }); @@ -209,10 +209,14 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getGitVersion(): Promise { return this.getValueForProperty(() => this.gitVerCache, async (): Promise => { - const output = await this.execCommand("git --version"); + const gitPath = await this.getGitPath(); + if (!gitPath) { + return null; + } + + const output = await this.execCommand(`${this.helpers.quoteString(gitPath)} --version`); const matches = SysInfo.GIT_VERSION_REGEXP.exec(output); return matches && matches[1]; - }); } @@ -340,6 +344,61 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { this.shouldCache = shouldCache; } + public getGitPath(): Promise { + return this.hostInfo.isWindows ? this.findGitWin32() : this.findGitUnix(); + } + + private async findGitWin32(): Promise { + let result: string; + const win32Paths = [process.env["ProgramFiles"], process.env["ProgramFiles(x86)"]]; + for (const win32Path of win32Paths) { + result = this.findSystemGitWin32(win32Path); + if (result) { + return result; + } + } + + result = this.findGitHubGitWin32(); + return result ? result : await this.findGitCore("where"); + } + + private findSystemGitWin32(base: string): string { + if (!base) { + return null; + } + + return this.findSpecificGit(path.join(base, "Git", "cmd", "git.exe")); + } + + private findGitHubGitWin32(): string { + const github = path.join(process.env["LOCALAPPDATA"], "GitHub"); + if (!this.fileSystem.exists(github)) { + return null; + } + + const children = this.fileSystem.readDirectory(github); + const git = children.filter(child => /^PortableGit/.test(child))[0]; + if (!this.fileSystem.exists(git)) { + return null; + } + + return this.findSpecificGit(path.join(github, git, "cmd", "git.exe")); + } + + private findSpecificGit(gitPath: string): string { + return this.fileSystem.exists(gitPath) ? gitPath : null; + } + + private async findGitUnix(): Promise { + return await this.findGitCore("which"); + } + + private async findGitCore(command: string, options?: any): Promise { + const result = await this.execCommand(`${command} git`); + + return result && result.split("\n")[0].trim(); + } + private async getValueForProperty(property: Function, getValueMethod: () => Promise): Promise { if (this.shouldCache) { const propertyName = this.helpers.getPropertyName(property); diff --git a/test/sys-info.ts b/test/sys-info.ts index 226faaddc5..3d0135ae06 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -6,7 +6,8 @@ import { ChildProcess } from "../lib/wrappers/child-process"; const JavaHomeName = "JAVA_HOME"; const AndroidHomeName = "ANDROID_HOME"; -const helpers = new Helpers(); +const PROGRAM_FILES = "ProgramFiles"; +const PROGRAM_FILES_ENV_PATH = "C:\\Program Files"; interface IChildProcessResultDescription { result?: any; @@ -29,6 +30,7 @@ interface IChildProcessResults { podVersion: IChildProcessResultDescription; pod: IChildProcessResultDescription; nativeScriptCliVersion: IChildProcessResultDescription; + git: IChildProcessResultDescription; } interface IHostInfoMockOptions { @@ -73,16 +75,19 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID "xcodebuild -version": childProcessResult.xCodeVersion, "pod --version": childProcessResult.podVersion, "pod": childProcessResult.pod, - 'adb': childProcessResult.adbVersion, - 'adb version': childProcessResult.adbVersion, + "adb": childProcessResult.adbVersion, + "adb version": childProcessResult.adbVersion, "'adb' version": childProcessResult.adbVersion, // for Mac and Linux - 'android': childProcessResult.androidInstalled, - 'android.bat': childProcessResult.androidInstalled, // for Windows + "android": childProcessResult.androidInstalled, + "android.bat": childProcessResult.androidInstalled, // for Windows "mono --version": childProcessResult.monoVersion, - "git --version": childProcessResult.gitVersion, + "'git' --version": childProcessResult.gitVersion, // for Mac and Linux + '"C:\\Program Files\\Git\\cmd\\git.exe" --version': childProcessResult.gitVersion, // for Windows + '"C:\\Program Files/Git/cmd/git.exe" --version': childProcessResult.gitVersion, // When running Windows test on the Non-Windows platform "gradle -v": childProcessResult.gradleVersion, "tns --version": childProcessResult.nativeScriptCliVersion, - "emulator": { shouldThrowError: false } + "emulator": { shouldThrowError: false }, + "which git": childProcessResult.git }; } @@ -128,9 +133,11 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: const fileSystem: any = { exists: () => Promise.resolve((fileSystemOptions || {}).existsResult), - extractZip: () => Promise.resolve() + extractZip: () => Promise.resolve(), + readDirectory: () => Promise.resolve([]) }; + const helpers = new Helpers(hostInfo); return new SysInfo(childProcess, fileSystem, helpers, hostInfo, winreg, androidToolsInfo); } @@ -169,6 +176,7 @@ describe("SysInfo unit tests", () => { } }; + const helpers = new Helpers(null); sysInfo = new SysInfo(childProcess, null, helpers, null, null, androidToolsInfo); }); @@ -221,7 +229,8 @@ describe("SysInfo unit tests", () => { gitVersion: { result: setStdOut("git version 1.9.5") }, podVersion: { result: setStdOut("0.38.2") }, pod: { result: setStdOut("success") }, - nativeScriptCliVersion: { result: setStdOut("2.5.0") } + nativeScriptCliVersion: { result: setStdOut("2.5.0") }, + git: { result: setStdOut("git") } }; delete process.env[JavaHomeName]; @@ -253,8 +262,11 @@ describe("SysInfo unit tests", () => { }); it("on Windows", async () => { + const originalProgramFiles = process.env[PROGRAM_FILES]; + process.env[PROGRAM_FILES] = PROGRAM_FILES_ENV_PATH; sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); let result = await sysInfo.getSysInfo(); + process.env[PROGRAM_FILES] = originalProgramFiles; assertCommonValues(result); assert.deepEqual(result.xcodeVer, null); assert.deepEqual(result.cocoaPodsVer, null); @@ -287,8 +299,11 @@ describe("SysInfo unit tests", () => { }); it("is null when OS is not Mac", async () => { + const originalProgramFiles = process.env[PROGRAM_FILES]; + process.env[PROGRAM_FILES] = PROGRAM_FILES_ENV_PATH; sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); let result = await sysInfo.getSysInfo(); + process.env[PROGRAM_FILES] = originalProgramFiles; assert.deepEqual(result.cocoaPodsVer, null); }); @@ -324,7 +339,8 @@ describe("SysInfo unit tests", () => { gitVersion: { shouldThrowError: true }, podVersion: { shouldThrowError: true }, pod: { shouldThrowError: true }, - nativeScriptCliVersion: { shouldThrowError: true } + nativeScriptCliVersion: { shouldThrowError: true }, + git: { shouldThrowError: false } }; androidToolsInfo.validateAndroidHomeEnvVariable = (): any[] => [1]; }); @@ -346,7 +362,10 @@ describe("SysInfo unit tests", () => { }; it("on Windows", async () => { + const originalProgramFiles = process.env[PROGRAM_FILES]; + process.env[PROGRAM_FILES] = PROGRAM_FILES_ENV_PATH; sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); + process.env[PROGRAM_FILES] = originalProgramFiles; await assertAllValuesAreNull(); }); diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 05fc149184..9d88a81328 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -81,6 +81,12 @@ declare module NativeScriptDoctor { */ getGitVersion(): Promise; + /** + * Returns the path to the currently installed Git. + * @return {Promise} Returns the path to the currently installed Git. It will return null if Git is not installed. + */ + getGitPath(): Promise; + /** * Returns the currently installed Gradle version. * @return {Promise} Returns the currently installed Gradle version. It will return null if Gradle is not installed. From b2c4d632b80e2c6550737db7dca8f8781fb9aeb9 Mon Sep 17 00:00:00 2001 From: Toma Nikolov Date: Tue, 20 Jun 2017 15:39:51 +0300 Subject: [PATCH 049/169] Bump version. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f91aa111c4..5c608e7b98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.4.1", + "version": "0.5.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From d97d35b9bd6f26d90b9ecd009f02386d857b17e4 Mon Sep 17 00:00:00 2001 From: Toma Nikolov Date: Tue, 20 Jun 2017 19:26:28 +0300 Subject: [PATCH 050/169] Update README.md. --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index e269da2c61..3f282f7f60 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,9 @@ Library that helps identifying if the environment can be used for development of const sysInfoData = await sysInfo.getSysInfo(); console.log("sysInfo: ", sysInfoData); + + const gitPath = await sysInfo.getGitPath(); + console.log("Path to the git executable: ", gitPath); } main(); @@ -273,6 +276,12 @@ Library that helps identifying if the environment can be used for development of * @return {void} */ setShouldCacheSysInfo(shouldCache: boolean): void; + + /** + * Returns the path to the currently installed Git. + * @return {Promise} Returns the path to the currently installed Git. It will return null if Git is not installed. + */ + getGitPath(): Promise; } interface ISysInfoData { @@ -462,6 +471,7 @@ Library that helps identifying if the environment can be used for development of main(); ``` - Interfaces: + ```TypeScript /** * Describes methods for getting and validating Android tools. */ From 5fccd040718e8ef97d4ec2fd2b26b02dbbb77b7b Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 27 Jun 2017 22:52:06 +0300 Subject: [PATCH 051/169] Fix getting CLI version In case CLI prints other things (like warnings from loading extensions) to its stdout, the `nativescript-doctor` returns incorrect version for CLI. Fix this by getting only the version from stdout. Add unit tests for this scenario. --- lib/sys-info.ts | 2 +- test/sys-info.ts | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index d232060e14..a436139ef0 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -298,7 +298,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getNativeScriptCliVersion(): Promise { return this.getValueForProperty(() => this.nativeScriptCliVersionCache, async (): Promise => { const output = await this.execCommand("tns --version"); - return output ? output.trim() : output; + return output ? this.getVersionFromString(output.trim()) : output; }); } diff --git a/test/sys-info.ts b/test/sys-info.ts index 3d0135ae06..7f9852bb61 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -126,7 +126,7 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: spawnFromEvent: async (command: string, args: string[], event: string, options: ISpawnFromEventOptions) => { return getResultFromChildProcess(childProcessResultDictionary[command], command, options); }, - execFile: async () => { + execFile: async (): Promise => { return undefined; } }; @@ -322,6 +322,29 @@ describe("SysInfo unit tests", () => { }); }); + describe("nativeScriptCliVersion", () => { + it("is null when tns is not installed", async () => { + childProcessResult.nativeScriptCliVersion = { shouldThrowError: true }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.nativeScriptCliVersion, null); + }); + + it("is correct when the version is the only row in `tns --version` output", async () => { + childProcessResult.nativeScriptCliVersion = { result: setStdOut("3.0.0") }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.nativeScriptCliVersion, "3.0.0"); + }); + + it("is correct when there are warnings in the `tns --version` output", async () => { + childProcessResult.nativeScriptCliVersion = { result: setStdOut("Some warning due to invalid extensions\\n3.0.0") }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + let result = await sysInfo.getSysInfo(); + assert.deepEqual(result.nativeScriptCliVersion, "3.0.0"); + }); + }); + describe("returns correct results when exceptions are raised during sysInfo data collection", () => { beforeEach(() => { childProcessResult = { From 0ca2d0e845fa085688c70d4739426bda97623298 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 27 Jun 2017 23:07:41 +0300 Subject: [PATCH 052/169] Fix transpilation `@types/temp` depends on `"@types/node": "*"`, so a new version of the `node.d.ts` is installed. This breaks our code. Fix the code, but we'll have to figure it out how to make sure it won't happen again. --- lib/sys-info.ts | 4 ++-- test/sys-info.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index a436139ef0..d050d12631 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -68,7 +68,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getJavaCompilerVersion(): Promise { return this.getValueForProperty(() => this.javaCompilerVerCache, async (): Promise => { const javaCompileExecutableName = "javac"; - const javaHome = process.env.JAVA_HOME; + const javaHome = process.env["JAVA_HOME"]; const pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName; try { const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`); @@ -135,7 +135,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { let mobileDeviceDir: string; if (this.hostInfo.isWindows) { - const commonProgramFiles = this.hostInfo.isWindows64 ? process.env["CommonProgramFiles(x86)"] : process.env.CommonProgramFiles; + const commonProgramFiles = this.hostInfo.isWindows64 ? process.env["CommonProgramFiles(x86)"] : process.env["CommonProgramFiles"]; coreFoundationDir = path.join(commonProgramFiles, "Apple", "Apple Application Support"); mobileDeviceDir = path.join(commonProgramFiles, "Apple", "Mobile Device Support"); } else if (this.hostInfo.isDarwin) { diff --git a/test/sys-info.ts b/test/sys-info.ts index 7f9852bb61..ef08069797 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -153,7 +153,7 @@ describe("SysInfo unit tests", () => { beforeEach(() => { // We need to mock this because on Mac the tests in which the platform is mocked to Windows in the process there will be no CommonProgramFiles. - process.env.CommonProgramFiles = process.env.CommonProgramFiles || "mocked on mac"; + process.env["CommonProgramFiles"] = process.env["CommonProgramFiles"] || "mocked on mac"; process.env["CommonProgramFiles(x86)"] = process.env["CommonProgramFiles(x86)"] || "mocked on mac"; }); From a0265d9ce1422aa5ef2773949af0344d5a653b9d Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 28 Jun 2017 10:12:50 +0300 Subject: [PATCH 053/169] Set version to 0.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c608e7b98..503148d337 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.5.0", + "version": "0.5.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 63cf457bacb73940be6a0e3d96df84f5840204e1 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 7 Aug 2017 13:42:04 +0300 Subject: [PATCH 054/169] Fix parsing of CLI's output The sysInfo spawns NativeScript CLI's commands to get CLI's version and the version of `nativescript-cloud`. However, in some cases, CLI's output contains warnings that Node.js version is not supported. These warnings contain version of Node.js and current code decides that this is the version of CLI (and nativescript-cloud). Fix the parsing by using different regular expression - in CLI's output the version is always on a new line, so rely on this. Add unit tests for this scenario and for getting the version of nativescript-cloud. --- lib/sys-info.ts | 10 +++- test/sys-info.ts | 119 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 91 insertions(+), 38 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index d050d12631..df5b7e77db 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -17,6 +17,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im; private static XCODE_VERSION_REGEXP = /Xcode (.*)/; private static VERSION_REGEXP = /(\d{1,})\.(\d{1,})\.*([\w-]{0,})/m; + private static CLI_OUTPUT_VERSION_REGEXP = /^(?:\d+\.){2}\d+.*?$/m; private static GIT_VERSION_REGEXP = /^git version (.*)/; private static GRADLE_VERSION_REGEXP = /Gradle (.*)/i; @@ -298,14 +299,14 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getNativeScriptCliVersion(): Promise { return this.getValueForProperty(() => this.nativeScriptCliVersionCache, async (): Promise => { const output = await this.execCommand("tns --version"); - return output ? this.getVersionFromString(output.trim()) : output; + return output ? this.getVersionFromCLIOutput(output.trim()) : output; }); } public getNativeScriptCloudVersion(): Promise { return this.getValueForProperty(() => this.nativeScriptCloudVersionCache, async (): Promise => { const output = await this.execCommand("tns cloud lib version"); - return output ? this.getVersionFromString(output.trim()) : output; + return output ? this.getVersionFromCLIOutput(output.trim()) : output; }); } @@ -442,6 +443,11 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { return null; } + private getVersionFromCLIOutput(commandOutput: string): string { + const matches = commandOutput.match(SysInfo.CLI_OUTPUT_VERSION_REGEXP); + return matches && matches[0]; + } + private async winVer(): Promise { let productName: string; let currentVersion: string; diff --git a/test/sys-info.ts b/test/sys-info.ts index ef08069797..323ededd27 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -1,5 +1,6 @@ import * as assert from "assert"; import * as path from "path"; +import { EOL } from "os"; import { SysInfo } from "../lib/sys-info"; import { Helpers } from "../lib/helpers"; import { ChildProcess } from "../lib/wrappers/child-process"; @@ -14,7 +15,13 @@ interface IChildProcessResultDescription { shouldThrowError?: boolean; } +interface ICLIOutputVersionTestCase { + testedProperty: string; + method: (sysInfo: SysInfo) => Promise; +} + interface IChildProcessResults { + [property: string]: IChildProcessResultDescription; uname: IChildProcessResultDescription; npmV: IChildProcessResultDescription; nodeV: IChildProcessResultDescription; @@ -30,6 +37,7 @@ interface IChildProcessResults { podVersion: IChildProcessResultDescription; pod: IChildProcessResultDescription; nativeScriptCliVersion: IChildProcessResultDescription; + nativeScriptCloudVersion: IChildProcessResultDescription; git: IChildProcessResultDescription; } @@ -86,6 +94,7 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID '"C:\\Program Files/Git/cmd/git.exe" --version': childProcessResult.gitVersion, // When running Windows test on the Non-Windows platform "gradle -v": childProcessResult.gradleVersion, "tns --version": childProcessResult.nativeScriptCliVersion, + "tns cloud lib version": childProcessResult.nativeScriptCloudVersion, "emulator": { shouldThrowError: false }, "which git": childProcessResult.git }; @@ -150,6 +159,7 @@ function setStdErr(value: string): { stderr: string } { describe("SysInfo unit tests", () => { let sysInfo: SysInfo; + const dotNetVersion = "4.5.1"; beforeEach(() => { // We need to mock this because on Mac the tests in which the platform is mocked to Windows in the process there will be no CommonProgramFiles. @@ -230,6 +240,7 @@ describe("SysInfo unit tests", () => { podVersion: { result: setStdOut("0.38.2") }, pod: { result: setStdOut("success") }, nativeScriptCliVersion: { result: setStdOut("2.5.0") }, + nativeScriptCloudVersion: { result: setStdOut("0.1.0") }, git: { result: setStdOut("git") } }; @@ -264,8 +275,8 @@ describe("SysInfo unit tests", () => { it("on Windows", async () => { const originalProgramFiles = process.env[PROGRAM_FILES]; process.env[PROGRAM_FILES] = PROGRAM_FILES_ENV_PATH; - sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion }); + const result = await sysInfo.getSysInfo(); process.env[PROGRAM_FILES] = originalProgramFiles; assertCommonValues(result); assert.deepEqual(result.xcodeVer, null); @@ -273,16 +284,16 @@ describe("SysInfo unit tests", () => { }); it("on Mac", async () => { - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getSysInfo(); assertCommonValues(result); assert.deepEqual(result.xcodeVer, "6.4.0"); assert.deepEqual(result.cocoaPodsVer, childProcessResult.podVersion.result.stdout); }); it("on Linux", async () => { - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion }); + const result = await sysInfo.getSysInfo(); assertCommonValues(result); assert.deepEqual(result.xcodeVer, null); assert.deepEqual(result.cocoaPodsVer, null); @@ -293,55 +304,90 @@ describe("SysInfo unit tests", () => { it("is null when cocoapods are not installed", async () => { // simulate error when pod --version command is executed childProcessResult.podVersion = { shouldThrowError: true }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getSysInfo(); assert.deepEqual(result.cocoaPodsVer, null); }); it("is null when OS is not Mac", async () => { const originalProgramFiles = process.env[PROGRAM_FILES]; process.env[PROGRAM_FILES] = PROGRAM_FILES_ENV_PATH; - sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion }); + const result = await sysInfo.getSysInfo(); process.env[PROGRAM_FILES] = originalProgramFiles; assert.deepEqual(result.cocoaPodsVer, null); }); it("is correct when cocoapods output has warning after version output", async () => { childProcessResult.podVersion = { result: setStdOut("0.38.2\nWARNING:\n") }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getSysInfo(); assert.deepEqual(result.cocoaPodsVer, "0.38.2"); }); it("is correct when cocoapods output has warnings before version output", async () => { childProcessResult.podVersion = { result: setStdOut("WARNING\nWARNING2\n0.38.2") }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getSysInfo(); assert.deepEqual(result.cocoaPodsVer, "0.38.2"); }); }); - describe("nativeScriptCliVersion", () => { - it("is null when tns is not installed", async () => { - childProcessResult.nativeScriptCliVersion = { shouldThrowError: true }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); - assert.deepEqual(result.nativeScriptCliVersion, null); - }); + const testData: ICLIOutputVersionTestCase[] = [ + { + testedProperty: "nativeScriptCliVersion", + method: (currentSysInfo: SysInfo) => currentSysInfo.getNativeScriptCliVersion() + }, + { + testedProperty: "nativeScriptCloudVersion", + method: (currentSysInfo: SysInfo) => currentSysInfo.getNativeScriptCloudVersion() + }]; + + testData.forEach((testCase) => { + describe(testCase.testedProperty, () => { + it("is null when tns is not installed", async () => { + childProcessResult[testCase.testedProperty] = { shouldThrowError: true }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await testCase.method(sysInfo); + assert.deepEqual(result, null); + }); - it("is correct when the version is the only row in `tns --version` output", async () => { - childProcessResult.nativeScriptCliVersion = { result: setStdOut("3.0.0") }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); - assert.deepEqual(result.nativeScriptCliVersion, "3.0.0"); - }); + it("is correct when the version is the only row in command output", async () => { + childProcessResult[testCase.testedProperty] = { result: setStdOut("3.0.0") }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await testCase.method(sysInfo); + assert.deepEqual(result, "3.0.0"); + }); - it("is correct when there are warnings in the `tns --version` output", async () => { - childProcessResult.nativeScriptCliVersion = { result: setStdOut("Some warning due to invalid extensions\\n3.0.0") }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); - let result = await sysInfo.getSysInfo(); - assert.deepEqual(result.nativeScriptCliVersion, "3.0.0"); + it("is correct when there are warnings in the command's output", async () => { + childProcessResult[testCase.testedProperty] = { result: setStdOut(`Some warning due to invalid extensions${EOL}3.0.0`) }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await testCase.method(sysInfo); + assert.deepEqual(result, "3.0.0"); + }); + + it("is correct when there are warnings with version in them in the command's output", async () => { + const cliOutput = ` +Support for Node.js 7.6.0 is not verified. This CLI might not install or run properly. + +3.0.0`; + childProcessResult[testCase.testedProperty] = { result: setStdOut(cliOutput) }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await testCase.method(sysInfo); + assert.deepEqual(result, "3.0.0"); + }); + + it("is correct when there are warnings in the command's output and searched version is a prerelease", async () => { + const expectedCliVersion = "3.2.0-2017-07-21-9480"; + const cliOutput = ` +Support for Node.js 7.6.0 is not verified. This CLI might not install or run properly. + +${expectedCliVersion}`; + childProcessResult[testCase.testedProperty] = { result: setStdOut(cliOutput) }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await testCase.method(sysInfo); + assert.deepEqual(result, expectedCliVersion); + }); }); }); @@ -363,6 +409,7 @@ describe("SysInfo unit tests", () => { podVersion: { shouldThrowError: true }, pod: { shouldThrowError: true }, nativeScriptCliVersion: { shouldThrowError: true }, + nativeScriptCloudVersion: { shouldThrowError: true }, git: { shouldThrowError: false } }; androidToolsInfo.validateAndroidHomeEnvVariable = (): any[] => [1]; @@ -370,7 +417,7 @@ describe("SysInfo unit tests", () => { describe("when all of calls throw", () => { let assertAllValuesAreNull = async () => { - let result = await sysInfo.getSysInfo(); + const result = await sysInfo.getSysInfo(); assert.deepEqual(result.npmVer, null); assert.deepEqual(result.javaVer, null); assert.deepEqual(result.javacVersion, null); @@ -387,18 +434,18 @@ describe("SysInfo unit tests", () => { it("on Windows", async () => { const originalProgramFiles = process.env[PROGRAM_FILES]; process.env[PROGRAM_FILES] = PROGRAM_FILES_ENV_PATH; - sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }); + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion }); process.env[PROGRAM_FILES] = originalProgramFiles; await assertAllValuesAreNull(); }); it("on Mac", async () => { - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); await assertAllValuesAreNull(); }); it("on Linux", async () => { - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1" }); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion }); await assertAllValuesAreNull(); }); }); From 9595b8de6c6877bc33e0dd7822c0df11d6f74cb6 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 7 Aug 2017 15:26:18 +0300 Subject: [PATCH 055/169] Set version to 0.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 503148d337..f6aab382d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.5.1", + "version": "0.5.2", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 8cc3a1a86596761ee76762bf9d56055c0fae3f34 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 8 Sep 2017 17:00:02 +0300 Subject: [PATCH 056/169] Allow using version 26 of Android SDK --- lib/android-tools-info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 93db85c55b..f4858cddec 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -8,7 +8,7 @@ import * as path from "path"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static ANDROID_TARGET_PREFIX = "android"; - private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25"]; + private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25", "android-26"]; private static MIN_REQUIRED_COMPILE_TARGET = 22; private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; From 7b7d42cc2de85b960b9668d3a3b955e0ad806ff8 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 8 Sep 2017 18:31:55 +0300 Subject: [PATCH 057/169] Fix exception when checking if xcproj is required In case Cocoapods version is below 1.0.0 and Xcode version contains only two digits, we fail as semver cannot work with versions with two digits. Append zero to the version, to make it correct semver. --- lib/helpers.ts | 9 +++++++++ lib/sys-info.ts | 5 ++++- test/sys-info.ts | 10 ++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/helpers.ts b/lib/helpers.ts index 1515eabbe6..b3dc07ed6c 100644 --- a/lib/helpers.ts +++ b/lib/helpers.ts @@ -22,6 +22,15 @@ export class Helpers { return this.hostInfo.isWindows ? this.cmdQuote(value) : this.bashQuote(value); } + public appendZeroesToVersion(version: string, requiredVersionLength: number): string { + const zeroesToAppend = requiredVersionLength - version.split(".").length; + for (let index = 0; index < zeroesToAppend; index++) { + version += ".0"; + } + + return version; + } + private bashQuote(s: string): string { if (s[0] === "'" && s[s.length - 1] === "'") { return s; diff --git a/lib/sys-info.ts b/lib/sys-info.ts index df5b7e77db..e5469e6283 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -313,7 +313,10 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getXcprojInfo(): Promise { return this.getValueForProperty(() => this.xcprojInfoCache, async (): Promise => { const cocoaPodsVersion = await this.getCocoaPodsVersion(); - const xcodeVersion = await this.getXcodeVersion(); + let xcodeVersion = await this.getXcodeVersion(); + if (xcodeVersion) { + xcodeVersion = this.helpers.appendZeroesToVersion(xcodeVersion, 3); + } // CocoaPods with version lower than 1.0.0 don't support Xcode 7.3 yet // https://github.com/CocoaPods/CocoaPods/issues/2530#issuecomment-210470123 diff --git a/test/sys-info.ts b/test/sys-info.ts index 323ededd27..bcc769b700 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -333,6 +333,16 @@ describe("SysInfo unit tests", () => { }); }); + describe("getXcprojInfo", () => { + it("does not fail when cocoapods version is below 1.0.0 and Xcode version contains only two digits", async () => { + childProcessResult.podVersion = { result: setStdOut("0.39.0") }; + childProcessResult.xCodeVersion = { result: setStdOut("Xcode 8.3") }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getXcprojInfo(); + assert.deepEqual(result, { shouldUseXcproj: true, xcprojAvailable: false }); + }); + }); + const testData: ICLIOutputVersionTestCase[] = [ { testedProperty: "nativeScriptCliVersion", From 66670322feec565d5e508a6e77bbef6c3e506707 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 8 Sep 2017 18:33:09 +0300 Subject: [PATCH 058/169] Remove bluebird dependency as it is not used anywhere --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index f6aab382d0..4778c5f4bb 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "typescript": "2.0.3" }, "dependencies": { - "bluebird": "3.4.6", "osenv": "0.1.3", "semver": "5.3.0", "temp": "0.8.3", From 940573ec6d37c8df2aa98459134b3fe5bb9f0f4e Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 12 Sep 2017 10:17:16 +0300 Subject: [PATCH 059/169] Set version to 0.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4778c5f4bb..f26f3247e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.5.2", + "version": "0.6.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From d36bdb4650b083e258599104e2c7f036df770a42 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 12 Sep 2017 10:36:46 +0300 Subject: [PATCH 060/169] Update npmignore --- .npmignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.npmignore b/.npmignore index 48802e3bd6..cdd6ddc90c 100644 --- a/.npmignore +++ b/.npmignore @@ -30,3 +30,6 @@ docs/html/ dev/ tscommand*.tmp.txt + +tslint.json +tsconfig.json From f3080d95ad4efd8380cca5e5af46ff359e37815c Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 29 Sep 2017 17:53:57 +0300 Subject: [PATCH 061/169] Remove getting cloud lib version Remove getting cloud lib version through spawning command as this is no longer required. CLI has API to get the installed extensions, so it should be used instead. --- README.md | 6 ------ lib/sys-info.ts | 9 --------- test/sys-info.ts | 8 -------- typings/interfaces.ts | 12 ------------ 4 files changed, 35 deletions(-) diff --git a/README.md b/README.md index 3f282f7f60..970d64e40d 100644 --- a/README.md +++ b/README.md @@ -414,12 +414,6 @@ Library that helps identifying if the environment can be used for development of */ nativeScriptCliVersion: string; - /** - * The version of `nativescript-cloud` library, as returned by `tns cloud lib version`. - * @type {string} - */ - nativeScriptCloudVersion: string; - /** * Information about xcproj. * @type {string} diff --git a/lib/sys-info.ts b/lib/sys-info.ts index e5469e6283..6232b06986 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -41,7 +41,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private sysInfoCache: NativeScriptDoctor.ISysInfoData; private isCocoaPodsWorkingCorrectlyCache: boolean; private nativeScriptCliVersionCache: string; - private nativeScriptCloudVersionCache: string; private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; private isCocoaPodsUpdateRequiredCache: boolean; private shouldCache: boolean = true; @@ -260,7 +259,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); - result.nativeScriptCloudVersion = await this.getNativeScriptCloudVersion(); result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly(); @@ -303,13 +301,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } - public getNativeScriptCloudVersion(): Promise { - return this.getValueForProperty(() => this.nativeScriptCloudVersionCache, async (): Promise => { - const output = await this.execCommand("tns cloud lib version"); - return output ? this.getVersionFromCLIOutput(output.trim()) : output; - }); - } - public getXcprojInfo(): Promise { return this.getValueForProperty(() => this.xcprojInfoCache, async (): Promise => { const cocoaPodsVersion = await this.getCocoaPodsVersion(); diff --git a/test/sys-info.ts b/test/sys-info.ts index bcc769b700..e051ee328d 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -37,7 +37,6 @@ interface IChildProcessResults { podVersion: IChildProcessResultDescription; pod: IChildProcessResultDescription; nativeScriptCliVersion: IChildProcessResultDescription; - nativeScriptCloudVersion: IChildProcessResultDescription; git: IChildProcessResultDescription; } @@ -94,7 +93,6 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID '"C:\\Program Files/Git/cmd/git.exe" --version': childProcessResult.gitVersion, // When running Windows test on the Non-Windows platform "gradle -v": childProcessResult.gradleVersion, "tns --version": childProcessResult.nativeScriptCliVersion, - "tns cloud lib version": childProcessResult.nativeScriptCloudVersion, "emulator": { shouldThrowError: false }, "which git": childProcessResult.git }; @@ -240,7 +238,6 @@ describe("SysInfo unit tests", () => { podVersion: { result: setStdOut("0.38.2") }, pod: { result: setStdOut("success") }, nativeScriptCliVersion: { result: setStdOut("2.5.0") }, - nativeScriptCloudVersion: { result: setStdOut("0.1.0") }, git: { result: setStdOut("git") } }; @@ -347,10 +344,6 @@ describe("SysInfo unit tests", () => { { testedProperty: "nativeScriptCliVersion", method: (currentSysInfo: SysInfo) => currentSysInfo.getNativeScriptCliVersion() - }, - { - testedProperty: "nativeScriptCloudVersion", - method: (currentSysInfo: SysInfo) => currentSysInfo.getNativeScriptCloudVersion() }]; testData.forEach((testCase) => { @@ -419,7 +412,6 @@ ${expectedCliVersion}`; podVersion: { shouldThrowError: true }, pod: { shouldThrowError: true }, nativeScriptCliVersion: { shouldThrowError: true }, - nativeScriptCloudVersion: { shouldThrowError: true }, git: { shouldThrowError: false } }; androidToolsInfo.validateAndroidHomeEnvVariable = (): any[] => [1]; diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 9d88a81328..1696fed9e6 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -105,12 +105,6 @@ declare module NativeScriptDoctor { */ getNativeScriptCliVersion(): Promise; - /** - * Returns the version of the installed `nativescript-cloud` version. - * @return {Promise} Returns the version of the installed `nativescript-cloud` version. - */ - getNativeScriptCloudVersion(): Promise; - /** * Checks if xcproj is required to build projects and if it is installed. * @return {Promise} Returns the collected information aboud xcproj. @@ -291,12 +285,6 @@ declare module NativeScriptDoctor { */ nativeScriptCliVersion: string; - /** - * The version of `nativescript-cloud` library, as returned by `tns cloud lib version`. - * @type {string} - */ - nativeScriptCloudVersion: string; - /** * Information about xcproj. * @type {string} From e0a9b3bd590fd9848ff586506114a506f989501b Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 2 Oct 2017 11:02:07 +0300 Subject: [PATCH 062/169] Set version to 0.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f26f3247e0..4276425b16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.6.0", + "version": "0.7.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 156b9161177b76a89bf7922844106d066904ce5f Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 10 Jan 2018 00:20:04 +0200 Subject: [PATCH 063/169] Add check for JAVA 9 * Add check for JAVA 9 Currently Gradle cannot work with JAVA 9, so detect if it has been used return correct warning. Fix detection of Javac version The command `javac -version` prints result to stderr when JAVA 8 is used and to stdout when JAVA 9 is used. Current check uses the stderr output, so when JAVA 9 is installed it fails to detect the correct version. In order to support both JAVA 8 and JAVA 9, capture both stdout and stderr and get the version from there. Also remove unneeded check for Java version - we care about JAVA Compiler, which is included in JDK. * Handle case when Javac version is a single number (9 for example) In some cases javac version is a single number, for example 9. In this case our validation fails to detect the correct version and to check if we support this version. In order to resolve this issue, use the `appendZeroesToVersion` method in order to make the versin semver valid. --- .travis.yml | 2 +- README.md | 14 ---- lib/android-tools-info.ts | 44 +++++------ lib/constants.ts | 5 ++ lib/doctor.ts | 5 +- lib/helpers.ts | 14 +++- lib/index.ts | 2 +- .../android-local-build-requirements.ts | 1 - lib/sys-info.ts | 21 +---- package.json | 2 + test/android-tools-info.ts | 77 +++++++++++++++++++ test/sys-info.ts | 11 --- typings/interfaces.ts | 12 --- 13 files changed, 122 insertions(+), 88 deletions(-) create mode 100644 test/android-tools-info.ts diff --git a/.travis.yml b/.travis.yml index b1358943b7..8a067e1e70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- '4' +- '6' git: submodules: false before_script: diff --git a/README.md b/README.md index 970d64e40d..8364947b37 100644 --- a/README.md +++ b/README.md @@ -79,8 +79,6 @@ Library that helps identifying if the environment can be used for development of // The default value is true. If set to false the result of each check for each element // of the sys info will not be cached. setShouldCacheSysInfo(false); - const javaVersion = await sysInfo.getJavaVersion(); - console.log("java: ", javaVersion); const javacVersion = await sysInfo.getJavaCompilerVersion(); console.log("javac: ", javacVersion); @@ -150,12 +148,6 @@ Library that helps identifying if the environment can be used for development of * Describes methods which helps collecting system information. */ interface ISysInfo { - /** - * Returns the currently installed Java version. - * @return {Promise} The currently installed Java version. - */ - getJavaVersion(): Promise; - /** * Returns the currently installed Java compiler version. * @return {Promise} The currently installed Java compiler version. @@ -336,12 +328,6 @@ Library that helps identifying if the environment can be used for development of nodeGypVer: string; // dependencies - /** - * Version of java, as returned by `java -version`. - * @type {string} - */ - javaVer: string; - /** * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. * @type {string} diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index f4858cddec..bf7da3a6d8 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -2,6 +2,7 @@ import { ChildProcess } from "./wrappers/child-process"; import { FileSystem } from "./wrappers/file-system"; import { HostInfo } from "./host-info"; import { Constants } from "./constants"; +import { Helpers } from './helpers'; import { EOL } from "os"; import * as semver from "semver"; import * as path from "path"; @@ -13,6 +14,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; + private static MAX_JAVA_VERSION = "1.9.0"; private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; private androidHome = process.env["ANDROID_HOME"]; @@ -20,7 +22,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { constructor(private childProcess: ChildProcess, private fs: FileSystem, - private hostInfo: HostInfo) { } + private hostInfo: HostInfo, + private helpers: Helpers) { } public getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData { if (!this.toolsInfo) { @@ -86,17 +89,27 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } - public validateJavacVersion(installedJavaVersion: string): NativeScriptDoctor.IWarning[] { + public validateJavacVersion(installedJavaCompilerVersion: string): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; let additionalMessage = "You will not be able to build your projects for Android." + EOL + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + " described in " + this.getSystemRequirementsLink(); - let matchingVersion = (installedJavaVersion || "").match(AndroidToolsInfo.VERSION_REGEX); - if (matchingVersion && matchingVersion[1]) { - if (semver.lt(matchingVersion[1], AndroidToolsInfo.MIN_JAVA_VERSION)) { + + const matchingVersion = this.helpers.appendZeroesToVersion(installedJavaCompilerVersion || "", 3).match(AndroidToolsInfo.VERSION_REGEX); + const installedJavaCompilerSemverVersion = matchingVersion && matchingVersion[1]; + if (installedJavaCompilerSemverVersion) { + let warning: string = null; + + if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) { + warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; + } else if (semver.gte(installedJavaCompilerSemverVersion, AndroidToolsInfo.MAX_JAVA_VERSION)) { + warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install version ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; + } + + if (warning) { errors.push({ - warning: `Javac version ${installedJavaVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`, + warning, additionalInformation: additionalMessage, platforms: [Constants.ANDROID_PLATFORM_NAME] }); @@ -140,7 +153,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { errors.push({ warning: "The ANDROID_HOME environment variable points to incorrect directory. You will not be able to perform any build-related operations for Android.", additionalInformation: "To be able to perform Android build-related operations, set the `ANDROID_HOME` variable to point to the root of your Android SDK installation directory, " + - "where you will find `tools` and `platform-tools` directories.", + "where you will find `tools` and `platform-tools` directories.", platforms: [Constants.ANDROID_PLATFORM_NAME] }); } @@ -299,22 +312,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } private getSystemRequirementsLink(): string { - let linkToSystemRequirements: string; - switch (process.platform) { - case "linux": - linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-linux.html#system-requirements"; - break; - case "win32": - linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-win.html#system-requirements"; - break; - case "darwin": - linkToSystemRequirements = "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-os-x.html#system-requirements"; - break; - default: - linkToSystemRequirements = ""; - } - - return linkToSystemRequirements; + return Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform] || ""; } private isAndroidHomeValid(): boolean { diff --git a/lib/constants.ts b/lib/constants.ts index 7af237f259..9c2490f646 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -2,4 +2,9 @@ export class Constants { public static ANDROID_PLATFORM_NAME = "Android"; public static IOS_PLATFORM_NAME = "iOS"; public static SUPPORTED_PLATFORMS = [Constants.ANDROID_PLATFORM_NAME, Constants.IOS_PLATFORM_NAME]; + public static SYSTEM_REQUIREMENTS_LINKS: IDictionary = { + "win32": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-win.html#system-requirements", + "linux": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-linux.html#system-requirements", + "darwin": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-os-x.html#system-requirements", + }; } diff --git a/lib/doctor.ts b/lib/doctor.ts index 6dc426bee4..829fdc4973 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -131,14 +131,13 @@ export class Doctor implements NativeScriptDoctor.IDoctor { }); } - if (!sysInfoData.javaVer) { + if (!sysInfoData.javacVersion) { result.push({ warning: "WARNING: The Java Development Kit (JDK) is not installed or is not configured properly.", additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL + "to perform some Android-related operations. To ensure that you can develop and" + EOL + "test your apps for Android, verify that you have installed the JDK as" + EOL - + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)" + EOL - + "or http://docs.oracle.com/javase/7/docs/webnotes/install/ (for JDK 7)." + EOL, + + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)." + EOL, platforms: [Constants.ANDROID_PLATFORM_NAME] }); } diff --git a/lib/helpers.ts b/lib/helpers.ts index b3dc07ed6c..cf3ef4e689 100644 --- a/lib/helpers.ts +++ b/lib/helpers.ts @@ -22,10 +22,18 @@ export class Helpers { return this.hostInfo.isWindows ? this.cmdQuote(value) : this.bashQuote(value); } + /** + * Appends zeroes to a version string until it reaches a specified length. + * @param {string} version The version on which to append zeroes. + * @param {number} requiredVersionLength The required length of the version string. + * @returns {string} Appended version string. In case input is null, undefined or empty string, it is returned immediately without appending anything. + */ public appendZeroesToVersion(version: string, requiredVersionLength: number): string { - const zeroesToAppend = requiredVersionLength - version.split(".").length; - for (let index = 0; index < zeroesToAppend; index++) { - version += ".0"; + if (version) { + const zeroesToAppend = requiredVersionLength - version.split(".").length; + for (let index = 0; index < zeroesToAppend; index++) { + version += ".0"; + } } return version; diff --git a/lib/index.ts b/lib/index.ts index 04cebe5196..e785e0dbd7 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -15,7 +15,7 @@ const winReg = new WinReg(); const hostInfo = new HostInfo(winReg); const fileSystem = new FileSystem(); const helpers = new Helpers(hostInfo); -const androidToolsInfo = new AndroidToolsInfo(childProcess, fileSystem, hostInfo); +const androidToolsInfo = new AndroidToolsInfo(childProcess, fileSystem, hostInfo, helpers); const sysInfo: NativeScriptDoctor.ISysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, winReg, androidToolsInfo); diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index 1fe8aece4a..0ad8da9699 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -6,7 +6,6 @@ export class AndroidLocalBuildRequirements { const androidToolsInfo = await this.androidToolsInfo.validateInfo(); if (androidToolsInfo.length || !await this.sysInfo.getJavaCompilerVersion() || - !await this.sysInfo.getJavaVersion() || !await this.sysInfo.getAdbVersion()) { return false; } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 6232b06986..152adc312e 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -4,16 +4,13 @@ import { HostInfo } from "./host-info"; import { ExecOptions } from "child_process"; import { WinReg } from "./winreg"; import { Helpers } from "./helpers"; -import { platform } from "os"; +import { platform, EOL } from "os"; import * as path from "path"; import * as osenv from "osenv"; import * as temp from "temp"; import * as semver from "semver"; export class SysInfo implements NativeScriptDoctor.ISysInfo { - // Different java has different format for `java -version` command. - private static JAVA_VERSION_REGEXP = /(?:openjdk|java) version \"((?:\d+\.)+(?:\d+))/i; - private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im; private static XCODE_VERSION_REGEXP = /Xcode (.*)/; private static VERSION_REGEXP = /(\d{1,})\.(\d{1,})\.*([\w-]{0,})/m; @@ -23,7 +20,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private monoVerRegExp = /version (\d+[.]\d+[.]\d+) /gm; - private javaVerCache: string; private javaCompilerVerCache: string; private xCodeVerCache: string; private npmVerCache: string; @@ -53,18 +49,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private winReg: WinReg, private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo) { } - public getJavaVersion(): Promise { - return this.getValueForProperty(() => this.javaVerCache, async (): Promise => { - try { - const spawnResult = await this.childProcess.spawnFromEvent("java", ["-version"], "exit"); - const matches = spawnResult && SysInfo.JAVA_VERSION_REGEXP.exec(spawnResult.stderr); - return matches && matches[1]; - } catch (err) { - return null; - } - }); - } - public getJavaCompilerVersion(): Promise { return this.getValueForProperty(() => this.javaCompilerVerCache, async (): Promise => { const javaCompileExecutableName = "javac"; @@ -72,7 +56,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { const pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName; try { const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`); - return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(output.stderr)[1]; + return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(`${output.stderr}${EOL}${output.stdout}`)[1]; } catch (err) { return null; } @@ -245,7 +229,6 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.nodeGypVer = await this.getNodeGypVersion(); result.dotNetVer = await this.hostInfo.dotNetVersion(); - result.javaVer = await this.getJavaVersion(); result.javacVersion = await this.getJavaCompilerVersion(); result.xcodeVer = await this.getXcodeVersion(); result.xcodeprojGemLocation = await this.getXcodeprojGemLocation(); diff --git a/package.json b/package.json index 4276425b16..40401f839e 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,12 @@ }, "homepage": "https://github.com/NativeScript/nativescript-doctor#readme", "devDependencies": { + "@types/chai": "4.1.0", "@types/mocha": "2.2.32", "@types/semver": "5.3.30", "@types/temp": "0.8.29", "@types/winreg": "1.2.30", + "chai": "4.1.2", "grunt": "1.0.1", "grunt-contrib-clean": "1.0.0", "grunt-contrib-watch": "1.0.0", diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts new file mode 100644 index 0000000000..507118e45f --- /dev/null +++ b/test/android-tools-info.ts @@ -0,0 +1,77 @@ +import { AndroidToolsInfo } from '../lib/android-tools-info'; +import { EOL } from 'os'; +import { assert } from "chai"; +import { ChildProcess } from '../lib/wrappers/child-process'; +import { FileSystem } from '../lib/wrappers/file-system'; +import { HostInfo } from '../lib/host-info'; +import { Helpers } from '../lib/helpers'; +import { Constants } from '../lib/constants'; + +interface ITestData { + javacVersion: string; + warnings?: string[]; +} + +describe("androidToolsInfo", () => { + const additionalInformation = "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + + " described in " + Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform]; + + const getAndroidToolsInfo = (): AndroidToolsInfo => { + const childProcess: ChildProcess = {}; + const fs: FileSystem = {}; + const hostInfo: HostInfo = {}; + const helpers: Helpers = new Helpers({}); + return new AndroidToolsInfo(childProcess, fs, hostInfo, helpers); + }; + + describe("validateJavacVersion", () => { + const testData: ITestData[] = [ + { + javacVersion: "1.8.0" + }, + { + javacVersion: "1.8.0_152" + }, + { + javacVersion: "9", + warnings: ["Javac version 9 is not supported. You have to install version 1.8.0."] + }, + { + javacVersion: "9.0.1", + warnings: ["Javac version 9.0.1 is not supported. You have to install version 1.8.0."] + }, + { + javacVersion: "1.7.0", + warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0."] + }, + { + javacVersion: "1.7.0_132", + warnings: ["Javac version 1.7.0_132 is not supported. You have to install at least 1.8.0."] + }, + { + javacVersion: null, + warnings: ["Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable."] + } + ]; + + testData.forEach(({ javacVersion, warnings }) => { + it(`returns correct result when version is ${javacVersion}`, () => { + const androidToolsInfo = getAndroidToolsInfo(); + const actualWarnings = androidToolsInfo.validateJavacVersion(javacVersion); + let expectedWarnings: NativeScriptDoctor.IWarning[] = []; + if (warnings && warnings.length) { + expectedWarnings = warnings.map(warning => { + return { + platforms: [Constants.ANDROID_PLATFORM_NAME], + warning, + additionalInformation + }; + }); + } + + assert.deepEqual(actualWarnings, expectedWarnings); + }); + }); + }); +}); diff --git a/test/sys-info.ts b/test/sys-info.ts index e051ee328d..7a1ac46fc6 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -25,7 +25,6 @@ interface IChildProcessResults { uname: IChildProcessResultDescription; npmV: IChildProcessResultDescription; nodeV: IChildProcessResultDescription; - javaVersion: IChildProcessResultDescription; javacVersion: IChildProcessResultDescription; nodeGypVersion: IChildProcessResultDescription; xCodeVersion: IChildProcessResultDescription; @@ -76,7 +75,6 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID "uname -a": childProcessResult.uname, "npm -v": childProcessResult.npmV, "node -v": childProcessResult.nodeV, - "java": childProcessResult.javaVersion, '"javac" -version': childProcessResult.javacVersion, "node-gyp -v": childProcessResult.nodeGypVersion, "xcodebuild -version": childProcessResult.xCodeVersion, @@ -188,11 +186,6 @@ describe("SysInfo unit tests", () => { sysInfo = new SysInfo(childProcess, null, helpers, null, null, androidToolsInfo); }); - it("java version.", async () => { - await sysInfo.getJavaVersion(); - assert.deepEqual(spawnFromEventCommand, "java -version"); - }); - it("java compiler version when there is JAVA_HOME.", async () => { const originalJavaHome = process.env[JavaHomeName]; process.env[JavaHomeName] = "mock"; @@ -226,7 +219,6 @@ describe("SysInfo unit tests", () => { uname: { result: setStdOut("name") }, npmV: { result: setStdOut("2.14.1") }, nodeV: { result: setStdOut("v6.0.0") }, - javaVersion: { result: setStdErr('java version "1.8.0_60"') }, javacVersion: { result: setStdErr("javac 1.8.0_60") }, nodeGypVersion: { result: setStdOut("2.0.0") }, xCodeVersion: { result: setStdOut("Xcode 6.4.0") }, @@ -254,7 +246,6 @@ describe("SysInfo unit tests", () => { let assertCommonValues = (result: NativeScriptDoctor.ISysInfoData) => { assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout); assert.deepEqual(result.nodeVer, "6.0.0"); - assert.deepEqual(result.javaVer, "1.8.0"); assert.deepEqual(result.javacVersion, "1.8.0_60"); assert.deepEqual(result.nodeGypVer, childProcessResult.nodeGypVersion.result.stdout); assert.deepEqual(result.adbVer, "1.0.32"); @@ -400,7 +391,6 @@ ${expectedCliVersion}`; uname: { shouldThrowError: true }, npmV: { shouldThrowError: true }, nodeV: { shouldThrowError: true }, - javaVersion: { shouldThrowError: true }, javacVersion: { shouldThrowError: true }, nodeGypVersion: { shouldThrowError: true }, xCodeVersion: { shouldThrowError: true }, @@ -421,7 +411,6 @@ ${expectedCliVersion}`; let assertAllValuesAreNull = async () => { const result = await sysInfo.getSysInfo(); assert.deepEqual(result.npmVer, null); - assert.deepEqual(result.javaVer, null); assert.deepEqual(result.javacVersion, null); assert.deepEqual(result.nodeGypVer, null); assert.deepEqual(result.xcodeVer, null); diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 1696fed9e6..7117624949 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -3,12 +3,6 @@ declare module NativeScriptDoctor { * Describes methods which helps collecting system information. */ interface ISysInfo { - /** - * Returns the currently installed Java version. - * @return {Promise} The currently installed Java version. - */ - getJavaVersion(): Promise; - /** * Returns the currently installed Java compiler version. * @return {Promise} The currently installed Java compiler version. @@ -207,12 +201,6 @@ declare module NativeScriptDoctor { nodeGypVer: string; // dependencies - /** - * Version of java, as returned by `java -version`. - * @type {string} - */ - javaVer: string; - /** * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. * @type {string} From 36d0a6067315e14a9eac21875b19068d9efb496d Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 11 Jan 2018 08:45:50 +0200 Subject: [PATCH 064/169] Add Android SDK 27 as verified Add version 27 of Android SDK as verified, so users will use it by default when it is installed. Use latest available appCompat version The current CLI logic finds appCompat version that matches the selected SDK version. However, the latest appCompat version is 26.0.0-alpha, so in case we have Android SDK 27, we are unable to find matchin appCompat. In order to resolve the issue and allow using Android SDK 27, get latest available appCompat version when there's no matching one --- lib/android-tools-info.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index bf7da3a6d8..f14959bf0b 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -9,7 +9,7 @@ import * as path from "path"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static ANDROID_TARGET_PREFIX = "android"; - private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25", "android-26"]; + private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25", "android-26", "android-27"]; private static MIN_REQUIRED_COMPILE_TARGET = 22; private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; @@ -271,6 +271,10 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (this.androidHome && requiredAppCompatRange) { const pathToAppCompat = path.join(this.androidHome, "extras", "android", "m2repository", "com", "android", "support", "appcompat-v7"); selectedAppCompatVersion = this.getMatchingDir(pathToAppCompat, requiredAppCompatRange); + if (!selectedAppCompatVersion) { + // get latest matching version, as there's no available appcompat versions for latest SDK versions. + selectedAppCompatVersion = this.getMatchingDir(pathToAppCompat, "*"); + } } return selectedAppCompatVersion; From 361a4438db9b774887cabc7b6dba281863841453 Mon Sep 17 00:00:00 2001 From: Rosen Vladimirov Date: Thu, 11 Jan 2018 11:41:23 +0200 Subject: [PATCH 065/169] Set version to 0.8.0 Set version to 0.8.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 40401f839e..a3805ec059 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.7.0", + "version": "0.8.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From c4374c57c241dbc8ef00ab801eda3cb51d06b0ca Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 23 Feb 2018 16:18:57 +0200 Subject: [PATCH 066/169] Integrate doctor package in {N} CLI --- README.md | 32 ++++++--- lib/doctor.ts | 23 ++++++- .../ios-local-build-requirements.ts | 2 +- lib/sys-info.ts | 47 +++++++++---- test/sys-info.ts | 56 +++++++++++++++- typings/interfaces.ts | 66 +++++++++++++++++-- 6 files changed, 193 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 8364947b37..2c6254dacf 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,10 @@ Library that helps identifying if the environment can be used for development of console.log("mono: ", monoVersion); const nodeVersion = await sysInfo.getNodeVersion(); - console.log("node: ", nodeVer); + console.log("node: ", nodeVersion); + + const npmVersion = await sysInfo.getNpmVersion(); + console.log("npm: ", npmVersion); const nodeGypVersion = await sysInfo.getNodeGypVersion(); console.log("node-gyp: ", nodeGypVersion); @@ -107,8 +110,8 @@ Library that helps identifying if the environment can be used for development of const osName = await sysInfo.getOs(); console.log("os: ", osName); - const xcodeprojGemLocation = await sysInfo.getXCodeProjGemLocation(); - console.log("xcodeproj gem location: ", xcodeprojGemLocation); + const xcodeprojLocation = await sysInfo.getXCodeProjLocation(); + console.log("xcodeproj location: ", xcodeprojLocation); const xcodeVersion = await sysInfo.getXCodeVersion(); console.log("xcode: ", xcodeVersion); @@ -131,6 +134,9 @@ Library that helps identifying if the environment can be used for development of const isCocoaPodsUpdateRequired = await sysInfo.isCocoaPodsUpdateRequired(); console.log("is CocoaPods update required: ", isCocoaPodsUpdateRequired); + const pythonInfo = await sysInfo.getPythonInfo(); + console.log("python info: ", pythonInfo ); + const sysInfoData = await sysInfo.getSysInfo(); console.log("sysInfo: ", sysInfoData); @@ -166,6 +172,12 @@ Library that helps identifying if the environment can be used for development of */ getNodeVersion(): Promise; + /** + * Returns the currently installed npm version. + * @return {Promise} Returns the currently installed npm version. + */ + getNpmVersion(): Promise; + /** * Returns the currently installed node-gyp version. * @return {Promise} Returns the currently installed node-gyp version. If node-gyp is not installed it will return null. @@ -173,10 +185,10 @@ Library that helps identifying if the environment can be used for development of getNodeGypVersion(): Promise; /** - * Returns the xcodeproj gem location. - * @return {Promise} Returns the xcodeproj gem location. If the the xcodeproj gem is not installed it will return null. + * Returns the xcodeproj location. + * @return {Promise} Returns the xcodeproj location. If the the xcodeproj is not installed it will return null. */ - getXcodeprojGemLocation(): Promise; + getXcodeprojLocation(): Promise; /** * Checks if iTunes is installed. @@ -198,9 +210,10 @@ Library that helps identifying if the environment can be used for development of /** * Returns the currently installed ADB version. + * @param {string} pathToAdb Defines path to adb * @return {Promise} Returns the currently installed ADB version. It will return null if ADB is not installed. */ - getAdbVersion(): Promise; + getAdbVersion(pathToAdb?: string): Promise; /** * Checks if Android is installed. @@ -258,9 +271,10 @@ Library that helps identifying if the environment can be used for development of /** * Returns the whole system information. + * @param {ISysInfoConfig} config * @return {Promise} The system information. */ - getSysInfo(): Promise; + getSysInfo(config?: ISysInfoConfig): Promise; /** * If set to true each method will cache it's result. The default value is true. @@ -386,7 +400,7 @@ Library that helps identifying if the environment can be used for development of * xcodeproj gem location, as returned by `which gem xcodeproj`. * @type {string} */ - xcodeprojGemLocation: string; + xcodeprojLocation: string; /** * true id CocoaPods can successfully execute pod install. diff --git a/lib/doctor.ts b/lib/doctor.ts index 829fdc4973..6669b14c67 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -28,9 +28,9 @@ export class Doctor implements NativeScriptDoctor.IDoctor { return false; } - public async getWarnings(): Promise { + public async getWarnings(config?: NativeScriptDoctor.ISysInfoConfig): Promise { let result: NativeScriptDoctor.IWarning[] = []; - const sysInfoData = await this.sysInfo.getSysInfo(); + const sysInfoData = await this.sysInfo.getSysInfo(config); const androidHomeValidationErrors = this.androidToolsInfo.validateAndroidHomeEnvVariable(); if (androidHomeValidationErrors.length > 0) { @@ -78,7 +78,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { }); } - if (!sysInfoData.xcodeprojGemLocation) { + if (!sysInfoData.xcodeprojLocation) { result.push({ warning: "WARNING: xcodeproj gem is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS." + EOL @@ -123,6 +123,23 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.IOS_PLATFORM_NAME] }); } + + if (!sysInfoData.pythonInfo.isInstalled) { + result.push({ + warning: `WARNING: Couldn't retrieve installed python packages.`, + additionalInformation: "We cannot verify your python installation is setup correctly. Please, make sure you have both 'python' and 'pip' installed." + EOL + + `Error while validating Python packages. Error is: ${sysInfoData.pythonInfo.installationErrorMessage}`, + platforms: [Constants.IOS_PLATFORM_NAME] + }); + } + + if (!sysInfoData.pythonInfo.isSixPackageInstalled) { + result.push({ + warning: `WARNING: The Python 'six' package not found.`, + additionalInformation: "This package is required by the Debugger library (LLDB) for iOS. You can install it by first making sure you have pip installed and then running 'pip install six' from the terminal.", + platforms: [Constants.IOS_PLATFORM_NAME] + }); + } } else { result.push({ warning: "NOTE: You can develop for iOS only on Mac OS X systems.", diff --git a/lib/local-build-requirements/ios-local-build-requirements.ts b/lib/local-build-requirements/ios-local-build-requirements.ts index 6db76da6ac..36f02e9731 100644 --- a/lib/local-build-requirements/ios-local-build-requirements.ts +++ b/lib/local-build-requirements/ios-local-build-requirements.ts @@ -7,7 +7,7 @@ export class IosLocalBuildRequirements { public async checkRequirements(): Promise { if (!this.hostInfo.isDarwin || !await this.sysInfo.getXcodeVersion() || - !await this.sysInfo.getXcodeprojGemLocation()) { + !await this.sysInfo.getXcodeprojLocation()) { return false; } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 152adc312e..c22746df84 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -25,7 +25,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private npmVerCache: string; private nodeVerCache: string; private nodeGypVerCache: string; - private xCodeprojGemLocationCache: string; + private xCodeprojLocationCache: string; private iTunesInstalledCache: boolean; private cocoaPodsVerCache: string; private osCache: string; @@ -38,6 +38,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private isCocoaPodsWorkingCorrectlyCache: boolean; private nativeScriptCliVersionCache: string; private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; + private pythonInfoCache: NativeScriptDoctor.IPythonInfo; private isCocoaPodsUpdateRequiredCache: boolean; private shouldCache: boolean = true; private isAndroidSdkConfiguredCorrectlyCache: boolean; @@ -102,9 +103,9 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } - public getXcodeprojGemLocation(): Promise { - return this.getValueForProperty(() => this.xCodeprojGemLocationCache, async (): Promise => { - const output = await this.execCommand("gem which xcodeproj"); + public getXcodeprojLocation(): Promise { + return this.getValueForProperty(() => this.xCodeprojLocationCache, async (): Promise => { + const output = await this.execCommand("which xcodeproj"); return output ? output.trim() : null; }); } @@ -152,12 +153,13 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } - public getAdbVersion(): Promise { + public getAdbVersion(pathToAdb?: string): Promise { return this.getValueForProperty(() => this.adbVerCache, async (): Promise => { let output: IProcessInfo = null; - const pathToAdbFromAndroidHome = await this.androidToolsInfo.getPathToAdbFromAndroidHome(); - if (pathToAdbFromAndroidHome) { - output = await this.childProcess.spawnFromEvent(pathToAdbFromAndroidHome, ["version"], "close", { ignoreError: true }); + + pathToAdb = pathToAdb || await this.androidToolsInfo.getPathToAdbFromAndroidHome(); + if (pathToAdb) { + output = await this.childProcess.spawnFromEvent(pathToAdb, ["version"], "close", { ignoreError: true }); } return output && output.stdout ? this.getVersionFromString(output.stdout) : null; @@ -213,7 +215,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } - public getSysInfo(): Promise { + public getSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise { return this.getValueForProperty(() => this.sysInfoCache, async (): Promise => { const result: NativeScriptDoctor.ISysInfoData = Object.create(null); @@ -231,10 +233,10 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.dotNetVer = await this.hostInfo.dotNetVersion(); result.javacVersion = await this.getJavaCompilerVersion(); result.xcodeVer = await this.getXcodeVersion(); - result.xcodeprojGemLocation = await this.getXcodeprojGemLocation(); + result.xcodeprojLocation = await this.getXcodeprojLocation(); result.itunesInstalled = await this.isITunesInstalled(); result.cocoaPodsVer = await this.getCocoaPodsVersion(); - result.adbVer = await this.getAdbVersion(); + result.adbVer = await this.getAdbVersion(config && config.androidToolsInfo && config.androidToolsInfo.pathToAdb); result.androidInstalled = await this.isAndroidInstalled(); result.monoVer = await this.getMonoVersion(); result.gitVer = await this.getGitVersion(); @@ -246,6 +248,8 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly(); + result.pythonInfo = await this.getPythonInfo(); + return result; }); } @@ -307,6 +311,27 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } + public getPythonInfo(): Promise { + return this.getValueForProperty(() => this.pythonInfoCache, async (): Promise => { + if (this.hostInfo.isDarwin) { + try { + await this.childProcess.exec(`python -c "import six"`); + } catch (error) { + // error.code = 1 so the Python is present, but we don't have six. + if (error.code === 1) { + return { isInstalled: true, isSixPackageInstalled: false }; + } + + return { isInstalled: false, isSixPackageInstalled: false, installationErrorMessage: error.message }; + } + + return { isInstalled: true, isSixPackageInstalled: true }; + } + + return null; + }); + } + public isCocoaPodsUpdateRequired(): Promise { return this.getValueForProperty(() => this.isCocoaPodsUpdateRequiredCache, async (): Promise => { let xcprojInfo = await this.getXcprojInfo(); diff --git a/test/sys-info.ts b/test/sys-info.ts index 7a1ac46fc6..51066f97b5 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -13,6 +13,7 @@ const PROGRAM_FILES_ENV_PATH = "C:\\Program Files"; interface IChildProcessResultDescription { result?: any; shouldThrowError?: boolean; + errorCode?: number; } interface ICLIOutputVersionTestCase { @@ -37,6 +38,7 @@ interface IChildProcessResults { pod: IChildProcessResultDescription; nativeScriptCliVersion: IChildProcessResultDescription; git: IChildProcessResultDescription; + pythonInfo?: IChildProcessResultDescription; } interface IHostInfoMockOptions { @@ -92,7 +94,8 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID "gradle -v": childProcessResult.gradleVersion, "tns --version": childProcessResult.nativeScriptCliVersion, "emulator": { shouldThrowError: false }, - "which git": childProcessResult.git + "which git": childProcessResult.git, + 'python -c "import six"': childProcessResult.pythonInfo }; } @@ -101,7 +104,12 @@ function getResultFromChildProcess(childProcessResultDescription: IChildProcessR if (options && options.ignoreError) { return null; } else { - throw new Error(`This one throws error. (${command})`); + const error = new Error(`This one throws error. (${command})`); + if (childProcessResultDescription.errorCode) { + (error).code = childProcessResultDescription.errorCode; + } + + throw error; } } @@ -331,6 +339,50 @@ describe("SysInfo unit tests", () => { }); }); + describe("when android info is incorrect", () => { + it("pathToAdb is null", async () => { + childProcessResult.adbVersion = { + result: null + }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1"}, null); + const adbVersion = await sysInfo.getAdbVersion(); + const isAndroidSdkConfiguredCorrectly = await sysInfo.isAndroidSdkConfiguredCorrectly(); + assert.deepEqual(adbVersion, null); + assert.deepEqual(isAndroidSdkConfiguredCorrectly, undefined); + }); + }); + + describe("pythonInfo", () => { + it("should return null when platform is windows", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1"}, null); + const pythonInfo = await sysInfo.getPythonInfo(); + assert.deepEqual(pythonInfo, null); + }); + it("should return null when platform is linux", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1"}, null); + const pythonInfo = await sysInfo.getPythonInfo(); + assert.deepEqual(pythonInfo, null); + }); + it("should return {isInstalled: true, isSixPackageInstalled: true} when python is correctly installed on Mac", async () => { + childProcessResult.pythonInfo = { result: "" }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }, null); + const pythonInfo = await sysInfo.getPythonInfo(); + assert.deepEqual(pythonInfo, { isInstalled: true, isSixPackageInstalled: true }); + }); + it("should return {isInstalled: false, isSixPackageInstalled: false} when python check throws an error", async () => { + childProcessResult.pythonInfo = { shouldThrowError: true }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }, null); + const pythonInfo = await sysInfo.getPythonInfo(); + assert.deepEqual(pythonInfo, { isInstalled: false, isSixPackageInstalled: false, installationErrorMessage: "This one throws error. (python -c \"import six\")" }); + }); + it("should return {isInstalled: true, isSixPackageInstalled: false} when python is installed but six package is not", async () => { + childProcessResult.pythonInfo = { shouldThrowError: true, errorCode: 1 }; + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1"}, null); + const pythonInfo = await sysInfo.getPythonInfo(); + assert.deepEqual(pythonInfo, { isInstalled: true, isSixPackageInstalled: false }); + }); + }); + const testData: ICLIOutputVersionTestCase[] = [ { testedProperty: "nativeScriptCliVersion", diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 7117624949..48f462e5ed 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -21,6 +21,12 @@ declare module NativeScriptDoctor { */ getNodeVersion(): Promise; + /** + * Returns the currently installed Npm version. + * @return {Promise} Returns the currently installed npm version. + */ + getNpmVersion(): Promise; + /** * Returns the currently installed node-gyp version. * @return {Promise} Returns the currently installed node-gyp version. If node-gyp is not installed it will return null. @@ -28,10 +34,10 @@ declare module NativeScriptDoctor { getNodeGypVersion(): Promise; /** - * Returns the xcodeproj gem location. - * @return {Promise} Returns the xcodeproj gem location. If the the xcodeproj gem is not installed it will return null. + * Returns the xcodeproj location. + * @return {Promise} Returns the xcodeproj location. If the the xcodeproj is not installed it will return null. */ - getXcodeprojGemLocation(): Promise; + getXcodeprojLocation(): Promise; /** * Checks if iTunes is installed. @@ -53,9 +59,10 @@ declare module NativeScriptDoctor { /** * Returns the currently installed ADB version. + * @param {string} pathToAdb Defines path to adb * @return {Promise} Returns the currently installed ADB version. It will return null if ADB is not installed. */ - getAdbVersion(): Promise; + getAdbVersion(pathToAdb?: string): Promise; /** * Checks if Android is installed. @@ -119,9 +126,10 @@ declare module NativeScriptDoctor { /** * Returns the whole system information. + * @param {ISysInfoConfig} config * @return {Promise} The system information. */ - getSysInfo(): Promise; + getSysInfo(config?: ISysInfoConfig): Promise; /** * If set to true each method will cache it's result. The default value is true. @@ -131,6 +139,25 @@ declare module NativeScriptDoctor { setShouldCacheSysInfo(shouldCache: boolean): void; } + interface ISysInfoConfig { + /** + * Path to package.json file of NativeScript CLI + * @type {string} + */ + pathToNativeScriptCliPackageJson: string; + /** + * Android tools data + * @type {{pathToAdb: string}} + */ + androidToolsInfo?: { + /** + * Path to adb + * @type {string} + */ + pathToAdb: string; + }; + } + /** * Describes methods which help identifying if the environment can be used for development of {N} apps. */ @@ -256,10 +283,10 @@ declare module NativeScriptDoctor { cocoaPodsVer: string; /** - * xcodeproj gem location, as returned by `which gem xcodeproj`. + * xcodeproj location, as returned by `which xcodeproj`. * @type {string} */ - xcodeprojGemLocation: string; + xcodeprojLocation: string; /** * true id CocoaPods can successfully execute pod install. @@ -290,6 +317,11 @@ declare module NativeScriptDoctor { * @type {boolean} */ isAndroidSdkConfiguredCorrectly: boolean; + + /** + * Information about python installation + */ + pythonInfo: IPythonInfo; } /** @@ -330,6 +362,26 @@ declare module NativeScriptDoctor { xcprojAvailable: boolean; } + /** + * Describes information about python + */ + interface IPythonInfo { + /** + * Determines whether python is installed on the host machine + */ + isInstalled: boolean; + + /** + * Determines whether python six package is installed + */ + isSixPackageInstalled: boolean; + + /** + * Error message from installation check + */ + installationErrorMessage?: string; + } + /** * Describes the constants used in the module. */ From ec3203af23f7a18a956636215f8495c6222d7ba4 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 27 Feb 2018 15:12:36 +0200 Subject: [PATCH 067/169] Set version to 0.9.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a3805ec059..7b3cd1ac85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.8.0", + "version": "0.9.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 59b86a5483ddaf07a4d5ebb0c21eb100f9c27327 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 28 Feb 2018 17:07:28 +0200 Subject: [PATCH 068/169] Introduce getInfos() --- lib/constants.ts | 2 + lib/doctor.ts | 262 +++++++++++++++++++++++++----------------- package.json | 2 +- typings/interfaces.ts | 34 ++++++ 4 files changed, 196 insertions(+), 104 deletions(-) diff --git a/lib/constants.ts b/lib/constants.ts index 9c2490f646..a850e287b2 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -7,4 +7,6 @@ export class Constants { "linux": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-linux.html#system-requirements", "darwin": "http://docs.nativescript.org/setup/ns-cli-setup/ns-setup-os-x.html#system-requirements", }; + public static INFO_TYPE_NAME = "info"; + public static WARNING_TYPE_NAME = "warning"; } diff --git a/lib/doctor.ts b/lib/doctor.ts index 6669b14c67..323351de6f 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -1,5 +1,5 @@ import { Constants } from "./constants"; -import { EOL } from "os"; +import { EOL, platform } from "os"; import { HostInfo } from "./host-info"; import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local-build-requirements"; @@ -28,150 +28,206 @@ export class Doctor implements NativeScriptDoctor.IDoctor { return false; } - public async getWarnings(config?: NativeScriptDoctor.ISysInfoConfig): Promise { - let result: NativeScriptDoctor.IWarning[] = []; + public async getInfos(config?: NativeScriptDoctor.ISysInfoConfig): Promise { + let result: NativeScriptDoctor.IInfo[] = []; const sysInfoData = await this.sysInfo.getSysInfo(config); - const androidHomeValidationErrors = this.androidToolsInfo.validateAndroidHomeEnvVariable(); - if (androidHomeValidationErrors.length > 0) { - result = result.concat(androidHomeValidationErrors); - } - - if (!sysInfoData.adbVer) { - result.push({ - warning: "WARNING: adb from the Android SDK is not installed or is not configured properly. ", + result = result.concat( + this.processValidationErrors({ + warnings: this.androidToolsInfo.validateAndroidHomeEnvVariable(), + infoMessage: "Your ANDROID_HOME environment variable is set and points to correct directory.", + platforms: [Constants.ANDROID_PLATFORM_NAME] + }), + this.processSysInfoItem({ + item: sysInfoData.adbVer, + infoMessage: "Your adb from the Android SDK is correctly installed.", + warningMessage: "adb from the Android SDK is not installed or is not configured properly. ", additionalInformation: "For Android-related operations, the NativeScript CLI will use a built-in version of adb." + EOL - + "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL - + "Android devices, verify that you have installed the latest Android SDK and" + EOL - + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, + + "To avoid possible issues with the native Android emulator, Genymotion or connected" + EOL + + "Android devices, verify that you have installed the latest Android SDK and" + EOL + + "its dependencies as described in http://developer.android.com/sdk/index.html#Requirements", platforms: [Constants.ANDROID_PLATFORM_NAME] - }); - } - - if (!sysInfoData.isAndroidSdkConfiguredCorrectly) { - result.push({ - warning: "WARNING: The Android SDK is not installed or is not configured properly.", + }), + this.processSysInfoItem({ + item: sysInfoData.isAndroidSdkConfiguredCorrectly, + infoMessage: "The Android SDK is installed.", + warningMessage: "The Android SDK is not installed or is not configured properly.", additionalInformation: "You will not be able to run your apps in the native emulator. To be able to run apps" + EOL - + "in the native Android emulator, verify that you have installed the latest Android SDK " + EOL - + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements" + EOL, + + "in the native Android emulator, verify that you have installed the latest Android SDK " + EOL + + "and its dependencies as described in http://developer.android.com/sdk/index.html#Requirements", platforms: [Constants.ANDROID_PLATFORM_NAME] - }); - } - - const androidToolsInfoValidationErrors = this.androidToolsInfo.validateInfo(); - if (androidToolsInfoValidationErrors.length > 0) { - result = result.concat(androidToolsInfoValidationErrors); - } - - const javacValidationErrors = this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion); - if (javacValidationErrors.length > 0) { - result = result.concat(javacValidationErrors); - } + }), + this.processValidationErrors({ + warnings: this.androidToolsInfo.validateInfo(), + infoMessage: "A compatible Android SDK for compilation is found.", + platforms: [Constants.ANDROID_PLATFORM_NAME] + }), + this.processValidationErrors({ + warnings: this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion), + infoMessage: "Javac is installed and is configured properly.", + platforms: [Constants.ANDROID_PLATFORM_NAME] + }) + ); if (this.hostInfo.isDarwin) { - if (!sysInfoData.xcodeVer) { - result.push({ - warning: "WARNING: Xcode is not installed or is not configured properly.", + result = result.concat( + this.processSysInfoItem({ + item: sysInfoData.xcodeVer, + infoMessage: "Xcode is installed and is configured properly.", + warningMessage: "Xcode is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS or run them in the iOS Simulator." + EOL - + "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode." + EOL, + + "To be able to build for iOS and run apps in the native emulator, verify that you have installed Xcode.", platforms: [Constants.IOS_PLATFORM_NAME] - }); - } - - if (!sysInfoData.xcodeprojLocation) { - result.push({ - warning: "WARNING: xcodeproj gem is not installed or is not configured properly.", + }), + this.processSysInfoItem({ + item: sysInfoData.xcodeprojLocation, + infoMessage: "xcodeproj is installed and is configured properly.", + warningMessage: "xcodeproj is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS." + EOL - + "To be able to build for iOS and run apps in the native emulator, verify that you have installed xcodeproj." + EOL, + + "To be able to build for iOS and run apps in the native emulator, verify that you have installed xcodeproj.", platforms: [Constants.IOS_PLATFORM_NAME] - }); - } - - if (!sysInfoData.cocoaPodsVer) { - result.push({ - warning: "WARNING: CocoaPods is not installed or is not configured properly.", + }), + this.processSysInfoItem({ + item: sysInfoData.cocoaPodsVer, + infoMessage: "CocoaPods are installed.", + warningMessage: "CocoaPods is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL - + "To be able to build such projects, verify that you have installed CocoaPods.", + + "To be able to build such projects, verify that you have installed CocoaPods.", platforms: [Constants.IOS_PLATFORM_NAME] - }); - } - - if (sysInfoData.cocoaPodsVer && sysInfoData.isCocoaPodsUpdateRequired) { - result.push({ - warning: "WARNING: CocoaPods update required.", + }), + this.processSysInfoItem({ + item: !sysInfoData.cocoaPodsVer || !sysInfoData.isCocoaPodsUpdateRequired, + infoMessage: "CocoaPods update is not required.", + warningMessage: "CocoaPods update required.", additionalInformation: `You are using CocoaPods version ${sysInfoData.cocoaPodsVer} which does not support Xcode ${sysInfoData.xcodeVer} yet.${EOL}${EOL}You can update your cocoapods by running $sudo gem install cocoapods from a terminal.${EOL}${EOL}In order for the NativeScript CLI to be able to work correctly with this setup you need to install xcproj command line tool and add it to your PATH.Xcproj can be installed with homebrew by running $ brew install xcproj from the terminal`, platforms: [Constants.IOS_PLATFORM_NAME] - }); - } + }) + ); if (sysInfoData.xcodeVer && sysInfoData.cocoaPodsVer) { let isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly(); - if (!isCocoaPodsWorkingCorrectly) { - result.push({ - warning: "WARNING: There was a problem with CocoaPods", + result = result.concat( + this.processSysInfoItem({ + item: isCocoaPodsWorkingCorrectly, + infoMessage: "CocoaPods are configured properly.", + warningMessage: "There was a problem with CocoaPods", additionalInformation: "Verify that CocoaPods are configured properly.", - platforms: [Constants.IOS_PLATFORM_NAME] - }); - } + platforms: [Constants.IOS_PLATFORM_NAME], + }) + ); } - if (sysInfoData.cocoaPodsVer && semver.valid(sysInfoData.cocoaPodsVer) && semver.lt(sysInfoData.cocoaPodsVer, Doctor.MIN_SUPPORTED_POD_VERSION)) { - result.push({ - warning: `WARNING: Your current CocoaPods version is earlier than ${Doctor.MIN_SUPPORTED_POD_VERSION}.`, + result = result.concat( + this.processSysInfoItem({ + item: !sysInfoData.cocoaPodsVer || !semver.valid(sysInfoData.cocoaPodsVer) || !semver.lt(sysInfoData.cocoaPodsVer, Doctor.MIN_SUPPORTED_POD_VERSION), + infoMessage: `Your current CocoaPods version is newer than ${Doctor.MIN_SUPPORTED_POD_VERSION}.`, + warningMessage: `Your current CocoaPods version is earlier than ${Doctor.MIN_SUPPORTED_POD_VERSION}.`, additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL - + `To be able to build such projects, verify that you have at least ${Doctor.MIN_SUPPORTED_POD_VERSION} version installed.`, + + `To be able to build such projects, verify that you have at least ${Doctor.MIN_SUPPORTED_POD_VERSION} version installed.`, platforms: [Constants.IOS_PLATFORM_NAME] - }); - } - - if (!sysInfoData.pythonInfo.isInstalled) { - result.push({ - warning: `WARNING: Couldn't retrieve installed python packages.`, + }), + this.processSysInfoItem({ + item: sysInfoData.pythonInfo.isInstalled, + infoMessage: "Python installed and configured correctly.", + warningMessage: `Couldn't retrieve installed python packages.`, additionalInformation: "We cannot verify your python installation is setup correctly. Please, make sure you have both 'python' and 'pip' installed." + EOL + `Error while validating Python packages. Error is: ${sysInfoData.pythonInfo.installationErrorMessage}`, platforms: [Constants.IOS_PLATFORM_NAME] - }); - } - - if (!sysInfoData.pythonInfo.isSixPackageInstalled) { - result.push({ - warning: `WARNING: The Python 'six' package not found.`, + }), + this.processSysInfoItem({ + item: sysInfoData.pythonInfo.isSixPackageInstalled, + infoMessage: `The Python 'six' package is found.`, + warningMessage: `The Python 'six' package not found.`, additionalInformation: "This package is required by the Debugger library (LLDB) for iOS. You can install it by first making sure you have pip installed and then running 'pip install six' from the terminal.", platforms: [Constants.IOS_PLATFORM_NAME] - }); - } + }) + ); } else { result.push({ - warning: "NOTE: You can develop for iOS only on Mac OS X systems.", - additionalInformation: "To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later." + EOL, - platforms: [Constants.IOS_PLATFORM_NAME] + message: "NOTE: You can develop for iOS only on Mac OS X systems.", + additionalInformation: "To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later.", + platforms: [Constants.IOS_PLATFORM_NAME], + type: Constants.INFO_TYPE_NAME }); } - if (!sysInfoData.javacVersion) { - result.push({ - warning: "WARNING: The Java Development Kit (JDK) is not installed or is not configured properly.", + result = result.concat( + this.processSysInfoItem({ + item: sysInfoData.javacVersion, + infoMessage: "The Java Development Kit (JDK) is installed and is configured properly.", + warningMessage: "The Java Development Kit (JDK) is not installed or is not configured properly.", additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL - + "to perform some Android-related operations. To ensure that you can develop and" + EOL - + "test your apps for Android, verify that you have installed the JDK as" + EOL - + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8)." + EOL, + + "to perform some Android-related operations. To ensure that you can develop and" + EOL + + "test your apps for Android, verify that you have installed the JDK as" + EOL + + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8).", platforms: [Constants.ANDROID_PLATFORM_NAME] - }); - } - - if (!sysInfoData.gitVer) { - result.push({ - warning: "WARNING: Git is not installed or not configured properly.", + }), + this.processSysInfoItem({ + item: sysInfoData.gitVer, + infoMessage: "Git is installed and is configured properly.", + warningMessage: "Git is not installed or not configured properly.", additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL - + "To be able to work with Screen Builder projects, download and install Git as described" + EOL - + "in https://git-scm.com/downloads and add the git executable to your PATH." + EOL, + + "To be able to work with Screen Builder projects, download and install Git as described" + EOL + + "in https://git-scm.com/downloads and add the git executable to your PATH.", platforms: Constants.SUPPORTED_PLATFORMS - }); - } + }) + ); return result; } + public async getWarnings(config?: NativeScriptDoctor.ISysInfoConfig): Promise { + const info = await this.getInfos(config); + return info.filter(item => item.type === Constants.WARNING_TYPE_NAME) + .map(item => this.convertInfoToWarning(item)); + } + + private processSysInfoItem(data: { item: string | boolean, infoMessage: string, warningMessage: string, additionalInformation?: string, platforms: string[] }): NativeScriptDoctor.IInfo { + if (!data.item) { + return { + message: `WARNING: ${data.warningMessage}`, + additionalInformation: data.additionalInformation, + platforms: data.platforms, + type: Constants.WARNING_TYPE_NAME + } + } + + return { + message: `${data.infoMessage}`, + platforms: data.platforms, + type: Constants.INFO_TYPE_NAME + }; + } + + private processValidationErrors(data: { warnings: NativeScriptDoctor.IWarning[], infoMessage: string, platforms: string[]}): NativeScriptDoctor.IInfo[] { + if (data.warnings.length > 0) { + return data.warnings.map(warning => this.convertWarningToInfo(warning)); + } + + return [{ + message: data.infoMessage, + platforms: data.platforms, + type: Constants.INFO_TYPE_NAME + }]; + } + + private convertWarningToInfo(warning: NativeScriptDoctor.IWarning): NativeScriptDoctor.IInfo { + return { + message: warning.warning, + additionalInformation: warning.additionalInformation, + platforms: warning.platforms, + type: Constants.WARNING_TYPE_NAME + }; + } + + private convertInfoToWarning(info: NativeScriptDoctor.IInfo): NativeScriptDoctor.IWarning { + return { + warning: info.message, + additionalInformation: info.additionalInformation, + platforms: info.platforms + }; + } + private isPlatformSupported(platform: string): boolean { return Constants.SUPPORTED_PLATFORMS.map(pl => pl.toLowerCase()).indexOf(platform.toLowerCase()) !== -1; } diff --git a/package.json b/package.json index 7b3cd1ac85..21d05a82e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.9.0", + "version": "0.10.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 48f462e5ed..f5368f3de5 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -174,6 +174,12 @@ declare module NativeScriptDoctor { * @return {Promise} Array of all the warnings from all checks. If there are no warnings will return empty array. */ getWarnings(): Promise; + + /** + * Executes all checks for the current environment and returns the info from each check + * @return {Promise} Array of all the infos from all checks. + */ + getInfos(): Promise; } interface ISysInfoData { @@ -347,6 +353,32 @@ declare module NativeScriptDoctor { platforms: string[]; } + interface IInfo { + /** + * The message. + * @type {string} + */ + message: string; + + /** + * Additional information for the warning. + * @type {string} + */ + additionalInformation?: string; + + /** + * The platforms which are affected by this warning. + * @type {string[]} + */ + platforms: string[]; + + /** + * The warning. + * @type {string} // can be warning, note or info + */ + type: string; + } + /** * Describes information about xcproj brew formula. */ @@ -389,6 +421,8 @@ declare module NativeScriptDoctor { ANDROID_PLATFORM_NAME: string; IOS_PLATFORM_NAME: string; SUPPORTED_PLATFORMS: string[]; + INFO_TYPE_NAME: string; + WARNING_TYPE_NAME: string; } /** From 19cc77002be761ddf608283c0b95f0ce606aaf32 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 9 Mar 2018 09:19:49 +0200 Subject: [PATCH 069/169] Remove unneeded note message --- lib/doctor.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 323351de6f..8c09a6ae50 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -142,13 +142,6 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.IOS_PLATFORM_NAME] }) ); - } else { - result.push({ - message: "NOTE: You can develop for iOS only on Mac OS X systems.", - additionalInformation: "To be able to work with iOS devices and projects, you need Mac OS X Mavericks or later.", - platforms: [Constants.IOS_PLATFORM_NAME], - type: Constants.INFO_TYPE_NAME - }); } result = result.concat( @@ -173,6 +166,15 @@ export class Doctor implements NativeScriptDoctor.IDoctor { }) ); + if (!this.hostInfo.isDarwin) { + result.push({ + message: "Local builds for iOS can be executed only on a macOS system. To build for iOS on a different operating system, you can use the NativeScript cloud infrastructure.", + additionalInformation: "", + platforms: [Constants.IOS_PLATFORM_NAME], + type: Constants.INFO_TYPE_NAME + }); + } + return result; } From efd8a22c53492e79e06176b555e9cbca01bb492e Mon Sep 17 00:00:00 2001 From: fatme Date: Tue, 13 Mar 2018 16:54:55 +0200 Subject: [PATCH 070/169] Get sysInfos based on specified platform In case when android platform is specified, checks only android related things. In case when iOS platform is specified, checks only iOS related things. When no platform is specified, checks both Android and iOS things. This will improve the time {N} CLI needs to check if environment is correctly configured for platform specific commands. This also will fix failing cloud builds. --- lib/doctor.ts | 101 ++++++++++++++++++++++-------------- lib/sys-info.ts | 102 +++++++++++++++++++++++------------- test/sys-info.ts | 70 +++++++++++++++++++++++++ typings/interfaces.ts | 117 +++++++++++++++++++----------------------- 4 files changed, 250 insertions(+), 140 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 8c09a6ae50..952168e90f 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -32,6 +32,51 @@ export class Doctor implements NativeScriptDoctor.IDoctor { let result: NativeScriptDoctor.IInfo[] = []; const sysInfoData = await this.sysInfo.getSysInfo(config); + result = result.concat( + this.processSysInfoItem({ + item: sysInfoData.gitVer, + infoMessage: "Git is installed and is configured properly.", + warningMessage: "Git is not installed or not configured properly.", + additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL + + "To be able to work with Screen Builder projects, download and install Git as described" + EOL + + "in https://git-scm.com/downloads and add the git executable to your PATH.", + platforms: Constants.SUPPORTED_PLATFORMS + }) + ); + + if (config && config.platform === Constants.ANDROID_PLATFORM_NAME) { + result = result.concat(this.getAndroidInfos(sysInfoData)); + } + + if (config && config.platform === Constants.IOS_PLATFORM_NAME) { + result = result.concat(await this.getiOSInfos(sysInfoData)); + } + + if (!config || !config.platform) { + result = result.concat(this.getAndroidInfos(sysInfoData), await this.getiOSInfos(sysInfoData)); + } + + if (!this.hostInfo.isDarwin) { + result.push({ + message: "Local builds for iOS can be executed only on a macOS system. To build for iOS on a different operating system, you can use the NativeScript cloud infrastructure.", + additionalInformation: "", + platforms: [Constants.IOS_PLATFORM_NAME], + type: Constants.INFO_TYPE_NAME + }); + } + + return result; + } + + public async getWarnings(config?: NativeScriptDoctor.ISysInfoConfig): Promise { + const info = await this.getInfos(config); + return info.filter(item => item.type === Constants.WARNING_TYPE_NAME) + .map(item => this.convertInfoToWarning(item)); + } + + private getAndroidInfos(sysInfoData: NativeScriptDoctor.ISysInfoData): NativeScriptDoctor.IInfo[] { + let result: NativeScriptDoctor.IInfo[] = []; + result = result.concat( this.processValidationErrors({ warnings: this.androidToolsInfo.validateAndroidHomeEnvVariable(), @@ -66,9 +111,24 @@ export class Doctor implements NativeScriptDoctor.IDoctor { warnings: this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion), infoMessage: "Javac is installed and is configured properly.", platforms: [Constants.ANDROID_PLATFORM_NAME] + }), + this.processSysInfoItem({ + item: sysInfoData.javacVersion, + infoMessage: "The Java Development Kit (JDK) is installed and is configured properly.", + warningMessage: "The Java Development Kit (JDK) is not installed or is not configured properly.", + additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL + + "to perform some Android-related operations. To ensure that you can develop and" + EOL + + "test your apps for Android, verify that you have installed the JDK as" + EOL + + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8).", + platforms: [Constants.ANDROID_PLATFORM_NAME] }) ); + return result; + } + + private async getiOSInfos(sysInfoData: NativeScriptDoctor.ISysInfoData): Promise { + let result: NativeScriptDoctor.IInfo[] = []; if (this.hostInfo.isDarwin) { result = result.concat( this.processSysInfoItem({ @@ -103,7 +163,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.IOS_PLATFORM_NAME] }) ); - + if (sysInfoData.xcodeVer && sysInfoData.cocoaPodsVer) { let isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly(); result = result.concat( @@ -116,7 +176,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { }) ); } - + result = result.concat( this.processSysInfoItem({ item: !sysInfoData.cocoaPodsVer || !semver.valid(sysInfoData.cocoaPodsVer) || !semver.lt(sysInfoData.cocoaPodsVer, Doctor.MIN_SUPPORTED_POD_VERSION), @@ -144,46 +204,9 @@ export class Doctor implements NativeScriptDoctor.IDoctor { ); } - result = result.concat( - this.processSysInfoItem({ - item: sysInfoData.javacVersion, - infoMessage: "The Java Development Kit (JDK) is installed and is configured properly.", - warningMessage: "The Java Development Kit (JDK) is not installed or is not configured properly.", - additionalInformation: "You will not be able to work with the Android SDK and you might not be able" + EOL - + "to perform some Android-related operations. To ensure that you can develop and" + EOL - + "test your apps for Android, verify that you have installed the JDK as" + EOL - + "described in http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html (for JDK 8).", - platforms: [Constants.ANDROID_PLATFORM_NAME] - }), - this.processSysInfoItem({ - item: sysInfoData.gitVer, - infoMessage: "Git is installed and is configured properly.", - warningMessage: "Git is not installed or not configured properly.", - additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL - + "To be able to work with Screen Builder projects, download and install Git as described" + EOL - + "in https://git-scm.com/downloads and add the git executable to your PATH.", - platforms: Constants.SUPPORTED_PLATFORMS - }) - ); - - if (!this.hostInfo.isDarwin) { - result.push({ - message: "Local builds for iOS can be executed only on a macOS system. To build for iOS on a different operating system, you can use the NativeScript cloud infrastructure.", - additionalInformation: "", - platforms: [Constants.IOS_PLATFORM_NAME], - type: Constants.INFO_TYPE_NAME - }); - } - return result; } - public async getWarnings(config?: NativeScriptDoctor.ISysInfoConfig): Promise { - const info = await this.getInfos(config); - return info.filter(item => item.type === Constants.WARNING_TYPE_NAME) - .map(item => this.convertInfoToWarning(item)); - } - private processSysInfoItem(data: { item: string | boolean, infoMessage: string, warningMessage: string, additionalInformation?: string, platforms: string[] }): NativeScriptDoctor.IInfo { if (!data.item) { return { diff --git a/lib/sys-info.ts b/lib/sys-info.ts index c22746df84..15a7fb65f5 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -9,6 +9,8 @@ import * as path from "path"; import * as osenv from "osenv"; import * as temp from "temp"; import * as semver from "semver"; +import { constants } from "zlib"; +import { Constants } from "./constants"; export class SysInfo implements NativeScriptDoctor.ISysInfo { private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im; @@ -34,7 +36,11 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private monoVerCache: string; private gitVerCache: string; private gradleVerCache: string; - private sysInfoCache: NativeScriptDoctor.ISysInfoData; + + private commonSysInfoCache: NativeScriptDoctor.ICommonSysInfoData; + private androidSysInfoCache: NativeScriptDoctor.IAndroidSysInfoData; + private iOSSysInfoCache: NativeScriptDoctor.IiOSSysInfoData; + private isCocoaPodsWorkingCorrectlyCache: boolean; private nativeScriptCliVersionCache: string; private xcprojInfoCache: NativeScriptDoctor.IXcprojInfo; @@ -215,43 +221,16 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } - public getSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise { - return this.getValueForProperty(() => this.sysInfoCache, async (): Promise => { - const result: NativeScriptDoctor.ISysInfoData = Object.create(null); - - // os stuff - result.platform = platform(); - result.shell = osenv.shell(); - result.os = await this.getOs(); - - // node stuff - result.procArch = process.arch; - result.nodeVer = await this.getNodeVersion(); - result.npmVer = await this.getNpmVersion(); - result.nodeGypVer = await this.getNodeGypVersion(); - - result.dotNetVer = await this.hostInfo.dotNetVersion(); - result.javacVersion = await this.getJavaCompilerVersion(); - result.xcodeVer = await this.getXcodeVersion(); - result.xcodeprojLocation = await this.getXcodeprojLocation(); - result.itunesInstalled = await this.isITunesInstalled(); - result.cocoaPodsVer = await this.getCocoaPodsVersion(); - result.adbVer = await this.getAdbVersion(config && config.androidToolsInfo && config.androidToolsInfo.pathToAdb); - result.androidInstalled = await this.isAndroidInstalled(); - result.monoVer = await this.getMonoVersion(); - result.gitVer = await this.getGitVersion(); - result.gradleVer = await this.getGradleVersion(); - result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); - - result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); - - result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); - result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly(); + public async getSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise { + if (config && config.platform === Constants.ANDROID_PLATFORM_NAME) { + return Object.assign(await this.getCommonSysInfo(), await this.getAndroidSysInfo(config)); + } - result.pythonInfo = await this.getPythonInfo(); + if (config && config.platform === Constants.IOS_PLATFORM_NAME) { + return Object.assign(await this.getCommonSysInfo(), await this.getiOSSysInfo()); + } - return result; - }); + return Object.assign(await this.getCommonSysInfo(), await this.getAndroidSysInfo(), await this.getiOSSysInfo()); } public isCocoaPodsWorkingCorrectly(): Promise { @@ -467,4 +446,55 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private unixVer(): Promise { return this.execCommand("uname -a"); } + + private getCommonSysInfo(): Promise { + return this.getValueForProperty(() => this.commonSysInfoCache, async (): Promise => { + const result: NativeScriptDoctor.ICommonSysInfoData = Object.create(null); + + // os stuff + result.platform = platform(); + result.shell = osenv.shell(); + result.os = await this.getOs(); + result.procArch = process.arch; + result.nodeVer = await this.getNodeVersion(); + result.npmVer = await this.getNpmVersion(); + result.nodeGypVer = await this.getNodeGypVersion(); + result.nativeScriptCliVersion = await this.getNativeScriptCliVersion(); + result.gitVer = await this.getGitVersion(); + + return result; + }); + } + + private async getiOSSysInfo(): Promise { + return this.getValueForProperty(() => this.iOSSysInfoCache, async (): Promise => { + const result: NativeScriptDoctor.IiOSSysInfoData = Object.create(null); + + result.xcodeVer = await this.getXcodeVersion(); + result.xcodeprojLocation = await this.getXcodeprojLocation(); + result.itunesInstalled = await this.isITunesInstalled(); + result.cocoaPodsVer = await this.getCocoaPodsVersion(); + result.isCocoaPodsWorkingCorrectly = await this.isCocoaPodsWorkingCorrectly(); + result.isCocoaPodsUpdateRequired = await this.isCocoaPodsUpdateRequired(); + result.pythonInfo = await this.getPythonInfo(); + + return result; + }); + } + + private async getAndroidSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise { + return this.getValueForProperty(() => this.androidSysInfoCache, async (): Promise => { + const result: NativeScriptDoctor.IAndroidSysInfoData = Object.create(null); + + result.dotNetVer = await this.hostInfo.dotNetVersion(); + result.javacVersion = await this.getJavaCompilerVersion(); + result.adbVer = await this.getAdbVersion(config && config.androidToolsInfo && config.androidToolsInfo.pathToAdb); + result.androidInstalled = await this.isAndroidInstalled(); + result.monoVer = await this.getMonoVersion(); + result.gradleVer = await this.getGradleVersion(); + result.isAndroidSdkConfiguredCorrectly = await this.isAndroidSdkConfiguredCorrectly(); + + return result; + }); + } } diff --git a/test/sys-info.ts b/test/sys-info.ts index 51066f97b5..af79f3b4e7 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -4,6 +4,7 @@ import { EOL } from "os"; import { SysInfo } from "../lib/sys-info"; import { Helpers } from "../lib/helpers"; import { ChildProcess } from "../lib/wrappers/child-process"; +import { constants } from "zlib"; const JavaHomeName = "JAVA_HOME"; const AndroidHomeName = "ANDROID_HOME"; @@ -493,5 +494,74 @@ ${expectedCliVersion}`; }); }); }); + + describe("returns correct sysInfo when", () => { + const assertCommonSysInfo = (result: NativeScriptDoctor.ISysInfoData) => { + assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout); + assert.deepEqual(result.nodeVer, "6.0.0"); + assert.deepEqual(result.nodeGypVer, childProcessResult.nodeGypVersion.result.stdout); + assert.deepEqual(result.gitVer, "1.9.5"); + assert.deepEqual(result.nativeScriptCliVersion, childProcessResult.nativeScriptCliVersion.result.stdout); + }; + + const assertAndroidSysInfo = (result: NativeScriptDoctor.IAndroidSysInfoData) => { + assert.deepEqual(result.adbVer, "1.0.32"); + assert.deepEqual(result.androidInstalled, false); + assert.deepEqual(result.monoVer, "1.0.6"); + assert.deepEqual(result.gradleVer, "2.8"); + assert.deepEqual(result.javacVersion, "1.8.0_60"); + assert.deepEqual(result.isAndroidSdkConfiguredCorrectly, undefined); + }; + + const assertiOSSysInfo = (result: NativeScriptDoctor.IiOSSysInfoData) => { + assert.deepEqual(result.xcodeVer, "6.4.0"); + assert.deepEqual(result.itunesInstalled, undefined); + assert.deepEqual(result.cocoaPodsVer, "0.38.2"); + assert.deepEqual(result.xcodeprojLocation, null); + assert.deepEqual(result.isCocoaPodsWorkingCorrectly, undefined); + assert.deepEqual(result.xcprojInfo, undefined); + assert.deepEqual(result.isCocoaPodsUpdateRequired, false); + assert.deepEqual(result.pythonInfo, {isInstalled: false, isSixPackageInstalled: false, installationErrorMessage: "Cannot read property 'shouldThrowError' of undefined"}); + }; + + it("iOS platform is specified", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getSysInfo({platform: "iOS"}); + + assertCommonSysInfo(result); + assertiOSSysInfo(result); + // Android specific properties should be undefined + assert.deepEqual(result.adbVer, undefined); + assert.deepEqual(result.androidInstalled, undefined); + assert.deepEqual(result.monoVer, undefined); + assert.deepEqual(result.gradleVer, undefined); + assert.deepEqual(result.javacVersion, undefined); + assert.deepEqual(result.isAndroidSdkConfiguredCorrectly, undefined); + }); + it("Android platform is specified", async () => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getSysInfo({platform: "Android"}); + + assertCommonSysInfo(result); + assertAndroidSysInfo(result); + // iOS specific properties should be undefined + assert.deepEqual(result.xcodeVer, undefined); + assert.deepEqual(result.itunesInstalled, undefined); + assert.deepEqual(result.cocoaPodsVer, undefined); + assert.deepEqual(result.xcodeprojLocation, undefined); + assert.deepEqual(result.isCocoaPodsWorkingCorrectly, undefined); + assert.deepEqual(result.xcprojInfo, undefined); + assert.deepEqual(result.isCocoaPodsUpdateRequired, undefined); + assert.deepEqual(result.pythonInfo, undefined); + + }); + it("no platform is specified", async() => { + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getSysInfo(); + assertCommonSysInfo(result); + assertAndroidSysInfo(result); + assertiOSSysInfo(result); + }); + }); }); }); diff --git a/typings/interfaces.ts b/typings/interfaces.ts index f5368f3de5..1355094eb0 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -140,11 +140,15 @@ declare module NativeScriptDoctor { } interface ISysInfoConfig { + /** + * The platform for which to check if environment is properly configured. + */ + platform?: string; /** * Path to package.json file of NativeScript CLI * @type {string} */ - pathToNativeScriptCliPackageJson: string; + pathToNativeScriptCliPackageJson?: string; /** * Android tools data * @type {{pathToAdb: string}} @@ -177,159 +181,142 @@ declare module NativeScriptDoctor { /** * Executes all checks for the current environment and returns the info from each check + * @param {NativeScriptDoctor.ISysInfoConfig} * @return {Promise} Array of all the infos from all checks. */ - getInfos(): Promise; + getInfos(config?: NativeScriptDoctor.ISysInfoConfig): Promise; } - interface ISysInfoData { - // os stuff + interface ICommonSysInfoData { /** * Os platform flavour, reported by os.platform. * @type {string} */ platform: string; - /** * Full os name, like `uname -a` on unix, registry query on win. * @type {string} */ os: string; - - /** - * .net version, applicable to windows only. - * @type {string} - */ - dotNetVer: string; - /** * The command shell in use, usually bash or cmd. * @type {string} */ shell: string; - - // node stuff /** * node.js version, returned by node -v. * @type {string} */ nodeVer: string; - /** * npm version, returned by `npm -v`. * @type {string} */ npmVer: string; - /** * Process architecture, returned by `process.arch`. * @type {string} */ procArch: string; - /** * node-gyp version as returned by `node-gyp -v`. * @type {string} */ nodeGypVer: string; - - // dependencies /** - * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. + * git version string, as returned by `git --version`. * @type {string} */ - xcodeVer: string; - + gitVer: string; /** - * Version string of adb, as returned by `adb version`. + * NativeScript CLI version string, as returned by `tns --version`. * @type {string} */ - adbVer: string; + nativeScriptCliVersion: string; + } + interface IiOSSysInfoData { + /** + * Xcode version string as returned by `xcodebuild -version`. Valid only on Mac. + * @type {string} + */ + xcodeVer: string; /** * Whether iTunes is installed on the machine. * @type {boolean} */ itunesInstalled: boolean; - /** - * Whether `android` executable can be run. - * @type {boolean} + * pod version string, as returned by `pod --version`. + * @type {string} */ - androidInstalled: boolean; - + cocoaPodsVer: string; /** - * mono version, relevant on Mac only. + * xcodeproj location, as returned by `which xcodeproj`. * @type {string} */ - monoVer: string; - + xcodeprojLocation: string; /** - * git version string, as returned by `git --version`. - * @type {string} + * true id CocoaPods can successfully execute pod install. + * @type {boolean} */ - gitVer: string; - + isCocoaPodsWorkingCorrectly: boolean; /** - * gradle version string as returned by `gradle -v`. + * Information about xcproj. * @type {string} */ - gradleVer: string; - + xcprojInfo: IXcprojInfo; /** - * javac version string as returned by `javac -version`. - * @type {string} + * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. + * @type {boolean} */ - javacVersion: string; - + isCocoaPodsUpdateRequired: boolean; /** - * pod version string, as returned by `pod --version`. - * @type {string} + * Information about python installation */ - cocoaPodsVer: string; + pythonInfo: IPythonInfo; + } + interface IAndroidSysInfoData { /** - * xcodeproj location, as returned by `which xcodeproj`. + * Version string of adb, as returned by `adb version`. * @type {string} */ - xcodeprojLocation: string; - + adbVer: string; /** - * true id CocoaPods can successfully execute pod install. + * Whether `android` executable can be run. * @type {boolean} */ - isCocoaPodsWorkingCorrectly: boolean; - + androidInstalled: boolean; /** - * NativeScript CLI version string, as returned by `tns --version`. + * mono version, relevant on Mac only. * @type {string} */ - nativeScriptCliVersion: string; - + monoVer: string; /** - * Information about xcproj. + * gradle version string as returned by `gradle -v`. * @type {string} */ - xcprojInfo: IXcprojInfo; - + gradleVer: string; /** - * true if the system requires xcproj to build projects successfully and the CocoaPods version is not compatible with the Xcode. - * @type {boolean} + * javac version string as returned by `javac -version`. + * @type {string} */ - isCocoaPodsUpdateRequired: boolean; - + javacVersion: string; /** * true if the Android SDK Tools are installed and configured correctly. * @type {boolean} */ isAndroidSdkConfiguredCorrectly: boolean; - /** - * Information about python installation + * .net version, applicable to windows only. + * @type {string} */ - pythonInfo: IPythonInfo; + dotNetVer?: string; } + interface ISysInfoData extends ICommonSysInfoData, IiOSSysInfoData, IAndroidSysInfoData { } + /** * Describes warning returned from nativescript-doctor check. */ From cc416b6d6e7659b0100e0206ad3483b3bd01da6c Mon Sep 17 00:00:00 2001 From: fatme Date: Tue, 13 Mar 2018 23:35:39 +0200 Subject: [PATCH 071/169] Fix PR comments --- lib/doctor.ts | 24 ++++-------------------- lib/sys-info.ts | 1 - test/sys-info.ts | 1 - 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 952168e90f..235e4cb3d0 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -32,30 +32,14 @@ export class Doctor implements NativeScriptDoctor.IDoctor { let result: NativeScriptDoctor.IInfo[] = []; const sysInfoData = await this.sysInfo.getSysInfo(config); - result = result.concat( - this.processSysInfoItem({ - item: sysInfoData.gitVer, - infoMessage: "Git is installed and is configured properly.", - warningMessage: "Git is not installed or not configured properly.", - additionalInformation: "You will not be able to create and work with Screen Builder projects." + EOL - + "To be able to work with Screen Builder projects, download and install Git as described" + EOL - + "in https://git-scm.com/downloads and add the git executable to your PATH.", - platforms: Constants.SUPPORTED_PLATFORMS - }) - ); - - if (config && config.platform === Constants.ANDROID_PLATFORM_NAME) { + if (!config || !config.platform || config.platform === Constants.ANDROID_PLATFORM_NAME) { result = result.concat(this.getAndroidInfos(sysInfoData)); } - if (config && config.platform === Constants.IOS_PLATFORM_NAME) { + if (!config || !config.platform || config.platform === Constants.IOS_PLATFORM_NAME) { result = result.concat(await this.getiOSInfos(sysInfoData)); } - if (!config || !config.platform) { - result = result.concat(this.getAndroidInfos(sysInfoData), await this.getiOSInfos(sysInfoData)); - } - if (!this.hostInfo.isDarwin) { result.push({ message: "Local builds for iOS can be executed only on a macOS system. To build for iOS on a different operating system, you can use the NativeScript cloud infrastructure.", @@ -163,7 +147,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.IOS_PLATFORM_NAME] }) ); - + if (sysInfoData.xcodeVer && sysInfoData.cocoaPodsVer) { let isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly(); result = result.concat( @@ -176,7 +160,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { }) ); } - + result = result.concat( this.processSysInfoItem({ item: !sysInfoData.cocoaPodsVer || !semver.valid(sysInfoData.cocoaPodsVer) || !semver.lt(sysInfoData.cocoaPodsVer, Doctor.MIN_SUPPORTED_POD_VERSION), diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 15a7fb65f5..a3ae77ecb8 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -9,7 +9,6 @@ import * as path from "path"; import * as osenv from "osenv"; import * as temp from "temp"; import * as semver from "semver"; -import { constants } from "zlib"; import { Constants } from "./constants"; export class SysInfo implements NativeScriptDoctor.ISysInfo { diff --git a/test/sys-info.ts b/test/sys-info.ts index af79f3b4e7..37b8a329a5 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -4,7 +4,6 @@ import { EOL } from "os"; import { SysInfo } from "../lib/sys-info"; import { Helpers } from "../lib/helpers"; import { ChildProcess } from "../lib/wrappers/child-process"; -import { constants } from "zlib"; const JavaHomeName = "JAVA_HOME"; const AndroidHomeName = "ANDROID_HOME"; From fd56e44f56ff5c944116ee3c8b64a1384628e3ea Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 14 Mar 2018 12:03:58 +0200 Subject: [PATCH 072/169] Set version to 0.11.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 21d05a82e9..1ee6dcf947 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.10.0", + "version": "0.11.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 61b050352543bbb21219a2b817a032448dd5856f Mon Sep 17 00:00:00 2001 From: Fatme Date: Tue, 20 Mar 2018 12:48:04 +0200 Subject: [PATCH 073/169] Update MIN_SUPPORTED_POD_VERSION to 1.0.0 --- lib/doctor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 235e4cb3d0..1211f4cb77 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -7,7 +7,7 @@ import { Helpers } from "./helpers"; import * as semver from "semver"; export class Doctor implements NativeScriptDoctor.IDoctor { - private static MIN_SUPPORTED_POD_VERSION = "0.38.2"; + private static MIN_SUPPORTED_POD_VERSION = "1.0.0"; constructor(private androidLocalBuildRequirements: AndroidLocalBuildRequirements, private helpers: Helpers, From 0a29cc7714097fac7fc4c32bd242983aaea34d4e Mon Sep 17 00:00:00 2001 From: Fatme Date: Tue, 20 Mar 2018 12:43:54 +0200 Subject: [PATCH 074/169] Fix isCocoaPodsWorkingCorrectly --- lib/doctor.ts | 4 ++-- lib/sys-info.ts | 5 ++++- test/sys-info.ts | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 235e4cb3d0..e68e8d9080 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -1,5 +1,5 @@ import { Constants } from "./constants"; -import { EOL, platform } from "os"; +import { EOL } from "os"; import { HostInfo } from "./host-info"; import { AndroidLocalBuildRequirements } from "./local-build-requirements/android-local-build-requirements"; import { IosLocalBuildRequirements } from "./local-build-requirements/ios-local-build-requirements"; @@ -198,7 +198,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { additionalInformation: data.additionalInformation, platforms: data.platforms, type: Constants.WARNING_TYPE_NAME - } + }; } return { diff --git a/lib/sys-info.ts b/lib/sys-info.ts index a3ae77ecb8..5aeeb4d3f6 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -235,6 +235,9 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public isCocoaPodsWorkingCorrectly(): Promise { return this.getValueForProperty(() => this.isCocoaPodsWorkingCorrectlyCache, async (): Promise => { if (this.hostInfo.isDarwin) { + if (!this.fileSystem.exists(path.join(osenv.home(), ".cocoapods"))) { + return true; + } temp.track(); const tempDirectory = temp.mkdirSync("nativescript-check-cocoapods"); const pathToXCodeProjectZip = path.join(__dirname, "..", "resources", "cocoapods-verification", "cocoapods.zip"); @@ -248,7 +251,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { if (spawnResult.exitCode) { return false; } else { - return await this.fileSystem.exists(path.join(xcodeProjectDir, "cocoapods.xcworkspace")); + return this.fileSystem.exists(path.join(xcodeProjectDir, "cocoapods.xcworkspace")); } } catch (err) { return null; diff --git a/test/sys-info.ts b/test/sys-info.ts index 37b8a329a5..d36d5a7c42 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -552,7 +552,6 @@ ${expectedCliVersion}`; assert.deepEqual(result.xcprojInfo, undefined); assert.deepEqual(result.isCocoaPodsUpdateRequired, undefined); assert.deepEqual(result.pythonInfo, undefined); - }); it("no platform is specified", async() => { sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); From 04dcc8a78567a4d047e63d757369c9812d70c14f Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 21 Mar 2018 15:07:46 +0200 Subject: [PATCH 075/169] Fix tests --- test/sys-info.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/sys-info.ts b/test/sys-info.ts index d36d5a7c42..5be4ffa725 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -8,7 +8,11 @@ import { ChildProcess } from "../lib/wrappers/child-process"; const JavaHomeName = "JAVA_HOME"; const AndroidHomeName = "ANDROID_HOME"; const PROGRAM_FILES = "ProgramFiles"; +const PROGRAM_FILES_X86 = "ProgramFiles(x86)"; +const LOCAL_APP_DATA = "LOCALAPPDATA"; const PROGRAM_FILES_ENV_PATH = "C:\\Program Files"; +const PROGRAM_FILEX_X86_ENV_PATH = "C:\\Program Files(x86)"; +const LOCAL_APP_DATA_ENV_PATH = "C:\\username\\localappdata"; interface IChildProcessResultDescription { result?: any; @@ -145,7 +149,7 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: }; const fileSystem: any = { - exists: () => Promise.resolve((fileSystemOptions || {}).existsResult), + exists: () => (fileSystemOptions || {}).existsResult, extractZip: () => Promise.resolve(), readDirectory: () => Promise.resolve([]) }; @@ -271,7 +275,9 @@ describe("SysInfo unit tests", () => { it("on Windows", async () => { const originalProgramFiles = process.env[PROGRAM_FILES]; process.env[PROGRAM_FILES] = PROGRAM_FILES_ENV_PATH; - sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion }); + process.env[PROGRAM_FILES_X86] = PROGRAM_FILEX_X86_ENV_PATH; + process.env[LOCAL_APP_DATA] = LOCAL_APP_DATA_ENV_PATH; + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion }, { existsResult: true }); const result = await sysInfo.getSysInfo(); process.env[PROGRAM_FILES] = originalProgramFiles; assertCommonValues(result); @@ -517,7 +523,7 @@ ${expectedCliVersion}`; assert.deepEqual(result.itunesInstalled, undefined); assert.deepEqual(result.cocoaPodsVer, "0.38.2"); assert.deepEqual(result.xcodeprojLocation, null); - assert.deepEqual(result.isCocoaPodsWorkingCorrectly, undefined); + assert.deepEqual(result.isCocoaPodsWorkingCorrectly, true); assert.deepEqual(result.xcprojInfo, undefined); assert.deepEqual(result.isCocoaPodsUpdateRequired, false); assert.deepEqual(result.pythonInfo, {isInstalled: false, isSixPackageInstalled: false, installationErrorMessage: "Cannot read property 'shouldThrowError' of undefined"}); @@ -538,7 +544,7 @@ ${expectedCliVersion}`; assert.deepEqual(result.isAndroidSdkConfiguredCorrectly, undefined); }); it("Android platform is specified", async () => { - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }, { existsResult: true }); const result = await sysInfo.getSysInfo({platform: "Android"}); assertCommonSysInfo(result); From a13706a55f78148a4618a310ef2d405dd2e3ed83 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 21 Mar 2018 15:10:35 +0200 Subject: [PATCH 076/169] Add grunt lint to travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 8a067e1e70..4b7fb8b331 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,5 @@ before_script: - npm install grunt-cli - npm install script: +- node_modules/.bin/grunt lint - node_modules/.bin/grunt pack --no-color From 0ad5a90e2dee6a90ee75ab11a46aaf2a8eaea3fa Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 22 Mar 2018 15:05:23 +0200 Subject: [PATCH 077/169] Set version to 0.12.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1ee6dcf947..3dbb0835ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.11.0", + "version": "0.12.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From af106ccf71015ff528194cca06f528a58509998f Mon Sep 17 00:00:00 2001 From: Svetozar Toskov Date: Fri, 23 Mar 2018 16:57:01 +0200 Subject: [PATCH 078/169] Add notices.txt and update copyright line --- LICENSE | 2 +- NOTICE.txt | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 NOTICE.txt diff --git a/LICENSE b/LICENSE index 8dada3edaf..797b3461fc 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright © 2016-2018 Telerik AD. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE.txt b/NOTICE.txt new file mode 100644 index 0000000000..7222c63770 --- /dev/null +++ b/NOTICE.txt @@ -0,0 +1,89 @@ +========================================================================= +== NOTICE file corresponding to section 4 d of == +== the Apache License, Version 2.0, == +== in this case for NativeScript Doctor v1* == +========================================================================= + +NativeScript Doctor v1* (the “Product”) + +Copyright © 2016-2018 Telerik AD. All Rights Reserved. + +For license information see the LICENSE.md file which accompanies this NOTICE.txt file. + +Portions of the Product include certain non-proprietary open source and commercial third-party components listed below (“Third-Party Components”). The authors of the Third-Party Components require Telerik AD (“Telerik”) to include the following notices and additional licensing terms as a condition of Telerik’s use of such Third-Party Components. You acknowledge that the authors of the Third-Party Components have no obligation to provide support to you for the Third-Party Components or the Product. You hereby undertake to comply with all licenses related to the applicable Third-Party Components. + + +1. Special Notices Regarding Open Source Third-Party Components incorporated in the Product: + +(1) BSD-Style License: + +(a) NativeScript Doctor v1* incorporates winreg v1.2.2. Such technology is subject to the following terms and conditions: +Copyright (c) 2016, Paul Bottin All rights reserved. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +(2) ISC-Style License: + +(a) NativeScript Doctor v1* incorporates semver v5.3. Such technology is subject to the following terms and conditions: +The ISC License +Copyright (c) Isaac Z. Schlueter and Contributors +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +(b) NativeScript Doctor v1* incorporates osenv v0.1.3. Such technology is subject to the following terms and conditions: +The ISC License +Copyright (c) Isaac Z. Schlueter and Contributors +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +(3) MIT-Style License: + +(a) NativeScript Doctor v1* incorporates temp v0.8.3. Such technology is subject to the following terms and conditions: +The MIT License (MIT) +Copyright (c) 2010-2014 Bruce Williams +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(b) NativeScript Doctor v1* incorporates node-unzip v1.11. Such technology is subject to the following terms and conditions: +Copyright (c) 2012 - 2013 Near Infinity Corporation +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +2. Special Notices Regarding Commercially Licensed Third-Party Components incorporated in the Product: None + + +NOTICE FROM TELERIK AD: Additional notices may be included in the release notes or other documentation that accompanies updates received in connection with support of the Product. + +3/26/2018 From a1800effcd93eb5adb3e5e88cf6d1ce74df16f7e Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 14 May 2018 11:25:27 +0300 Subject: [PATCH 079/169] feat: Allow using JAVA 8+ Allow using JAVA 9 and 10 - remove the check for max version. --- lib/android-tools-info.ts | 3 --- test/android-tools-info.ts | 8 -------- 2 files changed, 11 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index f14959bf0b..217047bd2a 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -14,7 +14,6 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; - private static MAX_JAVA_VERSION = "1.9.0"; private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; private androidHome = process.env["ANDROID_HOME"]; @@ -103,8 +102,6 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) { warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; - } else if (semver.gte(installedJavaCompilerSemverVersion, AndroidToolsInfo.MAX_JAVA_VERSION)) { - warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install version ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; } if (warning) { diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index 507118e45f..e9a70ed006 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -33,14 +33,6 @@ describe("androidToolsInfo", () => { { javacVersion: "1.8.0_152" }, - { - javacVersion: "9", - warnings: ["Javac version 9 is not supported. You have to install version 1.8.0."] - }, - { - javacVersion: "9.0.1", - warnings: ["Javac version 9.0.1 is not supported. You have to install version 1.8.0."] - }, { javacVersion: "1.7.0", warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0."] From 301d811dad16c54634b06863aeeac718872b3bdf Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 14 May 2018 11:29:25 +0300 Subject: [PATCH 080/169] chore: Set version to 0.13.0-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3dbb0835ce..69ab53f4df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.12.0", + "version": "0.13.0-rc.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 468609ed93793476b4acfae38bcad78f0c440d51 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 14 May 2018 11:53:02 +0300 Subject: [PATCH 081/169] chore: fix transpilation --- lib/wrappers/child-process.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wrappers/child-process.ts b/lib/wrappers/child-process.ts index dc0783a627..890ed9ff7e 100644 --- a/lib/wrappers/child-process.ts +++ b/lib/wrappers/child-process.ts @@ -78,7 +78,7 @@ export class ChildProcess { public execFile(command: string, args: string[]): Promise { return new Promise((resolve, reject) => { - childProcess.execFile(command, args, (error: any, stdout: NodeBuffer) => { + childProcess.execFile(command, args, (error, stdout) => { if (error) { reject(error); } else { From acebedb0dc1e0f3217a9b0002dc827e12e987229 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 14 May 2018 11:53:23 +0300 Subject: [PATCH 082/169] chore: Add tests for Java version 9 and 10 --- test/android-tools-info.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index e9a70ed006..dcb0066aa6 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -33,6 +33,18 @@ describe("androidToolsInfo", () => { { javacVersion: "1.8.0_152" }, + { + javacVersion: "9" + }, + { + javacVersion: "9.0.1" + }, + { + javacVersion: "10" + }, + { + javacVersion: "10.0.1" + }, { javacVersion: "1.7.0", warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0."] From 0255495983716d30a4ffc44b1a08e233cc308b50 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 21 May 2018 11:00:26 +0300 Subject: [PATCH 083/169] chore: Set version to 1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69ab53f4df..a65bc3e052 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "0.13.0-rc.0", + "version": "1.0.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 528c96293e51fb4f22db92a83f367d13c1c83b17 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 24 May 2018 10:11:13 +0300 Subject: [PATCH 084/169] feat: Validate Javac version with Android runtime version In NativeScript 4.1.0 we add support for Java 10. However, older versions of the Android runtime cannot work with Java 10, so verification for the current environment and local builds depends on the current Android runtime version. In order to handle this, add projectDir parameter to the API. In case it is passed, we'll check if Android Runtime version is specified in the package.json and we'll verify if it is supported for the current Java version. --- README.md | 13 +- lib/android-tools-info.ts | 59 +++++++- lib/constants.ts | 5 + lib/declarations.d.ts | 13 ++ lib/doctor.ts | 10 +- .../android-local-build-requirements.ts | 8 +- lib/wrappers/child-process.ts | 4 + lib/wrappers/file-system.ts | 5 + test/android-tools-info.ts | 137 ++++++++++++++++-- test/sys-info.ts | 6 +- typings/interfaces.ts | 14 +- 11 files changed, 247 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 2c6254dacf..78e0716e55 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ Library that helps identifying if the environment can be used for development of const pythonInfo = await sysInfo.getPythonInfo(); console.log("python info: ", pythonInfo ); - const sysInfoData = await sysInfo.getSysInfo(); + const sysInfoData = await sysInfo.getSysInfo({ projectDir: "/Users/username/myProject" }); console.log("sysInfo: ", sysInfoData); const gitPath = await sysInfo.getGitPath(); @@ -454,12 +454,13 @@ Library that helps identifying if the environment can be used for development of import { androidToolsInfo } from "nativescript-doctor" function main() { + const projectDir = "/Users/username/myProject"; console.log("path to adb from android home: ", await androidToolsInfo.getPathToAdbFromAndroidHome()); console.log("path to emulator executable: ", androidToolsInfo.getPathToEmulatorExecutable()); console.log("android tools info: ", androidToolsInfo.getToolsInfo()); console.log("ANROID_HOME validation errors: ", await androidToolsInfo.validateAndroidHomeEnvVariable()); console.log("android tools info validation errors: ", await androidToolsInfo.validateInfo()); - console.log("javac validation errors: ", await androidToolsInfo.validateJavacVersion(await sysInfo.getJavaCompilerVersion())); + console.log("javac validation errors: ", await androidToolsInfo.validateJavacVersion(await sysInfo.getJavaCompilerVersion(), projectDir)); } main(); @@ -478,16 +479,20 @@ Library that helps identifying if the environment can be used for development of /** * Checks if the Android tools are valid. + * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. + * If it is not passed or the project does not have Android runtime, this validation is skipped. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateInfo(): NativeScriptDoctor.IWarning[]; + validateInfo(projectDir?: string): NativeScriptDoctor.IWarning[]; /** * Checks if the current javac version is valid. * @param {string} installedJavaVersion The version of javac to check. + * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. + * If it is not passed or the project does not have Android runtime, this validation is skipped. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateJavacVersion(installedJavaVersion: string): NativeScriptDoctor.IWarning[]; + validateJavacVersion(installedJavaVersion: string, projectDir?: string): NativeScriptDoctor.IWarning[]; /** * Returns the path to the adb which is located in ANDROID_HOME. diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 217047bd2a..4521708494 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -38,7 +38,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return this.toolsInfo; } - public validateInfo(): NativeScriptDoctor.IWarning[] { + public validateInfo(projectDir?: string): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const toolsInfoData = this.getToolsInfo(); const isAndroidHomeValid = this.isAndroidHomeValid(); @@ -88,7 +88,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } - public validateJavacVersion(installedJavaCompilerVersion: string): NativeScriptDoctor.IWarning[] { + public validateJavacVersion(installedJavaCompilerVersion: string, projectDir?: string): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; let additionalMessage = "You will not be able to build your projects for Android." + EOL @@ -100,8 +100,31 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (installedJavaCompilerSemverVersion) { let warning: string = null; + const supportedVersions: IDictionary = { + "^10.0.0": "4.1.0-2018.5.18.1" + }; + if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) { warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; + } else { + const runtimeVersion = this.getAndroidRuntimeVersionFromProjectDir(projectDir); + if (runtimeVersion) { + // get the item from the dictionary that corresponds to our current Javac version: + let runtimeMinVersion: string = null; + Object.keys(supportedVersions) + .forEach(javacRange => { + if (semver.satisfies(installedJavaCompilerSemverVersion, javacRange)) { + runtimeMinVersion = supportedVersions[javacRange]; + } + }); + + if (runtimeMinVersion && semver.lt(runtimeVersion, runtimeMinVersion)) { + warning = `The Java compiler version ${installedJavaCompilerVersion} is not compatible with the current Android runtime version ${runtimeVersion}. ` + + `In order to use this Javac version, you need to update your Android runtime or downgrade your Java compiler version.`; + additionalMessage = "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, downgrade your Java compiler version or update your Android runtime."; + } + } } if (warning) { @@ -320,4 +343,36 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const errors = this.validateAndroidHomeEnvVariable(); return !errors && !errors.length; } + + private getAndroidRuntimeVersionFromProjectDir(projectDir: string): string { + let runtimeVersion: string = null; + if (projectDir && this.fs.exists(projectDir)) { + const pathToPackageJson = path.join(projectDir, Constants.PACKAGE_JSON); + + if (this.fs.exists(pathToPackageJson)) { + const content = this.fs.readJson(pathToPackageJson); + runtimeVersion = content && content.nativescript && content.nativescript["tns-android"] && content.nativescript["tns-android"].version; + } + } + + if (runtimeVersion) { + // Check if the version is not "next" or "rc", i.e. tag from npm + if (!semver.valid(runtimeVersion)) { + try { + const npmViewOutput = this.childProcess.execSync(`npm view ${Constants.ANDROID_RUNTIME} dist-tags --json`); + const jsonNpmViewOutput = JSON.parse(npmViewOutput); + runtimeVersion = jsonNpmViewOutput[runtimeVersion] || runtimeVersion; + } catch (err) { + // Maybe there's no npm here + } + } + } + + if (runtimeVersion && !semver.valid(runtimeVersion)) { + // If we got here, something terribly wrong happened. + throw new Error(`The determined Android runtime version ${runtimeVersion} based on project directory ${projectDir} is not valid. Unable to verify if the current system is setup for Android development.`); + } + + return runtimeVersion; + } } diff --git a/lib/constants.ts b/lib/constants.ts index a850e287b2..04b9e11776 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -9,4 +9,9 @@ export class Constants { }; public static INFO_TYPE_NAME = "info"; public static WARNING_TYPE_NAME = "warning"; + + public static PACKAGE_JSON = "package.json"; + public static NATIVESCRIPT_KEY = "nativescript"; + public static ANDROID_RUNTIME = "tns-android"; + public static VERSION_PROPERTY_NAME = "version"; } diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 6d0d6e70fb..9eda37c161 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -66,3 +66,16 @@ interface IHiveIds { interface IDictionary { [key: string]: T } + +interface IVersion { + version: string; +} + +interface INativeScriptNode { + ["tns-android"]: IVersion; + ["tns-ios"]: IVersion; +} + +interface INativeScriptProjectPackageJson { + nativescript: INativeScriptNode; +} diff --git a/lib/doctor.ts b/lib/doctor.ts index 8353d17aa2..7d20f22fdf 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -16,11 +16,11 @@ export class Doctor implements NativeScriptDoctor.IDoctor { private sysInfo: NativeScriptDoctor.ISysInfo, private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo) { } - public async canExecuteLocalBuild(platform: string): Promise { + public async canExecuteLocalBuild(platform: string, projectDir?: string): Promise { this.validatePlatform(platform); if (platform.toLowerCase() === Constants.ANDROID_PLATFORM_NAME.toLowerCase()) { - return await this.androidLocalBuildRequirements.checkRequirements(); + return await this.androidLocalBuildRequirements.checkRequirements(projectDir); } else if (platform.toLowerCase() === Constants.IOS_PLATFORM_NAME.toLowerCase()) { return await this.iOSLocalBuildRequirements.checkRequirements(); } @@ -33,7 +33,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { const sysInfoData = await this.sysInfo.getSysInfo(config); if (!config || !config.platform || config.platform === Constants.ANDROID_PLATFORM_NAME) { - result = result.concat(this.getAndroidInfos(sysInfoData)); + result = result.concat(this.getAndroidInfos(sysInfoData, config && config.projectDir)); } if (!config || !config.platform || config.platform === Constants.IOS_PLATFORM_NAME) { @@ -58,7 +58,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { .map(item => this.convertInfoToWarning(item)); } - private getAndroidInfos(sysInfoData: NativeScriptDoctor.ISysInfoData): NativeScriptDoctor.IInfo[] { + private getAndroidInfos(sysInfoData: NativeScriptDoctor.ISysInfoData, projectDir?: string): NativeScriptDoctor.IInfo[] { let result: NativeScriptDoctor.IInfo[] = []; result = result.concat( @@ -92,7 +92,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.ANDROID_PLATFORM_NAME] }), this.processValidationErrors({ - warnings: this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion), + warnings: this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion, projectDir), infoMessage: "Javac is installed and is configured properly.", platforms: [Constants.ANDROID_PLATFORM_NAME] }), diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index 0ad8da9699..153a76421b 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -2,11 +2,13 @@ export class AndroidLocalBuildRequirements { constructor(private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo, private sysInfo: NativeScriptDoctor.ISysInfo) { } - public async checkRequirements(): Promise { + public async checkRequirements(projectDir?: string): Promise { const androidToolsInfo = await this.androidToolsInfo.validateInfo(); + const javacVersion = await this.sysInfo.getJavaCompilerVersion(); if (androidToolsInfo.length || - !await this.sysInfo.getJavaCompilerVersion() || - !await this.sysInfo.getAdbVersion()) { + !javacVersion || + !await this.sysInfo.getAdbVersion() || + !await this.androidToolsInfo.validateJavacVersion(javacVersion, projectDir)) { return false; } diff --git a/lib/wrappers/child-process.ts b/lib/wrappers/child-process.ts index 890ed9ff7e..90366925e1 100644 --- a/lib/wrappers/child-process.ts +++ b/lib/wrappers/child-process.ts @@ -76,6 +76,10 @@ export class ChildProcess { }); } + public execSync(command: string, options?: childProcess.ExecSyncOptions): string { + return childProcess.execSync(command, options).toString(); + } + public execFile(command: string, args: string[]): Promise { return new Promise((resolve, reject) => { childProcess.execFile(command, args, (error, stdout) => { diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index c46bc23969..12ddb2a6bd 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -17,4 +17,9 @@ export class FileSystem { public readDirectory(path: string): string[] { return fs.readdirSync(path); } + + public readJson(path: string, options?: { encoding?: null; flag?: string; }): T { + const content = fs.readFileSync(path, options); + return JSON.parse(content.toString()); + } } diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index dcb0066aa6..0ddd268c02 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -10,16 +10,30 @@ import { Constants } from '../lib/constants'; interface ITestData { javacVersion: string; warnings?: string[]; + runtimeVersion?: string; + additionalInformation?: string; } describe("androidToolsInfo", () => { - const additionalInformation = "You will not be able to build your projects for Android." + EOL - + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + - " described in " + Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform]; + const defaultAdditionalInformation = "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + + " described in " + Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform]; - const getAndroidToolsInfo = (): AndroidToolsInfo => { + const getAndroidToolsInfo = (runtimeVersion?: string): AndroidToolsInfo => { const childProcess: ChildProcess = {}; - const fs: FileSystem = {}; + const fs: FileSystem = { + exists: () => true, + execSync: (): string => null, + readJson: (): any => { + return runtimeVersion ? { + nativescript: { + "tns-android": { + version: runtimeVersion + } + } + } : null; + } + }; const hostInfo: HostInfo = {}; const helpers: Helpers = new Helpers({}); return new AndroidToolsInfo(childProcess, fs, hostInfo, helpers); @@ -56,25 +70,130 @@ describe("androidToolsInfo", () => { { javacVersion: null, warnings: ["Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable."] + }, + { + javacVersion: "10", + runtimeVersion: "4.0.0", + warnings: [`The Java compiler version 10 is not compatible with the current Android runtime version 4.0.0. ` + + `In order to use this Javac version, you need to update your Android runtime or downgrade your Java compiler version.`], + additionalInformation: "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, downgrade your Java compiler version or update your Android runtime." + }, + { + javacVersion: "10", + runtimeVersion: "4.2.0" } ]; - testData.forEach(({ javacVersion, warnings }) => { + testData.forEach(({ javacVersion, warnings, runtimeVersion, additionalInformation }) => { it(`returns correct result when version is ${javacVersion}`, () => { - const androidToolsInfo = getAndroidToolsInfo(); - const actualWarnings = androidToolsInfo.validateJavacVersion(javacVersion); + const androidToolsInfo = getAndroidToolsInfo(runtimeVersion); + const actualWarnings = androidToolsInfo.validateJavacVersion(javacVersion, "/Users/username/projectDir"); + + let expectedWarnings: NativeScriptDoctor.IWarning[] = []; + if (warnings && warnings.length) { + expectedWarnings = warnings.map(warning => { + return { + platforms: [Constants.ANDROID_PLATFORM_NAME], + warning, + additionalInformation: additionalInformation || defaultAdditionalInformation + }; + }); + } + + assert.deepEqual(actualWarnings, expectedWarnings); + }); + }); + + const npmTagsTestData: ITestData[] = [ + { + javacVersion: "1.8.0", + runtimeVersion: "rc" + }, + { + javacVersion: "10", + runtimeVersion: "rc" + }, + { + javacVersion: "10", + runtimeVersion: "latest", + warnings: [`The Java compiler version 10 is not compatible with the current Android runtime version 4.0.0. ` + + `In order to use this Javac version, you need to update your Android runtime or downgrade your Java compiler version.`], + additionalInformation: "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, downgrade your Java compiler version or update your Android runtime." + }, + { + javacVersion: "10", + runtimeVersion: "old", + warnings: [`The Java compiler version 10 is not compatible with the current Android runtime version 4.1.0-2018.5.17.1. ` + + `In order to use this Javac version, you need to update your Android runtime or downgrade your Java compiler version.`], + additionalInformation: "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, downgrade your Java compiler version or update your Android runtime." + }, + { + javacVersion: "10", + runtimeVersion: "old", + warnings: [`The Java compiler version 10 is not compatible with the current Android runtime version 4.1.0-2018.5.17.1. ` + + `In order to use this Javac version, you need to update your Android runtime or downgrade your Java compiler version.`], + additionalInformation: "You will not be able to build your projects for Android." + EOL + + "To be able to build for Android, downgrade your Java compiler version or update your Android runtime." + }, + { + javacVersion: "1.8.0", + runtimeVersion: "latest" + }, + { + javacVersion: "1.8.0", + runtimeVersion: "old" + }, + ]; + + npmTagsTestData.forEach(({ javacVersion, warnings, runtimeVersion, additionalInformation }) => { + it(`returns correct result when javac version is ${javacVersion} and the runtime version is tag from npm: ${runtimeVersion}`, () => { + let execSyncCommand: string = null; + const childProcess: ChildProcess = { + execSync: (command: string) => { + execSyncCommand = command; + return JSON.stringify({ + latest: '4.0.0', + rc: '4.1.0-rc-2018.5.21.1', + next: '4.1.0-2018.5.23.2', + old: '4.1.0-2018.5.17.1' + }); + } + }; + + const fs: FileSystem = { + exists: (filePath: string): boolean => true, + execSync: (): string => null, + readJson: (): any => + ({ + nativescript: { + "tns-android": { + version: runtimeVersion + } + } + }) + }; + + const hostInfo: HostInfo = {}; + const helpers: Helpers = new Helpers({}); + const androidToolsInfo = new AndroidToolsInfo(childProcess, fs, hostInfo, helpers); + + const actualWarnings = androidToolsInfo.validateJavacVersion(javacVersion, "/Users/username/projectDir"); let expectedWarnings: NativeScriptDoctor.IWarning[] = []; if (warnings && warnings.length) { expectedWarnings = warnings.map(warning => { return { platforms: [Constants.ANDROID_PLATFORM_NAME], warning, - additionalInformation + additionalInformation: additionalInformation || defaultAdditionalInformation }; }); } assert.deepEqual(actualWarnings, expectedWarnings); + assert.equal(execSyncCommand, "npm view tns-android dist-tags --json"); }); }); }); diff --git a/test/sys-info.ts b/test/sys-info.ts index 5be4ffa725..634e8631fa 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -145,7 +145,8 @@ function mockSysInfo(childProcessResult: IChildProcessResults, hostInfoOptions?: }, execFile: async (): Promise => { return undefined; - } + }, + execSync: (command: string): string => null }; const fileSystem: any = { @@ -191,7 +192,8 @@ describe("SysInfo unit tests", () => { }, execFile: async () => { return undefined; - } + }, + execSync: (command: string): string => null }; const helpers = new Helpers(null); diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 1355094eb0..3a1f003d67 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -160,6 +160,12 @@ declare module NativeScriptDoctor { */ pathToAdb: string; }; + + /** + * The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. + * If it is not passed or the project does not have Android runtime, this validation is skipped. + */ + projectDir?: string; } /** @@ -424,16 +430,20 @@ declare module NativeScriptDoctor { /** * Checks if the Android tools are valid. + * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. + * If it is not passed or the project does not have Android runtime, this validation is skipped. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateInfo(): NativeScriptDoctor.IWarning[]; + validateInfo(projectDir?: string): NativeScriptDoctor.IWarning[]; /** * Checks if the current javac version is valid. * @param {string} installedJavaVersion The version of javac to check. + * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. + * If it is not passed or the project does not have Android runtime, this validation is skipped. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateJavacVersion(installedJavaVersion: string): NativeScriptDoctor.IWarning[]; + validateJavacVersion(installedJavaVersion: string, projectDir?: string): NativeScriptDoctor.IWarning[]; /** * Returns the path to the adb which is located in ANDROID_HOME. From 4519855b4a8a77dc754f5efd3ec83e6df6b8e7a6 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 24 May 2018 13:48:47 +0300 Subject: [PATCH 085/169] chore: Set version to 1.1.0-rc.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a65bc3e052..95ae56048b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.0.0", + "version": "1.1.0-rc.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From f235e17b4de4bde80b084491750347af733b1fcf Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 25 May 2018 13:45:15 +0300 Subject: [PATCH 086/169] chore: Set version to 1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 95ae56048b..476970570b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.1.0-rc.0", + "version": "1.1.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From a9abb0ab066aa29cf89debf41cbccf41f11d23ba Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 28 May 2018 14:16:49 +0300 Subject: [PATCH 087/169] feat: Validate Java version based on passed runtime version Allow verification of the environment based on a specified Android runtime version. This is required for cases where the package.json of the project is not updated yet, but we need to verify that we can use this runtime --- lib/android-tools-info.ts | 12 ++++++++---- lib/doctor.ts | 14 +++++++------- .../android-local-build-requirements.ts | 4 ++-- lib/sys-info.ts | 4 ++-- typings/interfaces.ts | 15 ++++++++++----- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 4521708494..2be98ea361 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -38,7 +38,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return this.toolsInfo; } - public validateInfo(projectDir?: string): NativeScriptDoctor.IWarning[] { + public validateInfo(): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const toolsInfoData = this.getToolsInfo(); const isAndroidHomeValid = this.isAndroidHomeValid(); @@ -88,7 +88,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } - public validateJavacVersion(installedJavaCompilerVersion: string, projectDir?: string): NativeScriptDoctor.IWarning[] { + public validateJavacVersion(installedJavaCompilerVersion: string, projectDir?: string, runtimeVersion?: string): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; let additionalMessage = "You will not be able to build your projects for Android." + EOL @@ -107,7 +107,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) { warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; } else { - const runtimeVersion = this.getAndroidRuntimeVersionFromProjectDir(projectDir); + runtimeVersion = this.getRealRuntimeVersion(runtimeVersion || this.getAndroidRuntimeVersionFromProjectDir(projectDir)); if (runtimeVersion) { // get the item from the dictionary that corresponds to our current Javac version: let runtimeMinVersion: string = null; @@ -355,6 +355,10 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } } + return runtimeVersion; + } + + private getRealRuntimeVersion(runtimeVersion: string): string { if (runtimeVersion) { // Check if the version is not "next" or "rc", i.e. tag from npm if (!semver.valid(runtimeVersion)) { @@ -370,7 +374,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (runtimeVersion && !semver.valid(runtimeVersion)) { // If we got here, something terribly wrong happened. - throw new Error(`The determined Android runtime version ${runtimeVersion} based on project directory ${projectDir} is not valid. Unable to verify if the current system is setup for Android development.`); + throw new Error(`The determined Android runtime version ${runtimeVersion} is not valid. Unable to verify if the current system is setup for Android development.`); } return runtimeVersion; diff --git a/lib/doctor.ts b/lib/doctor.ts index 7d20f22fdf..76cac71744 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -16,11 +16,11 @@ export class Doctor implements NativeScriptDoctor.IDoctor { private sysInfo: NativeScriptDoctor.ISysInfo, private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo) { } - public async canExecuteLocalBuild(platform: string, projectDir?: string): Promise { + public async canExecuteLocalBuild(platform: string, projectDir?: string, runtimeVersion?: string): Promise { this.validatePlatform(platform); if (platform.toLowerCase() === Constants.ANDROID_PLATFORM_NAME.toLowerCase()) { - return await this.androidLocalBuildRequirements.checkRequirements(projectDir); + return await this.androidLocalBuildRequirements.checkRequirements(projectDir, runtimeVersion); } else if (platform.toLowerCase() === Constants.IOS_PLATFORM_NAME.toLowerCase()) { return await this.iOSLocalBuildRequirements.checkRequirements(); } @@ -32,11 +32,11 @@ export class Doctor implements NativeScriptDoctor.IDoctor { let result: NativeScriptDoctor.IInfo[] = []; const sysInfoData = await this.sysInfo.getSysInfo(config); - if (!config || !config.platform || config.platform === Constants.ANDROID_PLATFORM_NAME) { - result = result.concat(this.getAndroidInfos(sysInfoData, config && config.projectDir)); + if (!config || !config.platform || config.platform.toLowerCase() === Constants.ANDROID_PLATFORM_NAME.toLowerCase()) { + result = result.concat(this.getAndroidInfos(sysInfoData, config && config.projectDir, config && config.androidRuntimeVersion)); } - if (!config || !config.platform || config.platform === Constants.IOS_PLATFORM_NAME) { + if (!config || !config.platform || config.platform.toLowerCase() === Constants.IOS_PLATFORM_NAME.toLowerCase()) { result = result.concat(await this.getiOSInfos(sysInfoData)); } @@ -58,7 +58,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { .map(item => this.convertInfoToWarning(item)); } - private getAndroidInfos(sysInfoData: NativeScriptDoctor.ISysInfoData, projectDir?: string): NativeScriptDoctor.IInfo[] { + private getAndroidInfos(sysInfoData: NativeScriptDoctor.ISysInfoData, projectDir?: string, runtimeVersion?: string): NativeScriptDoctor.IInfo[] { let result: NativeScriptDoctor.IInfo[] = []; result = result.concat( @@ -92,7 +92,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.ANDROID_PLATFORM_NAME] }), this.processValidationErrors({ - warnings: this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion, projectDir), + warnings: this.androidToolsInfo.validateJavacVersion(sysInfoData.javacVersion, projectDir, runtimeVersion), infoMessage: "Javac is installed and is configured properly.", platforms: [Constants.ANDROID_PLATFORM_NAME] }), diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index 153a76421b..d6748b7dcb 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -2,13 +2,13 @@ export class AndroidLocalBuildRequirements { constructor(private androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo, private sysInfo: NativeScriptDoctor.ISysInfo) { } - public async checkRequirements(projectDir?: string): Promise { + public async checkRequirements(projectDir?: string, runtimeVersion?: string): Promise { const androidToolsInfo = await this.androidToolsInfo.validateInfo(); const javacVersion = await this.sysInfo.getJavaCompilerVersion(); if (androidToolsInfo.length || !javacVersion || !await this.sysInfo.getAdbVersion() || - !await this.androidToolsInfo.validateJavacVersion(javacVersion, projectDir)) { + !await this.androidToolsInfo.validateJavacVersion(javacVersion, projectDir, runtimeVersion)) { return false; } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 5aeeb4d3f6..3a089d2775 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -221,11 +221,11 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { } public async getSysInfo(config?: NativeScriptDoctor.ISysInfoConfig): Promise { - if (config && config.platform === Constants.ANDROID_PLATFORM_NAME) { + if (config && config.platform && config.platform.toLowerCase() === Constants.ANDROID_PLATFORM_NAME.toLowerCase()) { return Object.assign(await this.getCommonSysInfo(), await this.getAndroidSysInfo(config)); } - if (config && config.platform === Constants.IOS_PLATFORM_NAME) { + if (config && config.platform && config.platform.toLowerCase() === Constants.IOS_PLATFORM_NAME.toLowerCase()) { return Object.assign(await this.getCommonSysInfo(), await this.getiOSSysInfo()); } diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 3a1f003d67..66407a7dce 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -166,6 +166,11 @@ declare module NativeScriptDoctor { * If it is not passed or the project does not have Android runtime, this validation is skipped. */ projectDir?: string; + + /** + * The runtime version against which the validation is executed. In case this parameter is passed, it takes predescences over the projectDir argument. + */ + androidRuntimeVersion?: string; } /** @@ -175,9 +180,10 @@ declare module NativeScriptDoctor { /** * Checks if a local build can be executed on the current machine. * @param {string} platform The platform for which to check if local build is possible. + * @param {string} runtimeVersion @optional The runtime version against which the validation is executed. In case this parameter is passed, it takes predescences over the projectDir argument. * @return {Promise} true if local build can be executed for the provided platform. */ - canExecuteLocalBuild(platform: string): Promise; + canExecuteLocalBuild(platform: string, runtimeVersion?: string): Promise; /** * Executes all checks for the current environment and returns the warnings from each check. @@ -430,20 +436,19 @@ declare module NativeScriptDoctor { /** * Checks if the Android tools are valid. - * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. - * If it is not passed or the project does not have Android runtime, this validation is skipped. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateInfo(projectDir?: string): NativeScriptDoctor.IWarning[]; + validateInfo(): NativeScriptDoctor.IWarning[]; /** * Checks if the current javac version is valid. * @param {string} installedJavaVersion The version of javac to check. * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. * If it is not passed or the project does not have Android runtime, this validation is skipped. + * @param {string} runtimeVersion @optional The runtime version against which the validation is executed. In case this parameter is passed, it takes predescences over the projectDir argument. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateJavacVersion(installedJavaVersion: string, projectDir?: string): NativeScriptDoctor.IWarning[]; + validateJavacVersion(installedJavaVersion: string, projectDir?: string, runtimeVersion?: string): NativeScriptDoctor.IWarning[]; /** * Returns the path to the adb which is located in ANDROID_HOME. From 91250320367d98a4f890e5db8e4cca33ffd4587b Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 28 May 2018 15:10:16 +0300 Subject: [PATCH 088/169] chore: Set verion to 1.2.0-rc.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 476970570b..01919ecdc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.1.0", + "version": "1.2.0-rc.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 87369a71b39e1902f678869d15a298372dcea5df Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 28 May 2018 16:13:41 +0300 Subject: [PATCH 089/169] chore: Fix JSDocs --- typings/interfaces.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 66407a7dce..f76f345e0c 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -168,7 +168,7 @@ declare module NativeScriptDoctor { projectDir?: string; /** - * The runtime version against which the validation is executed. In case this parameter is passed, it takes predescences over the projectDir argument. + * The runtime version against which the validation is executed. In case this parameter is passed, it takes precedence over the projectDir argument. */ androidRuntimeVersion?: string; } @@ -180,10 +180,12 @@ declare module NativeScriptDoctor { /** * Checks if a local build can be executed on the current machine. * @param {string} platform The platform for which to check if local build is possible. - * @param {string} runtimeVersion @optional The runtime version against which the validation is executed. In case this parameter is passed, it takes predescences over the projectDir argument. + * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. + * If it is not passed or the project does not have Android runtime, this validation is skipped. + * @param {string} runtimeVersion @optional The runtime version against which the validation is executed. In case this parameter is passed, it takes precedence over the projectDir argument. * @return {Promise} true if local build can be executed for the provided platform. */ - canExecuteLocalBuild(platform: string, runtimeVersion?: string): Promise; + canExecuteLocalBuild(platform: string, projectDir?: string, runtimeVersion?: string): Promise; /** * Executes all checks for the current environment and returns the warnings from each check. @@ -445,7 +447,7 @@ declare module NativeScriptDoctor { * @param {string} installedJavaVersion The version of javac to check. * @param {string} projectDir @optional The project directory. Used to determine the Android Runtime version and validate the Java compiler version against it. * If it is not passed or the project does not have Android runtime, this validation is skipped. - * @param {string} runtimeVersion @optional The runtime version against which the validation is executed. In case this parameter is passed, it takes predescences over the projectDir argument. + * @param {string} runtimeVersion @optional The runtime version against which the validation is executed. In case this parameter is passed, it takes precedence over the projectDir argument. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ validateJavacVersion(installedJavaVersion: string, projectDir?: string, runtimeVersion?: string): NativeScriptDoctor.IWarning[]; From 81fe42a2cd63812b138bcd579ecbb384d83bcf0d Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 28 May 2018 16:46:35 +0300 Subject: [PATCH 090/169] chore: Update version to 1.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 01919ecdc4..e30c41a54f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.2.0-rc.0", + "version": "1.2.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From b66ce51a3b6423fca9d2e1b72a83c26aebd2647a Mon Sep 17 00:00:00 2001 From: Teodor Bozhikov Date: Tue, 12 Jun 2018 14:35:05 +0300 Subject: [PATCH 091/169] chore: update community files --- LICENSE | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 LICENSE diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 index 797b3461fc..59dc28ed04 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Apache License + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright © 2016-2018 Telerik AD. All Rights Reserved. + Copyright (c) 2015-2018 Telerik EAD Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -198,4 +198,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. + limitations under the License. \ No newline at end of file From b7351b20d85ca5bb708e7e044c65f8a077a40a62 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 22 Jun 2018 13:14:58 +0300 Subject: [PATCH 092/169] fix: Check for Local Android build disregards issues in Javac version In case there's a problem with Javac version (for example it is 10.0.0, but current project uses Android runtime, that cannot be used with this Java version), the checkRequirements method disregards the warning. Fix the check and add tests. --- .../android-local-build-requirements.ts | 6 +- test/android-local-build-requirements.ts | 95 +++++++++++++++++++ 2 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 test/android-local-build-requirements.ts diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index d6748b7dcb..6c93c98d08 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -4,11 +4,11 @@ export class AndroidLocalBuildRequirements { public async checkRequirements(projectDir?: string, runtimeVersion?: string): Promise { const androidToolsInfo = await this.androidToolsInfo.validateInfo(); - const javacVersion = await this.sysInfo.getJavaCompilerVersion(); + const javacVersion = await this.sysInfo.getJavaCompilerVersion(); + const isJavacVersionInvalid = !javacVersion || (await this.androidToolsInfo.validateJavacVersion(javacVersion, projectDir, runtimeVersion)).length; if (androidToolsInfo.length || - !javacVersion || !await this.sysInfo.getAdbVersion() || - !await this.androidToolsInfo.validateJavacVersion(javacVersion, projectDir, runtimeVersion)) { + isJavacVersionInvalid) { return false; } diff --git a/test/android-local-build-requirements.ts b/test/android-local-build-requirements.ts new file mode 100644 index 0000000000..e36dc632e9 --- /dev/null +++ b/test/android-local-build-requirements.ts @@ -0,0 +1,95 @@ +import { AndroidLocalBuildRequirements } from '../lib/local-build-requirements/android-local-build-requirements'; +import { assert } from "chai"; + +interface ITestCaseData { + testName: string; + validateInfo?: NativeScriptDoctor.IWarning[]; + validateJavacVersion?: NativeScriptDoctor.IWarning[]; + getJavaCompilerVersion?: string; + getAdbVersion?: string; +} + +describe("androidLocalBuildRequirements", () => { + describe("checkRequirements", () => { + const setupTestCase = (results: ITestCaseData): AndroidLocalBuildRequirements => { + const androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo = { + validateInfo: (): NativeScriptDoctor.IWarning[] => results.validateInfo || [], + validateAndroidHomeEnvVariable: (): NativeScriptDoctor.IWarning[] => [], + getToolsInfo: (): NativeScriptDoctor.IAndroidToolsInfoData => null, + validateJavacVersion: (installedJavaVersion: string, projectDir?: string, runtimeVersion?: string): NativeScriptDoctor.IWarning[] => results.validateJavacVersion || [], + getPathToAdbFromAndroidHome: async (): Promise => undefined, + getPathToEmulatorExecutable: (): string => undefined + }; + + const sysInfo: NativeScriptDoctor.ISysInfo = { + getJavaCompilerVersion: async (): Promise => results.hasOwnProperty("getJavaCompilerVersion") ? results.getJavaCompilerVersion : "8.0.0", + getAdbVersion: async (pathToAdb?: string): Promise => results.hasOwnProperty("getAdbVersion") ? results.getAdbVersion : "1.0.39", + getXcodeVersion: async (): Promise => undefined, + getNodeVersion: async (): Promise => undefined, + getNpmVersion: async (): Promise => undefined, + getNodeGypVersion: async (): Promise => undefined, + getXcodeprojLocation: async (): Promise => undefined, + isITunesInstalled: async (): Promise => false, + getCocoaPodsVersion: async (): Promise => undefined, + getOs: async (): Promise => undefined, + isAndroidInstalled: async (): Promise => false, + getMonoVersion: async (): Promise => undefined, + getGitVersion: async (): Promise => undefined, + getGitPath: async (): Promise => undefined, + getGradleVersion: async (): Promise => undefined, + isCocoaPodsWorkingCorrectly: async (): Promise => false, + getNativeScriptCliVersion: async (): Promise => undefined, + getXcprojInfo: async (): Promise => null, + isCocoaPodsUpdateRequired: async (): Promise => true, + isAndroidSdkConfiguredCorrectly: async (): Promise => true, + getSysInfo: async (config?: NativeScriptDoctor.ISysInfoConfig): Promise => null, + setShouldCacheSysInfo: (shouldCache: boolean): void => undefined + }; + + const androidLocalBuildRequirements = new AndroidLocalBuildRequirements(androidToolsInfo, sysInfo); + return androidLocalBuildRequirements; + }; + + it("returns true when everything is setup correctly", async () => { + const androidLocalBuildRequirements = setupTestCase({ testName: "returns true when everything is setup correctly" }); + const result = await androidLocalBuildRequirements.checkRequirements(); + assert.isTrue(result); + }); + + describe("returns false", () => { + const getWarnings = (): NativeScriptDoctor.IWarning[] => { + return [{ + warning: "warning", + additionalInformation: "additional info", + platforms: ["android"] + }]; + }; + const testData: ITestCaseData[] = [ + { + testName: "when java is not installed", + getJavaCompilerVersion: null + }, + { + testName: "when java is installed, but it is not compatible for current project", + validateJavacVersion: getWarnings() + }, + { + testName: "when Android tools are not installed correctly", + validateInfo: getWarnings() + }, + { + testName: "when adb cannot be found", + getAdbVersion: null + } + ]; + + testData.forEach(testCase => { + it(testCase.testName, async () => { + const androidLocalBuildRequirements = setupTestCase(testCase); + const result = await androidLocalBuildRequirements.checkRequirements(); + assert.isFalse(result); + }); + }); + }); + }); +}); From 978d5efd6af77af78339c5b7fc019169d1a5dbe1 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 22 Jun 2018 13:58:28 +0300 Subject: [PATCH 093/169] chore: Bump version to 1.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e30c41a54f..a397c31b2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.2.0", + "version": "1.2.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From bd40a6f6da5e47fc15d403a63392cc3991f35c52 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 20 Sep 2018 17:19:26 +0300 Subject: [PATCH 094/169] feat: remove requirement for Android Support Repository installation In the past there was a requirement to have a local copy of the Android Support Repository in order to use it in your application. However, since some time the new versions of the libraries are in the Google repository, so there's no need to have them locally. --- lib/android-tools-info.ts | 39 --------------------------------------- typings/interfaces.ts | 5 ----- 2 files changed, 44 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 2be98ea361..3722181041 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -30,7 +30,6 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { infoData.androidHomeEnvVar = this.androidHome; infoData.compileSdkVersion = this.getCompileSdk(); infoData.buildToolsVersion = this.getBuildToolsVersion(); - infoData.supportRepositoryVersion = this.getAndroidSupportRepositoryVersion(); this.toolsInfo = infoData; } @@ -72,19 +71,6 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { }); } - if (!toolsInfoData.supportRepositoryVersion) { - let invalidSupportLibAdditionalMsg = `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage the Android Support Repository.`; - if (!isAndroidHomeValid) { - invalidSupportLibAdditionalMsg += ' In case you already have it installed, make sure `ANDROID_HOME` environment variable is set correctly.'; - } - - errors.push({ - warning: `You need to have Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later and the latest Android Support Repository installed on your system.`, - additionalInformation: invalidSupportLibAdditionalMsg, - platforms: [Constants.ANDROID_PLATFORM_NAME] - }); - } - return errors; } @@ -275,31 +261,6 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return buildToolsVersion; } - private getAppCompatRange(): string { - let compileSdkVersion = this.getCompileSdk(); - let requiredAppCompatRange: string; - if (compileSdkVersion) { - requiredAppCompatRange = `>=${compileSdkVersion} <${compileSdkVersion + 1}`; - } - - return requiredAppCompatRange; - } - - private getAndroidSupportRepositoryVersion(): string { - let selectedAppCompatVersion: string; - const requiredAppCompatRange = this.getAppCompatRange(); - if (this.androidHome && requiredAppCompatRange) { - const pathToAppCompat = path.join(this.androidHome, "extras", "android", "m2repository", "com", "android", "support", "appcompat-v7"); - selectedAppCompatVersion = this.getMatchingDir(pathToAppCompat, requiredAppCompatRange); - if (!selectedAppCompatVersion) { - // get latest matching version, as there's no available appcompat versions for latest SDK versions. - selectedAppCompatVersion = this.getMatchingDir(pathToAppCompat, "*"); - } - } - - return selectedAppCompatVersion; - } - private getLatestValidAndroidTarget(): string { const installedTargets = this.getInstalledTargets(); let latestValidAndroidTarget: string; diff --git a/typings/interfaces.ts b/typings/interfaces.ts index f76f345e0c..3aebd53a06 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -489,10 +489,5 @@ declare module NativeScriptDoctor { * The latest installed version of Android SDK that satisfies CLI's requirements. */ compileSdkVersion: number; - - /** - * The latest installed version of Android Support Repository that satisfies CLI's requirements. - */ - supportRepositoryVersion: string; } } From f8c35dacbb6239aaf715bd804af2eace7f439042 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 21 Sep 2018 16:10:26 +0300 Subject: [PATCH 095/169] release: cut the 1.3.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a397c31b2d..6b2cf2a2f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.2.1", + "version": "1.3.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 0872ba7555258faf4281c36f4bf42b18402553c2 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 28 Sep 2018 14:28:51 +0300 Subject: [PATCH 096/169] feat: allow using android-28 SDK for building apps: --- lib/android-tools-info.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 3722181041..a312f4e941 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -9,7 +9,19 @@ import * as path from "path"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static ANDROID_TARGET_PREFIX = "android"; - private static SUPPORTED_TARGETS = ["android-17", "android-18", "android-19", "android-21", "android-22", "android-23", "android-24", "android-25", "android-26", "android-27"]; + private static SUPPORTED_TARGETS = [ + "android-17", + "android-18", + "android-19", + "android-21", + "android-22", + "android-23", + "android-24", + "android-25", + "android-26", + "android-27", + "android-28", + ]; private static MIN_REQUIRED_COMPILE_TARGET = 22; private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; From 57426300038321b02a94926b7d2e0593f219d22d Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 28 Sep 2018 14:29:15 +0300 Subject: [PATCH 097/169] release: set version to 1.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6b2cf2a2f6..5c2ce475a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.3.0", + "version": "1.4.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 60eea4aeeaccdcafb84383490034425981c3e46c Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 2 Oct 2018 14:08:08 +0300 Subject: [PATCH 098/169] feat: drop support for Xcode versions below 9 Currently iOS apps cannot be build with Xcode versions below 9, so add a check for the min supported Xcode version. --- lib/constants.ts | 1 + lib/doctor.ts | 14 +- .../ios-local-build-requirements.ts | 10 +- package.json | 4 +- test/ios-local-build-requirements.ts | 125 ++++++++++++++++++ 5 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 test/ios-local-build-requirements.ts diff --git a/lib/constants.ts b/lib/constants.ts index 04b9e11776..cd74526e7f 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -14,4 +14,5 @@ export class Constants { public static NATIVESCRIPT_KEY = "nativescript"; public static ANDROID_RUNTIME = "tns-android"; public static VERSION_PROPERTY_NAME = "version"; + public static XCODE_MIN_REQUIRED_VERSION = 9; } diff --git a/lib/doctor.ts b/lib/doctor.ts index 76cac71744..db394870ee 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -186,6 +186,18 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.IOS_PLATFORM_NAME] }) ); + + if (sysInfoData.xcodeVer) { + result = result.concat( + this.processSysInfoItem({ + item: await this.iOSLocalBuildRequirements.isXcodeVersionValid(), + infoMessage: `Xcode version ${sysInfoData.xcodeVer} satisfies minimum required version ${Constants.XCODE_MIN_REQUIRED_VERSION}.`, + warningMessage: `Xcode version ${sysInfoData.xcodeVer} is lower than minimum required version ${Constants.XCODE_MIN_REQUIRED_VERSION}.`, + additionalInformation: "To build your application for iOS, update your Xcode.", + platforms: [Constants.IOS_PLATFORM_NAME] + }) + ); + } } return result; @@ -208,7 +220,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { }; } - private processValidationErrors(data: { warnings: NativeScriptDoctor.IWarning[], infoMessage: string, platforms: string[]}): NativeScriptDoctor.IInfo[] { + private processValidationErrors(data: { warnings: NativeScriptDoctor.IWarning[], infoMessage: string, platforms: string[] }): NativeScriptDoctor.IInfo[] { if (data.warnings.length > 0) { return data.warnings.map(warning => this.convertWarningToInfo(warning)); } diff --git a/lib/local-build-requirements/ios-local-build-requirements.ts b/lib/local-build-requirements/ios-local-build-requirements.ts index 36f02e9731..cff27d5b40 100644 --- a/lib/local-build-requirements/ios-local-build-requirements.ts +++ b/lib/local-build-requirements/ios-local-build-requirements.ts @@ -1,4 +1,6 @@ import { HostInfo } from "../host-info"; +import * as semver from "semver"; +import { Constants } from "../constants"; export class IosLocalBuildRequirements { constructor(private sysInfo: NativeScriptDoctor.ISysInfo, @@ -6,11 +8,17 @@ export class IosLocalBuildRequirements { public async checkRequirements(): Promise { if (!this.hostInfo.isDarwin || - !await this.sysInfo.getXcodeVersion() || + !await this.isXcodeVersionValid() || !await this.sysInfo.getXcodeprojLocation()) { return false; } return true; } + + public async isXcodeVersionValid(): Promise { + const xcodeVersion = await this.sysInfo.getXcodeVersion(); + + return !!xcodeVersion && (semver.major(semver.coerce(xcodeVersion)) >= Constants.XCODE_MIN_REQUIRED_VERSION); + } } diff --git a/package.json b/package.json index 5c2ce475a4..2be0b09080 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "devDependencies": { "@types/chai": "4.1.0", "@types/mocha": "2.2.32", - "@types/semver": "5.3.30", + "@types/semver": "5.5.0", "@types/temp": "0.8.29", "@types/winreg": "1.2.30", "chai": "4.1.2", @@ -43,7 +43,7 @@ }, "dependencies": { "osenv": "0.1.3", - "semver": "5.3.0", + "semver": "5.5.1", "temp": "0.8.3", "unzip": "0.1.11", "winreg": "1.2.2" diff --git a/test/ios-local-build-requirements.ts b/test/ios-local-build-requirements.ts new file mode 100644 index 0000000000..d7fb8f10f4 --- /dev/null +++ b/test/ios-local-build-requirements.ts @@ -0,0 +1,125 @@ +import { IosLocalBuildRequirements } from "../lib/local-build-requirements/ios-local-build-requirements"; +import { assert } from "chai"; +import { HostInfo } from "../lib/host-info"; +import { Constants } from "../lib/constants"; + +interface ITestCaseData { + testName: string; + expectedResult: boolean; + getXcodeVersion?: string; + minRequiredXcodeVersion?: number; + getXcodeprojLocation?: string; + isDarwin?: boolean; +} + +describe("iOSLocalBuildRequirements", () => { + const setupTestCase = (results: ITestCaseData): IosLocalBuildRequirements => { + const sysInfo: NativeScriptDoctor.ISysInfo = { + getXcodeVersion: async (): Promise => results.hasOwnProperty("getXcodeVersion") ? results.getXcodeVersion : "10.0", + getXcodeprojLocation: async (): Promise => results.hasOwnProperty("getXcodeprojLocation") ? results.getXcodeprojLocation : "path to xcodeproj", + }; + + const hostInfo: HostInfo = { + isDarwin: results.hasOwnProperty("isDarwin") ? results.isDarwin : true + }; + + const iOSLocalBuildRequirements = new IosLocalBuildRequirements(sysInfo, hostInfo); + return iOSLocalBuildRequirements; + }; + + describe("isXcodeVersionValid", () => { + const testCases: ITestCaseData[] = [ + { + testName: "returns false when Xcode is not installed", + getXcodeVersion: null, + expectedResult: false + }, + { + testName: "returns false when Xcode's major version is below min required version", + getXcodeVersion: "10.0", + minRequiredXcodeVersion: 11, + expectedResult: false + }, + { + testName: "returns true when Xcode's major version equals min required version", + getXcodeVersion: "10.0", + minRequiredXcodeVersion: 10, + expectedResult: true + }, + { + testName: "returns true when Xcode's major version equals min required version", + getXcodeVersion: "12.0", + minRequiredXcodeVersion: 10, + expectedResult: true + } + ]; + + testCases.forEach(testCase => { + it(testCase.testName, async () => { + const iOSLocalBuildRequirements = setupTestCase(testCase); + let originalXcodeVersion = Constants.XCODE_MIN_REQUIRED_VERSION; + Constants.XCODE_MIN_REQUIRED_VERSION = testCase.minRequiredXcodeVersion || Constants.XCODE_MIN_REQUIRED_VERSION; + + const isXcodeVersionValid = await iOSLocalBuildRequirements.isXcodeVersionValid(); + + // Get back the XCODE_MIN_REQUIRED_VERSION value. + Constants.XCODE_MIN_REQUIRED_VERSION = originalXcodeVersion; + + assert.equal(isXcodeVersionValid, testCase.expectedResult); + }); + }); + }); + + describe("checkRequirements", () => { + const testCases: ITestCaseData[] = [ + { + testName: "returns false when OS is not macOS", + isDarwin: false, + expectedResult: false + }, + { + testName: "returns false when Xcode is not installed", + getXcodeVersion: null, + expectedResult: false + }, + { + testName: "returns false when Xcode's major version is below min required version", + getXcodeVersion: "10.0", + minRequiredXcodeVersion: 11, + expectedResult: false + }, + { + testName: "returns false when xcodeproj is not installed", + getXcodeprojLocation: null, + expectedResult: false + }, + { + testName: "returns true when Xcode's major version equals min required version", + getXcodeVersion: "10.0", + minRequiredXcodeVersion: 10, + expectedResult: true + }, + { + testName: "returns true when Xcode's major version equals min required version", + getXcodeVersion: "12.0", + minRequiredXcodeVersion: 10, + expectedResult: true + } + ]; + + testCases.forEach(testCase => { + it(testCase.testName, async () => { + const iOSLocalBuildRequirements = setupTestCase(testCase); + let originalXcodeVersion = Constants.XCODE_MIN_REQUIRED_VERSION; + Constants.XCODE_MIN_REQUIRED_VERSION = testCase.minRequiredXcodeVersion || Constants.XCODE_MIN_REQUIRED_VERSION; + + const isXcodeVersionValid = await iOSLocalBuildRequirements.checkRequirements(); + + // Get back the XCODE_MIN_REQUIRED_VERSION value. + Constants.XCODE_MIN_REQUIRED_VERSION = originalXcodeVersion; + + assert.equal(isXcodeVersionValid, testCase.expectedResult); + }); + }); + }); +}); From de244dd232220c17bafa80c70c19fe442a128a81 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 3 Oct 2018 11:58:28 +0300 Subject: [PATCH 099/169] release: set version to 1.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2be0b09080..e6947cc071 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.4.0", + "version": "1.5.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From da0c5da22e512f3a5baa6f5d2c76e43b61af3baa Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 8 Oct 2018 12:41:13 +0300 Subject: [PATCH 100/169] feat: set min required compile SDK to 28 As we are going to set min required Android Support Library to be 28 (in the modules), we need to set the min required compile SDK to 28 as well (as Android Support Library 28 relies on resources included in this version of the SDK and the project cannot be build without them). This way CLI will not allow building an application without installing the Android SDK 28 first. --- lib/android-tools-info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index a312f4e941..9697a1f719 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -22,7 +22,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "android-27", "android-28", ]; - private static MIN_REQUIRED_COMPILE_TARGET = 22; + private static MIN_REQUIRED_COMPILE_TARGET = 28; private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; From 8e885fec5b73c52b71e7a13d46461fb85960194c Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 8 Oct 2018 12:43:23 +0300 Subject: [PATCH 101/169] release: set version to 1.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e6947cc071..3c769b7462 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.5.0", + "version": "1.6.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From e989cf1e4a5198e8891e94282f8861b9af367b32 Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Tue, 30 Oct 2018 14:26:26 -0300 Subject: [PATCH 102/169] Removed unzip old dependency and added yauzl to handle zip files --- package-lock.json | 3965 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- 2 files changed, 3968 insertions(+), 2 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..85a30162ca --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3965 @@ +{ + "name": "nativescript-doctor", + "version": "1.6.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chai": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.0.tgz", + "integrity": "sha512-OuYBlXWHYthxIudMXMeQr92f6D97YoT9CUYCRb0BEP4OavC95jNcczjjr4Ob3H5E1IqlWqwj+leUZPSeth27Qw==", + "dev": true + }, + "@types/events": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" + }, + "@types/mocha": { + "version": "2.2.32", + "resolved": "http://registry.npmjs.org/@types/mocha/-/mocha-2.2.32.tgz", + "integrity": "sha1-3aDabq8hldL/gI9CoXJbGhnn7Wk=", + "dev": true + }, + "@types/node": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.1.tgz", + "integrity": "sha512-i1sl+WCX2OCHeUi9oi7PiCNUtYFrpWhpcx878vpeq/tlZTKzcFdHePlyFHVbWqeuKN0SRPl/9ZFDSTsfv9h7VQ==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", + "dev": true + }, + "@types/temp": { + "version": "0.8.29", + "resolved": "http://registry.npmjs.org/@types/temp/-/temp-0.8.29.tgz", + "integrity": "sha1-w83BE+PBOPkOXpcNUeQbC39iZ40=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/winreg": { + "version": "1.2.30", + "resolved": "http://registry.npmjs.org/@types/winreg/-/winreg-1.2.30.tgz", + "integrity": "sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg=", + "dev": true + }, + "@types/yauzl": { + "version": "2.9.0", + "resolved": "http://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.0.tgz", + "integrity": "sha512-KVQbjKvieCq6d5LqZ8KIzzwygF88fWC+l7wvPbRPM3OI3f9ZAlhaKUlk3kjiyvOMqopSTM7enjduXXl5B+msXw==", + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "binary-extensions": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "dev": true + }, + "body-parser": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", + "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", + "dev": true, + "requires": { + "bytes": "2.2.0", + "content-type": "~1.0.1", + "debug": "~2.2.0", + "depd": "~1.1.0", + "http-errors": "~1.3.1", + "iconv-lite": "0.4.13", + "on-finished": "~2.3.0", + "qs": "5.2.0", + "raw-body": "~2.1.5", + "type-is": "~1.6.10" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.13", + "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + }, + "qs": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", + "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "bytes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", + "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "1.6.1", + "resolved": "http://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz", + "integrity": "sha1-L0RHq16W5Q+z14n9kNTHLg5McMI=", + "dev": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "coffee-script": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz", + "integrity": "sha1-EpOLz5vhlI+gBvkuDEyegXBRCMA=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true, + "optional": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "csproj2ts": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/csproj2ts/-/csproj2ts-0.0.7.tgz", + "integrity": "sha1-drEJRoMlbponCf1cY+7ya/R6FEI=", + "dev": true, + "requires": { + "es6-promise": "^2.0.1", + "lodash": "^3.3.1", + "semver": "^5.0.1", + "xml2js": "^0.4.5" + }, + "dependencies": { + "es6-promise": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz", + "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=", + "dev": true + }, + "lodash": { + "version": "3.10.1", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "meow": "^3.3.0" + } + }, + "debug": { + "version": "2.2.0", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-promise": { + "version": "0.1.2", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-0.1.2.tgz", + "integrity": "sha1-8RLCn+paCZhTn8tqL9IUQ9KPBfc=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "^2.1.0" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "~5.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "globule": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", + "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "grunt": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.1.tgz", + "integrity": "sha1-6HeHZOlEsY8yuw8QuQeEdcnftWs=", + "dev": true, + "requires": { + "coffee-script": "~1.10.0", + "dateformat": "~1.0.12", + "eventemitter2": "~0.4.13", + "exit": "~0.1.1", + "findup-sync": "~0.3.0", + "glob": "~7.0.0", + "grunt-cli": "~1.2.0", + "grunt-known-options": "~1.1.0", + "grunt-legacy-log": "~1.0.0", + "grunt-legacy-util": "~1.0.0", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.5.2", + "minimatch": "~3.0.0", + "nopt": "~3.0.6", + "path-is-absolute": "~1.0.0", + "rimraf": "~2.2.8" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "grunt-cli": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", + "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", + "dev": true, + "requires": { + "findup-sync": "~0.3.0", + "grunt-known-options": "~1.1.0", + "nopt": "~3.0.6", + "resolve": "~1.1.0" + } + }, + "rimraf": { + "version": "2.2.8", + "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, + "grunt-contrib-clean": { + "version": "1.0.0", + "resolved": "http://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.0.0.tgz", + "integrity": "sha1-ay7ZQRfix//jLuBFeMlv5GJam20=", + "dev": true, + "requires": { + "async": "^1.5.2", + "rimraf": "^2.5.1" + } + }, + "grunt-contrib-watch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz", + "integrity": "sha1-hKGnodar0m7VaEE0lscxM+mQAY8=", + "dev": true, + "requires": { + "async": "^1.5.0", + "gaze": "^1.0.0", + "lodash": "^3.10.1", + "tiny-lr": "^0.2.1" + }, + "dependencies": { + "lodash": { + "version": "3.10.1", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + } + } + }, + "grunt-known-options": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", + "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", + "dev": true + }, + "grunt-legacy-log": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.2.tgz", + "integrity": "sha512-WdedTJ/6zCXnI/coaouzqvkI19uwqbcPkdsXiDRKJyB5rOUlOxnCnTVbpeUdEckKVir2uHF3rDBYppj2p6N3+g==", + "dev": true, + "requires": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.5" + } + }, + "grunt-legacy-log-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz", + "integrity": "sha1-p7ji0Ps1taUPSvmG/BEnSevJbz0=", + "dev": true, + "requires": { + "chalk": "~1.1.1", + "lodash": "~4.3.0" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", + "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=", + "dev": true + } + } + }, + "grunt-legacy-util": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz", + "integrity": "sha1-OGqnjcbtUJhsKxiVcmWxtIq7m4Y=", + "dev": true, + "requires": { + "async": "~1.5.2", + "exit": "~0.1.1", + "getobject": "~0.1.0", + "hooker": "~0.2.3", + "lodash": "~4.3.0", + "underscore.string": "~3.2.3", + "which": "~1.2.1" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", + "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=", + "dev": true + } + } + }, + "grunt-shell": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-2.0.0.tgz", + "integrity": "sha1-Gb/NeysDOGFzEkT/mUpruLxqsmM=", + "dev": true, + "requires": { + "chalk": "^1.0.0", + "npm-run-path": "^2.0.0" + } + }, + "grunt-ts": { + "version": "6.0.0-beta.3", + "resolved": "https://registry.npmjs.org/grunt-ts/-/grunt-ts-6.0.0-beta.3.tgz", + "integrity": "sha1-aFhA1KrRDFIlnH4lUCxjb7M+JiY=", + "dev": true, + "requires": { + "chokidar": "~1.6.0", + "csproj2ts": "0.0.7", + "es6-promise": "~0.1.1", + "lodash": "^4.13.0", + "ncp": "0.5.1", + "rimraf": "2.2.6", + "semver": "^5.1.0", + "strip-bom": "^2.0.0", + "underscore": "1.5.1" + }, + "dependencies": { + "rimraf": { + "version": "2.2.6", + "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz", + "integrity": "sha1-xZWXVpsU2VatKcrMQr3d9fDqT0w=", + "dev": true + } + } + }, + "grunt-tslint": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/grunt-tslint/-/grunt-tslint-3.3.0.tgz", + "integrity": "sha1-1IYDHFQS2IQsixJuyBRh2qmJg6M=", + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", + "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "http-errors": { + "version": "1.3.1", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "statuses": "1" + } + }, + "http-parser-js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", + "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "js-yaml": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz", + "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=", + "dev": true, + "requires": { + "argparse": "^1.0.2", + "esprima": "^2.6.0" + } + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "livereload-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.3.0.tgz", + "integrity": "sha512-j1R0/FeGa64Y+NmqfZhyoVRzcFlOZ8sNlKzHjh4VvLULFACZhn68XrX5DFg2FhMvSMJmROuFxRSa560ECWKBMg==", + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "3.1.2", + "resolved": "http://registry.npmjs.org/mocha/-/mocha-3.1.2.tgz", + "integrity": "sha1-Ufk7Qyv34bF1/8Iog8zQvjLbprU=", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.5", + "glob": "7.0.5", + "growl": "1.9.2", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "glob": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz", + "integrity": "sha1-tCAqaQmbu00pKnwblbZoK2fr3JU=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "ms": { + "version": "0.7.1", + "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "nan": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "ncp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/ncp/-/ncp-0.5.1.tgz", + "integrity": "sha1-dDmFMW49tFkoG1hxaehFc1oFQ58=", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", + "integrity": "sha1-g88FxtZFj8TVrGNi6jJdkvJ1Qhc=", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "qs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", + "integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=", + "dev": true + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dev": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "raw-body": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", + "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "dev": true, + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.13", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.13", + "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.5.4", + "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", + "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz", + "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "requires": { + "os-tmpdir": "^1.0.0", + "rimraf": "~2.2.6" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" + } + } + }, + "tiny-lr": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", + "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", + "dev": true, + "requires": { + "body-parser": "~1.14.0", + "debug": "~2.2.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.2.0", + "parseurl": "~1.3.0", + "qs": "~5.1.0" + } + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "tslint": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-3.15.1.tgz", + "integrity": "sha1-2hZcqT2P3CwIa1EWXuG6y0jJjqU=", + "dev": true, + "requires": { + "colors": "^1.1.2", + "diff": "^2.2.1", + "findup-sync": "~0.3.0", + "glob": "^7.0.3", + "optimist": "~0.6.0", + "resolve": "^1.1.7", + "underscore.string": "^3.3.4" + }, + "dependencies": { + "diff": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", + "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=", + "dev": true + }, + "underscore.string": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", + "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", + "dev": true, + "requires": { + "sprintf-js": "^1.0.3", + "util-deprecate": "^1.0.2" + } + } + } + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typescript": { + "version": "2.0.3", + "resolved": "http://registry.npmjs.org/typescript/-/typescript-2.0.3.tgz", + "integrity": "sha1-M97J6uhrju4yfdQZygUMhTyr1RQ=", + "dev": true + }, + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, + "underscore": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.5.1.tgz", + "integrity": "sha1-0r3oF9F2/63olKtxRY5oKhS4bck=", + "dev": true + }, + "underscore.string": { + "version": "3.2.3", + "resolved": "http://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz", + "integrity": "sha1-gGmSYzZl1eX8tNsfs6hi62jp5to=", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "winreg": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", + "integrity": "sha1-hQmvo7ccW70RCm18YkfsZ3NsWY8=" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/package.json b/package.json index 3c769b7462..2853ed9de7 100644 --- a/package.json +++ b/package.json @@ -42,10 +42,11 @@ "typescript": "2.0.3" }, "dependencies": { + "@types/yauzl": "^2.9.0", "osenv": "0.1.3", "semver": "5.5.1", "temp": "0.8.3", - "unzip": "0.1.11", - "winreg": "1.2.2" + "winreg": "1.2.2", + "yauzl": "^2.10.0" } } From 3142fd5579c0d19ff6f6c1f9a0fa8a177af3b990 Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Tue, 30 Oct 2018 16:00:40 -0300 Subject: [PATCH 103/169] Implemented needed code to extract zip archives into a directory --- lib/wrappers/file-system.ts | 60 +++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 12ddb2a6bd..8f54221e0f 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -1,5 +1,10 @@ import * as fs from "fs"; -import { Extract } from "unzip"; +import * as path from "path"; +import * as yauzl from "yauzl"; +import * as util from "util"; + +const access = util.promisify(fs.access); +const mkdir = util.promisify(fs.mkdir); export class FileSystem { public exists(path: string): boolean { @@ -7,11 +12,39 @@ export class FileSystem { } public extractZip(pathToZip: string, outputDir: string): Promise { - return new Promise((resolve, reject) => { - const stream = fs.createReadStream(pathToZip).pipe(Extract({ path: outputDir })); - stream.on("close", resolve); - stream.on("error", reject); - }); + return new Promise((resolve, reject) => { + yauzl.open(pathToZip, { autoClose: true, lazyEntries: true }, (e, zipFile) => { + if (e) return reject(e); + + zipFile.on('entry', entry => { + const fn = entry.fileName; + if (/\/$/.test(fn)) { + return zipFile.readEntry(); + } + + zipFile.openReadStream(entry, (err, stream) => { + if(err) return reject(err); + + const filePath = `${outputDir}/${fn}`; + + return createParentDirsIfNeeded(filePath) + .catch(e => reject(e)) + .then(() => { + const outfile = createOutfile(filePath); + stream.once('end', () => { + zipFile.readEntry(); + outfile.close(); + }); + stream.pipe(outfile); + }); + }); + }); + + zipFile.once('end', () => resolve()); + + zipFile.readEntry(); + }); + }) } public readDirectory(path: string): string[] { @@ -23,3 +56,18 @@ export class FileSystem { return JSON.parse(content.toString()); } } + +function createParentDirsIfNeeded(filePath: string) { + const dirs = path.dirname(filePath).split(path.sep); + return dirs.reduce((p, dir, index) => p.then(parent => { + const current = `${parent}${path.sep}${dir}`; + + return access(current) + .catch(e => mkdir(current)) + .then(() => current); + }), Promise.resolve('')); +} + +function createOutfile(path: string): fs.WriteStream { + return fs.createWriteStream(path); +} \ No newline at end of file From 1ac6241cf18d33af2c31d5f8356131b4b9fa27b7 Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Tue, 30 Oct 2018 16:01:21 -0300 Subject: [PATCH 104/169] Updated packages to remove vulnerabilities --- package-lock.json | 1718 +++++++++++++++++---------------------------- package.json | 15 +- 2 files changed, 670 insertions(+), 1063 deletions(-) diff --git a/package-lock.json b/package-lock.json index 85a30162ca..f20c8ef6bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,25 @@ "@types/events": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true }, "@types/mocha": { "version": "2.2.32", @@ -24,7 +42,18 @@ "@types/node": { "version": "10.12.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.1.tgz", - "integrity": "sha512-i1sl+WCX2OCHeUi9oi7PiCNUtYFrpWhpcx878vpeq/tlZTKzcFdHePlyFHVbWqeuKN0SRPl/9ZFDSTsfv9h7VQ==" + "integrity": "sha512-i1sl+WCX2OCHeUi9oi7PiCNUtYFrpWhpcx878vpeq/tlZTKzcFdHePlyFHVbWqeuKN0SRPl/9ZFDSTsfv9h7VQ==", + "dev": true + }, + "@types/rimraf": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz", + "integrity": "sha512-Hm/bnWq0TCy7jmjeN5bKYij9vw5GrDFWME4IuxV08278NtU/VdGbzsBohcCUJ7+QMqmUq5hpRKB39HeQWJjztQ==", + "dev": true, + "requires": { + "@types/glob": "*", + "@types/node": "*" + } }, "@types/semver": { "version": "5.5.0", @@ -51,6 +80,7 @@ "version": "2.9.0", "resolved": "http://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.0.tgz", "integrity": "sha512-KVQbjKvieCq6d5LqZ8KIzzwygF88fWC+l7wvPbRPM3OI3f9ZAlhaKUlk3kjiyvOMqopSTM7enjduXXl5B+msXw==", + "dev": true, "requires": { "@types/events": "*", "@types/node": "*" @@ -82,13 +112,13 @@ "dev": true }, "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "argparse": { @@ -101,13 +131,10 @@ } }, "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -128,9 +155,9 @@ "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "assertion-error": { @@ -221,18 +248,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -242,36 +257,16 @@ "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", "dev": true }, - "body-parser": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", - "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", + "body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", "dev": true, "requires": { - "bytes": "2.2.0", - "content-type": "~1.0.1", - "debug": "~2.2.0", - "depd": "~1.1.0", - "http-errors": "~1.3.1", - "iconv-lite": "0.4.13", - "on-finished": "~2.3.0", - "qs": "5.2.0", - "raw-body": "~2.1.5", - "type-is": "~1.6.10" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.13", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - }, - "qs": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", - "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", - "dev": true - } + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" } }, "brace-expansion": { @@ -285,20 +280,38 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "buffer-crc32": { @@ -313,9 +326,9 @@ "dev": true }, "bytes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", - "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, "cache-base": { @@ -333,14 +346,6 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "camelcase": { @@ -393,20 +398,24 @@ "dev": true }, "chokidar": { - "version": "1.6.1", - "resolved": "http://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz", - "integrity": "sha1-L0RHq16W5Q+z14n9kNTHLg5McMI=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { - "anymatch": "^1.3.0", + "anymatch": "^2.0.0", "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "readdirp": "^2.0.0", + "upath": "^1.0.5" } }, "class-utils": { @@ -429,19 +438,13 @@ "requires": { "is-descriptor": "^0.1.0" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, - "coffee-script": { + "coffeescript": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz", - "integrity": "sha1-EpOLz5vhlI+gBvkuDEyegXBRCMA=", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", + "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", "dev": true }, "collection-visit": { @@ -454,6 +457,21 @@ "object-visit": "^1.0.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", @@ -479,10 +497,10 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", "dev": true }, "copy-descriptor": { @@ -498,27 +516,21 @@ "dev": true }, "csproj2ts": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/csproj2ts/-/csproj2ts-0.0.7.tgz", - "integrity": "sha1-drEJRoMlbponCf1cY+7ya/R6FEI=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/csproj2ts/-/csproj2ts-1.1.0.tgz", + "integrity": "sha512-sk0RTT51t4lUNQ7UfZrqjQx7q4g0m3iwNA6mvyh7gLsgQYvwKzfdyoAgicC9GqJvkoIkU0UmndV9c7VZ8pJ45Q==", "dev": true, "requires": { - "es6-promise": "^2.0.1", - "lodash": "^3.3.1", - "semver": "^5.0.1", - "xml2js": "^0.4.5" + "es6-promise": "^4.1.1", + "lodash": "^4.17.4", + "semver": "^5.4.1", + "xml2js": "^0.4.19" }, "dependencies": { "es6-promise": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz", - "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=", - "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", "dev": true } } @@ -543,12 +555,12 @@ } }, "debug": { - "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } }, "decamelize": { @@ -616,38 +628,39 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", "dev": true }, "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true + "error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "dev": true, + "requires": { + "string-template": "~0.2.1", + "xtend": "~4.0.0" + } }, "error-ex": { "version": "1.3.2", @@ -726,21 +739,53 @@ "dev": true }, "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "fill-range": "^2.1.0" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, "extend-shallow": { @@ -765,12 +810,68 @@ } }, "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } } }, "fast-levenshtein": { @@ -796,23 +897,27 @@ "pend": "~1.2.0" } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "find-up": { @@ -855,15 +960,6 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -1455,23 +1551,25 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } } }, "globule": { @@ -1485,25 +1583,25 @@ "minimatch": "~3.0.2" } }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "grunt": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.1.tgz", - "integrity": "sha1-6HeHZOlEsY8yuw8QuQeEdcnftWs=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.3.tgz", + "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==", "dev": true, "requires": { - "coffee-script": "~1.10.0", + "coffeescript": "~1.10.0", "dateformat": "~1.0.12", "eventemitter2": "~0.4.13", "exit": "~0.1.1", @@ -1511,14 +1609,15 @@ "glob": "~7.0.0", "grunt-cli": "~1.2.0", "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~1.0.0", - "grunt-legacy-util": "~1.0.0", + "grunt-legacy-log": "~2.0.0", + "grunt-legacy-util": "~1.1.1", "iconv-lite": "~0.4.13", "js-yaml": "~3.5.2", - "minimatch": "~3.0.0", + "minimatch": "~3.0.2", + "mkdirp": "~0.5.1", "nopt": "~3.0.6", "path-is-absolute": "~1.0.0", - "rimraf": "~2.2.8" + "rimraf": "~2.6.2" }, "dependencies": { "glob": { @@ -1548,10 +1647,13 @@ } }, "rimraf": { - "version": "2.2.8", - "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } } } }, @@ -1566,25 +1668,28 @@ } }, "grunt-contrib-watch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz", - "integrity": "sha1-hKGnodar0m7VaEE0lscxM+mQAY8=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", + "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", "dev": true, "requires": { - "async": "^1.5.0", - "gaze": "^1.0.0", - "lodash": "^3.10.1", - "tiny-lr": "^0.2.1" + "async": "^2.6.0", + "gaze": "^1.1.0", + "lodash": "^4.17.10", + "tiny-lr": "^1.1.1" }, "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + } + } + }, "grunt-known-options": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", @@ -1592,55 +1697,87 @@ "dev": true }, "grunt-legacy-log": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.2.tgz", - "integrity": "sha512-WdedTJ/6zCXnI/coaouzqvkI19uwqbcPkdsXiDRKJyB5rOUlOxnCnTVbpeUdEckKVir2uHF3rDBYppj2p6N3+g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", + "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", "dev": true, "requires": { "colors": "~1.1.2", - "grunt-legacy-log-utils": "~1.0.0", + "grunt-legacy-log-utils": "~2.0.0", "hooker": "~0.2.3", "lodash": "~4.17.5" } }, "grunt-legacy-log-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz", - "integrity": "sha1-p7ji0Ps1taUPSvmG/BEnSevJbz0=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", + "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", "dev": true, "requires": { - "chalk": "~1.1.1", - "lodash": "~4.3.0" + "chalk": "~2.4.1", + "lodash": "~4.17.10" }, "dependencies": { - "lodash": { - "version": "4.3.0", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", - "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, "grunt-legacy-util": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz", - "integrity": "sha1-OGqnjcbtUJhsKxiVcmWxtIq7m4Y=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", + "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", "dev": true, "requires": { "async": "~1.5.2", "exit": "~0.1.1", "getobject": "~0.1.0", "hooker": "~0.2.3", - "lodash": "~4.3.0", - "underscore.string": "~3.2.3", - "which": "~1.2.1" + "lodash": "~4.17.10", + "underscore.string": "~3.3.4", + "which": "~1.3.0" }, "dependencies": { - "lodash": { - "version": "4.3.0", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", - "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=", - "dev": true + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -1655,20 +1792,22 @@ } }, "grunt-ts": { - "version": "6.0.0-beta.3", - "resolved": "https://registry.npmjs.org/grunt-ts/-/grunt-ts-6.0.0-beta.3.tgz", - "integrity": "sha1-aFhA1KrRDFIlnH4lUCxjb7M+JiY=", + "version": "6.0.0-beta.21", + "resolved": "https://registry.npmjs.org/grunt-ts/-/grunt-ts-6.0.0-beta.21.tgz", + "integrity": "sha512-LhcTFTSWYHZEmHAl+7jHUPsOcQ4LSKZWrNDo5FcyQTuTWs3x82M03I1nALXBZ4NJOvcTJkQmXZV8/l3W+wubZQ==", "dev": true, "requires": { - "chokidar": "~1.6.0", - "csproj2ts": "0.0.7", + "chokidar": "^2.0.4", + "csproj2ts": "^1.1.0", + "detect-indent": "^4.0.0", + "detect-newline": "^2.1.0", "es6-promise": "~0.1.1", - "lodash": "^4.13.0", + "jsmin2": "^1.2.1", + "lodash": "~4.17.10", "ncp": "0.5.1", "rimraf": "2.2.6", - "semver": "^5.1.0", - "strip-bom": "^2.0.0", - "underscore": "1.5.1" + "semver": "^5.3.0", + "strip-bom": "^2.0.0" }, "dependencies": { "rimraf": { @@ -1738,14 +1877,6 @@ "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "has-values": { @@ -1758,26 +1889,6 @@ "kind-of": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -1789,6 +1900,12 @@ } } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, "hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", @@ -1801,16 +1918,6 @@ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", "dev": true }, - "http-errors": { - "version": "1.3.1", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "statuses": "1" - } - }, "http-parser-js": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", @@ -1858,6 +1965,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-arrayish": { @@ -1897,6 +2015,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-descriptor": { @@ -1918,21 +2047,6 @@ } } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -1940,9 +2054,9 @@ "dev": true }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-finite": { @@ -1955,21 +2069,32 @@ } }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "^2.1.1" } }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "is-plain-object": { @@ -1979,28 +2104,8 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -2013,6 +2118,12 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2020,21 +2131,10 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "istanbul": { "version": "0.4.5", @@ -2098,20 +2198,17 @@ "esprima": "^2.6.0" } }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "jsmin2": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jsmin2/-/jsmin2-1.2.1.tgz", + "integrity": "sha1-iPvi+/dfCpH2YCD9mBzWk/S/5X4=", "dev": true }, "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "levn": { "version": "0.3.0", @@ -2140,14 +2237,6 @@ "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - } } }, "lodash": { @@ -2156,74 +2245,12 @@ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "^3.0.0", - "lodash.keys": "^3.0.0" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "^3.0.0", - "lodash._basecreate": "^3.0.0", - "lodash._isiterateecall": "^3.0.0" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -2255,18 +2282,6 @@ "object-visit": "^1.0.0" } }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, "meow": { "version": "3.7.0", "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", @@ -2294,39 +2309,24 @@ } }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", - "dev": true - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "mime-db": "~1.37.0" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "minimatch": { @@ -2375,62 +2375,80 @@ } }, "mocha": { - "version": "3.1.2", - "resolved": "http://registry.npmjs.org/mocha/-/mocha-3.1.2.tgz", - "integrity": "sha1-Ufk7Qyv34bF1/8Iog8zQvjLbprU=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "dev": true, "requires": { - "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.2.0", - "diff": "1.4.0", + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", "escape-string-regexp": "1.0.5", - "glob": "7.0.5", - "growl": "1.9.2", - "json3": "3.3.2", - "lodash.create": "3.1.1", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "3.1.2" + "supports-color": "5.4.0" }, "dependencies": { "commander": { - "version": "2.9.0", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "ms": "2.0.0" } }, "glob": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz", - "integrity": "sha1-tCAqaQmbu00pKnwblbZoK2fr3JU=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "^3.0.0" } } } }, "ms": { - "version": "0.7.1", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "nan": { @@ -2457,26 +2475,6 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "ncp": { @@ -2555,6 +2553,15 @@ "requires": { "is-descriptor": "^0.1.0" } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, @@ -2565,24 +2572,6 @@ "dev": true, "requires": { "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" } }, "object.pick": { @@ -2592,23 +2581,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" } }, "once": { @@ -2671,18 +2643,6 @@ "os-tmpdir": "^1.0.0" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -2692,18 +2652,18 @@ "error-ex": "^1.2.0" } }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -2734,14 +2694,6 @@ "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - } } }, "pathval": { @@ -2788,12 +2740,6 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", @@ -2801,59 +2747,19 @@ "dev": true }, "qs": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", - "integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, "raw-body": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", - "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", "dev": true, "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.13", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.13", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - } + "bytes": "1", + "string_decoder": "0.10" } }, "read-pkg": { @@ -2877,333 +2783,21 @@ "read-pkg": "^1.0.0" } }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -3215,6 +2809,17 @@ } } }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", @@ -3225,15 +2830,6 @@ "strip-indent": "^1.0.1" } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -3304,6 +2900,12 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, "safe-regex": { "version": "1.1.0", "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -3443,18 +3045,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -3465,6 +3055,17 @@ "dev": true, "requires": { "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "source-map": { @@ -3560,10 +3161,16 @@ } } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "strip-ansi": { @@ -3616,17 +3223,34 @@ } }, "tiny-lr": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", - "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", + "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, "requires": { - "body-parser": "~1.14.0", - "debug": "~2.2.0", + "body": "^5.1.0", + "debug": "^3.1.0", "faye-websocket": "~0.10.0", - "livereload-js": "^2.2.0", - "parseurl": "~1.3.0", - "qs": "~5.1.0" + "livereload-js": "^2.3.0", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } } }, "to-object-path": { @@ -3636,6 +3260,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "to-regex": { @@ -3658,17 +3293,6 @@ "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } } }, "trim-newlines": { @@ -3725,16 +3349,6 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.18" - } - }, "typescript": { "version": "2.0.3", "resolved": "http://registry.npmjs.org/typescript/-/typescript-2.0.3.tgz", @@ -3761,17 +3375,15 @@ } } }, - "underscore": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.5.1.tgz", - "integrity": "sha1-0r3oF9F2/63olKtxRY5oKhS4bck=", - "dev": true - }, "underscore.string": { - "version": "3.2.3", - "resolved": "http://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz", - "integrity": "sha1-gGmSYzZl1eX8tNsfs6hi62jp5to=", - "dev": true + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", + "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", + "dev": true, + "requires": { + "sprintf-js": "^1.0.3", + "util-deprecate": "^1.0.2" + } }, "union-value": { "version": "1.0.0", @@ -3808,12 +3420,6 @@ } } }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -3851,21 +3457,15 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -3952,6 +3552,12 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", diff --git a/package.json b/package.json index 2853ed9de7..8e69ead616 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", "scripts": { - "test": "node_modules/.bin/istanbul cover node_modules/mocha/bin/_mocha" + "test": "node_modules/.bin/istanbul cover node_modules/.bin/mocha -- --recursive" }, "repository": { "type": "git", @@ -25,24 +25,25 @@ "devDependencies": { "@types/chai": "4.1.0", "@types/mocha": "2.2.32", + "@types/rimraf": "^2.0.2", "@types/semver": "5.5.0", "@types/temp": "0.8.29", "@types/winreg": "1.2.30", + "@types/yauzl": "^2.9.0", "chai": "4.1.2", - "grunt": "1.0.1", + "grunt": "^1.0.3", "grunt-contrib-clean": "1.0.0", - "grunt-contrib-watch": "1.0.0", + "grunt-contrib-watch": "^1.1.0", "grunt-shell": "2.0.0", - "grunt-ts": "6.0.0-beta.3", + "grunt-ts": "^6.0.0-beta.21", "grunt-tslint": "3.3.0", "istanbul": "0.4.5", - "mocha": "3.1.2", - "rimraf": "2.5.4", + "mocha": "^5.2.0", + "rimraf": "^2.5.4", "tslint": "3.15.1", "typescript": "2.0.3" }, "dependencies": { - "@types/yauzl": "^2.9.0", "osenv": "0.1.3", "semver": "5.5.1", "temp": "0.8.3", From df0ae36cc59d08b8e86a76035536bacd94454f10 Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Tue, 30 Oct 2018 16:01:49 -0300 Subject: [PATCH 105/169] Added tests to test the implemented method --- test/wrappers/example.zip | Bin 0 -> 25240 bytes test/wrappers/file-system.ts | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/wrappers/example.zip create mode 100644 test/wrappers/file-system.ts diff --git a/test/wrappers/example.zip b/test/wrappers/example.zip new file mode 100644 index 0000000000000000000000000000000000000000..9566af97103fe0a894e8aa52d04a14e471b3f34c GIT binary patch literal 25240 zcmbTdV|T7yx21i>wryK0wr$(CZQEE$R&3k0Z96Nrle(X(R&Ceb?QQ$1dOyth3(ncc z(R&}Kf;0#yDgXe01ds>l%3g+=i@t*b04W#%03`qy;9~0R!eD4;;$&}WLT6)dY-mGg zd|11Y@rcuxjm}OcPDNsJTfKokMXEEt1yeAdl_b*T!F_r~mh?qIz z5CNebT~BeS7Ft4>&u}2FM;G`x1oS6~m?x3Qos8Y!VBLB~y(`I-6ASLC6O$snPCB87aarhrIMHHQ^#|>)zC>g1f@}qaOD#6n^O)AHganG zaz#DWRy~VEeF*|^7VQ>gqq2nUIBWo<3)R2G z&4=9AC}oB|ltQk7B78ex)e=|FZmjQ5Y()K=ER4e5-_ zc71UO+R3q`G*_9ZJ9+^5VMK05NeYtY+bhxtr@VaKJIAR)mNN0vz{`fKr=VhiQ<@uc znd%O~yravdYX=OlilMyjl$)_gu{EBzs}W%@=veR1dhFYe2I-L`PY-Vn{c{<0&h>m* zYqX2}#=S!(u`zV_PP0(Oj;?8T-*j{Hwd00Z2GxS4mi!R#i)g{~(L}t}XisCP7sJd4 zVcS~r?v7G7zw8Ny#iA9*`rVSHB(2c zlIdTS?q079^2JnJ*VEIbCgql7-y_*Y=8IcX&r*iu&fGl`t{H(%l;JvUI*tdYeXeDW z)lL+Dp?H5zBrIt!Oz>c-;)-84o6okm(s@{{hr7@9)LfgSBl-kvLaVmml?hcKzl6@GK%%foihJo<{+N+ep|Un2sj35Jx_^~<@|S%n!&S``bnP|6R-#$7 zvFg_!8I(IJ;pozl)%>Qgn}#9Ull?eiV~Eq{kSvQNGb8^vT5_|{YmTSHwMj@AC^F^9 zXK#07>2_a~>gnQK_xq7y?i#@khN;0(+K8<=md|BwWrWEz*%vBwI=f=bw@zYVEA6kd znP?*@K$eXN!wOi0H-mlee_<>qb|8;pk#MNlcGwB*_MNFMP9)&TfojPkvb91VNUG{+ z)f4{}L`VG?CvadAVKfETkbg(I^mW~~8ovANPm80NaXiDP z&k`Ez`EBuI(YBVpP#aCw@f}9tKWVEnTtT$zKcZL&0|3zeKWHnxt)atztFLO(&Km-- z-wZuwi$p|Ftl3Qn`1zSB3o>Enj{=b}a(&=9V}*-9dev^WwM?Wl#kiQ-3onwDtMBox zPlu!tLN^UFUAz5TFZA7x9t7h3Uw1rNF{h)wzxqGFIiA&j6Fy`3waM}ElHxxkS)j;& z+AB7RNj&Fzr1S4kXi)6PpM)NQtsfp5b?JcbqwaR8y@Pz#hk{x_KbHaU(NF+FKS0#O z!s)ggePNB(0T)5n&n)I30f9*P`O8S=68T!Zh_wUrbPBC?9Y7IbWH=x(nh<%$RdxX6 z9qd333^9JuwG``UjQIhKJIw~9zKDpX@hAayaJejef!WvjXSm_4vH2r<;zc{vL|bYo zxsG-tBw~_iQV1;vGqBe6z_pNuMR8+x>}dLt#;Zo;b+24%&&Y(5rB zRYdvJ0*q5o>n$UMX-PhY6Dpe~F`vdgCFJ@UV<8t+X z$93P*q7EkZl^`d~y8Nj`vkk1KiSmA*#=bVXlx1 z3D;b;pirsF2H3tj5^REn{-ir2GaWXe*J{@d-G!QcUE8J?b|r4B+hCz-dELj3U>>;wS*d&lJ=CH?$3(_K#lNN7*Nhk)SL@~o z9NUUUYFW;yY^19VW*xdusd(qoPBGl?EObxPW?ITl{F>b#b7}(M$5k?K8V+-add$>= zn1>ezI2llvhvc)&6WLm)2j|?{EUF(J9*o>-qH0^7QQgJeBe7uS2fnC6lCN1hY9+hq z^+H^xA-qDd>u3#8KIKs(&94T`N?! zX&U$##=X2v6w*BXe}Mku=_dQ?%Cfc6p)37^MG1)iFIeRAzpw~hbyfRc=f7Z4wYv5{ zScK{q=MR>jJ`qspvNmZ}3&l)vrDS8N;C%%cL}(HjwV_lZq4E~{`?DjQxHNpn>s@Cf zeR`im!#~f8qEu+^GW`!L+?Pf$eejmjzR7$~my=TMYvrS5NhKDrE4uWb9R*>PKSUyN zr?a)g*i>iRqj)S@E8ZZ{i0*~6;0>|J1nX6bwv#(W83$d5iJbGP9f4cN_%w7U~T&jCk5YH=%D;WoN{~%6%_;# z9;6mV`w#;`*qgWIp&q{nY$zIZ; z>sS^=%&`2Sd4vy5D$BN9wl%BU-c~j-U($3n2p3{BZRq5bUbR-*>#3Wkl))gpk!*0h zHV}7Jef;9aj^&0+o;f8TCTsQi{)bE`VsOufaDs!Dg*Hn%@b%^+4MI<2*aVlkp)VCB zh|FS0Py9SL-9#Zwm3&C*d-CrqI;fm$ETvYw&r+tA`-#J!q;^bz416z1Y=QtL3g#cV@>%LhTEv+i<##V^*_18DHBOUCA{d5vJx z#y`K}_wbka7+9+K=r|xv>KxMy>(({q#MFx?%#fBu`x)jp&ukS=^07aVWlo%R7!Dk7 zsVgtaDk#9GnOE`<|H^aff)@ z(VJtYu=Zt@$bAozKR1SdhcGW=22F(fBzNa>G_;4QcN$nZ%?0JqbiS-H1xU;qkUOP4 zGC33>3zSv-);$6QCv$>!e6Vgv&g@|xnAHE~550&fKa_8Cn{7)JSR~!O8imwSQ3(%R zRuHY3HxlC@b|y~uGK*8IpuH2WXTVYr)^D8Fv9q>;1IOYkjItnz1**1bTB+x4?E}#> z=ztJ^47vzgN%2*TD8mK@7q^S17(w$N*utNCV{abFxALnj6#&5kVHh(qU1j5fHPGPeq2v9lj>YNiNjL!J6$m2UDfu?BSBhI11LD zBdLh>z?_Eyu|q%mmDTQb4f-albgq~%##*^@k3&Q9W z(fm2vd%arc>=-eXN}Ma*XnQhZKYb@!yi$soJ7mLxnjXCb0R|W+z^uhA;^lAd$eNN& zZhzTD8X)q|;Ai#oITx$a1O}ubRi>Y0db`nVr3i`i=ocl#c!g6VRs+XGp>ibwN6`fE z)1{a}g07Q3JCtcVTO4p$-a0<=b-Cp8pgiTwnL zhMuPqPeO?KzC9O0t}BO=-=G&$hOrfqU!*5wsEgL#RrVgdf!(mudOmtm^|QZYlewIs z%HRO4$*D;X){rCRIo_i?MQyFs2U*h~yscR6rmmndYoN(MRlW%V`jR#iaj|jS6h`xi zF0{0)v54lj?Z9G0?2HS1wc6SB{xNBFEGuq^kbFZxr)%0?yp=;Sy^QqqBbgS{FmVuB z&0B`Xdt%eA{^|*%k56@$VN2$)b-GY*@yx_fKTCwn$WZ$BSs*n5p&)$-B>%^(o`?@c zn0F(45lgGcJlhz%g!syChVa)_Kl)3qWx9P*hHvQ{-wr=7=h{s#x7Eux7w6S;{N{Gt z@zrenP|vW4^Fkezp%B`E5K4S~-2>FT8ck4*9+bMI zho0v518P4p?#r3NlbVf8x&+h07gFTqsD3vOCbpe*TlIcR*rt+$b_9PwX2v*E=l-8I=lheGMWyfF!zFn_eoa!^JdAr$K{OYLZszMYcBX%xwy#oZe(G;wraYa5E;d_pxCzh4UI0_1Ungv`&5_3l;%a!X^2BM9OqdIY@nslc`yN4S?1s=XGMkod& z?`NRj1mYB`inQp;)G`smRrQSfuLno>a2^@7I2vJStk|m=n-d95Ia3+EC+5}{7z%4y z?N!o)h_>GTUQOy>v(Qd>hkyD1^F%RhLvn`whk{-Hp3krD_|4$8 zy^hKk(D1Z`4FyDRen=KMnK}Vd&y*O8B-V$m^mcP@%o^UeBim3erFsCt^S86Kv-f9@$~yoX;aZFJ{LWka^=P4t`Z+q5uRc^UQUBgLuGSG3^(|G%0bs9JawfYHbS1X=z7nQhr+mZV7$H~=`2 zeR>(&{Yqp9XdA3YaHB|b!V8t6@+Z5k#S>P0))2zgrI)R1u@Cq^4sG}+zV0D&QEAR*I!XrbbJa%XnJzg7S3?cx*$;ojJ z0XzZE6uA#&f**^8)tPR3u2`7& zR1;eQ1yKG8OOY+E-dxcB#N!r^G+y@e#?EXbqv$h1`mcpZ?HraXvXO(O23PggP4yfIho6N2u<2h+`iI>+^!0OO$_rR$T(a%2G z_vxjxbWFJ>`~wxxLG4b1{7~_(tq<9#2hXo3VVK`LI9SMzt>*i9_`94i6txsM(eyq8LBF9G&wzySiBy)T(n;|t>9rHR(|Cj7ZwI`gp=D@NfcYF z(9VG>=ucG6V=91b2IkwC3k<*cE#aFv$QQ$@BrIu8>#E(tVnL`BLf{=8qvCow)0M%g z<#(2(AZ{M9HxRWA zu;XiuoQiI+dZ}*0T4?Gw*Lu$NBH6 z^}qMlSN~KF*#A%~Y_Cxh7n*`0%0lG^NxE8@LTZzwS71v;K?Fx9cs9MBm3O}4gn#ed zwbw2o5Lw5LWV(c8pC3=|3l_rf8K3+;@Qp1rK4*xYn{j-Cx4MwT+fs%4E4+B!>jaD5 zeAc{vM8$Om7UvG{dm_%g$xHaeq=RseMJMtQ&CDxyl#_OX&>ID+Xmxtf%;~ZO?l^EZ zGbC#1Pr3(-A1!LG?x#ygA~-Cg28!J`rD_!CpbMIX?!w%X=AhWL#xZuj^eBhsAlE7I zg2@;fYO$gGIUI#@E)k?Qs`Q$%Y>q#P#1Eb@MaVJnFO$V!NVxptt7cc1xay*PXulUQ zzqx`bY9>)@kmO+~OGJ)=CY{!c7mzNK)aaBLJ5|H2;NbNv{e*J+i%F0@D!SvSaRZ)~ z5e)iy5ZY?@l7QPEDJco)L0GYMJ^}$vTWGEdR3392S+@PkSHF&x&Z#s&{GTkqb;3E( zY+T^1gi=bNP?$^mn&f!nI~X$*I7FTV!)MA*XG>COJZ4c<5V&uw1C)TJSd0z@2(ecq z4_^mFea}9KUjTx=5HbqBY6ZI^umj2_^T377Jkx^qWF;*h`X9m9^S4bOtED@ZFJ<05 zX9)a{al0?GM(NGw_=;MV7952uOsX_Q?to?ODJ|=2a0`>7jO^sdLN&e$_&xc7TK#R> z7nDaxrpz@a$SsC>0vYP9xGsUnfR#eizmK);h3v4(*nJ?gFhD`bFA7$p%K%dI*F|k= zMBMv={tJ)Rq50I4d^ht7Q*`OHg9aq;(p38N6LP-$qk}6`&Ify_>I8l|_qLSzKGL`! zwJfNWGpe{-wIm?;fW^=^wb(m0UqW;xdki|&Y3$OtiCT)))oHY>5hZVN>@4R4rgTcL z3`v;v+Zaz3M{vvH@uN#zEZ#*WajQuR^h(R#CiiLus;5rD!IOt>**^YXz?Zt6?ROp1 zuvd1Xqke%6p&yb5HvO4s)JR6Bfrwx-VVu(7EIHlf)`RNFnv7IK<6w;Y9w~VR!m(>B zZ@+M1f6qR*914;AV96!TP1Vn#0Y6m0p9-8~x_zFjl#WVyv>6Q|y@@5F2;O9xld1kg z!CUw}+?;=bkDbYV@DENz7;_F<=kl2h`NkYi-BEpFeHoBP6mqf5ekEFQGBxcC=oCgz z1(idgqd?0MhMdsFX(p>CE$;jN(g{%o_|tpg);SRRvdR$7^Pv>wHd^zl;Fgxr$7Y^m z#{D(8LuL)RV0hI)WEZPK>+j)+2i4PF*G8c47i*bT^}w-fR&j^4wNHeyYyQd|*M6m_ zDke+*vN>v$&X#QU0?`a|WzJEHQl+3x{?sz6@IpFvjWjAK$mfY>?nK->ju8iSLC$nJP5g-JEh@Ku2R0w?F8%Z|sAe!{tQJ^?YGqmwW>S`Xd zL&K4|kh8|lC8N=-P+puAE-2$a<&fH;pTx)wPvgp8wS>2;*i+|yXQ$#cLt?fLSs`|H zdn9QDyjkc|Mb4%?9nDS{3CcyrB22PutYnt#*5{(e1yzKn`O)U=wQvE;?`MIqlbekX z7r!aK%@MIMl<3n-Ru z&pux7_6+QwOS*fn1{-xXC_G`VCnY-`dswLZQ~iCoa_hmq*&23Ne#1L@CrUwdWL^Xb z%yPe<$9Xu6~W**1hNEDN&Zm*GXT%dHf`o#N)IvFh5hg=m+c4+g zWV(>CV`*T8Dqpc-e$IA#|Bs0GUvbHwJMllq|Fkoh=l}re|At#jd*}bZt@po1(En<^ z9d85Vuu-|rM?tUa$VLqEVp+`Lpkadr{wcjv(Akn2jQ=UUx&P{>T~_I)p#_5tDY=Y# zU$-CL&0LdZ1^$YHC~@~}D1i3)Q$xir(+|LH+{4!E2KJ^X9txfPW0)oqxX(P1;-}<{ z;8Srjo+K*f?QqebEh?i(qWH52wO5=WsRD|m9qepvyLSq(OVx3j)>$o=p)M)bU_wae zsp~@pzf`53MrJw`s+-ePOk`XFD*W|Y4i}w+oGo%We?)yvWto`A&s~x%C32oV)!8C zrl$3t+M(!jp1m{rhO9VpwX*nQzM)PbwfF_Oc zehQh;>);jg2=?b$`FK&~t*K^9T)Oll76{yVobq;z^W|FC3wKSPj)m3cDBTG--t@viEf68{$~P zHcK(nI0mPjW|$>0kA@`vfTk0z17*u_nt^Y--;X;*iX zwkxkw^P?(r_T<%btE!`5xa7ChuWAxkE?xDy+|ec4J_!%n5N_6%bZ$#c30tm*fhRUq z>p0LCPE89|TpGOs7BMm#{@b1Eu-vr{ejRxeQr8zJid_pm$?596hq{~LnG3GYJj|IN5br)@{X}QY%T4ZKir?)VPw92B(ABeD99PiM5}d2ijMH1p^rCp z;}iAO5zqHqq0?ZerwpPyc6Y*C^Snczf+yzkEcPkK?9!i4(ufQ{AB9}R6Ypd!-~H=@KDRx-fWVU^XCS~s^b=Flkl6>+TQim zvAxfFPvZvtLGchHBh(DDt7N0@qR~1F20p8f7Anay9hbdUF{5(dbnf@qZ%%ICNil4_ zC|xESaV%qw;G8prKb=@b%hK^E5~rX>Kkr{R0+S+Omw2(p_|v=cJMi#dF=F_vnhUQC z|Jfg_4(3FJ0RsSM(EmqE^lv2O-#cYp`AtUDF9yG1yrwyz>BZ*c60rP=$~jh9@39U6 zkT;8@w5Wow7hV0%dg)0}?~ITZo}%%)?o-^&7cO5T1V>d0(HXDN>}^uZDKA>8ziL`C zg-uVsnMM3ssyg(^)H4S@ivDetSmv(vRV8<&1sVn(4|_0L>jl6EZekP{cb#!X-tL04)#W1YMT6K8e`$g%9BSnNubK8QLz9 zMuN~N0G=4EazMGClmZh|nnXW15|klnkju6}Y&Pfyk5n^6mq3tEms}P4#G4+Iu&_ng zESBO4>mlt@5K2Nc4D{$Ygs*KhI)lnZ1uPykTtbd7dJRy`3-;P=hz}$qY4u+F3JJD1 z>aVC;AK+h|%nKcE{IWe$A9A{w=-7j@a>XdzDq6pKhvpWR1~bgWSy2KaofPM?mCv`K z6BaT(AsV@{YqqTN%8{ravk<+Y9L`0dRb0N|H=%DT1NNG3>Zlk(_#$MVP~_au{65iB zk#CA;xM9CFLd_zmA9{;}LJzoIg|v+?@~P;K&1^YryVpy_N|8I8#lC)Mqe)eTHdmX^ z+!88qj1MIUcx7K{*I1+^(>7@V^F1Kk1{u{TZrfa{!i0T`r@0gkn1|`%v`Y5d>h_j&fYpp^`RW;K9yESgw zMmb9B`@@cpiOR5g!%}G(0{CcW%lrE7&Qar^prw!ZvFMu`WPpDflK|oD21}W>V8B9S zKx7;ech=hZm(>GDC0o>@*2IK0OS!hHpn2`gy_|@36#spLphO1VH*xcMWF+ki+?`*v zVV@jdnh;I{kZA%0W9LjrzLgL#boU>X-^K-&;h4ZLPg(sx6r=@w7KIsY8Py*RPBQZ43o=n87x@v9F-?wCqEiJ(sw<1iWVOZ>vgM$Qcm*f4 zJ?c$5D;LHUAj4uyt{VPro{`z)ZEzeMF%VMV5VF%YS+md(dle>_SG6p2x2;v)S_}+r zb9V)=4nb}9=ZHkIvf|)k)V1s~!E5G!B8Ck=RWfM^(tU}5ht3Dxbtp^D{kYx?w8 zLq%Rrfl*2*6GJajDmdUcsGX#lZu{4_@7%IWws*)sLNPCua01t$n6jvth%lktJsAUA zLKI$&LbjTRqD4bQ3_!$(3t_k17VKFJ)Ni4Nvo^O z9tq#xP8W=CZh+(bH7xZ5c$qQV%5?jIxs0y`;4ol}_t2zV$`<`iB6N}6pDI7Fo~1{tEA@V>c6Z`D`+i-{{vmaEpBdOf98#FgD6$!#&BnqWt z*+%9o+;Qeu8**J?_l3DfcJ06c{89(4p`q2CFuhOJNso2)h7-cxQt8I;s%U=>Z*LSM zJws^3YvgK9T3UTtbf@tre>^xow4bW(rRvV^c{x1#;_&=EI!+SoYaA~5`3CYI5Ak2j z%18r1n*Qezve*Lvi2s{eojw2Wiak6-^-Yd@Z~xGlRd>>tpum<%xBaK<;{e-E=|J@k z+uc+?#umtexSVD@!uV1xb2MneRJFfTw)^mJl3s({89AHuX?J%OF({4eaUcBZuS4T=QB# zt7AKiZcL7cLrsZa#ESill-u2|L1c-^MadeNJ%1))hdl`4aFi(og%o{!VT!gGMYgZ9 zgJyC{l5WQ1KdmBw&hbKF6fKTt;32@!?d)O%Qe!)C29GKTk){6dN~qHD654D@%b z$x+`=z~>N#zFlGXdih#Z54V4=LMUp=l|2>@8Z(2>Axzj@eQuGXAZL59sE)% z{^eea=wp6yB$7m7CdWri@#Nv^qsrL7F9HO4aWsUWI|`9}pFK2Qhex#FZg@6YE9f3T ze)1haE^dH+GtlGy&C&)d`m9~FNXGD;+DUI$!0QBeWy1TDDVOd~>~pPHq}_mfvn4g% zs($Hg&++UCez~pWp3QOUw_=_On_5Rz9i#G#oaB0+Q%+(twk&y0j`8`+E)a6c6nvpz zV(lg9;ze%AO7s0uQ@S_}4FrA$>V;PZ1@X{E=Mg9~9=UL%-J}O%<#2(+Z<1GK%aP_r z3W?;VAG`1>L3MP4Se5m6>$B6D0V`?cs+Wd^cWqD@KHH#BA#j(GZayw;07ikvypb-| z0QFN7S4NDLw>Kx2DwDmg1t$TB&`M+Oz!f~RPCr3tfJQtNp%xEG6L1)c1PnNwYQb&N zQbWP8R$wa)%${VgQ6FM#Z9fnv53Abkr89+P3^#1BLs}P-7|R5Zw3=Byund@U@!uSI zIlYFXqai#m3W@-uMQy9&qNg-&igUKSF7S}mw0vtI-dXlp-gzBS=^&4^5MTVvt59#s*IYy%kc_ZC6%fm9GrHIhcLxHIIPl>HdA!K?7><9{ z*TKrgn4W8WC z(Jo*}YH8et@KaHiAl zxDqGKsA-0|Z4?an83aO@RfD9-Qa|#+jI{Rc?aCB6`dMLijB23bJijH z&C`~%%+rnG4@AI_Bqe)hcIjnG#o}80>XA>1oXsRr#hp|^(&KTm119ZuhpXJr{=g4J zV`h}OYd#1eSjuqfc?=c~HE7azN-cKagXi(;2mYJM&65jiO4GNe*gU%xnpy?PBb?o^ zRnEb+-`mj=kPNTXFGoBo`#mXEGQO+Yop5;70EupA$ja33|Gu^Sim&LHa7R}uyH-17 zpBbJQr8r^kxjwkU>9gGUqBPL{b2GlaQ(4v08R~(&c*JoBKPsvAO-(x?k?paMIhE6z zri2~{!?YO#gH#uAad+k>$DM|Yf(b1xAtWfQR$I6BNX76)m_R)j1Tzve$npW&1hbz&+^~zg7=)Vi`7jy-J+u*=3FU|8Zh9S~qaqm4@6|9MG5Yv1xpjlR@Xniq2BUCe&T2Y|Dc!TCu+edSRW_OskspB2?rh z@h*ADre+d?&{B*@1j9dBj7bQrKRIN0dK|*d|LhnmYK;P!OM#qY_eYwAx^e%0m8KN6 zBNnmg10I!+ekV&WS$XHj7&ZYN1O)fYESwt;U5s?;MCtZZFfqk0c@1%y1Ho#npi56= zF+%SsRZN9#AtbsN;hGLzxSXDL(Z&;(tmW17N{M^-#^d!C%1q*OHsbG69sWLXoofs_ z!BF4@9SSe@jTgeqe-PrQrAv)k(mGZFVR4|t3n02wOUK~cHXYI(Qhnx-IxE&?4;`rL z(=*h;S$iWNP-{W!EI#T-|D~zh44KH+mSZ5`Wn|A2%&HO}7U~7E^HkDpS9@_+1C7IE z>N3?C`aT}^wWY_u&6+@E$A-|=HyhlZW!@enDWOv!q4f@@lTD6@=n z21=Yb3qf~(am}V2lSH}l!n^l1}4)1NADWdZFPx`Fmw`&69n@&uXYrE=N} zV@Hj@A&5oKBWB=_6MCq%O@P+U6scrLY4`~_VR!MRPov~+W;CeDH3&|g)9e`cv0iPU z*duqygFX3*Rr!&>SrJ9{?1I!p4gY=ML$va{ij&^rJvyd`LjQ+juKYUZ z0nU84lCN`=gcXqXo~p|qYig8IRpmgM2+T)&AImAJv85&FBF9XeMJNV%(?yb}=`A6xtx3&3 z8Ie-M)jVcHLEJ6ba274wul7~Zbj)uxYUcg{Nxk0Yy@ylJoR(~N!H@9Kg1U^R^Em>w z6X#mZ5s+zet)^6$H*F_$L}jtV5FM^MLbn0{#(WUVA`NhFdad)A}h_|dYxikQZngdGc9o6Q?ibmjx+)nDv-zTd9ZY6)3q51x*?cy zNF)sSN>aFTvRe=$KaW9}?u#}Rih`D$(HBBT!e&ClJ$VTy6l8=?&4nE&Z$X5+V-Cznb7r`mp%p=KOUnXYzEC*fo=f}r0w z1q;+UsIO07SdibqDkDC*TXIkxS$w%?a-;Fzd@5{cJ_|hQB7?p(g|2GtaPC*NY<{JD!umgp|?rpGBdTLHu$06Whet-Y(UdmD|r~tbWd& zs5Mt)h}UnGzRJIdf>hA1pr3LA9Phra($2`y0}(ttc)Vc_m_@E&b{fO#lrvF9e zw8g}~MZj*&0si+#y34eWTbg{sMqLh@&3{A$mq z89lXTcz%m;f%&$P8Ia*hVgi9Wtk`7~q|sARG|g{`aQ96KLh?IWChWSOyr;`^tBi^+ z(^Ovd%*uWEv@YYqyK&lxquf=Uni#$BNmqH4`Xp5Kb&DCTSk#3>C~-#yKK-mi+VLv_ zvLf^I3E%BDxxu@ZZ?Br^*&I=7aU4vV+~Rgf*jH!5bS#`U4>#&P1mpB};laP_LMp)H z3>X^gi5ic8F6qt%C)rEZW&FDyVxG_aQ9GUhM~}j$gd`9*0(AX1u=@?=W1hs25+cU=BN+WN|d*f@R_`VXzp+E#a z+7R615E8_M+VHc4OCTIJXR|qfk9U-5m(!kjKY3e>`S^G_6q)bbwJ1#E+_uQf;&@VG znwxG%&?-#7CwK|A)8nIzsOH2^kp;SVQ*=6kCOrzf0OJ~kZIEt<$SS5YAQ6)RkqzJF z%H4Om(YO7U=qnbh^l_4V5Yvx70*2pM5s1|T*XJIF!*>_sl=}mTw~u)+y5;am$eg$B z$V}&jsjBBfA$rvboiI;tLKEP7lDNio^jI-NT$WnNwH1V;G=6Ja* zlnL>5J8w$=;tT`+XJsb%U~wW-!KdfBeJ*oq*1ZpfU|;hQUiMTsCOY5kMKV3%uhN^_ z?*oe`aFO4@mL}%X(nW7UM0gb7=E9_Ey>~h~%^Wi!5B|<5&lftzUt;vG71;9fnsnv& zY7Dno4ME|q!L6Z_%h3c*EHwYDEi+V3nO+ano8ZoAD3(}4x{91|N%J~`dK|g(yW|wj z_YcajaZ{lX44lEhfJbRz?=bdG%RSJO!-uBt-pV7)wI19E&@!rC-|daYp%@?`_i8Jp z;U`0BQq^jyJ9uV52|7O)dfkK2b~wB;;47wM2oh`n^|ja&Y?%&%-vyyoEKI2CMr<|O zNuKZxz_z!feOD)_?AcYQflGsW;+|%oOxWPkqG!S^Thv3Q(i+hQRSm_6&P6*KGx^Vr ztXueG+^dT2UZZw~GoVq*@KWWkl;|^^R^$YoeQf0Vd3xxNy>1}fMk~yTypjo9vrRFK ztacB-i;k7w^(3l84%n{|ZH>nEdS~uGgc@H-ihaLK?CoxB>`LOsk)-!Hijgqx?e1Ln zO8mrR_@ZqJn?L@SJ+%do_DTX+06HeH&3PIv z92wml>$t0D^3MLM=6|>SeA(12T+fK@m94G$;l!Ukrg?d(y1UzjBM$+4LsY(<%Sk_f4PwX}3khS-kgZ{KxBib4KZGydx?g&L>G zjhW!xZ2;3?F3>YRx(hqz?fJ74*oE=|KEfzDz!O!7B543V<(vNNfpk2c{>XwVan>>^ z`>!DBWo=07{p@lEKiRlEymLy&rp)BP!Do7&gL^JlAHdtC3PiFWNU2ViN&x}ythWMD zA%bb8!_u+DbP+Pt#N$uvZ(&bv)ahC&8^FqhBYpS9C~66}dh^tti{CI5;VSm9C; zpp?i@F@Ac0BsRboCxFTgAYF{Y2ck?>1+Zgbo^MAnon*EYLkd*O1L0!lL;+G(r~&6t z9sus3BQW_Aur-up*4wFt5krAjNko$bP2;G5lz1jsmY)0sbf|l_P)s& z1mwfu{qc4Zot>vXKkz?umyckGJXne8D^ui}5#-`Lt9;$g<7eFM{r{6YjFenc9Tiww}@8Y9%C3UHqH>W@i#HT%|5VlEcI+TXGoT`qC zpE*gf?A?$6`SV(KWzy zG5HFE1~|yu-cHUbKvA$&IhI?POi3%&09=8}4!}V3XCi^*qPv`m#`4Q2iTpoNdovYK zPn6Uq6i#HYToYedKv`oY4_?D=Y`)nQ2O4KSmlAYS&+NaHa*=B0VAXA5lrYe|Gwe6J zFkXb^n57_*p&I?D7XJL!c1oa=P-wLb8D=yu87?&y5J+_vvN|&T{m;L`>Kx2q&|+zm zISCq<=$ zDWPl!9f5$y1CQ`70Xjtzx(1`-0hpI5G9r>A9bg3JmDtMlB7*QLnmMW`s~(}wRSHnN z@~q&OqQ0Ld%+#mi^fT#Bv@NA$|vmArDX0Ty%XSn z`f$A470@Nm=tS*_<$zmQWwG&wM2F!bh7c&AR<(HSwjRO;sg5+o2qrX46Il+yb>|g zAu3d2;%M9h6_w0H!E9xB)d-0%lo?5uTOk#G8qlFZDd&zW6k_;-1Bh@BiduJK0pD8~ zvd}RPadT0$+R*|ix)rp7cl!DfDM_R(i6&&~Lg-GhD{B^uzaJS~6@-!1j1*~xfIDRB za?I{ZZ}CudNIcCBEliA{?t-cK3(kdQP!VxhulNz9;GpdB0G7c3=j6gs)|v6Q9D6SN zj&aR!e3e&{)i|JBZWzEqUYF`Gul*V=!`4@W;Mt(*Kk>X{Qgv@q->JOMn%xbSoy@yI zc(%o7tG&{sB(6QjtER>FeG=7>uj|f> zCmIuGtwny2nvN<`m+w&cClrKejUddMdjmeegIR@t17~}YkaLmn*VYCM=NHvItl~)V zcJSlFD-dR}h4a1y&fiSo-`n@qxu@!!vnN$*l1|e7_9Eoz^feX*@_FO3I(35cK`>DA44ZIhG;#|U zqyV(&n|R^YP5Yjy<{G1>qXOmtUiLL%9EP-+N+d#^GOIv?+F^R&aX__mUI5!g%&U>S z_1k+zY1J_6%;rzCY$ep+gh7Jw4M$(+oC2Kk4+VuS)Y7Xnm#;`EEigQ3RLfad&2;W~ z-g>M@&n3Vf#OFC^ve2%;`Rs|m8oajq?WmnrVHJ}&t{ZU3u{Fr42XQV3-x^EpfgK(U zsV?`bNe zyx&*6trA;YB(JBj?CUTidVisSls2FZ21VWnE(MggJ%|$^H;N;9uY6O#n0tkV)aCm@ zuBl*>sYTO^ zju^m&4SM_i7OM76_0VC!CI@)PR;Srbf#c+xe$b>Wz(X}=@|db*8B2bdKV>pb#0Q}m zgD*r^pTuul_qfRvY(??ukbq$rhOhPY>-s|HOmdDxn!ykDA*B2_pBeJ1wT<~iaYI?> zBZbiMyMU&(ZD)mSasnMZC&D*=tCg6bsYr8qPVQ6Jxs8H5SuyR!G0iM#zP0ym^LSil zw`;Sds5MPW^tvnua#Qz>PK$Zh75HC;g8_CQYAQX~tFFRF!?L5A9V_uY6@uHXKGZzT zSW4|=+*i^?;M{qj3tf_5=d3r{5uVZ#H#~hg@S<3;xS^>|tcMH9To9{63pOTXYqB>9 zrhOyRiJ`LrY0+HNXE z-JI6b+>K0E2xA9{BKS(ZoIMkDe2+P5FV@t)Mmj*M=q*4tO{ zt1K;+>YJRDOy83S>Ah|ZoK=su_{^kP2D-QiraryD_7U=ovyi=}$eB}HWXkt`EEI$^bV7o<%Frtvyo z-a{bm_7mAIH%3p$Y?oz;Y8t$nnp!XC+S@sfObCNnZn)~mub8?|ZkbW2`wf86hd3Gq zVC_>dga%?}Z$I{V96ICNU6>NWlP-4qjahOzW9!{E+RSUMhOKVr^b6Fl#oW zC#s&S4XCZicIta8&djCb&88wyJ50W`Dlx}ndz|!heThl@pbKJS1z;_E=cU-wp@`9@Qr` z05?DT7Lov=9oEz|5T)kJ-rC|ho~C^QD;3U5GeO&qAVj8sK#TFxiz9UelhFP%9Z z<5qbx_{G%9l_b!lCcv0~U?jMDiFV6rYnEWe(cBZAi5r7hdVUf0fE#h--ZvKc1Opzp zdWBEEahrFH0)jS?dF6E2*d6prGB_hNhO| z#2?Zh!IRR%7@?OZNa)?=W;0LLXtekhYjoeCS7yi=x~Z1(ILGh03t5ka<1rwfFNT+F zw?Ov{qYn6~36*5nnxYAtg0DDH32mMcF4``Hm}>)L4C?On(qhd*>h<3&UBN{us}hr^ z3o8*;YKf!c(6H|=Fy=o=7Pn6Gqzhb$M$D_tid>;4)8U{MClVT9Z+ugf7Qheiv1QLx z{}^w`v)R(PI!6jU;le3Ujk2GN1%+Ixc5dQN!!5l_3q41w9r&9hBCjfsW2`UEi)zj- zq5XXe{NSBRQ>#O%c2Q&DSQj~`c6~w@x=MnV?M_Onn7fc3A->8~2-N#YQUWkovjD3`VU4OMe}>pFE}Kf5A(dqe3yBiyMTbaot>&@ zd|Or~rqdus9N2z5x=KvX7naAE`_{k%Nh*|aVDzP@G}aMsXr*jOSne&90H4uk*`e`%zG^7kn6)0hWI2Pe3K4chh|nA6jcPS7Mb8E zrVRXND!c6lBRW|Cd4yz(mj`Ob8tUt{lQN3+YJ31H73oLFU?@eV@_8bfDh% zB`WxcY-hy%sYVAr43ybCI?t47=SJsP%F=N45a&0=q`VQ(^?-bXh%}w^^n{{!BJgC) z@&e+TTtT=VpK6Q?W*HA*zA-QEfX^HgrJjYQ0vIpZ^avBLYEKu<5vC)p@{Gi$Gz;IqN45G*uOHH zh_nRizdOdkpoAMO*^1kuF0*ZfevBwev1}C87g$9dPX1I=m<@Gt2l}X`jm<$#i_LQ7e4^GWny+XFF`+PK zw-+7@we1b8!ai_IHKwrnd`>`B*@4l1xjVI)$(odg4tjhHZw$irN=h zxrSq+)!T=L>f^Da2+(XZMu%fYb%^%Z&)Pu|HiIsE(>bZ@SPUvQ=?bPVu45I3K8yso zostsdKLl5?b?;Iy!jk3ir;5|-!dUfTPtPYSv>;8DYh*Y+HO*?#5oS2HR_F1yd69Hg zxFF1cg&{d~H+RRfp2GC>ZChTl`Id1=elV-_<1Umi*Re5E(}UofY%9ftHiY}KztBP_ z&f2qJ?MSwEp0JmD*nT`@yvm9-Lc)_OB3>9EqgcSshw32#g-R4Z7Q)7jD@3xE*pTB@ z4ikxuLvT^&ovxlEX*7Y0JhLR_ENrC$yRZsSmJa^!X1Gj#t&j<>N zEQdmgqs2)qBpM}T&)jgfFikt4DrCc4QdG<^Px&RNIVa*h>?dZ&tkoo&>5+uMr_72M zrDP>w5rmRgO0T8vmtLM*BWJr^AI*dfslT}8C_m1Ms2=*%Rf2+Z1$x~=;7=h4*iWp| z9ZploYRRi^P_4Dp-aHP_S`JcsFL_gSHf+VF?g;hvGSVT<#h7L0z*|`_`WQx0CPaI! zRWEtkefNtpm&QF9i@Ig@!_`=p7vZEEEoQ!mGF{;=`&jiyvpT^caKFI2-sN3a&L!ZS zWmWPl+Ce8TS{7|z{CRs*{MFu_ofN%8rMa1b*?^WIkL@zZ7G7ZqcU*UK1cEE13O7j< z=%rTsc@iky*W@B6M=mlTysb39k!M06I=XR({Jv(9@^zDlvRZV?U7o% z8Aaac2^jJ{Ara^&zEotZT5z=jS3-^ax8y-<56i1hC*wC=clFMFE2(}) z-#e(#d{)OYXR$S2_Tsb4sA~=#a5x^&@!&>17L12~mxOwIER+96B4!g7Y&bjS^b}eg zKLix#(S^fMWiv+2rcOWD9R}3F2vuD1V#C&l>kkkBq;1^E9OdU~JvVN(!D#7L<3z!_ zO~2l_W%V=5Cq&;Ves+0@$i~QW&T&5lf#s|7HTWE$z6+RIxtj{>*YMSB4?12hXq6RP zXJ5;&DGRA*HPQ~SMY;|5%9#P^h~jm5t_8lT+Hh(s*TtmpXjF2{|ebqocT9H1#}M!iZmp&RwL0PDLI)TY!? z`9hibgRa;dbaM#&%~2$SVL~j!8*o#NW*%(qkakY}%sE@x<=yZO{!?Djq9DsV;SP{+ zP_TSdadZ-}`gn@(9j$HsQT~YiF8%VfI@2g>x2Ev9Cu~t0kOu1= zCMp!)eEN<7Ya0KJ4sNJ2{T;RCXDP&1eKzhpteQ0b7)!wpLyX);jE-9`EK?~!>2EHi zyHzUg;+bMkCKOx`<<^T!s8n*e{2T0@)W?D9%4O-RJ$N;63cHSCP991WW4K6?%Y`nB zl)zoBMDP2qk-a3G&43WsN*^(#WpKHjZY~( z%|Noa*V)^Smxz&DX^8hGcIiYgD+c23J4St??C$;+{?tbn#6vq_{yehY$`kNjUTn^$ zAzIeARs2*qH@Vgim@1Q2y1|tgtkx2ticg23gI?iNR-Pev3xrtKCWWX>DBbjU+t^hI ze4f3tv|TTG+m~rADCpB@XyfN4;pw7+?eNX7Pno#9lx(2y3<)%eTWU>oZa<88bk-MPEh!P?HfSzPc@> z!m$4mG!tLWkmlNx5j#kjs>^1I>Y5)=7Ynk?svuM6quP(i)GTQbt^=J6Ryz$*?JaOh z+rG(Gz7FIU?k1~SHSdw%+xwWPjeeWcM@Vo(_JR^2d3#fG`Rb;u5uh}SmDOqifoL4p6QK-!syxuAnx$XH!mZxwyQ%cC50uB_=*|r5w5VZckwkg-`0!)#c7c z2PF02xFlbzv7q^zjhT4LyL=A&r6|U}q%ccy{W^%>>cVD$&*JN((8d8;qIuJCGfgge zZ(=F80V#+ojr?1eLYZ~an#$&{hHmEve0uPb&aJG+$uON(f%1kmlr1dw=YZp4fJ&?A3J?)3)c~RjS&c;1-(P z>v3OZ@TKU1H|?a0W_PnD2UoT5EGX|Sd~rQ3aSdU$$v41Le&M^#)tRnM1Z|=cMo(^{ z@)4UVlU0&?E?Mlu;8vzZx;XJ(Za4OFMBL}`OKFqkO?ur~zi9`(6T`aN<8Hrtp^4df zcP!})CrhIN%oPv{?Z`G{vUI`)k*6-%9w=D)nP-{4nLY|KtzHUydoV2eK=$x}{=JX= zaZ2j(CF%l_`~BdL543+4Y~7s<9UM%ZoSA<2zC=%*)k#gB{nbS8|NG&wA8`f-^sDwB zaay6Fpa6fuF|)KWWq9n4cQLhfX8hxinWmIko$Nou>M6=tzh_42*wzRKC3ep&YSc~c zc+_OO$=I|!qijr=YM1_Ydr&1ej~rxs?KQyO+leeOJMM2USis#48~Yxye56?3IdLPQq=Orm3k2i&Pot;XK~>h|>@^Y(zDKJ2Vg}ON*CN^} z6JhTSR*CU^pNk9?mnguV$uc#3-LM zbunU@ZCyNi`ux-W8QupZH{Ghtsr@*?HjV)GDBmCU&;MG89|ZiTeo;mLR=*;(F1rP0 zl=e&d@B$0$-)d`}$Ft{+(omnw4{>70&`q-OX`NAe$l+})ODxo`_Z%hWi=u^IlU&P+ zDFq{ju2TRCr7 zf%gRdMzL}|3PtO^*DHgJ1e93E=jS5E7h#dmwc1sXA(N|U@Z#LQ=?OOcdpnn!Vpm<) z$Req%B9p4hM9*)UiSk=$ekmKw5?J0B8+i3i>fugWZEvNy)g@}wZ+X(ENUD9p&Vg25 zZ9zBvH(avUP`8L94;2oI0lViqrY%bokD-0;`ucR)=hGET`!Vt}sOVFfTYr zvj=y$URHbPKwRUKH*t+nTZC;*{p+{c~ zD1I?NU%HcfG1vRNnD2^?Jk_$NV-*cfva&jDBgmZKwL0@)CErP^C_`ldI*to>j&zwK zV%ZdmZe=)d^^TZ$-<|5n&z@-H3vL3$IDRL&1HO7|5h6IR87C_-kjJW2T~xf1lK{ovWBOlo`+2JKM>Zr?f4Vs54-t4(xFG0zo$e0h2qaC!jBXWTEAZQ4-~&A437-o6NW!A Wz&#p1K|!HEz9%2UXtnP5v;PCkHHRty literal 0 HcmV?d00001 diff --git a/test/wrappers/file-system.ts b/test/wrappers/file-system.ts new file mode 100644 index 0000000000..d3cdc78527 --- /dev/null +++ b/test/wrappers/file-system.ts @@ -0,0 +1,47 @@ +import { tmpdir } from "os"; +import { assert } from "chai"; +import * as rimraf from "rimraf"; + +import { FileSystem } from "../../lib/wrappers/file-system"; + +describe('FileSystem', () => { + describe('extractZip', () => { + const d = new Date(); + const datetime = [ + d.getFullYear(), + d.getMonth() + 1, + d.getDate(), + d.getHours(), + d.getMinutes(), + d.getSeconds(), + d.getMilliseconds() + ].join(''); + const tmpDir = `${tmpdir()}/${datetime}`; + const testFilePath = `${__dirname}/example.zip`; + const filesThatNeedToExtsit = [ + `${tmpDir}/test/android-local-build-requirements.ts`, + `${tmpDir}/test/android-tools-info.ts`, + `${tmpDir}/test/ios-local-build-requirements.ts`, + `${tmpDir}/test/sys-info.ts`, + `${tmpDir}/test/wrappers/file-system.ts` + ]; + + it('should extract in example zip archive in tmp folder', done => { + const fs = new FileSystem(); + + fs.extractZip(testFilePath, tmpDir) + .then(() => { + const allExists = filesThatNeedToExtsit + .map(fs.exists) + .reduce((acc, r) => acc && r, true); + + assert.isTrue(allExists); + + done(); + }) + .catch(e => done(e)); + }); + + afterEach(done => rimraf(tmpDir, done)); + }); +}); From 4ce4bda547221e47052f6bbbbac9497862ec0975 Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Tue, 30 Oct 2018 16:27:13 -0300 Subject: [PATCH 106/169] Fixed tslint warnings --- lib/wrappers/file-system.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 8f54221e0f..97c51f7e77 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -13,8 +13,10 @@ export class FileSystem { public extractZip(pathToZip: string, outputDir: string): Promise { return new Promise((resolve, reject) => { - yauzl.open(pathToZip, { autoClose: true, lazyEntries: true }, (e, zipFile) => { - if (e) return reject(e); + yauzl.open(pathToZip, { autoClose: true, lazyEntries: true }, (openError, zipFile) => { + if (openError) { + return reject(openError); + } zipFile.on('entry', entry => { const fn = entry.fileName; @@ -22,13 +24,15 @@ export class FileSystem { return zipFile.readEntry(); } - zipFile.openReadStream(entry, (err, stream) => { - if(err) return reject(err); + zipFile.openReadStream(entry, (openStreamError, stream) => { + if(openStreamError) { + return reject(openStreamError); + }; const filePath = `${outputDir}/${fn}`; return createParentDirsIfNeeded(filePath) - .catch(e => reject(e)) + .catch(createParentDirError => reject(createParentDirError)) .then(() => { const outfile = createOutfile(filePath); stream.once('end', () => { @@ -44,7 +48,7 @@ export class FileSystem { zipFile.readEntry(); }); - }) + }); } public readDirectory(path: string): string[] { @@ -70,4 +74,4 @@ function createParentDirsIfNeeded(filePath: string) { function createOutfile(path: string): fs.WriteStream { return fs.createWriteStream(path); -} \ No newline at end of file +} From 15247ca218c44818436b6f62e259856dfd3119d9 Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Tue, 30 Oct 2018 16:33:46 -0300 Subject: [PATCH 107/169] Updated minimal version of node because ns-cli requires node v8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4b7fb8b331..d7b3076749 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- '6' +- '8' git: submodules: false before_script: From 86f2b884826dab58dd97cd5c2311b732b7bfde2f Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Thu, 1 Nov 2018 16:02:56 -0300 Subject: [PATCH 108/169] Fixed unecessary function and parameter --- lib/wrappers/file-system.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 97c51f7e77..21ab0b9a11 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -34,7 +34,7 @@ export class FileSystem { return createParentDirsIfNeeded(filePath) .catch(createParentDirError => reject(createParentDirError)) .then(() => { - const outfile = createOutfile(filePath); + const outfile = fs.createWriteStream(filePath); stream.once('end', () => { zipFile.readEntry(); outfile.close(); @@ -63,7 +63,7 @@ export class FileSystem { function createParentDirsIfNeeded(filePath: string) { const dirs = path.dirname(filePath).split(path.sep); - return dirs.reduce((p, dir, index) => p.then(parent => { + return dirs.reduce((p, dir) => p.then(parent => { const current = `${parent}${path.sep}${dir}`; return access(current) @@ -71,7 +71,3 @@ function createParentDirsIfNeeded(filePath: string) { .then(() => current); }), Promise.resolve('')); } - -function createOutfile(path: string): fs.WriteStream { - return fs.createWriteStream(path); -} From 27be25da0ef7e0a09b38709c396bd60d47010ce8 Mon Sep 17 00:00:00 2001 From: "Reinaldo A. C. Rauch" Date: Thu, 1 Nov 2018 16:03:15 -0300 Subject: [PATCH 109/169] Fixed deps version numbers --- package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 8e69ead616..a129655e28 100644 --- a/package.json +++ b/package.json @@ -25,21 +25,21 @@ "devDependencies": { "@types/chai": "4.1.0", "@types/mocha": "2.2.32", - "@types/rimraf": "^2.0.2", + "@types/rimraf": "2.0.2", "@types/semver": "5.5.0", "@types/temp": "0.8.29", "@types/winreg": "1.2.30", - "@types/yauzl": "^2.9.0", + "@types/yauzl": "2.9.0", "chai": "4.1.2", - "grunt": "^1.0.3", + "grunt": "1.0.3", "grunt-contrib-clean": "1.0.0", - "grunt-contrib-watch": "^1.1.0", + "grunt-contrib-watch": "1.1.0", "grunt-shell": "2.0.0", - "grunt-ts": "^6.0.0-beta.21", + "grunt-ts": "6.0.0-beta.21", "grunt-tslint": "3.3.0", "istanbul": "0.4.5", - "mocha": "^5.2.0", - "rimraf": "^2.5.4", + "mocha": "5.2.0", + "rimraf": "2.5.4", "tslint": "3.15.1", "typescript": "2.0.3" }, @@ -48,6 +48,6 @@ "semver": "5.5.1", "temp": "0.8.3", "winreg": "1.2.2", - "yauzl": "^2.10.0" + "yauzl": "2.10.0" } } From 09ed759af1c377cc052f4df243908ee2fa82433a Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 19 Nov 2018 11:52:27 +0200 Subject: [PATCH 110/169] release: update version to 1.7.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f20c8ef6bb..564c5785b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.6.0", + "version": "1.7.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a129655e28..8e5484baaa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.6.0", + "version": "1.7.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 3df3023a43bb16204f8813c4790b491390ccef12 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 28 Nov 2018 08:11:53 +0200 Subject: [PATCH 111/169] fix: don't close out stream in order to prevent sporadic "badf, write" error Sometimes the out stream is closed before receiving stream's end event. In this case "EBADF: bad file descriptor, write" error is thrown. --- lib/wrappers/file-system.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 21ab0b9a11..85eb1cb8bc 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -37,7 +37,6 @@ export class FileSystem { const outfile = fs.createWriteStream(filePath); stream.once('end', () => { zipFile.readEntry(); - outfile.close(); }); stream.pipe(outfile); }); From 4174ee52f0360cea11963339c32012c26cc3087d Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 28 Nov 2018 08:12:22 +0200 Subject: [PATCH 112/169] chore: update version to 1.8.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8e5484baaa..c293d213fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.7.0", + "version": "1.8.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 05e37ac85820109e9499e5a4b91b5b4c2a0c2adc Mon Sep 17 00:00:00 2001 From: Fatme Date: Thu, 29 Nov 2018 08:57:47 +0200 Subject: [PATCH 113/169] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c293d213fc..dbaae2e253 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.8.0", + "version": "1.8.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 8eccfad4cf0deb6d04f5b0742df96eb49bb06346 Mon Sep 17 00:00:00 2001 From: Veselina Radeva Date: Sat, 1 Dec 2018 03:49:13 +0200 Subject: [PATCH 114/169] chore: update community files --- LICENSE | 2 +- LICENSE.proui | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100755 LICENSE.proui diff --git a/LICENSE b/LICENSE index 59dc28ed04..9d63a0a676 100755 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) 2015-2018 Telerik EAD + Copyright (c) 2015-2018 Progress Software Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/LICENSE.proui b/LICENSE.proui new file mode 100755 index 0000000000..a9688d571a --- /dev/null +++ b/LICENSE.proui @@ -0,0 +1,125 @@ +End User License Agreement for Progress NativeScript UI + +(Last Updated December 1, 2018) + +The Software is being made available by Progress Software Corporation (“Progress,” “Licensor”, “we,” “us,” or “our”) to You on the condition that You agree to these terms and conditions (the “Agreement”). “Licensee,” “You,” or “Your” refers to the person accessing or using the Software, or, if the Software is being used on behalf of an organization, such as an employer, “Licensee,” "You," or “Your” means such organization. In the latter case, the person accessing or using the Software represents and warrants that he or she has the authority to do so and bind such organization to this Agreement. Violation of any of the terms below will result in the termination of this Agreement. BY DOWNLOADING, INSTALLING OR OTHERWISE USING THE SOFTWARE MADE AVAILABLE BY PROGRESS THROUGH THIS WEB SITE (https://www.npmjs.com/), YOU ACKNOWLEDGE THAT YOU HAVE REVIEWED AND THAT YOU ACCEPT THESE TERMS AND ARE AUTHORIZED TO ACT ON BEHALF OF, AND BIND TO THIS AGREEMENT, THE COMPANY ON BEHALF OF WHICH YOU ENTER IN THIS AGREEMENT. IF YOU DO NOT HAVE SUCH AUTHORITY, OR IF YOU DO NOT AGREE WITH THESE TERMS, YOU MUST NOT DOWNLOAD, INSTALL OR USE THE SOFTWARE. + +Content Management System and/or component vendors are not allowed to use the Software (as defined below) without the express permission of Progress. If You or the company You represent is a Content Management System and/or component vendor, You may not purchase a license for or use the Software unless You contact Progress directly and obtain permission. + +This is a license agreement and not an agreement for sale. 1. Definitions For purposes of this Agreement: + +“Integrated Products” means Your proprietary software applications which: (i) are developed by Your Licensed Developers; (ii) add substantial functionality beyond the functionality provided by the incorporated components of the Programs; and (iii) are not commercial alternatives for, or competitive in the marketplace with, the Programs or any components of the Programs. + +“Licensed Developers” means Your employees or third-party contractors authorized to develop software specifically for You using the Software in accordance with this Agreement. + +2. Software License + +2.1 License Grant. Subject to the terms and conditions set forth in this Agreement, Progress hereby grants to Licensee and Licensee hereby accepts, a limited, non-transferable, perpetual, sublicenseable (solely as set forth in Section 2.3), non-exclusive license (the “License”) to use the Progress computer software identified as Progress NativeScript UI and any updates, upgrades, modifications and error corrections thereto provided to Licensee (the “Programs”) and any accompanying documentation (the “Documentation”, together with the Programs, collectively the “Software”) solely as specified in this Agreement. You are granted a Developer License pursuant to Section 2.4. + +2.2 Scope of Use. The Software is licensed, not sold, on a per-seat basis. The number of Licensed Developers using the Software must correspond to the maximum number of License seats You have obtained from Progress hereunder. This means that, at any given time, the number of Licensed Developers cannot exceed the number of License seats that You have obtained from Progress and for which You have paid Telerik any applicable License Fees pursuant to this Agreement. The Software is in +“use” on a computer when it is loaded into temporary memory (i.e. RAM) or installed into permanent memory (e.g. hard disk or other storage device). Your Licensed Developers may install the Software on multiple machines, so long as the Software is not being used simultaneously for development purposes at any given time by more Licensed Developers than You have License seats. You are not limited by the number of License seats with respect to how many individuals within Your organization may access and use the Software for testing and building purposes. You may also embed copies of the Programs in Your Integrated Products that You license and distribute to Your own end-user licensees, including but not limited to, Your employees (“Authorized End-Users”), solely in accordance with the requirements set forth in Section 2.3 below. + +2.3 License for Redistribution + +2.3.1 License Grant. Subject to the terms of this Agreement, You are granted a limited, nontransferable, royalty-free license to redistribute and sublicense the use of the Programs solely to Authorized End- Users: (i) in object code form only; (ii) as embedded within Your Integrated Product for internal company use, hosted applications, websites, commercial solutions deployed at Your Authorized End Users sites, or shrink- or click-wrapped software solutions; and (iii) pursuant to an end user license agreement or terms of use that: imposes the limitations set forth in this paragraph on Your Authorized End-Users; prohibits distribution of the Programs by Your Authorized End-Users; limits the liability of Your licensors or suppliers to the maximum extent permitted by applicable law; and prohibits any attempt to disassemble the code, or attempt in any manner to reconstruct, discover, reuse or modify any source code or underlying algorithms of the Programs, except to the limited extent as is permitted by law notwithstanding contractual prohibition. Notwithstanding subsection 2.3.1(iii), if Your Integrated Product is only distributed to Your employees for internal use, You are not required to distribute Your Integrated Product pursuant to an end user license agreement or terms of use. In no event are You allowed to distribute the Software or sublicense its use (a) in any format other than in object form, (b) as a standalone product or (c) as a part of any product other than Your Integrated Product. + +2.3.2 The foregoing license to redistribute the Programs is conditioned upon the following: + +2.3.2.1 You hereby acknowledge and agree that You are solely responsible for Your Authorized End- User’s use of the Programs in accordance with the limitations set forth in subsection 2.3.1 and liable for such Authorized End-User’s breach of such limitations, even if You are not required to distribute an end user license agreement or terms of use under subsection 2.3.1(iii). + +2.3.2.2 You must ensure that the Software is not distributed in any form that allows it to be reused by any application other than Your Integrated Product. If You have any questions regarding redistribution, please contact support@telerik.com. For use of the Software in design-time (i.e. within a development environment) Your Authorized End-Users need to obtain their own Developer Licenses from Progress. + +2.3.2.3 You must prohibit Your Authorized End-Users from using the Software independently from Your Integrated Products, or from decompiling, reverse engineering or otherwise seeking to discover the source code of the Programs. + +2.3.2.4 You must include a valid copyright message in Your Integrated Products in a location viewable by Authorized End-Users (e.g. “About” box) that will serve to protect Progress’ copyright and other intellectual property rights in the Software. + +2.3.2.5 You are not allowed to, and are expressly prohibited from granting Your Authorized End-Users any right to further sublicense the Software. + +2.4 Developer License + +2.4.1 General. Subject to the terms and conditions set forth in this Agreement, Licensor hereby grants to Licensee and Licensee hereby accepts, a limited, non-transferable, perpetual, royalty-free, sublicenseable (solely as set forth in Section 2.3), non-exclusive license to install, use, include with Integrated Products and redistribute the Programs in executable, object code form only. + +2.4.2 Support. No dedicated technical support is provided with the Software, however, as part of your license you are allowed to access those support resources offered by Progress at its sole discretion (which may include documentation, Knowledge Base articles, forums). Technical support may be available for purchase separately, please contact the authorized distributor, Telerik Inc, if you are interested in more information about obtaining a paid support subscription. + +2.4.3 Updates. During the Term of this License, Progress may, but is under no obligation to, provide updates to the Software. Updates, if any, will replace and/or supplement (and may disable) the version of the Software that formed the basis for Your eligibility for the update. You may use the resulting updated Software only in accordance with the terms of this License. + +3. License Limitations + +3.1 You are not allowed to use, copy, modify, distribute, resell, transfer, rent, lease, or sublicense the Software and Your associated rights except as expressly permitted in this Agreement. Under no circumstances shall You grant further redistribution or sublicense rights to any Authorized End-Users or third party or redistribute any source code of the Programs to any Authorized End-User or third party. + +3.2 You may not use the Progress product names, logos or trademarks to market Your Integrated Product. + +3.3 Except to the limited extent as is permitted by law notwithstanding contractual prohibition, You are not allowed to disassemble, decompile or “unlock”, decode or otherwise reverse translate or engineer, or attempt in any manner to reconstruct or discover any source code or underlying algorithms of the Programs that are provided to You in object code form only. + +4. Delivery +Progress shall make available for download to Licensee a master copy of the Software. + +5. Term and Termination +This Agreement and the License granted hereunder shall continue until terminated in accordance with this Section. Unless otherwise specified in this Agreement, the License granted hereunder shall last as long as You use the Software in compliance with the terms herein. Unless otherwise prohibited by law, and without prejudice to Progress’ other rights or remedies, Progress shall have the right to terminate this Agreement and the License granted hereunder immediately if You breach any of the material terms of this Agreement, and You fail to cure such material breach within thirty (30) days of receipt of notice from Progress. Upon termination of this Agreement, all Licenses granted to You hereunder shall terminate automatically and You shall immediately cease use and distribution of the Programs; provided, however, that any sublicenses granted to Your Authorized End-Users in accordance with Section 2.3 shall survive such termination. You must also destroy (i) all copies of the Programs not integrated into a live, functioning instance(s) of Your Integrated Product(s) already installed, +implemented and deployed for Your Authorized End-User(s), and (ii) any product and company logos provided by Progress in connection with this Agreement. + +6. Product Discontinuance + +Progress reserves the right to discontinue the Software or any component of the Software, whether offered as a standalone product or solely as a component, at any time. + +7. Intellectual Property + +All title and ownership rights in and to the Software (including but not limited to any images, photographs, animations, video, audio, music, or text embedded in the Software), the intellectual property embodied in the Software, and any trademarks or service marks of Progress that are used in connection with the Software are and shall at all times remain exclusively owned by Progress and its licensors. All title and intellectual property rights in and to the content that may be accessed through use of the Software is the property of the respective content owner and may be protected by applicable copyright or other intellectual property laws and treaties. This Agreement grants You no rights to use such content. This Software may contain or be accompanied by certain third party components which are subject to additional restriction. These components, if any, are identified in, and subject to, special license terms and conditions set forth in the “readme.txt” file, the “notices.txt” file, or the “Third Party Software” file accompanying the Software (“Special Notices”). The Special Notices include important licensing and warranty information and disclaimers. In the event of a conflict between the Special Notices and the other portions of this Agreement, the Special Notices will take precedence (but solely with respect to the third party component(s) to which the Special Notice relates). Any open source software that may be delivered by Progress embedded in or in association with Progress products is provided pursuant to the open source license applicable to the software and subject to the disclaimers and limitations on liability set forth in such license. + +8. Collection and Use of Data + +Progress uses tools to deliver certain Software features and extensions, identify trends and bugs, collect activation information, usage statistics and track other data related to Your use of the Software as further described in the most current version of Progress’ Privacy Policy (located at: https://www.progress.com/legal/privacy-policy). By Your acceptance of the terms of this Agreement and/or use of the Software, You authorize the collection, use and disclosure of this data for the purposes provided for in this Agreement and/or the Privacy Policy. + +9. Limited Warranty + +THE SOFTWARE IS LICENSED ‘AS IS’. YOU BEAR THE RISK OF USING THE SOFTWARE. PROGRESS GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL RIGHTS UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, PROGRESS EXCLUDES THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. YOUR SOLE REMEDY FOR ANY FAILURE OR ANY FORM OF DAMAGE CAUSED BY THIS SOFTWARE IS A FULL REFUND OF THE LICENSE FEE WE HAVE RECEIVED FROM YOU, WHICH IN THE CASE OF A FREE OR NO COST LICENSE IS $0. + +10. Limitation of Liability + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL PROGRESS BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED. IN ANY CASE, PROGRESS’ ENTIRE LIABILITY UNDER ANY PROVISION OF THIS AGREEMENT SHALL NOT EXCEED FIVE U.S. DOLLARS ($5), NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT BE APPLICABLE. PROGRESS IS NOT RESPONSIBLE FOR ANY LIABILITY ARISING OUT OF CONTENT PROVIDED BY LICENSEE OR A THIRD PARTY THAT IS ACCESSED THROUGH THE SOFTWARE AND/OR ANY MATERIAL LINKED THROUGH SUCH CONTENT. ANY DATA INCLUDED WITH OR IN THE SOFTWARE IS FOR TESTING USE ONLY AND PROGRESS HEREBY DISCLAIMS ANY AND ALL LIABILITY ARISING THEREFROM. + +11. Indemnity + +You agree to indemnify, hold harmless, and defend Progress and its resellers from and against any and all claims, lawsuits and proceedings (collectively “Claims”), and all expenses, costs (including attorney's fees), judgments, damages and other liabilities resulting from such Claims, that arise or result from (i) Your use of the Software in violation of this Agreement, (ii) the use or distribution of Your Integrated Product or (iii) Your modification of the Program’s source code. + +12. Confidentiality + +Except as otherwise provided herein, each party expressly undertakes to retain in confidence all information and know-how transmitted or disclosed to the other that the disclosing party has identified as being proprietary and/or confidential or that, by the nature of the circumstances surrounding the disclosure, ought in good faith to be treated as proprietary and/or confidential, and expressly undertakes to make no use of such information and know-how except under the terms and during the existence of this Agreement. However, neither party shall have an obligation to maintain the confidentiality of information that: (i) it received rightfully from a third party without an obligation to maintain such information in confidence; (ii) the disclosing party has disclosed to a third party without any obligation to maintain such information in confidence; (iii) was known to the receiving party prior to its disclosure by the disclosing party; or (iv) is independently developed by the receiving party without use of the confidential information of the disclosing party. Further, either party may disclose confidential information of the other party as required by governmental or judicial order, provided such party gives the other party prompt written notice prior to such disclosure and complies with any protective order (or equivalent) imposed on such disclosure. Without limiting the foregoing, Licensee shall treat any source code for the Programs as confidential information and shall not disclose, disseminate or distribute such materials to any third party without Progress’ prior written permission. Each party’s obligations under this Section 12 shall apply at all times during the term of this Agreement and for five (5) years following termination of this Agreement, provided, however, that (i) obligations with respect to source code shall survive in perpetuity and (ii) trade secrets shall be maintained as such until they fall into the public domain. + +13. Governing Law + +This License will be governed by the law of the Commonwealth of Massachusetts, U.S.A., without regard to the conflict of laws principles thereof. If any dispute, controversy, or claim cannot be resolved by a good faith discussion between the parties, then it shall be submitted for resolution to a state or Federal court or competent jurisdiction in Boston, Massachusetts, USA, and the parties hereby agree to submit to the jurisdiction and venue of such court. The Uniform Computer Information Transactions Act and the United Nations Convention on the International Sale of Goods shall not apply to this Agreement. Failure of a party to enforce any provision of this Agreement shall not constitute or be construed as a waiver of such provision or of the right to enforce such provision. + +14. Entire Agreement + +This Agreement shall constitute the entire agreement between the parties with respect to the subject matter hereof and supersedes all prior and contemporaneous communications regarding the subject matter hereof. Use of any purchase order or other Licensee document in connection herewith shall be for administrative convenience only and all terms and conditions stated therein shall be void and of no effect unless otherwise agreed to in writing by both parties. In cases where this license is being obtained through an approved third party, these terms shall supersede any third party license or purchase agreement. + +15. No Assignment + +You may not assign, sublicense, sub-contract, or otherwise transfer this Agreement, or any rights or obligations under it, without Progress’ prior written consent. + +16. Survival + +Any provisions of the Agreement containing license restrictions, including but not limited to those related to the Program source code, warranties and warranty disclaimers, confidentiality obligations, limitations of liability and/or indemnity terms, and any provision of the Agreement which, by its nature, is intended to survive shall remain in effect following any termination or expiration of the Agreement. + +17. Severability + +If a particular provision of this Agreement is terminated or held by a court of competent jurisdiction to be invalid, illegal, or unenforceable, this Agreement shall remain in full force and effect as to the remaining provisions. + +18. Force Majeure + +Neither party shall be deemed in default of this Agreement if failure or delay in performance is caused by an act of God, fire, flood, severe weather conditions, material shortage or unavailability of transportation, government ordinance, laws, regulations or restrictions, war or civil disorder, or any other cause beyond the reasonable control of such party. + +19. Export Classifications + +You expressly agree not to export or re-export Progress Software or Your Integrated Product to any country, person, entity or end user subject to U.S. export restrictions. You specifically agree not to export, re-export, or transfer the Software to any country to which the U.S. has embargoed or restricted the export of goods or services, or to any national of any such country, wherever located, who intends to transmit or transport the products back to such country, or to any person or entity who has been prohibited from participating in U.S. export transactions by any federal agency of the U.S. government. You warrant and represent that neither the U.S.A. Bureau of Industry and Security nor any other federal agency has suspended, revoked or denied Your export privileges. + +20. Commercial Software + +The Programs and the Documentation are "Commercial Items", as that term is defined at 48 C.F.R. §2.101, consisting of "Commercial Computer Software" and "Commercial Computer Software Documentation", as such terms are used in 48 C.F.R. §12.212 or 48 C.F.R. §227.7202, as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Software and Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial Items and (b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States. + +21. Reports and Audit Rights + +Licensee shall grant Progress audit rights against Licensee twice within a calendar three hundred and sixty-five (365) day period upon two weeks written notice, to verify Licensee’s compliance with this Agreement. Licensee shall keep adequate records to verify Licensee’s compliance with this Agreement. + +YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, THAT YOU UNDERSTAND THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE INSTALLATION OF THE SOFTWARE PRODUCT, BY LOADING OR RUNNING THE SOFTWARE PRODUCT, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, YOU AGREE TO BE BOUND BY THIS AGREEMENT’S TERMS AND CONDITIONS. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN SEPARATE AGREEMENTS BETWEEN PROGRESS AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES. From 0652d5bb5f7a247e0f163b8ce4cbf24ad8e2a385 Mon Sep 17 00:00:00 2001 From: radeva Date: Sat, 1 Dec 2018 06:32:29 +0200 Subject: [PATCH 115/169] Delete LICENSE.proui --- LICENSE.proui | 125 -------------------------------------------------- 1 file changed, 125 deletions(-) delete mode 100755 LICENSE.proui diff --git a/LICENSE.proui b/LICENSE.proui deleted file mode 100755 index a9688d571a..0000000000 --- a/LICENSE.proui +++ /dev/null @@ -1,125 +0,0 @@ -End User License Agreement for Progress NativeScript UI - -(Last Updated December 1, 2018) - -The Software is being made available by Progress Software Corporation (“Progress,” “Licensor”, “we,” “us,” or “our”) to You on the condition that You agree to these terms and conditions (the “Agreement”). “Licensee,” “You,” or “Your” refers to the person accessing or using the Software, or, if the Software is being used on behalf of an organization, such as an employer, “Licensee,” "You," or “Your” means such organization. In the latter case, the person accessing or using the Software represents and warrants that he or she has the authority to do so and bind such organization to this Agreement. Violation of any of the terms below will result in the termination of this Agreement. BY DOWNLOADING, INSTALLING OR OTHERWISE USING THE SOFTWARE MADE AVAILABLE BY PROGRESS THROUGH THIS WEB SITE (https://www.npmjs.com/), YOU ACKNOWLEDGE THAT YOU HAVE REVIEWED AND THAT YOU ACCEPT THESE TERMS AND ARE AUTHORIZED TO ACT ON BEHALF OF, AND BIND TO THIS AGREEMENT, THE COMPANY ON BEHALF OF WHICH YOU ENTER IN THIS AGREEMENT. IF YOU DO NOT HAVE SUCH AUTHORITY, OR IF YOU DO NOT AGREE WITH THESE TERMS, YOU MUST NOT DOWNLOAD, INSTALL OR USE THE SOFTWARE. - -Content Management System and/or component vendors are not allowed to use the Software (as defined below) without the express permission of Progress. If You or the company You represent is a Content Management System and/or component vendor, You may not purchase a license for or use the Software unless You contact Progress directly and obtain permission. - -This is a license agreement and not an agreement for sale. 1. Definitions For purposes of this Agreement: - -“Integrated Products” means Your proprietary software applications which: (i) are developed by Your Licensed Developers; (ii) add substantial functionality beyond the functionality provided by the incorporated components of the Programs; and (iii) are not commercial alternatives for, or competitive in the marketplace with, the Programs or any components of the Programs. - -“Licensed Developers” means Your employees or third-party contractors authorized to develop software specifically for You using the Software in accordance with this Agreement. - -2. Software License - -2.1 License Grant. Subject to the terms and conditions set forth in this Agreement, Progress hereby grants to Licensee and Licensee hereby accepts, a limited, non-transferable, perpetual, sublicenseable (solely as set forth in Section 2.3), non-exclusive license (the “License”) to use the Progress computer software identified as Progress NativeScript UI and any updates, upgrades, modifications and error corrections thereto provided to Licensee (the “Programs”) and any accompanying documentation (the “Documentation”, together with the Programs, collectively the “Software”) solely as specified in this Agreement. You are granted a Developer License pursuant to Section 2.4. - -2.2 Scope of Use. The Software is licensed, not sold, on a per-seat basis. The number of Licensed Developers using the Software must correspond to the maximum number of License seats You have obtained from Progress hereunder. This means that, at any given time, the number of Licensed Developers cannot exceed the number of License seats that You have obtained from Progress and for which You have paid Telerik any applicable License Fees pursuant to this Agreement. The Software is in -“use” on a computer when it is loaded into temporary memory (i.e. RAM) or installed into permanent memory (e.g. hard disk or other storage device). Your Licensed Developers may install the Software on multiple machines, so long as the Software is not being used simultaneously for development purposes at any given time by more Licensed Developers than You have License seats. You are not limited by the number of License seats with respect to how many individuals within Your organization may access and use the Software for testing and building purposes. You may also embed copies of the Programs in Your Integrated Products that You license and distribute to Your own end-user licensees, including but not limited to, Your employees (“Authorized End-Users”), solely in accordance with the requirements set forth in Section 2.3 below. - -2.3 License for Redistribution - -2.3.1 License Grant. Subject to the terms of this Agreement, You are granted a limited, nontransferable, royalty-free license to redistribute and sublicense the use of the Programs solely to Authorized End- Users: (i) in object code form only; (ii) as embedded within Your Integrated Product for internal company use, hosted applications, websites, commercial solutions deployed at Your Authorized End Users sites, or shrink- or click-wrapped software solutions; and (iii) pursuant to an end user license agreement or terms of use that: imposes the limitations set forth in this paragraph on Your Authorized End-Users; prohibits distribution of the Programs by Your Authorized End-Users; limits the liability of Your licensors or suppliers to the maximum extent permitted by applicable law; and prohibits any attempt to disassemble the code, or attempt in any manner to reconstruct, discover, reuse or modify any source code or underlying algorithms of the Programs, except to the limited extent as is permitted by law notwithstanding contractual prohibition. Notwithstanding subsection 2.3.1(iii), if Your Integrated Product is only distributed to Your employees for internal use, You are not required to distribute Your Integrated Product pursuant to an end user license agreement or terms of use. In no event are You allowed to distribute the Software or sublicense its use (a) in any format other than in object form, (b) as a standalone product or (c) as a part of any product other than Your Integrated Product. - -2.3.2 The foregoing license to redistribute the Programs is conditioned upon the following: - -2.3.2.1 You hereby acknowledge and agree that You are solely responsible for Your Authorized End- User’s use of the Programs in accordance with the limitations set forth in subsection 2.3.1 and liable for such Authorized End-User’s breach of such limitations, even if You are not required to distribute an end user license agreement or terms of use under subsection 2.3.1(iii). - -2.3.2.2 You must ensure that the Software is not distributed in any form that allows it to be reused by any application other than Your Integrated Product. If You have any questions regarding redistribution, please contact support@telerik.com. For use of the Software in design-time (i.e. within a development environment) Your Authorized End-Users need to obtain their own Developer Licenses from Progress. - -2.3.2.3 You must prohibit Your Authorized End-Users from using the Software independently from Your Integrated Products, or from decompiling, reverse engineering or otherwise seeking to discover the source code of the Programs. - -2.3.2.4 You must include a valid copyright message in Your Integrated Products in a location viewable by Authorized End-Users (e.g. “About” box) that will serve to protect Progress’ copyright and other intellectual property rights in the Software. - -2.3.2.5 You are not allowed to, and are expressly prohibited from granting Your Authorized End-Users any right to further sublicense the Software. - -2.4 Developer License - -2.4.1 General. Subject to the terms and conditions set forth in this Agreement, Licensor hereby grants to Licensee and Licensee hereby accepts, a limited, non-transferable, perpetual, royalty-free, sublicenseable (solely as set forth in Section 2.3), non-exclusive license to install, use, include with Integrated Products and redistribute the Programs in executable, object code form only. - -2.4.2 Support. No dedicated technical support is provided with the Software, however, as part of your license you are allowed to access those support resources offered by Progress at its sole discretion (which may include documentation, Knowledge Base articles, forums). Technical support may be available for purchase separately, please contact the authorized distributor, Telerik Inc, if you are interested in more information about obtaining a paid support subscription. - -2.4.3 Updates. During the Term of this License, Progress may, but is under no obligation to, provide updates to the Software. Updates, if any, will replace and/or supplement (and may disable) the version of the Software that formed the basis for Your eligibility for the update. You may use the resulting updated Software only in accordance with the terms of this License. - -3. License Limitations - -3.1 You are not allowed to use, copy, modify, distribute, resell, transfer, rent, lease, or sublicense the Software and Your associated rights except as expressly permitted in this Agreement. Under no circumstances shall You grant further redistribution or sublicense rights to any Authorized End-Users or third party or redistribute any source code of the Programs to any Authorized End-User or third party. - -3.2 You may not use the Progress product names, logos or trademarks to market Your Integrated Product. - -3.3 Except to the limited extent as is permitted by law notwithstanding contractual prohibition, You are not allowed to disassemble, decompile or “unlock”, decode or otherwise reverse translate or engineer, or attempt in any manner to reconstruct or discover any source code or underlying algorithms of the Programs that are provided to You in object code form only. - -4. Delivery -Progress shall make available for download to Licensee a master copy of the Software. - -5. Term and Termination -This Agreement and the License granted hereunder shall continue until terminated in accordance with this Section. Unless otherwise specified in this Agreement, the License granted hereunder shall last as long as You use the Software in compliance with the terms herein. Unless otherwise prohibited by law, and without prejudice to Progress’ other rights or remedies, Progress shall have the right to terminate this Agreement and the License granted hereunder immediately if You breach any of the material terms of this Agreement, and You fail to cure such material breach within thirty (30) days of receipt of notice from Progress. Upon termination of this Agreement, all Licenses granted to You hereunder shall terminate automatically and You shall immediately cease use and distribution of the Programs; provided, however, that any sublicenses granted to Your Authorized End-Users in accordance with Section 2.3 shall survive such termination. You must also destroy (i) all copies of the Programs not integrated into a live, functioning instance(s) of Your Integrated Product(s) already installed, -implemented and deployed for Your Authorized End-User(s), and (ii) any product and company logos provided by Progress in connection with this Agreement. - -6. Product Discontinuance - -Progress reserves the right to discontinue the Software or any component of the Software, whether offered as a standalone product or solely as a component, at any time. - -7. Intellectual Property - -All title and ownership rights in and to the Software (including but not limited to any images, photographs, animations, video, audio, music, or text embedded in the Software), the intellectual property embodied in the Software, and any trademarks or service marks of Progress that are used in connection with the Software are and shall at all times remain exclusively owned by Progress and its licensors. All title and intellectual property rights in and to the content that may be accessed through use of the Software is the property of the respective content owner and may be protected by applicable copyright or other intellectual property laws and treaties. This Agreement grants You no rights to use such content. This Software may contain or be accompanied by certain third party components which are subject to additional restriction. These components, if any, are identified in, and subject to, special license terms and conditions set forth in the “readme.txt” file, the “notices.txt” file, or the “Third Party Software” file accompanying the Software (“Special Notices”). The Special Notices include important licensing and warranty information and disclaimers. In the event of a conflict between the Special Notices and the other portions of this Agreement, the Special Notices will take precedence (but solely with respect to the third party component(s) to which the Special Notice relates). Any open source software that may be delivered by Progress embedded in or in association with Progress products is provided pursuant to the open source license applicable to the software and subject to the disclaimers and limitations on liability set forth in such license. - -8. Collection and Use of Data - -Progress uses tools to deliver certain Software features and extensions, identify trends and bugs, collect activation information, usage statistics and track other data related to Your use of the Software as further described in the most current version of Progress’ Privacy Policy (located at: https://www.progress.com/legal/privacy-policy). By Your acceptance of the terms of this Agreement and/or use of the Software, You authorize the collection, use and disclosure of this data for the purposes provided for in this Agreement and/or the Privacy Policy. - -9. Limited Warranty - -THE SOFTWARE IS LICENSED ‘AS IS’. YOU BEAR THE RISK OF USING THE SOFTWARE. PROGRESS GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL RIGHTS UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, PROGRESS EXCLUDES THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. YOUR SOLE REMEDY FOR ANY FAILURE OR ANY FORM OF DAMAGE CAUSED BY THIS SOFTWARE IS A FULL REFUND OF THE LICENSE FEE WE HAVE RECEIVED FROM YOU, WHICH IN THE CASE OF A FREE OR NO COST LICENSE IS $0. - -10. Limitation of Liability - -TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL PROGRESS BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED. IN ANY CASE, PROGRESS’ ENTIRE LIABILITY UNDER ANY PROVISION OF THIS AGREEMENT SHALL NOT EXCEED FIVE U.S. DOLLARS ($5), NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT BE APPLICABLE. PROGRESS IS NOT RESPONSIBLE FOR ANY LIABILITY ARISING OUT OF CONTENT PROVIDED BY LICENSEE OR A THIRD PARTY THAT IS ACCESSED THROUGH THE SOFTWARE AND/OR ANY MATERIAL LINKED THROUGH SUCH CONTENT. ANY DATA INCLUDED WITH OR IN THE SOFTWARE IS FOR TESTING USE ONLY AND PROGRESS HEREBY DISCLAIMS ANY AND ALL LIABILITY ARISING THEREFROM. - -11. Indemnity - -You agree to indemnify, hold harmless, and defend Progress and its resellers from and against any and all claims, lawsuits and proceedings (collectively “Claims”), and all expenses, costs (including attorney's fees), judgments, damages and other liabilities resulting from such Claims, that arise or result from (i) Your use of the Software in violation of this Agreement, (ii) the use or distribution of Your Integrated Product or (iii) Your modification of the Program’s source code. - -12. Confidentiality - -Except as otherwise provided herein, each party expressly undertakes to retain in confidence all information and know-how transmitted or disclosed to the other that the disclosing party has identified as being proprietary and/or confidential or that, by the nature of the circumstances surrounding the disclosure, ought in good faith to be treated as proprietary and/or confidential, and expressly undertakes to make no use of such information and know-how except under the terms and during the existence of this Agreement. However, neither party shall have an obligation to maintain the confidentiality of information that: (i) it received rightfully from a third party without an obligation to maintain such information in confidence; (ii) the disclosing party has disclosed to a third party without any obligation to maintain such information in confidence; (iii) was known to the receiving party prior to its disclosure by the disclosing party; or (iv) is independently developed by the receiving party without use of the confidential information of the disclosing party. Further, either party may disclose confidential information of the other party as required by governmental or judicial order, provided such party gives the other party prompt written notice prior to such disclosure and complies with any protective order (or equivalent) imposed on such disclosure. Without limiting the foregoing, Licensee shall treat any source code for the Programs as confidential information and shall not disclose, disseminate or distribute such materials to any third party without Progress’ prior written permission. Each party’s obligations under this Section 12 shall apply at all times during the term of this Agreement and for five (5) years following termination of this Agreement, provided, however, that (i) obligations with respect to source code shall survive in perpetuity and (ii) trade secrets shall be maintained as such until they fall into the public domain. - -13. Governing Law - -This License will be governed by the law of the Commonwealth of Massachusetts, U.S.A., without regard to the conflict of laws principles thereof. If any dispute, controversy, or claim cannot be resolved by a good faith discussion between the parties, then it shall be submitted for resolution to a state or Federal court or competent jurisdiction in Boston, Massachusetts, USA, and the parties hereby agree to submit to the jurisdiction and venue of such court. The Uniform Computer Information Transactions Act and the United Nations Convention on the International Sale of Goods shall not apply to this Agreement. Failure of a party to enforce any provision of this Agreement shall not constitute or be construed as a waiver of such provision or of the right to enforce such provision. - -14. Entire Agreement - -This Agreement shall constitute the entire agreement between the parties with respect to the subject matter hereof and supersedes all prior and contemporaneous communications regarding the subject matter hereof. Use of any purchase order or other Licensee document in connection herewith shall be for administrative convenience only and all terms and conditions stated therein shall be void and of no effect unless otherwise agreed to in writing by both parties. In cases where this license is being obtained through an approved third party, these terms shall supersede any third party license or purchase agreement. - -15. No Assignment - -You may not assign, sublicense, sub-contract, or otherwise transfer this Agreement, or any rights or obligations under it, without Progress’ prior written consent. - -16. Survival - -Any provisions of the Agreement containing license restrictions, including but not limited to those related to the Program source code, warranties and warranty disclaimers, confidentiality obligations, limitations of liability and/or indemnity terms, and any provision of the Agreement which, by its nature, is intended to survive shall remain in effect following any termination or expiration of the Agreement. - -17. Severability - -If a particular provision of this Agreement is terminated or held by a court of competent jurisdiction to be invalid, illegal, or unenforceable, this Agreement shall remain in full force and effect as to the remaining provisions. - -18. Force Majeure - -Neither party shall be deemed in default of this Agreement if failure or delay in performance is caused by an act of God, fire, flood, severe weather conditions, material shortage or unavailability of transportation, government ordinance, laws, regulations or restrictions, war or civil disorder, or any other cause beyond the reasonable control of such party. - -19. Export Classifications - -You expressly agree not to export or re-export Progress Software or Your Integrated Product to any country, person, entity or end user subject to U.S. export restrictions. You specifically agree not to export, re-export, or transfer the Software to any country to which the U.S. has embargoed or restricted the export of goods or services, or to any national of any such country, wherever located, who intends to transmit or transport the products back to such country, or to any person or entity who has been prohibited from participating in U.S. export transactions by any federal agency of the U.S. government. You warrant and represent that neither the U.S.A. Bureau of Industry and Security nor any other federal agency has suspended, revoked or denied Your export privileges. - -20. Commercial Software - -The Programs and the Documentation are "Commercial Items", as that term is defined at 48 C.F.R. §2.101, consisting of "Commercial Computer Software" and "Commercial Computer Software Documentation", as such terms are used in 48 C.F.R. §12.212 or 48 C.F.R. §227.7202, as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Software and Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial Items and (b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States. - -21. Reports and Audit Rights - -Licensee shall grant Progress audit rights against Licensee twice within a calendar three hundred and sixty-five (365) day period upon two weeks written notice, to verify Licensee’s compliance with this Agreement. Licensee shall keep adequate records to verify Licensee’s compliance with this Agreement. - -YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, THAT YOU UNDERSTAND THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE INSTALLATION OF THE SOFTWARE PRODUCT, BY LOADING OR RUNNING THE SOFTWARE PRODUCT, OR BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, YOU AGREE TO BE BOUND BY THIS AGREEMENT’S TERMS AND CONDITIONS. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN SEPARATE AGREEMENTS BETWEEN PROGRESS AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES. From 650adfa15d04fb63f0ec0ce1e54f81d793653a61 Mon Sep 17 00:00:00 2001 From: radeva Date: Sat, 1 Dec 2018 07:05:25 +0200 Subject: [PATCH 116/169] chore: Update Notice.txt --- NOTICE.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 7222c63770..3e0fec49de 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -6,14 +6,13 @@ NativeScript Doctor v1* (the “Product”) -Copyright © 2016-2018 Telerik AD. All Rights Reserved. +Copyright © 2016-2018 Progress Software Corporation and/or one of its subsidiaries or affiliates. All rights reserved. For license information see the LICENSE.md file which accompanies this NOTICE.txt file. -Portions of the Product include certain non-proprietary open source and commercial third-party components listed below (“Third-Party Components”). The authors of the Third-Party Components require Telerik AD (“Telerik”) to include the following notices and additional licensing terms as a condition of Telerik’s use of such Third-Party Components. You acknowledge that the authors of the Third-Party Components have no obligation to provide support to you for the Third-Party Components or the Product. You hereby undertake to comply with all licenses related to the applicable Third-Party Components. - - -1. Special Notices Regarding Open Source Third-Party Components incorporated in the Product: +Portions of the Product include certain open source and commercial third-party components listed below (ìThird-Party Componentsî). The authors of the Third-Party Components require Progress Software Corporation (ìPSCî) to include the following notices and additional licensing terms as a condition of PSCís use of such Third-Party Components. You acknowledge that the authors of the Third-Party Components have no obligation to provide support to you for the Third-Party Components or the Product. You hereby undertake to comply with all licenses related to the applicable Third-Party Components. Notwithstanding anything to the contrary, to the extent that any of the terms and conditions of the Product Agreement conflict, vary, or are in addition to the terms and conditions of the aforementioned third-party licenses for these technology, such terms and conditions are offered by PSC alone and not by any other party. + +1. Special Notices Regarding Open Source Third-Party Components incorporated in the Product: (1) BSD-Style License: @@ -82,8 +81,8 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2. Special Notices Regarding Commercially Licensed Third-Party Components incorporated in the Product: None + +NOTICE FROM PROGRESS SOFTWARE CORPORATION: Additional notices may be included in the release notes or other documentation that accompanies updates received in connection with support of the Product. -NOTICE FROM TELERIK AD: Additional notices may be included in the release notes or other documentation that accompanies updates received in connection with support of the Product. - -3/26/2018 +11/20/2018 From 986d7a072ed4cb31b53cce24c0c37e99bc9f002e Mon Sep 17 00:00:00 2001 From: Emil Tabakov Date: Mon, 7 Jan 2019 12:53:22 +0200 Subject: [PATCH 117/169] chore: update community files --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 9d63a0a676..061c440288 100755 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) 2015-2018 Progress Software Corporation + Copyright (c) 2015-2019 Progress Software Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From d6ad87ede475ecb751ec7074f12352c567b2aeb7 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 27 Mar 2019 16:18:30 +0200 Subject: [PATCH 118/169] fix: prompts to install javac should not be shown on macOS macOS has handle when you try to execute java or javac to prompt to install it. However, we do not want to bother the user with such prompts. Currently we are executing `javac -version` to determine the version. Instead of this, check if there's `javac` in the PATH before executing the command. In case there's no javac in the path, do not execute `javac -version`, so we'll not prompt the user to install it. --- lib/constants.ts | 1 + lib/sys-info.ts | 51 +++++++++++++++++++++++++++++++++++++-------- package-lock.json | 30 ++++++++++++++++++++------- package.json | 2 +- test/sys-info.ts | 53 ++++++++++++++++++++++++++++++++++------------- 5 files changed, 105 insertions(+), 32 deletions(-) diff --git a/lib/constants.ts b/lib/constants.ts index cd74526e7f..076da69faf 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -15,4 +15,5 @@ export class Constants { public static ANDROID_RUNTIME = "tns-android"; public static VERSION_PROPERTY_NAME = "version"; public static XCODE_MIN_REQUIRED_VERSION = 9; + public static JAVAC_EXECUTABLE_NAME = "javac"; } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 3a089d2775..a92478d431 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -57,15 +57,8 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getJavaCompilerVersion(): Promise { return this.getValueForProperty(() => this.javaCompilerVerCache, async (): Promise => { - const javaCompileExecutableName = "javac"; - const javaHome = process.env["JAVA_HOME"]; - const pathToJavaCompilerExecutable = javaHome ? path.join(javaHome, "bin", javaCompileExecutableName) : javaCompileExecutableName; - try { - const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`); - return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(`${output.stderr}${EOL}${output.stdout}`)[1]; - } catch (err) { - return null; - } + const javacVersion = (await this.getJavacVersionFromJavaHome()) || (await this.getJavacVersionFromPath()); + return javacVersion; }); } @@ -499,4 +492,44 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { return result; }); } + + private async getJavacVersionFromPath(): Promise { + let javacVersion: string = null; + + try { + const detectionCommand = this.hostInfo.isWindows ? "where" : "which"; + // if this command succeeds, we have javac in the PATH. In case it is not there, it will throw an error. + await this.childProcess.exec(`${detectionCommand} ${Constants.JAVAC_EXECUTABLE_NAME}`); + javacVersion = await this.executeJavacVersion(Constants.JAVAC_EXECUTABLE_NAME); + } catch (err) { /* intentionally left blank */ } + + return javacVersion; + } + + private async getJavacVersionFromJavaHome(): Promise { + let javacVersion: string = null; + + try { + const javaHome = process.env["JAVA_HOME"]; + const javacExecutableFile = this.hostInfo.isWindows ? `${Constants.JAVAC_EXECUTABLE_NAME}.exe` : Constants.JAVAC_EXECUTABLE_NAME; + + if (javaHome) { + const pathToJavaCompilerExecutable = path.join(javaHome, "bin", javacExecutableFile); + if (this.fileSystem.exists(pathToJavaCompilerExecutable)) { + javacVersion = await this.executeJavacVersion(pathToJavaCompilerExecutable); + } + } + } catch (err) { /* intentionally left blank */ } + + return javacVersion; + } + + private async executeJavacVersion(pathToJavaCompilerExecutable: string): Promise { + try { + const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`); + return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(`${output.stderr}${EOL}${output.stdout}`)[1]; + } catch (err) { + return null; + } + } } diff --git a/package-lock.json b/package-lock.json index 564c5785b4..e1c56c726c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.7.0", + "version": "1.8.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1016,12 +1016,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1036,17 +1038,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1163,7 +1168,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1175,6 +1181,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1189,6 +1196,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1196,12 +1204,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -1220,6 +1230,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1300,7 +1311,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1312,6 +1324,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1433,6 +1446,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/package.json b/package.json index dbaae2e253..b11ab238c3 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", "scripts": { - "test": "node_modules/.bin/istanbul cover node_modules/.bin/mocha -- --recursive" + "test": "node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive" }, "repository": { "type": "git", diff --git a/test/sys-info.ts b/test/sys-info.ts index 634e8631fa..fed762dbf9 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -82,6 +82,8 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID "npm -v": childProcessResult.npmV, "node -v": childProcessResult.nodeV, '"javac" -version': childProcessResult.javacVersion, + 'which javac': { result: '' }, + 'where javac': { result: '' }, "node-gyp -v": childProcessResult.nodeGypVersion, "xcodebuild -version": childProcessResult.xCodeVersion, "pod --version": childProcessResult.podVersion, @@ -178,16 +180,19 @@ describe("SysInfo unit tests", () => { describe("Should execute correct commands to check for", () => { let spawnFromEventCommand: string; - let execCommand: string; + let execCommands: string[] = []; + let fileSystem: any; + let hostInfo: any; beforeEach(() => { + execCommands = []; const childProcess: ChildProcess = { spawnFromEvent: async (command: string, args: string[], event: string) => { spawnFromEventCommand = `${command} ${args.join(" ")}`; return { stdout: "", stderr: "" }; }, exec: async (command: string) => { - execCommand = command; + execCommands.push(command); return { stdout: "", stderr: "" }; }, execFile: async () => { @@ -197,7 +202,17 @@ describe("SysInfo unit tests", () => { }; const helpers = new Helpers(null); - sysInfo = new SysInfo(childProcess, null, helpers, null, null, androidToolsInfo); + fileSystem = { + exists: () => false, + extractZip: () => Promise.resolve(), + readDirectory: () => Promise.resolve([]) + }; + + hostInfo = { + isWindows: false + }; + + sysInfo = new SysInfo(childProcess, fileSystem, helpers, hostInfo, null, androidToolsInfo); }); it("java compiler version when there is JAVA_HOME.", async () => { @@ -205,21 +220,31 @@ describe("SysInfo unit tests", () => { process.env[JavaHomeName] = "mock"; const pathToJavac = path.join(process.env[JavaHomeName], "bin", "javac"); + fileSystem.exists = () => true; await sysInfo.getJavaCompilerVersion(); process.env[JavaHomeName] = originalJavaHome; - assert.deepEqual(execCommand, `"${pathToJavac}" -version`); + assert.deepEqual(execCommands[0], `"${pathToJavac}" -version`); }); - it("java compiler version when there is no JAVA_HOME.", async () => { + it("java compiler version when there is no JAVA_HOME on non-Windows OS", async () => { const originalJavaHome = process.env[JavaHomeName]; delete process.env[JavaHomeName]; + await sysInfo.getJavaCompilerVersion(); + process.env[JavaHomeName] = originalJavaHome; + assert.deepEqual(execCommands, ['which javac', '"javac" -version']); + }); + + it("java compiler version when there is no JAVA_HOME on Window OS", async () => { + const originalJavaHome = process.env[JavaHomeName]; + hostInfo.isWindows = true; + delete process.env[JavaHomeName]; await sysInfo.getJavaCompilerVersion(); process.env[JavaHomeName] = originalJavaHome; - assert.deepEqual(execCommand, `"javac" -version`); + assert.deepEqual(execCommands, ['where javac', '"javac" -version']); }); }); @@ -352,7 +377,7 @@ describe("SysInfo unit tests", () => { childProcessResult.adbVersion = { result: null }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1"}, null); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1" }, null); const adbVersion = await sysInfo.getAdbVersion(); const isAndroidSdkConfiguredCorrectly = await sysInfo.isAndroidSdkConfiguredCorrectly(); assert.deepEqual(adbVersion, null); @@ -362,12 +387,12 @@ describe("SysInfo unit tests", () => { describe("pythonInfo", () => { it("should return null when platform is windows", async () => { - sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1"}, null); + sysInfo = mockSysInfo(childProcessResult, { isWindows: true, isDarwin: false, dotNetVersion: "4.5.1" }, null); const pythonInfo = await sysInfo.getPythonInfo(); assert.deepEqual(pythonInfo, null); }); it("should return null when platform is linux", async () => { - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1"}, null); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: false, dotNetVersion: "4.5.1" }, null); const pythonInfo = await sysInfo.getPythonInfo(); assert.deepEqual(pythonInfo, null); }); @@ -385,7 +410,7 @@ describe("SysInfo unit tests", () => { }); it("should return {isInstalled: true, isSixPackageInstalled: false} when python is installed but six package is not", async () => { childProcessResult.pythonInfo = { shouldThrowError: true, errorCode: 1 }; - sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1"}, null); + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion: "4.5.1" }, null); const pythonInfo = await sysInfo.getPythonInfo(); assert.deepEqual(pythonInfo, { isInstalled: true, isSixPackageInstalled: false }); }); @@ -528,12 +553,12 @@ ${expectedCliVersion}`; assert.deepEqual(result.isCocoaPodsWorkingCorrectly, true); assert.deepEqual(result.xcprojInfo, undefined); assert.deepEqual(result.isCocoaPodsUpdateRequired, false); - assert.deepEqual(result.pythonInfo, {isInstalled: false, isSixPackageInstalled: false, installationErrorMessage: "Cannot read property 'shouldThrowError' of undefined"}); + assert.deepEqual(result.pythonInfo, { isInstalled: false, isSixPackageInstalled: false, installationErrorMessage: "Cannot read property 'shouldThrowError' of undefined" }); }; it("iOS platform is specified", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); - const result = await sysInfo.getSysInfo({platform: "iOS"}); + const result = await sysInfo.getSysInfo({ platform: "iOS" }); assertCommonSysInfo(result); assertiOSSysInfo(result); @@ -547,7 +572,7 @@ ${expectedCliVersion}`; }); it("Android platform is specified", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }, { existsResult: true }); - const result = await sysInfo.getSysInfo({platform: "Android"}); + const result = await sysInfo.getSysInfo({ platform: "Android" }); assertCommonSysInfo(result); assertAndroidSysInfo(result); @@ -561,7 +586,7 @@ ${expectedCliVersion}`; assert.deepEqual(result.isCocoaPodsUpdateRequired, undefined); assert.deepEqual(result.pythonInfo, undefined); }); - it("no platform is specified", async() => { + it("no platform is specified", async () => { sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); const result = await sysInfo.getSysInfo(); assertCommonSysInfo(result); From e1024d7fa8bda51e9cc673a422c72a4ad5e05823 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 27 Mar 2019 23:34:00 +0200 Subject: [PATCH 119/169] feat: expose methods for getting JAVA version Expose methods for getting JAVA version from PATH, from JAVA_HOME and wrapper for both of them. This is required for some verifications around avdmanager executable --- lib/constants.ts | 1 + lib/sys-info.ts | 66 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/lib/constants.ts b/lib/constants.ts index 076da69faf..b23074945e 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -16,4 +16,5 @@ export class Constants { public static VERSION_PROPERTY_NAME = "version"; public static XCODE_MIN_REQUIRED_VERSION = 9; public static JAVAC_EXECUTABLE_NAME = "javac"; + public static JAVA_EXECUTABLE_NAME = "java"; } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index a92478d431..864d646fa4 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -22,6 +22,9 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private monoVerRegExp = /version (\d+[.]\d+[.]\d+) /gm; private javaCompilerVerCache: string; + private javaVerCache: string; + private javaVerJavaHomeCache: string; + private javaVerPathCache: string; private xCodeVerCache: string; private npmVerCache: string; private nodeVerCache: string; @@ -62,6 +65,25 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } + public getJavaVersion(): Promise { + return this.getValueForProperty(() => this.javaVerCache, async (): Promise => { + const javacVersion = (await this.getJavaVersionFromJavaHome()) || (await this.getJavaVersionFromPath()); + return javacVersion; + }); + } + + public getJavaVersionFromPath(): Promise { + return this.getValueForProperty(() => this.javaVerPathCache, (): Promise => { + return this.getVersionOfJavaExecutableFromPath(Constants.JAVA_EXECUTABLE_NAME); + }); + } + + public getJavaVersionFromJavaHome(): Promise { + return this.getValueForProperty(() => this.javaVerJavaHomeCache, (): Promise => { + return this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVA_EXECUTABLE_NAME); + }); + } + public getXcodeVersion(): Promise { return this.getValueForProperty(() => this.xCodeVerCache, async (): Promise => { if (this.hostInfo.isDarwin) { @@ -494,39 +516,47 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { } private async getJavacVersionFromPath(): Promise { - let javacVersion: string = null; - - try { - const detectionCommand = this.hostInfo.isWindows ? "where" : "which"; - // if this command succeeds, we have javac in the PATH. In case it is not there, it will throw an error. - await this.childProcess.exec(`${detectionCommand} ${Constants.JAVAC_EXECUTABLE_NAME}`); - javacVersion = await this.executeJavacVersion(Constants.JAVAC_EXECUTABLE_NAME); - } catch (err) { /* intentionally left blank */ } + return this.getVersionOfJavaExecutableFromPath(Constants.JAVAC_EXECUTABLE_NAME); + } - return javacVersion; + private getJavacVersionFromJavaHome(): Promise { + return this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVAC_EXECUTABLE_NAME); } - private async getJavacVersionFromJavaHome(): Promise { - let javacVersion: string = null; + private async getVersionOfJavaExecutableFromJavaHome(javaExecutableName: string): Promise { + let javaExecutableVersion: string = null; try { const javaHome = process.env["JAVA_HOME"]; - const javacExecutableFile = this.hostInfo.isWindows ? `${Constants.JAVAC_EXECUTABLE_NAME}.exe` : Constants.JAVAC_EXECUTABLE_NAME; + const javaExecutableFile = this.hostInfo.isWindows ? `${javaExecutableName}.exe` : javaExecutableName; if (javaHome) { - const pathToJavaCompilerExecutable = path.join(javaHome, "bin", javacExecutableFile); - if (this.fileSystem.exists(pathToJavaCompilerExecutable)) { - javacVersion = await this.executeJavacVersion(pathToJavaCompilerExecutable); + const pathToJavaExecutable = path.join(javaHome, "bin", javaExecutableFile); + if (this.fileSystem.exists(pathToJavaExecutable)) { + javaExecutableVersion = await this.getVersionOfJavaExecutable(pathToJavaExecutable); } } } catch (err) { /* intentionally left blank */ } - return javacVersion; + return javaExecutableVersion; + } + + private async getVersionOfJavaExecutableFromPath(javaExecutableName: string): Promise { + let javaExecutableVersion: string = null; + + try { + const detectionCommand = this.hostInfo.isWindows ? "where" : "which"; + // if this command succeeds, we have javac in the PATH. In case it is not there, it will throw an error. + await this.childProcess.exec(`${detectionCommand} ${javaExecutableName}`); + javaExecutableVersion = await this.getVersionOfJavaExecutable(javaExecutableName); + } catch (err) { /* intentionally left blank */ } + + return javaExecutableVersion; } - private async executeJavacVersion(pathToJavaCompilerExecutable: string): Promise { + private async getVersionOfJavaExecutable(pathToExecutable: string): Promise { try { - const output = await this.childProcess.exec(`"${pathToJavaCompilerExecutable}" -version`); + const output = await this.childProcess.exec(`"${pathToExecutable}" -version`); return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(`${output.stderr}${EOL}${output.stdout}`)[1]; } catch (err) { return null; From d17e9db55ab7e6aa7295f86604852dd25ff68d05 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 28 Mar 2019 15:54:10 +0200 Subject: [PATCH 120/169] fix: parse java output correctly --- lib/sys-info.ts | 36 ++++++++++------------ test/sys-info.ts | 69 +++++++++++++++++++++++++++++++++++++++++++ typings/interfaces.ts | 5 ++++ 3 files changed, 90 insertions(+), 20 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 864d646fa4..e096cab1fd 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -13,6 +13,7 @@ import { Constants } from "./constants"; export class SysInfo implements NativeScriptDoctor.ISysInfo { private static JAVA_COMPILER_VERSION_REGEXP = /^javac (.*)/im; + private static JAVA_VERSION_REGEXP = /^(?:(?:java)|(?:openjdk)).*?\"(.*)\"/im; private static XCODE_VERSION_REGEXP = /Xcode (.*)/; private static VERSION_REGEXP = /(\d{1,})\.(\d{1,})\.*([\w-]{0,})/m; private static CLI_OUTPUT_VERSION_REGEXP = /^(?:\d+\.){2}\d+.*?$/m; @@ -60,27 +61,29 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getJavaCompilerVersion(): Promise { return this.getValueForProperty(() => this.javaCompilerVerCache, async (): Promise => { - const javacVersion = (await this.getJavacVersionFromJavaHome()) || (await this.getJavacVersionFromPath()); + const javacVersion = (await this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVAC_EXECUTABLE_NAME, SysInfo.JAVA_COMPILER_VERSION_REGEXP)) || + (await this.getVersionOfJavaExecutableFromPath(Constants.JAVAC_EXECUTABLE_NAME, SysInfo.JAVA_COMPILER_VERSION_REGEXP)); + return javacVersion; }); } public getJavaVersion(): Promise { return this.getValueForProperty(() => this.javaVerCache, async (): Promise => { - const javacVersion = (await this.getJavaVersionFromJavaHome()) || (await this.getJavaVersionFromPath()); - return javacVersion; + const javaVersion = (await this.getJavaVersionFromJavaHome()) || (await this.getJavaVersionFromPath()); + return javaVersion; }); } public getJavaVersionFromPath(): Promise { return this.getValueForProperty(() => this.javaVerPathCache, (): Promise => { - return this.getVersionOfJavaExecutableFromPath(Constants.JAVA_EXECUTABLE_NAME); + return this.getVersionOfJavaExecutableFromPath(Constants.JAVA_EXECUTABLE_NAME, SysInfo.JAVA_VERSION_REGEXP); }); } public getJavaVersionFromJavaHome(): Promise { return this.getValueForProperty(() => this.javaVerJavaHomeCache, (): Promise => { - return this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVA_EXECUTABLE_NAME); + return this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVA_EXECUTABLE_NAME, SysInfo.JAVA_VERSION_REGEXP); }); } @@ -505,6 +508,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.dotNetVer = await this.hostInfo.dotNetVersion(); result.javacVersion = await this.getJavaCompilerVersion(); + result.javaVersion = await this.getJavaVersion(); result.adbVer = await this.getAdbVersion(config && config.androidToolsInfo && config.androidToolsInfo.pathToAdb); result.androidInstalled = await this.isAndroidInstalled(); result.monoVer = await this.getMonoVersion(); @@ -515,15 +519,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } - private async getJavacVersionFromPath(): Promise { - return this.getVersionOfJavaExecutableFromPath(Constants.JAVAC_EXECUTABLE_NAME); - } - - private getJavacVersionFromJavaHome(): Promise { - return this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVAC_EXECUTABLE_NAME); - } - - private async getVersionOfJavaExecutableFromJavaHome(javaExecutableName: string): Promise { + private async getVersionOfJavaExecutableFromJavaHome(javaExecutableName: string, regExp: RegExp): Promise { let javaExecutableVersion: string = null; try { @@ -533,7 +529,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { if (javaHome) { const pathToJavaExecutable = path.join(javaHome, "bin", javaExecutableFile); if (this.fileSystem.exists(pathToJavaExecutable)) { - javaExecutableVersion = await this.getVersionOfJavaExecutable(pathToJavaExecutable); + javaExecutableVersion = await this.getVersionOfJavaExecutable(pathToJavaExecutable, regExp); } } } catch (err) { /* intentionally left blank */ } @@ -541,23 +537,23 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { return javaExecutableVersion; } - private async getVersionOfJavaExecutableFromPath(javaExecutableName: string): Promise { + private async getVersionOfJavaExecutableFromPath(javaExecutableName: string, regExp: RegExp): Promise { let javaExecutableVersion: string = null; try { const detectionCommand = this.hostInfo.isWindows ? "where" : "which"; // if this command succeeds, we have javac in the PATH. In case it is not there, it will throw an error. await this.childProcess.exec(`${detectionCommand} ${javaExecutableName}`); - javaExecutableVersion = await this.getVersionOfJavaExecutable(javaExecutableName); + javaExecutableVersion = await this.getVersionOfJavaExecutable(javaExecutableName, regExp); } catch (err) { /* intentionally left blank */ } return javaExecutableVersion; } - private async getVersionOfJavaExecutable(pathToExecutable: string): Promise { + private async getVersionOfJavaExecutable(executable: string, regExp: RegExp): Promise { try { - const output = await this.childProcess.exec(`"${pathToExecutable}" -version`); - return SysInfo.JAVA_COMPILER_VERSION_REGEXP.exec(`${output.stderr}${EOL}${output.stdout}`)[1]; + const output = await this.childProcess.exec(`"${executable}" -version`); + return regExp.exec(`${output.stderr}${EOL}${output.stdout}`)[1]; } catch (err) { return null; } diff --git a/test/sys-info.ts b/test/sys-info.ts index fed762dbf9..9028d27e2c 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -31,6 +31,7 @@ interface IChildProcessResults { npmV: IChildProcessResultDescription; nodeV: IChildProcessResultDescription; javacVersion: IChildProcessResultDescription; + javaVersion: IChildProcessResultDescription; nodeGypVersion: IChildProcessResultDescription; xCodeVersion: IChildProcessResultDescription; adbVersion: IChildProcessResultDescription; @@ -82,8 +83,11 @@ function createChildProcessResults(childProcessResult: IChildProcessResults): ID "npm -v": childProcessResult.npmV, "node -v": childProcessResult.nodeV, '"javac" -version': childProcessResult.javacVersion, + '"java" -version': childProcessResult.javaVersion, 'which javac': { result: '' }, 'where javac': { result: '' }, + 'which java': { result: '' }, + 'where java': { result: '' }, "node-gyp -v": childProcessResult.nodeGypVersion, "xcodebuild -version": childProcessResult.xCodeVersion, "pod --version": childProcessResult.podVersion, @@ -246,6 +250,38 @@ describe("SysInfo unit tests", () => { process.env[JavaHomeName] = originalJavaHome; assert.deepEqual(execCommands, ['where javac', '"javac" -version']); }); + + it("java version when there is JAVA_HOME.", async () => { + const originalJavaHome = process.env[JavaHomeName]; + process.env[JavaHomeName] = "mock"; + + const pathToJava = path.join(process.env[JavaHomeName], "bin", "java"); + fileSystem.exists = () => true; + await sysInfo.getJavaVersion(); + + process.env[JavaHomeName] = originalJavaHome; + assert.deepEqual(execCommands[0], `"${pathToJava}" -version`); + }); + + it("java version when there is no JAVA_HOME on non-Windows OS", async () => { + const originalJavaHome = process.env[JavaHomeName]; + + delete process.env[JavaHomeName]; + await sysInfo.getJavaVersion(); + + process.env[JavaHomeName] = originalJavaHome; + assert.deepEqual(execCommands, ['which java', '"java" -version']); + }); + + it("java version when there is no JAVA_HOME on Window OS", async () => { + const originalJavaHome = process.env[JavaHomeName]; + hostInfo.isWindows = true; + delete process.env[JavaHomeName]; + await sysInfo.getJavaVersion(); + + process.env[JavaHomeName] = originalJavaHome; + assert.deepEqual(execCommands, ['where java', '"java" -version']); + }); }); describe("getSysInfo", () => { @@ -259,6 +295,11 @@ describe("SysInfo unit tests", () => { npmV: { result: setStdOut("2.14.1") }, nodeV: { result: setStdOut("v6.0.0") }, javacVersion: { result: setStdErr("javac 1.8.0_60") }, + javaVersion: { + result: setStdErr(`java version "1.8.0_202" +Java(TM) SE Runtime Environment (build 1.8.0_202-b08) +Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)`) + }, nodeGypVersion: { result: setStdOut("2.0.0") }, xCodeVersion: { result: setStdOut("Xcode 6.4.0") }, adbVersion: { result: setStdOut("Android Debug Bridge version 1.0.32") }, @@ -286,6 +327,7 @@ describe("SysInfo unit tests", () => { assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout); assert.deepEqual(result.nodeVer, "6.0.0"); assert.deepEqual(result.javacVersion, "1.8.0_60"); + assert.deepEqual(result.javaVersion, "1.8.0_202"); assert.deepEqual(result.nodeGypVer, childProcessResult.nodeGypVersion.result.stdout); assert.deepEqual(result.adbVer, "1.0.32"); assert.deepEqual(result.androidInstalled, true); @@ -477,6 +519,7 @@ ${expectedCliVersion}`; npmV: { shouldThrowError: true }, nodeV: { shouldThrowError: true }, javacVersion: { shouldThrowError: true }, + javaVersion: { shouldThrowError: true }, nodeGypVersion: { shouldThrowError: true }, xCodeVersion: { shouldThrowError: true }, adbVersion: { shouldThrowError: true }, @@ -594,5 +637,31 @@ ${expectedCliVersion}`; assertiOSSysInfo(result); }); }); + + describe("getJavaVersion", () => { + it("parses correctly OpenJDK output", async () => { + childProcessResult.javaVersion = { + result: setStdOut(`openjdk version "1.8.0_64" +OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_64-b08) +OpenJDK 64-Bit Server VM (build 25.202-b08, mixed mode)`) + }; + + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getJavaVersion(); + assert.equal(result, "1.8.0_64"); + }); + + it("parses correctly OpenJDK output", async () => { + childProcessResult.javaVersion = { + result: setStdOut(`java version "1.8.0_25" +Java(TM) SE Runtime Environment (build 1.8.0_25-b08) +Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)`) + }; + + sysInfo = mockSysInfo(childProcessResult, { isWindows: false, isDarwin: true, dotNetVersion }); + const result = await sysInfo.getJavaVersion(); + assert.equal(result, "1.8.0_25"); + }); + }); }); }); diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 3aebd53a06..5c05c9a6f6 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -317,6 +317,11 @@ declare module NativeScriptDoctor { * @type {string} */ javacVersion: string; + /** + * java version string as returned by `java -version`. + * @type {string} + */ + javaVersion: string; /** * true if the Android SDK Tools are installed and configured correctly. * @type {boolean} From 644c3816c79b0719093bdf13895a5d9787fb04eb Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 28 Mar 2019 16:19:05 +0200 Subject: [PATCH 121/169] release: cut 1.9.0 release --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e1c56c726c..6cbd27a901 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.8.1", + "version": "1.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b11ab238c3..d51f0f4800 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.8.1", + "version": "1.9.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 9c6cd0d0fb44117796f8c8c9bd19265f84c75160 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 28 Mar 2019 16:57:38 +0200 Subject: [PATCH 122/169] fix: add missing typings --- package-lock.json | 3585 ---------------------- test/android-local-build-requirements.ts | 3 + typings/interfaces.ts | 18 + 3 files changed, 21 insertions(+), 3585 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 6cbd27a901..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,3585 +0,0 @@ -{ - "name": "nativescript-doctor", - "version": "1.9.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/chai": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.0.tgz", - "integrity": "sha512-OuYBlXWHYthxIudMXMeQr92f6D97YoT9CUYCRb0BEP4OavC95jNcczjjr4Ob3H5E1IqlWqwj+leUZPSeth27Qw==", - "dev": true - }, - "@types/events": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "2.2.32", - "resolved": "http://registry.npmjs.org/@types/mocha/-/mocha-2.2.32.tgz", - "integrity": "sha1-3aDabq8hldL/gI9CoXJbGhnn7Wk=", - "dev": true - }, - "@types/node": { - "version": "10.12.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.1.tgz", - "integrity": "sha512-i1sl+WCX2OCHeUi9oi7PiCNUtYFrpWhpcx878vpeq/tlZTKzcFdHePlyFHVbWqeuKN0SRPl/9ZFDSTsfv9h7VQ==", - "dev": true - }, - "@types/rimraf": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz", - "integrity": "sha512-Hm/bnWq0TCy7jmjeN5bKYij9vw5GrDFWME4IuxV08278NtU/VdGbzsBohcCUJ7+QMqmUq5hpRKB39HeQWJjztQ==", - "dev": true, - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, - "@types/semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", - "dev": true - }, - "@types/temp": { - "version": "0.8.29", - "resolved": "http://registry.npmjs.org/@types/temp/-/temp-0.8.29.tgz", - "integrity": "sha1-w83BE+PBOPkOXpcNUeQbC39iZ40=", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/winreg": { - "version": "1.2.30", - "resolved": "http://registry.npmjs.org/@types/winreg/-/winreg-1.2.30.tgz", - "integrity": "sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg=", - "dev": true - }, - "@types/yauzl": { - "version": "2.9.0", - "resolved": "http://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.0.tgz", - "integrity": "sha512-KVQbjKvieCq6d5LqZ8KIzzwygF88fWC+l7wvPbRPM3OI3f9ZAlhaKUlk3kjiyvOMqopSTM7enjduXXl5B+msXw==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/node": "*" - } - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", - "dev": true - }, - "body": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", - "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", - "dev": true, - "requires": { - "continuable-cache": "^0.3.1", - "error": "^7.0.0", - "raw-body": "~1.1.0", - "safe-json-parse": "~1.0.1" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", - "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", - "dev": true, - "requires": { - "assertion-error": "^1.0.1", - "check-error": "^1.0.1", - "deep-eql": "^3.0.0", - "get-func-name": "^2.0.0", - "pathval": "^1.0.0", - "type-detect": "^4.0.0" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "coffeescript": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", - "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true, - "optional": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "continuable-cache": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", - "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "csproj2ts": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/csproj2ts/-/csproj2ts-1.1.0.tgz", - "integrity": "sha512-sk0RTT51t4lUNQ7UfZrqjQx7q4g0m3iwNA6mvyh7gLsgQYvwKzfdyoAgicC9GqJvkoIkU0UmndV9c7VZ8pJ45Q==", - "dev": true, - "requires": { - "es6-promise": "^4.1.1", - "lodash": "^4.17.4", - "semver": "^5.4.1", - "xml2js": "^0.4.19" - }, - "dependencies": { - "es6-promise": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", - "dev": true - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "error": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", - "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", - "dev": true, - "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-promise": { - "version": "0.1.2", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-0.1.2.tgz", - "integrity": "sha1-8RLCn+paCZhTn8tqL9IUQ9KPBfc=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "eventemitter2": { - "version": "0.4.14", - "resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "requires": { - "pend": "~1.2.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "findup-sync": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", - "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", - "dev": true, - "requires": { - "glob": "~5.0.0" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true - } - } - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "dev": true, - "requires": { - "globule": "^1.0.0" - } - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "globule": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", - "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", - "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "grunt": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.3.tgz", - "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==", - "dev": true, - "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", - "eventemitter2": "~0.4.13", - "exit": "~0.1.1", - "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", - "iconv-lite": "~0.4.13", - "js-yaml": "~3.5.2", - "minimatch": "~3.0.2", - "mkdirp": "~0.5.1", - "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" - }, - "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "grunt-cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", - "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", - "dev": true, - "requires": { - "findup-sync": "~0.3.0", - "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - } - } - }, - "grunt-contrib-clean": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.0.0.tgz", - "integrity": "sha1-ay7ZQRfix//jLuBFeMlv5GJam20=", - "dev": true, - "requires": { - "async": "^1.5.2", - "rimraf": "^2.5.1" - } - }, - "grunt-contrib-watch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", - "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", - "dev": true, - "requires": { - "async": "^2.6.0", - "gaze": "^1.1.0", - "lodash": "^4.17.10", - "tiny-lr": "^1.1.1" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - } - } - }, - "grunt-known-options": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", - "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", - "dev": true - }, - "grunt-legacy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", - "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", - "dev": true, - "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.5" - } - }, - "grunt-legacy-log-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", - "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", - "dev": true, - "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "grunt-legacy-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", - "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", - "dev": true, - "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "grunt-shell": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-2.0.0.tgz", - "integrity": "sha1-Gb/NeysDOGFzEkT/mUpruLxqsmM=", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "npm-run-path": "^2.0.0" - } - }, - "grunt-ts": { - "version": "6.0.0-beta.21", - "resolved": "https://registry.npmjs.org/grunt-ts/-/grunt-ts-6.0.0-beta.21.tgz", - "integrity": "sha512-LhcTFTSWYHZEmHAl+7jHUPsOcQ4LSKZWrNDo5FcyQTuTWs3x82M03I1nALXBZ4NJOvcTJkQmXZV8/l3W+wubZQ==", - "dev": true, - "requires": { - "chokidar": "^2.0.4", - "csproj2ts": "^1.1.0", - "detect-indent": "^4.0.0", - "detect-newline": "^2.1.0", - "es6-promise": "~0.1.1", - "jsmin2": "^1.2.1", - "lodash": "~4.17.10", - "ncp": "0.5.1", - "rimraf": "2.2.6", - "semver": "^5.3.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.2.6", - "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz", - "integrity": "sha1-xZWXVpsU2VatKcrMQr3d9fDqT0w=", - "dev": true - } - } - }, - "grunt-tslint": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/grunt-tslint/-/grunt-tslint-3.3.0.tgz", - "integrity": "sha1-1IYDHFQS2IQsixJuyBRh2qmJg6M=", - "dev": true - }, - "handlebars": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", - "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", - "dev": true, - "requires": { - "async": "^2.5.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, - "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "istanbul": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", - "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "js-yaml": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz", - "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=", - "dev": true, - "requires": { - "argparse": "^1.0.2", - "esprima": "^2.6.0" - } - }, - "jsmin2": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jsmin2/-/jsmin2-1.2.1.tgz", - "integrity": "sha1-iPvi+/dfCpH2YCD9mBzWk/S/5X4=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "livereload-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.3.0.tgz", - "integrity": "sha512-j1R0/FeGa64Y+NmqfZhyoVRzcFlOZ8sNlKzHjh4VvLULFACZhn68XrX5DFg2FhMvSMJmROuFxRSa560ECWKBMg==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "meow": { - "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "commander": { - "version": "2.15.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "ncp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/ncp/-/ncp-0.5.1.tgz", - "integrity": "sha1-dDmFMW49tFkoG1hxaehFc1oFQ58=", - "dev": true - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", - "integrity": "sha1-g88FxtZFj8TVrGNi6jJdkvJ1Qhc=", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "raw-body": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", - "dev": true, - "requires": { - "bytes": "1", - "string_decoder": "0.10" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.5.4", - "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-json-parse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", - "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==" - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdx-correct": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", - "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz", - "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "string-template": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "temp": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", - "requires": { - "os-tmpdir": "^1.0.0", - "rimraf": "~2.2.6" - }, - "dependencies": { - "rimraf": { - "version": "2.2.8", - "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" - } - } - }, - "tiny-lr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", - "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", - "dev": true, - "requires": { - "body": "^5.1.0", - "debug": "^3.1.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.3.0", - "object-assign": "^4.1.0", - "qs": "^6.4.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "tslint": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-3.15.1.tgz", - "integrity": "sha1-2hZcqT2P3CwIa1EWXuG6y0jJjqU=", - "dev": true, - "requires": { - "colors": "^1.1.2", - "diff": "^2.2.1", - "findup-sync": "~0.3.0", - "glob": "^7.0.3", - "optimist": "~0.6.0", - "resolve": "^1.1.7", - "underscore.string": "^3.3.4" - }, - "dependencies": { - "diff": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", - "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=", - "dev": true - }, - "underscore.string": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", - "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", - "dev": true, - "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" - } - } - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typescript": { - "version": "2.0.3", - "resolved": "http://registry.npmjs.org/typescript/-/typescript-2.0.3.tgz", - "integrity": "sha1-M97J6uhrju4yfdQZygUMhTyr1RQ=", - "dev": true - }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, - "underscore.string": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", - "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", - "dev": true, - "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", - "dev": true, - "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "winreg": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", - "integrity": "sha1-hQmvo7ccW70RCm18YkfsZ3NsWY8=" - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "dev": true, - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" - } - }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } -} diff --git a/test/android-local-build-requirements.ts b/test/android-local-build-requirements.ts index e36dc632e9..cd6c7125df 100644 --- a/test/android-local-build-requirements.ts +++ b/test/android-local-build-requirements.ts @@ -23,6 +23,9 @@ describe("androidLocalBuildRequirements", () => { const sysInfo: NativeScriptDoctor.ISysInfo = { getJavaCompilerVersion: async (): Promise => results.hasOwnProperty("getJavaCompilerVersion") ? results.getJavaCompilerVersion : "8.0.0", + getJavaVersion: async (): Promise => results.hasOwnProperty("getJavaVersion") ? results.getJavaCompilerVersion : "8.0.0", + getJavaVersionFromJavaHome: async (): Promise => results.hasOwnProperty("getJavaVersionFromJavaHome") ? results.getJavaCompilerVersion : "8.0.0", + getJavaVersionFromPath: async (): Promise => results.hasOwnProperty("getJavaVersionFromPath") ? results.getJavaCompilerVersion : "8.0.0", getAdbVersion: async (pathToAdb?: string): Promise => results.hasOwnProperty("getAdbVersion") ? results.getAdbVersion : "1.0.39", getXcodeVersion: async (): Promise => undefined, getNodeVersion: async (): Promise => undefined, diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 5c05c9a6f6..37f7c490fb 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -9,6 +9,24 @@ declare module NativeScriptDoctor { */ getJavaCompilerVersion(): Promise; + /** + * Returns the currently installed Java version. + * @return {Promise} The currently installed Java version. + */ + getJavaVersion(): Promise; + + /** + * Gets JAVA version based on the executable in PATH. + * @return {Promise} + */ + getJavaVersionFromPath(): Promise; + + /** + * Gets JAVA version based on the JAVA from JAVA_HOME. + * @return {Promise} + */ + getJavaVersionFromJavaHome(): Promise; + /** * Returns the currently installed version of Xcode. * @return {Promise} Returns the currently installed version of Xcode or null if Xcode is not installed or executed on Linux or Windows. From 1d934b8dbe5a4f82196e3fed6a44eb4d26ff7ad5 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 28 Mar 2019 16:58:12 +0200 Subject: [PATCH 123/169] release: cut 1.9.1 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d51f0f4800..be482f5d21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.9.0", + "version": "1.9.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 0e6e1b924d40ebb3609104417f50fd7867054e67 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 1 Apr 2019 18:46:16 +0300 Subject: [PATCH 124/169] fix: javac detection does not work as required by Gradle The current `javac` detection tries to get the `javac` path from JAVA_HOME and to verify it is correct. In case it fails somewhere, it fallbacks to check the `javac` from PATH. So, from users' perspective it seems javac is setup correctly. However, Gradle works in slightly different manner - it checks if you have JAVA_HOME and if so - verifies `java` from it. In case there's no `java` in the `$JAVA_HOME/bin/java`, an error is thrown. Make our check for `javac` in the same way - in case you have set JAVA_HOME, we'll verify `javac` from there. This is exactly the same as the one we had prior 1.9.0 version, so this is just a regression fix. Add unit tests to cover this scenario. --- lib/sys-info.ts | 2 +- test/sys-info.ts | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index e096cab1fd..46b8cfebfa 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -61,7 +61,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public getJavaCompilerVersion(): Promise { return this.getValueForProperty(() => this.javaCompilerVerCache, async (): Promise => { - const javacVersion = (await this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVAC_EXECUTABLE_NAME, SysInfo.JAVA_COMPILER_VERSION_REGEXP)) || + const javacVersion = process.env["JAVA_HOME"] ? (await this.getVersionOfJavaExecutableFromJavaHome(Constants.JAVAC_EXECUTABLE_NAME, SysInfo.JAVA_COMPILER_VERSION_REGEXP)) : (await this.getVersionOfJavaExecutableFromPath(Constants.JAVAC_EXECUTABLE_NAME, SysInfo.JAVA_COMPILER_VERSION_REGEXP)); return javacVersion; diff --git a/test/sys-info.ts b/test/sys-info.ts index 9028d27e2c..b68bffbcef 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -241,6 +241,31 @@ describe("SysInfo unit tests", () => { assert.deepEqual(execCommands, ['which javac', '"javac" -version']); }); + it("null when there is incorrect JAVA_HOME on non-Windows OS", async () => { + const originalJavaHome = process.env[JavaHomeName]; + process.env[JavaHomeName] = "/some/invalid/dir/name/where/java/does/not/exist"; + + const result = await sysInfo.getJavaCompilerVersion(); + + process.env[JavaHomeName] = originalJavaHome; + + assert.deepEqual(result, null); + assert.deepEqual(execCommands, []); + }); + + it("null when there is incorrect JAVA_HOME on Window OS", async () => { + const originalJavaHome = process.env[JavaHomeName]; + hostInfo.isWindows = true; + process.env[JavaHomeName] = "C:\\Program Files\\Not existing dir"; + + const result = await sysInfo.getJavaCompilerVersion(); + + process.env[JavaHomeName] = originalJavaHome; + + assert.deepEqual(result, null); + assert.deepEqual(execCommands, []); + }); + it("java compiler version when there is no JAVA_HOME on Window OS", async () => { const originalJavaHome = process.env[JavaHomeName]; hostInfo.isWindows = true; From 6cd9eafdd9416dbf5d2ba063e0c6d0f7b5b06e10 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 2 Apr 2019 10:23:53 +0300 Subject: [PATCH 125/169] relese: cut 1.9.2 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be482f5d21..784b403d2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.9.1", + "version": "1.9.2", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 1a580192e7e0dd695e1eec5de6c5c7dd26638090 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 17 Jun 2019 17:31:04 +0300 Subject: [PATCH 126/169] feat: set min required Xcode version to 10 With NativeScript 6.0.0 release we will require Xcode 10 as min supported. --- lib/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/constants.ts b/lib/constants.ts index b23074945e..499b1b79be 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -14,7 +14,7 @@ export class Constants { public static NATIVESCRIPT_KEY = "nativescript"; public static ANDROID_RUNTIME = "tns-android"; public static VERSION_PROPERTY_NAME = "version"; - public static XCODE_MIN_REQUIRED_VERSION = 9; + public static XCODE_MIN_REQUIRED_VERSION = 10; public static JAVAC_EXECUTABLE_NAME = "javac"; public static JAVA_EXECUTABLE_NAME = "java"; } From d88db1794fabc6d7d81450eea8deef463cec4edb Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Mon, 17 Jun 2019 17:32:03 +0300 Subject: [PATCH 127/169] chore: set version to 1.10.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 784b403d2d..d2f823c33a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.9.2", + "version": "1.10.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 66d7ec2b490223723febfc0dffa8702aa9d6464f Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Tue, 23 Jul 2019 16:49:21 +0300 Subject: [PATCH 128/169] feat: add target validation and more tools info --- .gitignore | 2 +- lib/android-tools-info.ts | 102 +++++++++++++++-------- package.json | 9 +- test/android-local-build-requirements.ts | 6 +- test/sys-info.ts | 6 +- tslint.json | 55 ++++++++---- typings/interfaces.ts | 10 +++ 7 files changed, 134 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index b67e3ae40d..970a48f281 100644 --- a/.gitignore +++ b/.gitignore @@ -64,5 +64,5 @@ test-reports.xml *.js *.js.map /lib/.d.ts - +.d.ts !/*.js diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 9697a1f719..9f4420e2c9 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -6,10 +6,11 @@ import { Helpers } from './helpers'; import { EOL } from "os"; import * as semver from "semver"; import * as path from "path"; +import * as _ from "lodash"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { - private static ANDROID_TARGET_PREFIX = "android"; - private static SUPPORTED_TARGETS = [ + public readonly ANDROID_TARGET_PREFIX = "android"; + public readonly SUPPORTED_TARGETS = [ "android-17", "android-18", "android-19", @@ -22,13 +23,15 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "android-27", "android-28", ]; - private static MIN_REQUIRED_COMPILE_TARGET = 28; - private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; - private static VERSION_REGEX = /((\d+\.){2}\d+)/; + public readonly MIN_REQUIRED_COMPILE_TARGET = 28; + public readonly REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; + public readonly VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; - private androidHome = process.env["ANDROID_HOME"]; + public get androidHome(): string { + return process.env["ANDROID_HOME"]; + } private pathToEmulatorExecutable: string; constructor(private childProcess: ChildProcess, @@ -40,8 +43,11 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (!this.toolsInfo) { const infoData: NativeScriptDoctor.IAndroidToolsInfoData = Object.create(null); infoData.androidHomeEnvVar = this.androidHome; - infoData.compileSdkVersion = this.getCompileSdk(); + infoData.installedTargets = this.getInstalledTargets(); + infoData.latestValidAndroidTarget = this.getLatestValidAndroidTarget(infoData.installedTargets); + infoData.compileSdkVersion = this.getCompileSdk(infoData.latestValidAndroidTarget); infoData.buildToolsVersion = this.getBuildToolsVersion(); + infoData.maxSupportedSdkVersion = this.getMaxSupportedVersion(); this.toolsInfo = infoData; } @@ -55,7 +61,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const isAndroidHomeValid = this.isAndroidHomeValid(); if (!toolsInfoData.compileSdkVersion) { errors.push({ - warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later.`, + warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${this.MIN_REQUIRED_COMPILE_TARGET} or later.`, additionalInformation: `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage your Android SDK versions.`, platforms: [Constants.ANDROID_PLATFORM_NAME] }); @@ -93,7 +99,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + " described in " + this.getSystemRequirementsLink(); - const matchingVersion = this.helpers.appendZeroesToVersion(installedJavaCompilerVersion || "", 3).match(AndroidToolsInfo.VERSION_REGEX); + const matchingVersion = this.helpers.appendZeroesToVersion(installedJavaCompilerVersion || "", 3).match(this.VERSION_REGEX); const installedJavaCompilerSemverVersion = matchingVersion && matchingVersion[1]; if (installedJavaCompilerSemverVersion) { let warning: string = null; @@ -145,7 +151,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public async getPathToAdbFromAndroidHome(): Promise { if (this.androidHome) { - let pathToAdb = path.join(this.androidHome, "platform-tools", "adb"); + const pathToAdb = path.join(this.androidHome, "platform-tools", "adb"); try { await this.childProcess.execFile(pathToAdb, ["help"]); return pathToAdb; @@ -179,6 +185,43 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } + public validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] { + const errors: NativeScriptDoctor.IWarning[] = []; + const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; + const targetSupported = _.includes(this.SUPPORTED_TARGETS, newTarget); + + if (!_.includes(this.SUPPORTED_TARGETS, newTarget)) { + const supportedVersions = this.SUPPORTED_TARGETS.sort(); + const minSupportedVersion = this.parseAndroidSdkString(_.first(supportedVersions)); + + if (!targetSupported && targetSdk && (targetSdk < minSupportedVersion)) { + errors.push({ + warning:`The selected Android target SDK ${newTarget} is not supported. You must target ${minSupportedVersion} or later.`, + additionalInformation: "", + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); + } + } + + return []; + } + + public validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] { + const errors: NativeScriptDoctor.IWarning[] = []; + const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; + const targetSupported = _.includes(this.SUPPORTED_TARGETS, newTarget); + + if (!targetSupported && !targetSdk || targetSdk > this.getMaxSupportedVersion()) { + errors.push({ + warning:`Support for the selected Android target SDK ${newTarget} is not verified. Your Android app might not work as expected.`, + additionalInformation: "", + platforms: [Constants.ANDROID_PLATFORM_NAME] + }); + } + + return errors; + } + public getPathToEmulatorExecutable(): string { if (!this.pathToEmulatorExecutable) { const emulatorExecutableName = "emulator"; @@ -222,12 +265,11 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return sdkManagementToolPath; } - private getCompileSdk(): number { - let latestValidAndroidTarget = this.getLatestValidAndroidTarget(); + private getCompileSdk(latestValidAndroidTarget: string): number { if (latestValidAndroidTarget) { - let integerVersion = this.parseAndroidSdkString(latestValidAndroidTarget); + const integerVersion = this.parseAndroidSdkString(latestValidAndroidTarget); - if (integerVersion && integerVersion >= AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET) { + if (integerVersion && integerVersion >= this.MIN_REQUIRED_COMPILE_TARGET) { return integerVersion; } } @@ -236,11 +278,11 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private getMatchingDir(pathToDir: string, versionRange: string): string { let selectedVersion: string; if (this.fs.exists(pathToDir)) { - let subDirs = this.fs.readDirectory(pathToDir); + const subDirs = this.fs.readDirectory(pathToDir); - let subDirsVersions = subDirs + const subDirsVersions = subDirs .map(dirName => { - let dirNameGroups = dirName.match(AndroidToolsInfo.VERSION_REGEX); + const dirNameGroups = dirName.match(this.VERSION_REGEX); if (dirNameGroups) { return dirNameGroups[1]; } @@ -249,7 +291,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { }) .filter(dirName => !!dirName); - let version = semver.maxSatisfying(subDirsVersions, versionRange); + const version = semver.maxSatisfying(subDirsVersions, versionRange); if (version) { selectedVersion = subDirs.find(dir => dir.indexOf(version) !== -1); } @@ -259,36 +301,26 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } private getBuildToolsRange(): string { - return `${AndroidToolsInfo.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion()}`; + return `${this.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion()}`; } private getBuildToolsVersion(): string { let buildToolsVersion: string; if (this.androidHome) { - let pathToBuildTools = path.join(this.androidHome, "build-tools"); - let buildToolsRange = this.getBuildToolsRange(); + const pathToBuildTools = path.join(this.androidHome, "build-tools"); + const buildToolsRange = this.getBuildToolsRange(); buildToolsVersion = this.getMatchingDir(pathToBuildTools, buildToolsRange); } return buildToolsVersion; } - private getLatestValidAndroidTarget(): string { - const installedTargets = this.getInstalledTargets(); - let latestValidAndroidTarget: string; - const sortedAndroidToolsInfo = AndroidToolsInfo.SUPPORTED_TARGETS.sort(); - - sortedAndroidToolsInfo.forEach(s => { - if (installedTargets.indexOf(s) >= 0) { - latestValidAndroidTarget = s; - } - }); - - return latestValidAndroidTarget; + private getLatestValidAndroidTarget(installedTargets: string[]): string { + return _.findLast(this.SUPPORTED_TARGETS.sort(), supportedTarget => _.includes(installedTargets, supportedTarget)); } private parseAndroidSdkString(androidSdkString: string): number { - return parseInt(androidSdkString.replace(`${AndroidToolsInfo.ANDROID_TARGET_PREFIX}-`, "")); + return parseInt(androidSdkString.replace(`${this.ANDROID_TARGET_PREFIX}-`, "")); } private getInstalledTargets(): string[] { @@ -305,7 +337,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } private getMaxSupportedVersion(): number { - return this.parseAndroidSdkString(AndroidToolsInfo.SUPPORTED_TARGETS.sort()[AndroidToolsInfo.SUPPORTED_TARGETS.length - 1]); + return this.parseAndroidSdkString(this.SUPPORTED_TARGETS.sort()[this.SUPPORTED_TARGETS.length - 1]); } private getSystemRequirementsLink(): string { diff --git a/package.json b/package.json index d2f823c33a..bd6116c035 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "homepage": "https://github.com/NativeScript/nativescript-doctor#readme", "devDependencies": { "@types/chai": "4.1.0", + "@types/lodash": "4.14.123", "@types/mocha": "2.2.32", "@types/rimraf": "2.0.2", "@types/semver": "5.5.0", @@ -36,12 +37,14 @@ "grunt-contrib-watch": "1.1.0", "grunt-shell": "2.0.0", "grunt-ts": "6.0.0-beta.21", - "grunt-tslint": "3.3.0", + "grunt-tslint": "5.0.2", "istanbul": "0.4.5", + "lodash": "4.17.11", "mocha": "5.2.0", "rimraf": "2.5.4", - "tslint": "3.15.1", - "typescript": "2.0.3" + "tslint": "5.14.0", + "tslint-microsoft-contrib": "6.1.0", + "typescript": "3.3.4000" }, "dependencies": { "osenv": "0.1.3", diff --git a/test/android-local-build-requirements.ts b/test/android-local-build-requirements.ts index cd6c7125df..4be02230ba 100644 --- a/test/android-local-build-requirements.ts +++ b/test/android-local-build-requirements.ts @@ -13,12 +13,16 @@ describe("androidLocalBuildRequirements", () => { describe("checkRequirements", () => { const setupTestCase = (results: ITestCaseData): AndroidLocalBuildRequirements => { const androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo = { + ANDROID_TARGET_PREFIX: "", + androidHome: "", validateInfo: (): NativeScriptDoctor.IWarning[] => results.validateInfo || [], validateAndroidHomeEnvVariable: (): NativeScriptDoctor.IWarning[] => [], getToolsInfo: (): NativeScriptDoctor.IAndroidToolsInfoData => null, validateJavacVersion: (installedJavaVersion: string, projectDir?: string, runtimeVersion?: string): NativeScriptDoctor.IWarning[] => results.validateJavacVersion || [], getPathToAdbFromAndroidHome: async (): Promise => undefined, - getPathToEmulatorExecutable: (): string => undefined + getPathToEmulatorExecutable: (): string => undefined, + validateMinSupportedTargetSdk: (): NativeScriptDoctor.IWarning[] => [], + validataMaxSupportedTargetSdk: (): NativeScriptDoctor.IWarning[] => [] }; const sysInfo: NativeScriptDoctor.ISysInfo = { diff --git a/test/sys-info.ts b/test/sys-info.ts index b68bffbcef..5f53f53024 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -57,6 +57,8 @@ interface IFileSystemMockOptions { } const androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo = { + ANDROID_TARGET_PREFIX: "", + androidHome: "", getPathToAdbFromAndroidHome: async () => { return "adb"; }, @@ -74,7 +76,9 @@ const androidToolsInfo: NativeScriptDoctor.IAndroidToolsInfo = { }, validateJavacVersion: (): any[] => { return []; - } + }, + validateMinSupportedTargetSdk: (): NativeScriptDoctor.IWarning[] => [], + validataMaxSupportedTargetSdk: (): NativeScriptDoctor.IWarning[] => [] }; function createChildProcessResults(childProcessResult: IChildProcessResults): IDictionary { diff --git a/tslint.json b/tslint.json index 4f0f281bc8..3c69354342 100644 --- a/tslint.json +++ b/tslint.json @@ -1,49 +1,74 @@ { + "rulesDirectory": "node_modules/tslint-microsoft-contrib", "rules": { "class-name": true, "curly": true, "eofline": true, - "indent": true, + "mocha-avoid-only": true, + "indent": [ + true, + "tabs" + ], "interface-name": true, "jsdoc-format": true, - "max-line-length": [false, 140], + "max-line-length": [ + false, + 140 + ], + "prefer-const": true, "no-consecutive-blank-lines": true, "no-construct": true, "no-debugger": true, - "no-duplicate-key": true, "no-duplicate-variable": true, "no-shadowed-variable": true, "no-empty": true, "no-eval": true, "no-switch-case-fall-through": true, "no-trailing-whitespace": true, - "no-unreachable": true, "no-unused-expression": true, - "no-unused-variable": true, "no-use-before-declare": true, "no-var-keyword": true, "no-var-requires": false, "one-line": [ true, - "check-open-brace", "check-catch", - "check-else" + "check-finally", + "check-else", + "check-open-brace", + "check-whitespace" + ], + "no-floating-promises": true, + "quotemark": [ + false, + "double" ], - "quotemark": [false, "double"], "semicolon": true, + "space-before-function-paren": false, "switch-default": false, - "triple-equals": [true, "allow-null-check"], - "use-strict": true, - "variable-name": [false, "allow-leading-underscore"], - "whitespace": [ + "trailing-comma": [ false, + { + "multiline": "always", + "singleline": "always" + } + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "use-isnan": true, + "variable-name": [ + true, + "ban-keywords", + "allow-leading-underscore" + ], + "whitespace": [ + true, "check-branch", "check-decl", "check-operator", "check-module", - "check-separator", - "check-type", - "check-typecast" + "check-separator" ] } } \ No newline at end of file diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 37f7c490fb..4932897375 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -453,6 +453,9 @@ declare module NativeScriptDoctor { * Describes methods for getting and validating Android tools. */ interface IAndroidToolsInfo { + ANDROID_TARGET_PREFIX: string; + androidHome: string; + /** * Returns the Android tools info. * @return {NativeScriptDoctor.IAndroidToolsInfoData} returns the Android tools info. @@ -487,6 +490,9 @@ declare module NativeScriptDoctor { */ validateAndroidHomeEnvVariable(): NativeScriptDoctor.IWarning[]; + validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[]; + validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[]; + /** * Returns the path to the emulator executable. * @return {string} The path to the emulator executable. @@ -512,5 +518,9 @@ declare module NativeScriptDoctor { * The latest installed version of Android SDK that satisfies CLI's requirements. */ compileSdkVersion: number; + + installedTargets: string[]; + maxSupportedSdkVersion: number; + latestValidAndroidTarget: string; } } From b22e93b91f93b31503d6dab2e23820ad8018b50f Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 24 Jul 2019 12:18:27 +0300 Subject: [PATCH 129/169] chore: fix linting --- Gruntfile.js | 3 +- lib/doctor.ts | 2 +- lib/helpers.ts | 2 +- lib/sys-info.ts | 4 +- lib/wrappers/file-system.ts | 16 +++---- test/ios-local-build-requirements.ts | 4 +- test/sys-info.ts | 4 +- test/wrappers/file-system.ts | 68 ++++++++++++++-------------- 8 files changed, 52 insertions(+), 51 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index e3fabf9117..252b427b3a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -29,7 +29,8 @@ module.exports = function (grunt) { src: ["lib/**/*.ts", "test/**/*.ts", "typings/**/*.ts", "!**/*.d.ts"] }, options: { - configuration: grunt.file.readJSON("./tslint.json") + configuration: grunt.file.readJSON("./tslint.json"), + project: "tsconfig.json" } } }, diff --git a/lib/doctor.ts b/lib/doctor.ts index db394870ee..9306ed78d4 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -149,7 +149,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { ); if (sysInfoData.xcodeVer && sysInfoData.cocoaPodsVer) { - let isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly(); + const isCocoaPodsWorkingCorrectly = await this.sysInfo.isCocoaPodsWorkingCorrectly(); result = result.concat( this.processSysInfoItem({ item: isCocoaPodsWorkingCorrectly, diff --git a/lib/helpers.ts b/lib/helpers.ts index cf3ef4e689..d72bf9de86 100644 --- a/lib/helpers.ts +++ b/lib/helpers.ts @@ -5,7 +5,7 @@ export class Helpers { public getPropertyName(method: Function): string { if (method) { - let match = method.toString().match(/(?:return\s+?.*\.(.+);)|(?:=>\s*?.*\.(.+)\b)/); + const match = method.toString().match(/(?:return\s+?.*\.(.+);)|(?:=>\s*?.*\.(.+)\b)/); if (match) { return (match[1] || match[2]).trim(); } diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 46b8cfebfa..76fdd1b12f 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -265,7 +265,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { const xcodeProjectDir = path.join(tempDirectory, "cocoapods"); try { - let spawnResult = await this.childProcess.spawnFromEvent("pod", ["install"], "exit", { spawnOptions: { cwd: xcodeProjectDir } }); + const spawnResult = await this.childProcess.spawnFromEvent("pod", ["install"], "exit", { spawnOptions: { cwd: xcodeProjectDir } }); if (spawnResult.exitCode) { return false; } else { @@ -333,7 +333,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { public isCocoaPodsUpdateRequired(): Promise { return this.getValueForProperty(() => this.isCocoaPodsUpdateRequiredCache, async (): Promise => { - let xcprojInfo = await this.getXcprojInfo(); + const xcprojInfo = await this.getXcprojInfo(); if (xcprojInfo.shouldUseXcproj && !xcprojInfo.xcprojAvailable) { return true; } else { diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 85eb1cb8bc..fcfef69558 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -7,8 +7,8 @@ const access = util.promisify(fs.access); const mkdir = util.promisify(fs.mkdir); export class FileSystem { - public exists(path: string): boolean { - return fs.existsSync(path); + public exists(filePath: string): boolean { + return fs.existsSync(filePath); } public extractZip(pathToZip: string, outputDir: string): Promise { @@ -25,9 +25,9 @@ export class FileSystem { } zipFile.openReadStream(entry, (openStreamError, stream) => { - if(openStreamError) { + if (openStreamError) { return reject(openStreamError); - }; + } const filePath = `${outputDir}/${fn}`; @@ -50,12 +50,12 @@ export class FileSystem { }); } - public readDirectory(path: string): string[] { - return fs.readdirSync(path); + public readDirectory(directoryPath: string): string[] { + return fs.readdirSync(directoryPath); } - public readJson(path: string, options?: { encoding?: null; flag?: string; }): T { - const content = fs.readFileSync(path, options); + public readJson(filePath: string, options?: { encoding?: null; flag?: string; }): T { + const content = fs.readFileSync(filePath, options); return JSON.parse(content.toString()); } } diff --git a/test/ios-local-build-requirements.ts b/test/ios-local-build-requirements.ts index d7fb8f10f4..31ccc48016 100644 --- a/test/ios-local-build-requirements.ts +++ b/test/ios-local-build-requirements.ts @@ -57,7 +57,7 @@ describe("iOSLocalBuildRequirements", () => { testCases.forEach(testCase => { it(testCase.testName, async () => { const iOSLocalBuildRequirements = setupTestCase(testCase); - let originalXcodeVersion = Constants.XCODE_MIN_REQUIRED_VERSION; + const originalXcodeVersion = Constants.XCODE_MIN_REQUIRED_VERSION; Constants.XCODE_MIN_REQUIRED_VERSION = testCase.minRequiredXcodeVersion || Constants.XCODE_MIN_REQUIRED_VERSION; const isXcodeVersionValid = await iOSLocalBuildRequirements.isXcodeVersionValid(); @@ -110,7 +110,7 @@ describe("iOSLocalBuildRequirements", () => { testCases.forEach(testCase => { it(testCase.testName, async () => { const iOSLocalBuildRequirements = setupTestCase(testCase); - let originalXcodeVersion = Constants.XCODE_MIN_REQUIRED_VERSION; + const originalXcodeVersion = Constants.XCODE_MIN_REQUIRED_VERSION; Constants.XCODE_MIN_REQUIRED_VERSION = testCase.minRequiredXcodeVersion || Constants.XCODE_MIN_REQUIRED_VERSION; const isXcodeVersionValid = await iOSLocalBuildRequirements.checkRequirements(); diff --git a/test/sys-info.ts b/test/sys-info.ts index 5f53f53024..15c8db2a53 100644 --- a/test/sys-info.ts +++ b/test/sys-info.ts @@ -352,7 +352,7 @@ Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)`) }); describe("returns correct results when everything is installed", () => { - let assertCommonValues = (result: NativeScriptDoctor.ISysInfoData) => { + const assertCommonValues = (result: NativeScriptDoctor.ISysInfoData) => { assert.deepEqual(result.npmVer, childProcessResult.npmV.result.stdout); assert.deepEqual(result.nodeVer, "6.0.0"); assert.deepEqual(result.javacVersion, "1.8.0_60"); @@ -565,7 +565,7 @@ ${expectedCliVersion}`; }); describe("when all of calls throw", () => { - let assertAllValuesAreNull = async () => { + const assertAllValuesAreNull = async () => { const result = await sysInfo.getSysInfo(); assert.deepEqual(result.npmVer, null); assert.deepEqual(result.javacVersion, null); diff --git a/test/wrappers/file-system.ts b/test/wrappers/file-system.ts index d3cdc78527..97754017be 100644 --- a/test/wrappers/file-system.ts +++ b/test/wrappers/file-system.ts @@ -5,43 +5,43 @@ import * as rimraf from "rimraf"; import { FileSystem } from "../../lib/wrappers/file-system"; describe('FileSystem', () => { - describe('extractZip', () => { - const d = new Date(); - const datetime = [ - d.getFullYear(), - d.getMonth() + 1, - d.getDate(), - d.getHours(), - d.getMinutes(), - d.getSeconds(), - d.getMilliseconds() - ].join(''); - const tmpDir = `${tmpdir()}/${datetime}`; - const testFilePath = `${__dirname}/example.zip`; - const filesThatNeedToExtsit = [ - `${tmpDir}/test/android-local-build-requirements.ts`, - `${tmpDir}/test/android-tools-info.ts`, - `${tmpDir}/test/ios-local-build-requirements.ts`, - `${tmpDir}/test/sys-info.ts`, - `${tmpDir}/test/wrappers/file-system.ts` - ]; + describe('extractZip', () => { + const d = new Date(); + const datetime = [ + d.getFullYear(), + d.getMonth() + 1, + d.getDate(), + d.getHours(), + d.getMinutes(), + d.getSeconds(), + d.getMilliseconds() + ].join(''); + const tmpDir = `${tmpdir()}/${datetime}`; + const testFilePath = `${__dirname}/example.zip`; + const filesThatNeedToExtsit = [ + `${tmpDir}/test/android-local-build-requirements.ts`, + `${tmpDir}/test/android-tools-info.ts`, + `${tmpDir}/test/ios-local-build-requirements.ts`, + `${tmpDir}/test/sys-info.ts`, + `${tmpDir}/test/wrappers/file-system.ts` + ]; - it('should extract in example zip archive in tmp folder', done => { - const fs = new FileSystem(); + it('should extract in example zip archive in tmp folder', done => { + const fs = new FileSystem(); - fs.extractZip(testFilePath, tmpDir) - .then(() => { - const allExists = filesThatNeedToExtsit - .map(fs.exists) - .reduce((acc, r) => acc && r, true); + fs.extractZip(testFilePath, tmpDir) + .then(() => { + const allExists = filesThatNeedToExtsit + .map(fs.exists) + .reduce((acc, r) => acc && r, true); - assert.isTrue(allExists); + assert.isTrue(allExists); - done(); - }) - .catch(e => done(e)); - }); + done(); + }) + .catch(e => done(e)); + }); - afterEach(done => rimraf(tmpDir, done)); - }); + afterEach(done => rimraf(tmpDir, done)); + }); }); From 734dd43f0295f8e62da06f3d723a6557a4271de3 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 24 Jul 2019 18:43:11 +0300 Subject: [PATCH 130/169] refactor: remove unused properties from tools info --- lib/android-tools-info.ts | 7 +++---- typings/interfaces.ts | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 9f4420e2c9..2ecb494e03 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -44,10 +44,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const infoData: NativeScriptDoctor.IAndroidToolsInfoData = Object.create(null); infoData.androidHomeEnvVar = this.androidHome; infoData.installedTargets = this.getInstalledTargets(); - infoData.latestValidAndroidTarget = this.getLatestValidAndroidTarget(infoData.installedTargets); - infoData.compileSdkVersion = this.getCompileSdk(infoData.latestValidAndroidTarget); + infoData.compileSdkVersion = this.getCompileSdk(infoData.installedTargets); infoData.buildToolsVersion = this.getBuildToolsVersion(); - infoData.maxSupportedSdkVersion = this.getMaxSupportedVersion(); this.toolsInfo = infoData; } @@ -265,7 +263,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return sdkManagementToolPath; } - private getCompileSdk(latestValidAndroidTarget: string): number { + private getCompileSdk(installedTargets: string[]): number { + const latestValidAndroidTarget = this.getLatestValidAndroidTarget(installedTargets); if (latestValidAndroidTarget) { const integerVersion = this.parseAndroidSdkString(latestValidAndroidTarget); diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 4932897375..24334c6b38 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -520,7 +520,5 @@ declare module NativeScriptDoctor { compileSdkVersion: number; installedTargets: string[]; - maxSupportedSdkVersion: number; - latestValidAndroidTarget: string; } } From 2e3d178556a67e5dff62f6878b2cc92ea132c157 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 24 Jul 2019 19:07:21 +0300 Subject: [PATCH 131/169] chore: add description to new properties and methods in interfaces --- typings/interfaces.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 24334c6b38..fba9eb16ad 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -490,7 +490,18 @@ declare module NativeScriptDoctor { */ validateAndroidHomeEnvVariable(): NativeScriptDoctor.IWarning[]; + /** + * Validates if the provided targetSdk is greater that the minimum supported target SDK. + * @param {number} targetSdk The targetSdk to be validated. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. + */ validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[]; + + /** + * Validates if the provided targetSdk is lower that the maximum supported target SDK. + * @param {number} targetSdk The targetSdk to be validated. + * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. + */ validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[]; /** @@ -519,6 +530,9 @@ declare module NativeScriptDoctor { */ compileSdkVersion: number; + /** + * A list of the installed Android SDKs. + */ installedTargets: string[]; } } From 76e3e4d7b3572b10d1a1e84c0f03af7e6e8edd77 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 24 Jul 2019 19:30:17 +0300 Subject: [PATCH 132/169] feat: add Android SDK 29 to supported targets --- lib/android-tools-info.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 2ecb494e03..ba97af91a4 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -22,6 +22,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "android-26", "android-27", "android-28", + "android-29" ]; public readonly MIN_REQUIRED_COMPILE_TARGET = 28; public readonly REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; From 3752c9fc09407d50c26260a3b3acb5ff16a81c68 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Thu, 25 Jul 2019 16:22:11 +0300 Subject: [PATCH 133/169] chore: meke unused outside properties private --- lib/android-tools-info.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index ba97af91a4..18108c7068 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -10,7 +10,7 @@ import * as _ from "lodash"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public readonly ANDROID_TARGET_PREFIX = "android"; - public readonly SUPPORTED_TARGETS = [ + private static SUPPORTED_TARGETS = [ "android-17", "android-18", "android-19", @@ -24,9 +24,9 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "android-28", "android-29" ]; - public readonly MIN_REQUIRED_COMPILE_TARGET = 28; - public readonly REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; - public readonly VERSION_REGEX = /((\d+\.){2}\d+)/; + private static MIN_REQUIRED_COMPILE_TARGET = 28; + private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; + private static VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; @@ -60,7 +60,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const isAndroidHomeValid = this.isAndroidHomeValid(); if (!toolsInfoData.compileSdkVersion) { errors.push({ - warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${this.MIN_REQUIRED_COMPILE_TARGET} or later.`, + warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later.`, additionalInformation: `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage your Android SDK versions.`, platforms: [Constants.ANDROID_PLATFORM_NAME] }); @@ -98,7 +98,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + " described in " + this.getSystemRequirementsLink(); - const matchingVersion = this.helpers.appendZeroesToVersion(installedJavaCompilerVersion || "", 3).match(this.VERSION_REGEX); + const matchingVersion = this.helpers.appendZeroesToVersion(installedJavaCompilerVersion || "", 3).match(AndroidToolsInfo.VERSION_REGEX); const installedJavaCompilerSemverVersion = matchingVersion && matchingVersion[1]; if (installedJavaCompilerSemverVersion) { let warning: string = null; @@ -187,10 +187,10 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; - const targetSupported = _.includes(this.SUPPORTED_TARGETS, newTarget); + const targetSupported = _.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget); - if (!_.includes(this.SUPPORTED_TARGETS, newTarget)) { - const supportedVersions = this.SUPPORTED_TARGETS.sort(); + if (!_.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget)) { + const supportedVersions = AndroidToolsInfo.SUPPORTED_TARGETS.sort(); const minSupportedVersion = this.parseAndroidSdkString(_.first(supportedVersions)); if (!targetSupported && targetSdk && (targetSdk < minSupportedVersion)) { @@ -208,7 +208,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; - const targetSupported = _.includes(this.SUPPORTED_TARGETS, newTarget); + const targetSupported = _.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget); if (!targetSupported && !targetSdk || targetSdk > this.getMaxSupportedVersion()) { errors.push({ @@ -269,7 +269,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (latestValidAndroidTarget) { const integerVersion = this.parseAndroidSdkString(latestValidAndroidTarget); - if (integerVersion && integerVersion >= this.MIN_REQUIRED_COMPILE_TARGET) { + if (integerVersion && integerVersion >= AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET) { return integerVersion; } } @@ -282,7 +282,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const subDirsVersions = subDirs .map(dirName => { - const dirNameGroups = dirName.match(this.VERSION_REGEX); + const dirNameGroups = dirName.match(AndroidToolsInfo.VERSION_REGEX); if (dirNameGroups) { return dirNameGroups[1]; } @@ -301,7 +301,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } private getBuildToolsRange(): string { - return `${this.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion()}`; + return `${AndroidToolsInfo.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion()}`; } private getBuildToolsVersion(): string { @@ -316,7 +316,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } private getLatestValidAndroidTarget(installedTargets: string[]): string { - return _.findLast(this.SUPPORTED_TARGETS.sort(), supportedTarget => _.includes(installedTargets, supportedTarget)); + return _.findLast(AndroidToolsInfo.SUPPORTED_TARGETS.sort(), supportedTarget => _.includes(installedTargets, supportedTarget)); } private parseAndroidSdkString(androidSdkString: string): number { @@ -337,7 +337,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } private getMaxSupportedVersion(): number { - return this.parseAndroidSdkString(this.SUPPORTED_TARGETS.sort()[this.SUPPORTED_TARGETS.length - 1]); + return this.parseAndroidSdkString(AndroidToolsInfo.SUPPORTED_TARGETS.sort()[AndroidToolsInfo.SUPPORTED_TARGETS.length - 1]); } private getSystemRequirementsLink(): string { From 4ff13c2c9a903df06d95e43d77cf1a01f8419130 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Thu, 25 Jul 2019 16:22:39 +0300 Subject: [PATCH 134/169] chore: bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bd6116c035..2bddbf5b0f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.10.0", + "version": "1.11.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 21d994af5f67b7bd526fd6701fec95dcec760ba2 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 31 Jul 2019 17:55:28 +0300 Subject: [PATCH 135/169] fix: validateMinSupportedTargetSdk always returns empty warnings array --- lib/android-tools-info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 18108c7068..1b46ad774d 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -202,7 +202,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } } - return []; + return errors; } public validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] { From 221d1ca58cf92c41430789e6a4c4b553e1df2b96 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Tue, 6 Aug 2019 18:00:34 +0300 Subject: [PATCH 136/169] fix: use Android SDK28 if runtime lower that 6.1.0 --- lib/android-tools-info.ts | 92 +++++++++++-------- lib/doctor.ts | 2 +- .../android-local-build-requirements.ts | 2 +- test/android-tools-info.ts | 42 ++++++++- typings/interfaces.ts | 26 ++++-- 5 files changed, 116 insertions(+), 48 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 1b46ad774d..1d411365b9 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -10,20 +10,31 @@ import * as _ from "lodash"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public readonly ANDROID_TARGET_PREFIX = "android"; - private static SUPPORTED_TARGETS = [ - "android-17", - "android-18", - "android-19", - "android-21", - "android-22", - "android-23", - "android-24", - "android-25", - "android-26", - "android-27", - "android-28", - "android-29" - ]; + private getSupportedTargets(projectDir: string) { + const runtimeVersion = this.getRuntimeVersion({projectDir}); + let baseTargets = [ + "android-17", + "android-18", + "android-19", + "android-21", + "android-22", + "android-23", + "android-24", + "android-25", + "android-26", + "android-27", + "android-28", + "android-29" + ]; + + if (runtimeVersion && semver.lt(semver.coerce(runtimeVersion), "6.1.0")) { + baseTargets.sort(); + const indexOfSdk29 = baseTargets.indexOf("android-29"); + baseTargets = baseTargets.slice(0, indexOfSdk29); + } + + return baseTargets; + } private static MIN_REQUIRED_COMPILE_TARGET = 28; private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; @@ -40,13 +51,13 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private hostInfo: HostInfo, private helpers: Helpers) { } - public getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData { + public getToolsInfo(config: Partial = {}): NativeScriptDoctor.IAndroidToolsInfoData { if (!this.toolsInfo) { const infoData: NativeScriptDoctor.IAndroidToolsInfoData = Object.create(null); infoData.androidHomeEnvVar = this.androidHome; infoData.installedTargets = this.getInstalledTargets(); - infoData.compileSdkVersion = this.getCompileSdk(infoData.installedTargets); - infoData.buildToolsVersion = this.getBuildToolsVersion(); + infoData.compileSdkVersion = this.getCompileSdk(infoData.installedTargets, config.projectDir); + infoData.buildToolsVersion = this.getBuildToolsVersion(config.projectDir); this.toolsInfo = infoData; } @@ -54,9 +65,9 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return this.toolsInfo; } - public validateInfo(): NativeScriptDoctor.IWarning[] { + public validateInfo(config: Partial = {}): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; - const toolsInfoData = this.getToolsInfo(); + const toolsInfoData = this.getToolsInfo(config); const isAndroidHomeValid = this.isAndroidHomeValid(); if (!toolsInfoData.compileSdkVersion) { errors.push({ @@ -67,7 +78,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } if (!toolsInfoData.buildToolsVersion) { - const buildToolsRange = this.getBuildToolsRange(); + const buildToolsRange = this.getBuildToolsRange(config.projectDir); const versionRangeMatches = buildToolsRange.match(/^.*?([\d\.]+)\s+.*?([\d\.]+)$/); let message = `You can install any version in the following range: '${buildToolsRange}'.`; @@ -110,7 +121,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) { warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; } else { - runtimeVersion = this.getRealRuntimeVersion(runtimeVersion || this.getAndroidRuntimeVersionFromProjectDir(projectDir)); + runtimeVersion = this.getRuntimeVersion({runtimeVersion, projectDir}); if (runtimeVersion) { // get the item from the dictionary that corresponds to our current Javac version: let runtimeMinVersion: string = null; @@ -184,13 +195,14 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } - public validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] { + public validateMinSupportedTargetSdk({targetSdk, projectDir}: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; - const targetSupported = _.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget); + const supportedTargets = this.getSupportedTargets(projectDir); + const targetSupported = _.includes(supportedTargets, newTarget); - if (!_.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget)) { - const supportedVersions = AndroidToolsInfo.SUPPORTED_TARGETS.sort(); + if (!_.includes(supportedTargets, newTarget)) { + const supportedVersions = supportedTargets.sort(); const minSupportedVersion = this.parseAndroidSdkString(_.first(supportedVersions)); if (!targetSupported && targetSdk && (targetSdk < minSupportedVersion)) { @@ -205,12 +217,12 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } - public validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] { + public validataMaxSupportedTargetSdk({targetSdk, projectDir}: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; - const targetSupported = _.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget); + const targetSupported = _.includes(this.getSupportedTargets(projectDir), newTarget); - if (!targetSupported && !targetSdk || targetSdk > this.getMaxSupportedVersion()) { + if (!targetSupported && !targetSdk || targetSdk > this.getMaxSupportedVersion(projectDir)) { errors.push({ warning:`Support for the selected Android target SDK ${newTarget} is not verified. Your Android app might not work as expected.`, additionalInformation: "", @@ -264,8 +276,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return sdkManagementToolPath; } - private getCompileSdk(installedTargets: string[]): number { - const latestValidAndroidTarget = this.getLatestValidAndroidTarget(installedTargets); + private getCompileSdk(installedTargets: string[], projectDir: string): number { + const latestValidAndroidTarget = this.getLatestValidAndroidTarget(installedTargets, projectDir); if (latestValidAndroidTarget) { const integerVersion = this.parseAndroidSdkString(latestValidAndroidTarget); @@ -300,23 +312,23 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return selectedVersion; } - private getBuildToolsRange(): string { - return `${AndroidToolsInfo.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion()}`; + private getBuildToolsRange(projectDir: string): string { + return `${AndroidToolsInfo.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion(projectDir)}`; } - private getBuildToolsVersion(): string { + private getBuildToolsVersion(projectDir: string): string { let buildToolsVersion: string; if (this.androidHome) { const pathToBuildTools = path.join(this.androidHome, "build-tools"); - const buildToolsRange = this.getBuildToolsRange(); + const buildToolsRange = this.getBuildToolsRange(projectDir); buildToolsVersion = this.getMatchingDir(pathToBuildTools, buildToolsRange); } return buildToolsVersion; } - private getLatestValidAndroidTarget(installedTargets: string[]): string { - return _.findLast(AndroidToolsInfo.SUPPORTED_TARGETS.sort(), supportedTarget => _.includes(installedTargets, supportedTarget)); + private getLatestValidAndroidTarget(installedTargets: string[], projectDir: string): string { + return _.findLast(this.getSupportedTargets(projectDir).sort(), supportedTarget => _.includes(installedTargets, supportedTarget)); } private parseAndroidSdkString(androidSdkString: string): number { @@ -336,8 +348,9 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } } - private getMaxSupportedVersion(): number { - return this.parseAndroidSdkString(AndroidToolsInfo.SUPPORTED_TARGETS.sort()[AndroidToolsInfo.SUPPORTED_TARGETS.length - 1]); + private getMaxSupportedVersion(projectDir: string): number { + const supportedTargets = this.getSupportedTargets(projectDir); + return this.parseAndroidSdkString(supportedTargets.sort()[supportedTargets.length - 1]); } private getSystemRequirementsLink(): string { @@ -363,7 +376,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return runtimeVersion; } - private getRealRuntimeVersion(runtimeVersion: string): string { + private getRuntimeVersion({ runtimeVersion, projectDir } : { runtimeVersion?: string, projectDir?: string}): string { + runtimeVersion = runtimeVersion || this.getAndroidRuntimeVersionFromProjectDir(projectDir); if (runtimeVersion) { // Check if the version is not "next" or "rc", i.e. tag from npm if (!semver.valid(runtimeVersion)) { diff --git a/lib/doctor.ts b/lib/doctor.ts index 9306ed78d4..360c81312f 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -87,7 +87,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.ANDROID_PLATFORM_NAME] }), this.processValidationErrors({ - warnings: this.androidToolsInfo.validateInfo(), + warnings: this.androidToolsInfo.validateInfo({projectDir}), infoMessage: "A compatible Android SDK for compilation is found.", platforms: [Constants.ANDROID_PLATFORM_NAME] }), diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/lib/local-build-requirements/android-local-build-requirements.ts index 6c93c98d08..fc4ccbff92 100644 --- a/lib/local-build-requirements/android-local-build-requirements.ts +++ b/lib/local-build-requirements/android-local-build-requirements.ts @@ -3,7 +3,7 @@ export class AndroidLocalBuildRequirements { private sysInfo: NativeScriptDoctor.ISysInfo) { } public async checkRequirements(projectDir?: string, runtimeVersion?: string): Promise { - const androidToolsInfo = await this.androidToolsInfo.validateInfo(); + const androidToolsInfo = await this.androidToolsInfo.validateInfo({projectDir}); const javacVersion = await this.sysInfo.getJavaCompilerVersion(); const isJavacVersionInvalid = !javacVersion || (await this.androidToolsInfo.validateJavacVersion(javacVersion, projectDir, runtimeVersion)).length; if (androidToolsInfo.length || diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index 0ddd268c02..6f41ead901 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -15,10 +15,13 @@ interface ITestData { } describe("androidToolsInfo", () => { + const originalAndroidHome = process.env["ANDROID_HOME"]; const defaultAdditionalInformation = "You will not be able to build your projects for Android." + EOL + "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL + " described in " + Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform]; - + before(() => { + process.env["ANDROID_HOME"] = "test"; + }); const getAndroidToolsInfo = (runtimeVersion?: string): AndroidToolsInfo => { const childProcess: ChildProcess = {}; const fs: FileSystem = { @@ -32,6 +35,23 @@ describe("androidToolsInfo", () => { } } } : null; + }, + readDirectory: (path: string) => { + if (path.indexOf("build-tools") >= 0) { + return [ + "20.0.0", + "27.0.3", + "28.0.3", + "29.0.1" + ]; + } else { + return [ + "android-16", + "android-27", + "android-28", + "android-29" + ]; + } } }; const hostInfo: HostInfo = {}; @@ -39,6 +59,22 @@ describe("androidToolsInfo", () => { return new AndroidToolsInfo(childProcess, fs, hostInfo, helpers); }; + describe("getToolsInfo", () => { + it("runtime 6.0.0", () => { + const androidToolsInfo = getAndroidToolsInfo("6.0.0"); + const toolsInfo = androidToolsInfo.getToolsInfo({projectDir: "test"}); + + assert.equal(toolsInfo.compileSdkVersion, 28); + }); + + it("runtime 6.0.0", () => { + const androidToolsInfo = getAndroidToolsInfo("6.1.0"); + const toolsInfo = androidToolsInfo.getToolsInfo({projectDir: "test"}); + + assert.equal(toolsInfo.compileSdkVersion, 29); + }); + }); + describe("validateJavacVersion", () => { const testData: ITestData[] = [ { @@ -197,4 +233,8 @@ describe("androidToolsInfo", () => { }); }); }); + + after(() => { + process.env["ANDROID_HOME"] = originalAndroidHome; + }); }); diff --git a/typings/interfaces.ts b/typings/interfaces.ts index fba9eb16ad..4cfcb20586 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -460,13 +460,13 @@ declare module NativeScriptDoctor { * Returns the Android tools info. * @return {NativeScriptDoctor.IAndroidToolsInfoData} returns the Android tools info. */ - getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData; + getToolsInfo(config: IProjectDir): NativeScriptDoctor.IAndroidToolsInfoData; /** * Checks if the Android tools are valid. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateInfo(): NativeScriptDoctor.IWarning[]; + validateInfo(config: IProjectDir): NativeScriptDoctor.IWarning[]; /** * Checks if the current javac version is valid. @@ -492,17 +492,17 @@ declare module NativeScriptDoctor { /** * Validates if the provided targetSdk is greater that the minimum supported target SDK. - * @param {number} targetSdk The targetSdk to be validated. + * @param {ITargetValidationOptions} options The targetSdk to be validated and the project directory - used to determine the Android Runtime version. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[]; + validateMinSupportedTargetSdk(options: ITargetValidationOptions): NativeScriptDoctor.IWarning[]; /** * Validates if the provided targetSdk is lower that the maximum supported target SDK. - * @param {number} targetSdk The targetSdk to be validated. + * @param {ITargetValidationOptions} options The targetSdk to be validated and the project directory - used to determine the Android Runtime version. * @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return []. */ - validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[]; + validataMaxSupportedTargetSdk(options: ITargetValidationOptions): NativeScriptDoctor.IWarning[]; /** * Returns the path to the emulator executable. @@ -511,6 +511,13 @@ declare module NativeScriptDoctor { getPathToEmulatorExecutable(): string; } + /** + * The targetSdk to be validated. + */ + interface ITargetValidationOptions extends Partial { + targetSdk: number; + } + /** * Describes information about installed Android tools and SDKs. */ @@ -535,4 +542,11 @@ declare module NativeScriptDoctor { */ installedTargets: string[]; } + + /** + * Object with a single property - projectDir. This is the root directory where NativeScript project is located. + */ + interface IProjectDir { + projectDir: string; + } } From a3b35d2fc7eeb507603c39b50e9d693b0fd9d3fe Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Wed, 7 Aug 2019 15:45:33 +0300 Subject: [PATCH 137/169] chore: fix comments --- package.json | 2 +- test/android-tools-info.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2bddbf5b0f..4667ef61d6 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "grunt-ts": "6.0.0-beta.21", "grunt-tslint": "5.0.2", "istanbul": "0.4.5", - "lodash": "4.17.11", "mocha": "5.2.0", "rimraf": "2.5.4", "tslint": "5.14.0", @@ -47,6 +46,7 @@ "typescript": "3.3.4000" }, "dependencies": { + "lodash": "4.17.15", "osenv": "0.1.3", "semver": "5.5.1", "temp": "0.8.3", diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index 6f41ead901..663fefb441 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -67,7 +67,7 @@ describe("androidToolsInfo", () => { assert.equal(toolsInfo.compileSdkVersion, 28); }); - it("runtime 6.0.0", () => { + it("runtime 6.1.0", () => { const androidToolsInfo = getAndroidToolsInfo("6.1.0"); const toolsInfo = androidToolsInfo.getToolsInfo({projectDir: "test"}); From 07bf7b17063c3420f1aa8d389803a991f5c2e466 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Tue, 27 Aug 2019 18:12:58 +0300 Subject: [PATCH 138/169] fix: runtime supports sdk 28 only and user has 29 or no sdk, doctor prints wrong message --- lib/android-tools-info.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 1d411365b9..36e39e3d25 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -69,9 +69,11 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const errors: NativeScriptDoctor.IWarning[] = []; const toolsInfoData = this.getToolsInfo(config); const isAndroidHomeValid = this.isAndroidHomeValid(); + const runtimeVersion = this.getRuntimeVersion(config); + const supportsOnlyMinRequiredCompileTarget = this.getMaxSupportedCompileVersion(runtimeVersion) === AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET; if (!toolsInfoData.compileSdkVersion) { errors.push({ - warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET} or later.`, + warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET}${supportsOnlyMinRequiredCompileTarget ? "" : " or later"}.`, additionalInformation: `Run \`\$ ${this.getPathToSdkManagementTool()}\` to manage your Android SDK versions.`, platforms: [Constants.ANDROID_PLATFORM_NAME] }); @@ -398,4 +400,12 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return runtimeVersion; } + + private getMaxSupportedCompileVersion(runtimeVersion: string): number { + if (runtimeVersion && semver.lt(semver.coerce(runtimeVersion), "6.1.0")) { + return 28; + } + + return this.parseAndroidSdkString(_.last(this.getSupportedTargets(runtimeVersion).sort())); + } } From 7e111a182e9251bbce37ef8854b1d944825a29c4 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 28 Aug 2019 10:39:12 +0300 Subject: [PATCH 139/169] chore: bump version to 1.11.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4667ef61d6..c83fd8b60f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.11.0", + "version": "1.11.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From aa4e89dd48b72f16b23303c2eb9d12cb6c24e1de Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Mon, 14 Oct 2019 14:41:15 +0300 Subject: [PATCH 140/169] feat: expose the local java path --- lib/sys-info.ts | 38 +++++++++++++++++++++--- package.json | 4 +-- test/android-local-build-requirements.ts | 1 + typings/interfaces.ts | 11 +++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index 76fdd1b12f..aef0fee182 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -23,6 +23,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private monoVerRegExp = /version (\d+[.]\d+[.]\d+) /gm; private javaCompilerVerCache: string; + private javaPathCache: string; private javaVerCache: string; private javaVerJavaHomeCache: string; private javaVerPathCache: string; @@ -75,6 +76,13 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { }); } + public getJavaPath(): Promise { + return this.getValueForProperty(() => this.javaPathCache, async (): Promise => { + const javaPath = (await this.getJavaExecutablePathFromJavaHome(Constants.JAVA_EXECUTABLE_NAME)) || (await this.getJavaExecutablePathFromPath(Constants.JAVA_EXECUTABLE_NAME)); + return javaPath; + }); + } + public getJavaVersionFromPath(): Promise { return this.getValueForProperty(() => this.javaVerPathCache, (): Promise => { return this.getVersionOfJavaExecutableFromPath(Constants.JAVA_EXECUTABLE_NAME, SysInfo.JAVA_VERSION_REGEXP); @@ -509,6 +517,7 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { result.dotNetVer = await this.hostInfo.dotNetVersion(); result.javacVersion = await this.getJavaCompilerVersion(); result.javaVersion = await this.getJavaVersion(); + result.javaPath = await this.getJavaPath(); result.adbVer = await this.getAdbVersion(config && config.androidToolsInfo && config.androidToolsInfo.pathToAdb); result.androidInstalled = await this.isAndroidInstalled(); result.monoVer = await this.getMonoVersion(); @@ -521,6 +530,16 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { private async getVersionOfJavaExecutableFromJavaHome(javaExecutableName: string, regExp: RegExp): Promise { let javaExecutableVersion: string = null; + const javaExecutablePath = this.getJavaExecutablePathFromJavaHome(javaExecutableName); + if (javaExecutablePath) { + javaExecutableVersion = await this.getVersionOfJavaExecutable(javaExecutablePath, regExp); + } + + return javaExecutableVersion; + } + + private getJavaExecutablePathFromJavaHome(javaExecutableName: string): string { + let javaExecutablePath: string = null; try { const javaHome = process.env["JAVA_HOME"]; @@ -529,25 +548,36 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { if (javaHome) { const pathToJavaExecutable = path.join(javaHome, "bin", javaExecutableFile); if (this.fileSystem.exists(pathToJavaExecutable)) { - javaExecutableVersion = await this.getVersionOfJavaExecutable(pathToJavaExecutable, regExp); + javaExecutablePath = pathToJavaExecutable; } } } catch (err) { /* intentionally left blank */ } - return javaExecutableVersion; + return javaExecutablePath; } private async getVersionOfJavaExecutableFromPath(javaExecutableName: string, regExp: RegExp): Promise { let javaExecutableVersion: string = null; + const javaExecutablePath = await this.getJavaExecutablePathFromPath(javaExecutableName); + if (javaExecutablePath) { + javaExecutableVersion = await this.getVersionOfJavaExecutable(javaExecutablePath, regExp); + } + + return javaExecutableVersion; + } + + private async getJavaExecutablePathFromPath(javaExecutableName: string): Promise { + let javaExecutablePath: string = null; + try { const detectionCommand = this.hostInfo.isWindows ? "where" : "which"; // if this command succeeds, we have javac in the PATH. In case it is not there, it will throw an error. await this.childProcess.exec(`${detectionCommand} ${javaExecutableName}`); - javaExecutableVersion = await this.getVersionOfJavaExecutable(javaExecutableName, regExp); + javaExecutablePath = javaExecutableName; } catch (err) { /* intentionally left blank */ } - return javaExecutableVersion; + return javaExecutablePath; } private async getVersionOfJavaExecutable(executable: string, regExp: RegExp): Promise { diff --git a/package.json b/package.json index c83fd8b60f..73068422c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.11.1", + "version": "1.12.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", @@ -53,4 +53,4 @@ "winreg": "1.2.2", "yauzl": "2.10.0" } -} +} \ No newline at end of file diff --git a/test/android-local-build-requirements.ts b/test/android-local-build-requirements.ts index 4be02230ba..704befb394 100644 --- a/test/android-local-build-requirements.ts +++ b/test/android-local-build-requirements.ts @@ -30,6 +30,7 @@ describe("androidLocalBuildRequirements", () => { getJavaVersion: async (): Promise => results.hasOwnProperty("getJavaVersion") ? results.getJavaCompilerVersion : "8.0.0", getJavaVersionFromJavaHome: async (): Promise => results.hasOwnProperty("getJavaVersionFromJavaHome") ? results.getJavaCompilerVersion : "8.0.0", getJavaVersionFromPath: async (): Promise => results.hasOwnProperty("getJavaVersionFromPath") ? results.getJavaCompilerVersion : "8.0.0", + getJavaPath: async (): Promise => undefined, getAdbVersion: async (pathToAdb?: string): Promise => results.hasOwnProperty("getAdbVersion") ? results.getAdbVersion : "1.0.39", getXcodeVersion: async (): Promise => undefined, getNodeVersion: async (): Promise => undefined, diff --git a/typings/interfaces.ts b/typings/interfaces.ts index 4cfcb20586..c7ccb845c3 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -15,6 +15,12 @@ declare module NativeScriptDoctor { */ getJavaVersion(): Promise; + /** + * Returns the currently installed Java path based on JAVA_HOME and PATH.. + * @return {Promise} The currently installed Java path. + */ + getJavaPath(): Promise; + /** * Gets JAVA version based on the executable in PATH. * @return {Promise} @@ -340,6 +346,11 @@ declare module NativeScriptDoctor { * @type {string} */ javaVersion: string; + /** + * java path based on JAVA_HOME and PATH. + * @type {string} + */ + javaPath: string; /** * true if the Android SDK Tools are installed and configured correctly. * @type {boolean} From 8b53f57c62553d8a32ba1b08010c57415b9de0f1 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 16 Oct 2019 10:33:34 +0300 Subject: [PATCH 141/169] docs: improve missing CocoaPods warning. --- lib/doctor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/doctor.ts b/lib/doctor.ts index 360c81312f..33fd608454 100644 --- a/lib/doctor.ts +++ b/lib/doctor.ts @@ -87,7 +87,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { platforms: [Constants.ANDROID_PLATFORM_NAME] }), this.processValidationErrors({ - warnings: this.androidToolsInfo.validateInfo({projectDir}), + warnings: this.androidToolsInfo.validateInfo({ projectDir }), infoMessage: "A compatible Android SDK for compilation is found.", platforms: [Constants.ANDROID_PLATFORM_NAME] }), @@ -136,7 +136,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor { infoMessage: "CocoaPods are installed.", warningMessage: "CocoaPods is not installed or is not configured properly.", additionalInformation: "You will not be able to build your projects for iOS if they contain plugin with CocoaPod file." + EOL - + "To be able to build such projects, verify that you have installed CocoaPods.", + + "To be able to build such projects, verify that you have installed CocoaPods (`sudo gem install cocoapods`).", platforms: [Constants.IOS_PLATFORM_NAME] }), this.processSysInfoItem({ From c9f7d868768f94d476b6aba7cfeceac9da89fa8c Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 5 Feb 2020 15:52:19 +0200 Subject: [PATCH 142/169] fix: Java 13 is not supported, but it is not detected as such Currently Java 13 is not supported, but if you have it installed, `nativescript-doctor` decides it is okay and allows you to build. At that point you receive non-descriptive error message. Fix the case by forbidding Java 13 and above until we support it. --- lib/android-tools-info.ts | 5 +++-- test/android-tools-info.ts | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 36e39e3d25..e1b3d0a381 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -39,6 +39,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; + private static MAX_JAVA_VERSION = "13.0.0"; private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; public get androidHome(): string { @@ -120,8 +121,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "^10.0.0": "4.1.0-2018.5.18.1" }; - if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) { - warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`; + if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION) || semver.gte(installedJavaCompilerSemverVersion, AndroidToolsInfo.MAX_JAVA_VERSION)) { + warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION} and below ${AndroidToolsInfo.MAX_JAVA_VERSION}.`; } else { runtimeVersion = this.getRuntimeVersion({runtimeVersion, projectDir}); if (runtimeVersion) { diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index 663fefb441..713b57ad60 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -97,11 +97,19 @@ describe("androidToolsInfo", () => { }, { javacVersion: "1.7.0", - warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0."] + warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0 and below 13.0.0."] }, { javacVersion: "1.7.0_132", - warnings: ["Javac version 1.7.0_132 is not supported. You have to install at least 1.8.0."] + warnings: ["Javac version 1.7.0_132 is not supported. You have to install at least 1.8.0 and below 13.0.0."] + }, + { + javacVersion: "13.0.0", + warnings: ["Javac version 13.0.0 is not supported. You have to install at least 1.8.0 and below 13.0.0."] + }, + { + javacVersion: "14.1.0", + warnings: ["Javac version 14.1.0 is not supported. You have to install at least 1.8.0 and below 13.0.0."] }, { javacVersion: null, From 9ea8b62a37999b02738041939938cd71c289a363 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 5 Feb 2020 16:13:20 +0200 Subject: [PATCH 143/169] fix: ensure temp files are deleted Ensure the temp files created by nativescript-doctor are deleted --- lib/sys-info.ts | 6 +++++- lib/wrappers/file-system.ts | 5 +++++ package.json | 4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/sys-info.ts b/lib/sys-info.ts index aef0fee182..69d33bf706 100644 --- a/lib/sys-info.ts +++ b/lib/sys-info.ts @@ -275,11 +275,15 @@ export class SysInfo implements NativeScriptDoctor.ISysInfo { try { const spawnResult = await this.childProcess.spawnFromEvent("pod", ["install"], "exit", { spawnOptions: { cwd: xcodeProjectDir } }); if (spawnResult.exitCode) { + this.fileSystem.deleteEntry(tempDirectory); return false; } else { - return this.fileSystem.exists(path.join(xcodeProjectDir, "cocoapods.xcworkspace")); + const exists = this.fileSystem.exists(path.join(xcodeProjectDir, "cocoapods.xcworkspace")); + this.fileSystem.deleteEntry(tempDirectory); + return exists; } } catch (err) { + this.fileSystem.deleteEntry(tempDirectory); return null; } } else { diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index fcfef69558..944cac5f78 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -2,6 +2,7 @@ import * as fs from "fs"; import * as path from "path"; import * as yauzl from "yauzl"; import * as util from "util"; +import * as shelljs from "shelljs"; const access = util.promisify(fs.access); const mkdir = util.promisify(fs.mkdir); @@ -58,6 +59,10 @@ export class FileSystem { const content = fs.readFileSync(filePath, options); return JSON.parse(content.toString()); } + + public deleteEntry(filePath: string): void { + shelljs.rm("-rf", filePath); + } } function createParentDirsIfNeeded(filePath: string) { diff --git a/package.json b/package.json index 73068422c8..65f49c36da 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@types/mocha": "2.2.32", "@types/rimraf": "2.0.2", "@types/semver": "5.5.0", + "@types/shelljs": "0.8.6", "@types/temp": "0.8.29", "@types/winreg": "1.2.30", "@types/yauzl": "2.9.0", @@ -49,8 +50,9 @@ "lodash": "4.17.15", "osenv": "0.1.3", "semver": "5.5.1", + "shelljs": "0.7.6", "temp": "0.8.3", "winreg": "1.2.2", "yauzl": "2.10.0" } -} \ No newline at end of file +} From e28b334155f3689c434883772636235a8d125f35 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 5 Feb 2020 16:14:10 +0200 Subject: [PATCH 144/169] release: cut 1.13.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 65f49c36da..fe7a6d5b98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.12.0", + "version": "1.13.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 6f76db9a80668dac7c2c18b0a3adadcc1267d5b9 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 29 May 2020 21:26:01 -0700 Subject: [PATCH 145/169] feat(node): support for node 14+ (#60) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fe7a6d5b98..15eff289b7 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "lodash": "4.17.15", "osenv": "0.1.3", "semver": "5.5.1", - "shelljs": "0.7.6", + "shelljs": "~0.8.4", "temp": "0.8.3", "winreg": "1.2.2", "yauzl": "2.10.0" From 3f506d8b218a9891cb23e403142b158f46b41569 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 29 May 2020 22:10:54 -0700 Subject: [PATCH 146/169] chore(release): 1.14.0 --- .gitignore | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 970a48f281..bc592ea82e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ build/Release # Dependency directories node_modules jspm_packages +package-lock.json # Optional npm cache directory .npm diff --git a/package.json b/package.json index 15eff289b7..a13cd0bf67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.13.0", + "version": "1.14.0", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 3b4510f85c400affec4e7b5d8cc860dd25299145 Mon Sep 17 00:00:00 2001 From: Toby Miller Date: Sat, 30 May 2020 01:21:33 -0400 Subject: [PATCH 147/169] fix(file-system): Resolve paths before testing for existence (#59) Co-authored-by: Nathan Walker --- lib/wrappers/file-system.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 944cac5f78..57549a24c8 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -9,7 +9,7 @@ const mkdir = util.promisify(fs.mkdir); export class FileSystem { public exists(filePath: string): boolean { - return fs.existsSync(filePath); + return fs.existsSync(path.resolve(filePath)); } public extractZip(pathToZip: string, outputDir: string): Promise { From c2fc09aa22a50eee95934040de9fe602bae41c0d Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 29 May 2020 22:25:33 -0700 Subject: [PATCH 148/169] chore(release): v1.14.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a13cd0bf67..b1dde986a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nativescript-doctor", - "version": "1.14.0", + "version": "1.14.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 20612a2b36bbe684dfe7b9c7191399c8bade9773 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 24 Jun 2020 22:14:10 -0700 Subject: [PATCH 149/169] feat(android): support v30 (#61) --- lib/android-tools-info.ts | 6 ++++-- package.json | 12 +++++++++--- test/android-tools-info.ts | 15 +++++++++++++++ tslint.json | 1 - 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index e1b3d0a381..b8094a4cc7 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -10,12 +10,13 @@ import * as _ from "lodash"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public readonly ANDROID_TARGET_PREFIX = "android"; - private getSupportedTargets(projectDir: string) { + public getSupportedTargets(projectDir: string) { const runtimeVersion = this.getRuntimeVersion({projectDir}); let baseTargets = [ "android-17", "android-18", "android-19", + "android-20", "android-21", "android-22", "android-23", @@ -24,7 +25,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "android-26", "android-27", "android-28", - "android-29" + "android-29", + "android-30" ]; if (runtimeVersion && semver.lt(semver.coerce(runtimeVersion), "6.1.0")) { diff --git a/package.json b/package.json index b1dde986a7..4f1d74d4d3 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,16 @@ { "name": "nativescript-doctor", - "version": "1.14.1", + "version": "1.14.2", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", "scripts": { - "test": "node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive" + "clean": "npx rimraf node_modules package-lock.json && npm i && ./node_modules/.bin/grunt clean", + "build": "./node_modules/.bin/grunt", + "build.all": "./node_modules/.bin/grunt ts:devall", + "pack": "./node_modules/.bin/grunt pack", + "test": "node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive", + "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" }, "repository": { "type": "git", @@ -33,6 +38,7 @@ "@types/winreg": "1.2.30", "@types/yauzl": "2.9.0", "chai": "4.1.2", + "conventional-changelog-cli": "^2.0.34", "grunt": "1.0.3", "grunt-contrib-clean": "1.0.0", "grunt-contrib-watch": "1.1.0", @@ -44,7 +50,7 @@ "rimraf": "2.5.4", "tslint": "5.14.0", "tslint-microsoft-contrib": "6.1.0", - "typescript": "3.3.4000" + "typescript": "~3.8.3" }, "dependencies": { "lodash": "4.17.15", diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index 713b57ad60..b693ae2fed 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -75,6 +75,21 @@ describe("androidToolsInfo", () => { }); }); + describe("supportedAndroidSdks", () => { + it("should support android-17 - android-30", () => { + const min = 17; + const max = 30; + let cnt = 0; + const androidToolsInfo = getAndroidToolsInfo("6.5.0"); + const supportedTargets = androidToolsInfo.getSupportedTargets("test"); + for (let i = 0; i < supportedTargets.length; i++) { + assert.equal(supportedTargets[i], `android-${min+i}`); + cnt = min+i; + } + assert.equal(cnt, max); + }); + }); + describe("validateJavacVersion", () => { const testData: ITestData[] = [ { diff --git a/tslint.json b/tslint.json index 3c69354342..5386dd58d9 100644 --- a/tslint.json +++ b/tslint.json @@ -66,7 +66,6 @@ true, "check-branch", "check-decl", - "check-operator", "check-module", "check-separator" ] From 385e3ef553f4b51341f183ed98ec57040a70afc7 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 24 Jun 2020 22:15:46 -0700 Subject: [PATCH 150/169] chore(release): 1.14.2 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..feb927b308 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +## [1.14.2](https://github.com/NativeScript/nativescript-doctor/compare/v1.14.1...v1.14.2) (2020-06-25) + + +### Features + +* **android:** support v30 ([#61](https://github.com/NativeScript/nativescript-doctor/issues/61)) ([20612a2](https://github.com/NativeScript/nativescript-doctor/commit/20612a2b36bbe684dfe7b9c7191399c8bade9773)) + + + From 6b88f4c2195cf15e20e9df043270b1cf105093fe Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Sat, 29 Aug 2020 09:33:15 -0700 Subject: [PATCH 151/169] feat: nativescript 7 support --- README.md | 14 +++++++------- lib/android-tools-info.ts | 13 +++++++++++-- lib/declarations.d.ts | 4 +++- package.json | 4 ++-- test/android-tools-info.ts | 10 ++++++++-- typings/interfaces.ts | 2 +- typings/nativescript-doctor.d.ts | 2 +- 7 files changed, 33 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 78e0716e55..28237a8c5a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# nativescript-doctor +# @nativescript/doctor Library that helps identifying if the environment can be used for development of {N} apps. # Installation 1. Using npm ```bash - $ npm install nativescript-doctor --save + $ npm install @nativescript/doctor --save ``` # Requirements @@ -14,7 +14,7 @@ Library that helps identifying if the environment can be used for development of * Module `doctor`: - Usage: ```TypeScript - import { doctor } from "nativescript-doctor" + import { doctor } from "@nativescript/doctor" async function main() { const canExecuteLocalBuildForAndroid = await doctor.canExecuteLocalBuild("Android"); @@ -47,7 +47,7 @@ Library that helps identifying if the environment can be used for development of } /** - * Describes warning returned from nativescript-doctor check. + * Describes warning returned from @nativescript/doctor check. */ interface IWarning { /** @@ -73,7 +73,7 @@ Library that helps identifying if the environment can be used for development of * Module `sysInfo`: - Usage: ```TypeScript - import { sysInfo, setShouldCacheSysInfo } from "nativescript-doctor"; + import { sysInfo, setShouldCacheSysInfo } from "@nativescript/doctor"; async function main() { // The default value is true. If set to false the result of each check for each element @@ -451,7 +451,7 @@ Library that helps identifying if the environment can be used for development of * Module `androidToolsInfo`: - Usage: ```TypeScript - import { androidToolsInfo } from "nativescript-doctor" + import { androidToolsInfo } from "@nativescript/doctor" function main() { const projectDir = "/Users/username/myProject"; @@ -542,7 +542,7 @@ Library that helps identifying if the environment can be used for development of * Module `constants`: - Usage: ```TypeScript - import { constants } from "nativescript-doctor" + import { constants } from "@nativescript/doctor" function main() { for(let constantName in constants) { diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index b8094a4cc7..b733454ccf 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -373,8 +373,17 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const pathToPackageJson = path.join(projectDir, Constants.PACKAGE_JSON); if (this.fs.exists(pathToPackageJson)) { - const content = this.fs.readJson(pathToPackageJson); - runtimeVersion = content && content.nativescript && content.nativescript["tns-android"] && content.nativescript["tns-android"].version; + const content = this.fs.readJson(pathToPackageJson); + const scopedRuntime = "@nativescript/android"; + const oldRuntime = "tns-android"; + if (content) { + if (content.devDependencies && content.devDependencies[scopedRuntime]) { + runtimeVersion = content.devDependencies[scopedRuntime]; + } else if (content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version) { + runtimeVersion = content && content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version; + } + } + } } diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 9eda37c161..3759dc8945 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -77,5 +77,7 @@ interface INativeScriptNode { } interface INativeScriptProjectPackageJson { - nativescript: INativeScriptNode; + nativescript: INativeScriptNode; + dependencies?: any; + devDependencies?: any; } diff --git a/package.json b/package.json index 4f1d74d4d3..40198f6397 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "nativescript-doctor", - "version": "1.14.2", + "name": "@nativescript/doctor", + "version": "2.0.1", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index b693ae2fed..e8f2e814b5 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -33,7 +33,10 @@ describe("androidToolsInfo", () => { "tns-android": { version: runtimeVersion } - } + }, + devDependencies: { + "@nativescript/android": runtimeVersion + } } : null; }, readDirectory: (path: string) => { @@ -231,7 +234,10 @@ describe("androidToolsInfo", () => { "tns-android": { version: runtimeVersion } - } + }, + devDependencies: { + "@nativescript/android": runtimeVersion + } }) }; diff --git a/typings/interfaces.ts b/typings/interfaces.ts index c7ccb845c3..867431c6d7 100644 --- a/typings/interfaces.ts +++ b/typings/interfaces.ts @@ -366,7 +366,7 @@ declare module NativeScriptDoctor { interface ISysInfoData extends ICommonSysInfoData, IiOSSysInfoData, IAndroidSysInfoData { } /** - * Describes warning returned from nativescript-doctor check. + * Describes warning returned from @nativescript/doctor check. */ interface IWarning { /** diff --git a/typings/nativescript-doctor.d.ts b/typings/nativescript-doctor.d.ts index 5d73fc99ed..3423e88e14 100644 --- a/typings/nativescript-doctor.d.ts +++ b/typings/nativescript-doctor.d.ts @@ -1,7 +1,7 @@ /// -declare module "nativescript-doctor" { +declare module "@nativescript/doctor" { export const doctor: NativeScriptDoctor.IDoctor; export const sysInfo: NativeScriptDoctor.ISysInfo; export const constants: NativeScriptDoctor.IConstants; From 20641e7528c189161138822504389436ce6805ce Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Sat, 29 Aug 2020 20:24:11 +0200 Subject: [PATCH 152/169] fix: support tgz runtime versions --- lib/android-tools-info.ts | 33 ++++++++++++++++++++++----------- package.json | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index b733454ccf..622469e835 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -368,22 +368,33 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } private getAndroidRuntimeVersionFromProjectDir(projectDir: string): string { + let runtimePackage: string = null; let runtimeVersion: string = null; if (projectDir && this.fs.exists(projectDir)) { const pathToPackageJson = path.join(projectDir, Constants.PACKAGE_JSON); if (this.fs.exists(pathToPackageJson)) { - const content = this.fs.readJson(pathToPackageJson); - const scopedRuntime = "@nativescript/android"; - const oldRuntime = "tns-android"; - if (content) { - if (content.devDependencies && content.devDependencies[scopedRuntime]) { - runtimeVersion = content.devDependencies[scopedRuntime]; - } else if (content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version) { - runtimeVersion = content && content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version; - } - } - + const content = this.fs.readJson(pathToPackageJson); + const scopedRuntime = "@nativescript/android"; + const oldRuntime = "tns-android"; + if (content) { + if (content.devDependencies && content.devDependencies[scopedRuntime]) { + runtimePackage = scopedRuntime; + runtimeVersion = content.devDependencies[scopedRuntime]; + } else if (content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version) { + runtimePackage = oldRuntime; + runtimeVersion = content && content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version; + } + } + + } + } + + if (runtimeVersion && runtimeVersion.includes('tgz')) { + try { + runtimeVersion = require(`${runtimePackage}/package.json`).version; + } catch (err) { + runtimeVersion = null; } } diff --git a/package.json b/package.json index 40198f6397..2ae573d39f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/doctor", - "version": "2.0.1", + "version": "2.0.3", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From a7d71a0dde6e174d507098dad388ba7d6db3163b Mon Sep 17 00:00:00 2001 From: rigor789 Date: Sun, 6 Sep 2020 14:05:54 +0200 Subject: [PATCH 153/169] fix: runtime version validation and getMaxSupportedCompileVersion --- lib/android-tools-info.ts | 113 ++++++++++++++++++++++++-------------- lib/constants.ts | 3 +- lib/declarations.d.ts | 2 +- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 622469e835..9f8aee111f 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -72,8 +72,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { const errors: NativeScriptDoctor.IWarning[] = []; const toolsInfoData = this.getToolsInfo(config); const isAndroidHomeValid = this.isAndroidHomeValid(); - const runtimeVersion = this.getRuntimeVersion(config); - const supportsOnlyMinRequiredCompileTarget = this.getMaxSupportedCompileVersion(runtimeVersion) === AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET; + const supportsOnlyMinRequiredCompileTarget = this.getMaxSupportedCompileVersion(config) === AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET; + if (!toolsInfoData.compileSdkVersion) { errors.push({ warning: `Cannot find a compatible Android SDK for compilation. To be able to build for Android, install Android SDK ${AndroidToolsInfo.MIN_REQUIRED_COMPILE_TARGET}${supportsOnlyMinRequiredCompileTarget ? "" : " or later"}.`, @@ -367,48 +367,78 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return !errors && !errors.length; } - private getAndroidRuntimeVersionFromProjectDir(projectDir: string): string { - let runtimePackage: string = null; - let runtimeVersion: string = null; - if (projectDir && this.fs.exists(projectDir)) { - const pathToPackageJson = path.join(projectDir, Constants.PACKAGE_JSON); - - if (this.fs.exists(pathToPackageJson)) { - const content = this.fs.readJson(pathToPackageJson); - const scopedRuntime = "@nativescript/android"; - const oldRuntime = "tns-android"; - if (content) { - if (content.devDependencies && content.devDependencies[scopedRuntime]) { - runtimePackage = scopedRuntime; - runtimeVersion = content.devDependencies[scopedRuntime]; - } else if (content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version) { - runtimePackage = oldRuntime; - runtimeVersion = content && content.nativescript && content.nativescript[oldRuntime] && content.nativescript[oldRuntime].version; - } - } - - } - } - - if (runtimeVersion && runtimeVersion.includes('tgz')) { - try { - runtimeVersion = require(`${runtimePackage}/package.json`).version; - } catch (err) { - runtimeVersion = null; - } - } - - return runtimeVersion; + private getAndroidRuntimePackageFromProjectDir(projectDir: string): { name: string, version: string } { + if (!projectDir || !this.fs.exists(projectDir)) { + return null + } + const pathToPackageJson = path.join(projectDir, Constants.PACKAGE_JSON); + + if(!this.fs.exists(pathToPackageJson)) { + return null + } + + const content = this.fs.readJson(pathToPackageJson); + + if(!content) { + return null + } + + // in case we have a nativescript key and a runtime with a version + // we are dealing with a legacy project and should respect the values + // in the nativescript key + if(content && content.nativescript && content.nativescript['tns-android'] && content.nativescript['tns-android'].version) { + return { + name: Constants.ANDROID_OLD_RUNTIME, + version: content.nativescript && content.nativescript['tns-android'] && content.nativescript['tns-android'].version + }; + } + + if(content && content.devDependencies) { + const foundRuntime = Object.keys(content.devDependencies).find(depName => { + return depName === Constants.ANDROID_SCOPED_RUNTIME || depName === Constants.ANDROID_OLD_RUNTIME + }) + + if(foundRuntime) { + let version = content.devDependencies[foundRuntime] + + if(version.includes('tgz')) { + try { + const packagePath = require.resolve(`${foundRuntime}/package.json`, { + paths: [projectDir] + }) + version = require(packagePath).version; + } catch (err) { + version = '*'; + } + } + + return { + name: foundRuntime, + version + } + } + } + + return null } private getRuntimeVersion({ runtimeVersion, projectDir } : { runtimeVersion?: string, projectDir?: string}): string { - runtimeVersion = runtimeVersion || this.getAndroidRuntimeVersionFromProjectDir(projectDir); + let runtimePackage = { + name: Constants.ANDROID_SCOPED_RUNTIME, + version: runtimeVersion + } + if(!runtimeVersion) { + runtimePackage = this.getAndroidRuntimePackageFromProjectDir(projectDir) + runtimeVersion = runtimePackage?.version; + } + if (runtimeVersion) { // Check if the version is not "next" or "rc", i.e. tag from npm - if (!semver.valid(runtimeVersion)) { + if (!semver.validRange(runtimeVersion)) { try { - const npmViewOutput = this.childProcess.execSync(`npm view ${Constants.ANDROID_RUNTIME} dist-tags --json`); + const npmViewOutput = this.childProcess.execSync(`npm view ${runtimePackage.name} dist-tags --json`); const jsonNpmViewOutput = JSON.parse(npmViewOutput); + runtimeVersion = jsonNpmViewOutput[runtimeVersion] || runtimeVersion; } catch (err) { // Maybe there's no npm here @@ -416,7 +446,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { } } - if (runtimeVersion && !semver.valid(runtimeVersion)) { + if (runtimeVersion && !semver.validRange(runtimeVersion)) { // If we got here, something terribly wrong happened. throw new Error(`The determined Android runtime version ${runtimeVersion} is not valid. Unable to verify if the current system is setup for Android development.`); } @@ -424,11 +454,10 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return runtimeVersion; } - private getMaxSupportedCompileVersion(runtimeVersion: string): number { - if (runtimeVersion && semver.lt(semver.coerce(runtimeVersion), "6.1.0")) { + private getMaxSupportedCompileVersion(config: Partial & { runtimeVersion?: string}): number { + if (config.runtimeVersion && semver.lt(semver.coerce(config.runtimeVersion), "6.1.0")) { return 28; } - - return this.parseAndroidSdkString(_.last(this.getSupportedTargets(runtimeVersion).sort())); + return this.parseAndroidSdkString(_.last(this.getSupportedTargets(config.projectDir).sort())); } } diff --git a/lib/constants.ts b/lib/constants.ts index 499b1b79be..226f0dd4aa 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -12,7 +12,8 @@ export class Constants { public static PACKAGE_JSON = "package.json"; public static NATIVESCRIPT_KEY = "nativescript"; - public static ANDROID_RUNTIME = "tns-android"; + public static ANDROID_OLD_RUNTIME = "tns-android"; + public static ANDROID_SCOPED_RUNTIME = "@nativescript/android"; public static VERSION_PROPERTY_NAME = "version"; public static XCODE_MIN_REQUIRED_VERSION = 10; public static JAVAC_EXECUTABLE_NAME = "javac"; diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 3759dc8945..6d9a03cfed 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -79,5 +79,5 @@ interface INativeScriptNode { interface INativeScriptProjectPackageJson { nativescript: INativeScriptNode; dependencies?: any; - devDependencies?: any; + devDependencies?: { [name: string]: string }; } From 9a822082f6e0b8487d58121c9ce5f0d736d431bf Mon Sep 17 00:00:00 2001 From: rigor789 Date: Sun, 6 Sep 2020 14:12:02 +0200 Subject: [PATCH 154/169] style: reformat code --- lib/android-tools-info.ts | 122 ++++++++++++++++++------------------- lib/declarations.d.ts | 6 +- test/android-tools-info.ts | 24 ++++---- 3 files changed, 76 insertions(+), 76 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 9f8aee111f..0f0cae94bd 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -11,7 +11,7 @@ import * as _ from "lodash"; export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { public readonly ANDROID_TARGET_PREFIX = "android"; public getSupportedTargets(projectDir: string) { - const runtimeVersion = this.getRuntimeVersion({projectDir}); + const runtimeVersion = this.getRuntimeVersion({ projectDir }); let baseTargets = [ "android-17", "android-18", @@ -126,7 +126,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION) || semver.gte(installedJavaCompilerSemverVersion, AndroidToolsInfo.MAX_JAVA_VERSION)) { warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION} and below ${AndroidToolsInfo.MAX_JAVA_VERSION}.`; } else { - runtimeVersion = this.getRuntimeVersion({runtimeVersion, projectDir}); + runtimeVersion = this.getRuntimeVersion({ runtimeVersion, projectDir }); if (runtimeVersion) { // get the item from the dictionary that corresponds to our current Javac version: let runtimeMinVersion: string = null; @@ -200,7 +200,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } - public validateMinSupportedTargetSdk({targetSdk, projectDir}: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] { + public validateMinSupportedTargetSdk({ targetSdk, projectDir }: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; const supportedTargets = this.getSupportedTargets(projectDir); @@ -212,7 +212,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { if (!targetSupported && targetSdk && (targetSdk < minSupportedVersion)) { errors.push({ - warning:`The selected Android target SDK ${newTarget} is not supported. You must target ${minSupportedVersion} or later.`, + warning: `The selected Android target SDK ${newTarget} is not supported. You must target ${minSupportedVersion} or later.`, additionalInformation: "", platforms: [Constants.ANDROID_PLATFORM_NAME] }); @@ -222,14 +222,14 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } - public validataMaxSupportedTargetSdk({targetSdk, projectDir}: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] { + public validataMaxSupportedTargetSdk({ targetSdk, projectDir }: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`; const targetSupported = _.includes(this.getSupportedTargets(projectDir), newTarget); if (!targetSupported && !targetSdk || targetSdk > this.getMaxSupportedVersion(projectDir)) { errors.push({ - warning:`Support for the selected Android target SDK ${newTarget} is not verified. Your Android app might not work as expected.`, + warning: `Support for the selected Android target SDK ${newTarget} is not verified. Your Android app might not work as expected.`, additionalInformation: "", platforms: [Constants.ANDROID_PLATFORM_NAME] }); @@ -369,68 +369,68 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private getAndroidRuntimePackageFromProjectDir(projectDir: string): { name: string, version: string } { if (!projectDir || !this.fs.exists(projectDir)) { - return null - } + return null; + } const pathToPackageJson = path.join(projectDir, Constants.PACKAGE_JSON); - if(!this.fs.exists(pathToPackageJson)) { - return null - } + if (!this.fs.exists(pathToPackageJson)) { + return null; + } - const content = this.fs.readJson(pathToPackageJson); + const content = this.fs.readJson(pathToPackageJson); - if(!content) { - return null - } + if (!content) { + return null; + } // in case we have a nativescript key and a runtime with a version - // we are dealing with a legacy project and should respect the values - // in the nativescript key - if(content && content.nativescript && content.nativescript['tns-android'] && content.nativescript['tns-android'].version) { - return { - name: Constants.ANDROID_OLD_RUNTIME, - version: content.nativescript && content.nativescript['tns-android'] && content.nativescript['tns-android'].version - }; - } - - if(content && content.devDependencies) { - const foundRuntime = Object.keys(content.devDependencies).find(depName => { - return depName === Constants.ANDROID_SCOPED_RUNTIME || depName === Constants.ANDROID_OLD_RUNTIME - }) - - if(foundRuntime) { - let version = content.devDependencies[foundRuntime] - - if(version.includes('tgz')) { - try { - const packagePath = require.resolve(`${foundRuntime}/package.json`, { - paths: [projectDir] - }) - version = require(packagePath).version; - } catch (err) { - version = '*'; - } - } - - return { - name: foundRuntime, - version - } - } - } - - return null + // we are dealing with a legacy project and should respect the values + // in the nativescript key + if (content && content.nativescript && content.nativescript['tns-android'] && content.nativescript['tns-android'].version) { + return { + name: Constants.ANDROID_OLD_RUNTIME, + version: content.nativescript && content.nativescript['tns-android'] && content.nativescript['tns-android'].version + }; + } + + if (content && content.devDependencies) { + const foundRuntime = Object.keys(content.devDependencies).find(depName => { + return depName === Constants.ANDROID_SCOPED_RUNTIME || depName === Constants.ANDROID_OLD_RUNTIME; + }); + + if (foundRuntime) { + let version = content.devDependencies[foundRuntime]; + + if (version.includes('tgz')) { + try { + const packagePath = require.resolve(`${foundRuntime}/package.json`, { + paths: [projectDir] + }); + version = require(packagePath).version; + } catch (err) { + version = '*'; + } + } + + return { + name: foundRuntime, + version + }; + } + } + + return null; } - private getRuntimeVersion({ runtimeVersion, projectDir } : { runtimeVersion?: string, projectDir?: string}): string { - let runtimePackage = { - name: Constants.ANDROID_SCOPED_RUNTIME, - version: runtimeVersion - } - if(!runtimeVersion) { - runtimePackage = this.getAndroidRuntimePackageFromProjectDir(projectDir) - runtimeVersion = runtimePackage?.version; - } + private getRuntimeVersion({ runtimeVersion, projectDir }: { runtimeVersion?: string, projectDir?: string }): string { + let runtimePackage = { + name: Constants.ANDROID_SCOPED_RUNTIME, + version: runtimeVersion + }; + if (!runtimeVersion) { + runtimePackage = this.getAndroidRuntimePackageFromProjectDir(projectDir); + runtimeVersion = runtimePackage && runtimePackage.version; + } if (runtimeVersion) { // Check if the version is not "next" or "rc", i.e. tag from npm @@ -454,7 +454,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return runtimeVersion; } - private getMaxSupportedCompileVersion(config: Partial & { runtimeVersion?: string}): number { + private getMaxSupportedCompileVersion(config: Partial & { runtimeVersion?: string }): number { if (config.runtimeVersion && semver.lt(semver.coerce(config.runtimeVersion), "6.1.0")) { return 28; } diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 6d9a03cfed..5421682ccb 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -77,7 +77,7 @@ interface INativeScriptNode { } interface INativeScriptProjectPackageJson { - nativescript: INativeScriptNode; - dependencies?: any; - devDependencies?: { [name: string]: string }; + nativescript: INativeScriptNode; + dependencies?: any; + devDependencies?: { [name: string]: string }; } diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index e8f2e814b5..a25d538ed7 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -33,10 +33,10 @@ describe("androidToolsInfo", () => { "tns-android": { version: runtimeVersion } - }, - devDependencies: { - "@nativescript/android": runtimeVersion - } + }, + devDependencies: { + "@nativescript/android": runtimeVersion + } } : null; }, readDirectory: (path: string) => { @@ -65,14 +65,14 @@ describe("androidToolsInfo", () => { describe("getToolsInfo", () => { it("runtime 6.0.0", () => { const androidToolsInfo = getAndroidToolsInfo("6.0.0"); - const toolsInfo = androidToolsInfo.getToolsInfo({projectDir: "test"}); + const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" }); assert.equal(toolsInfo.compileSdkVersion, 28); }); it("runtime 6.1.0", () => { const androidToolsInfo = getAndroidToolsInfo("6.1.0"); - const toolsInfo = androidToolsInfo.getToolsInfo({projectDir: "test"}); + const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" }); assert.equal(toolsInfo.compileSdkVersion, 29); }); @@ -86,8 +86,8 @@ describe("androidToolsInfo", () => { const androidToolsInfo = getAndroidToolsInfo("6.5.0"); const supportedTargets = androidToolsInfo.getSupportedTargets("test"); for (let i = 0; i < supportedTargets.length; i++) { - assert.equal(supportedTargets[i], `android-${min+i}`); - cnt = min+i; + assert.equal(supportedTargets[i], `android-${min + i}`); + cnt = min + i; } assert.equal(cnt, max); }); @@ -234,10 +234,10 @@ describe("androidToolsInfo", () => { "tns-android": { version: runtimeVersion } - }, - devDependencies: { - "@nativescript/android": runtimeVersion - } + }, + devDependencies: { + "@nativescript/android": runtimeVersion + } }) }; From 5213c84df2d9934758ec1a491931976542ed0a5a Mon Sep 17 00:00:00 2001 From: rigor789 Date: Sun, 6 Sep 2020 14:18:28 +0200 Subject: [PATCH 155/169] chore(release): v2.0.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ae573d39f..ff628f5b76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/doctor", - "version": "2.0.3", + "version": "2.0.4", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 92077dc680dbb4b7430bc8a7c4fef364adc105ec Mon Sep 17 00:00:00 2001 From: rigor789 Date: Sun, 6 Sep 2020 14:22:04 +0200 Subject: [PATCH 156/169] chore: update changelog --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index feb927b308..2fa18e0ce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +## [2.0.4](https://github.com/NativeScript/nativescript-doctor/compare/v2.0.3...v2.0.4) (2020-09-06) + + +### Bug Fixes + +* runtime version validation and getMaxSupportedCompileVersion ([a7d71a0](https://github.com/NativeScript/nativescript-doctor/commit/a7d71a0dde6e174d507098dad388ba7d6db3163b)) + + + +## [2.0.3](https://github.com/NativeScript/nativescript-doctor/compare/v2.0.1...v2.0.3) (2020-09-06) + + +### Bug Fixes + +* support tgz runtime versions ([20641e7](https://github.com/NativeScript/nativescript-doctor/commit/20641e7528c189161138822504389436ce6805ce)) + + + +## [2.0.1](https://github.com/NativeScript/nativescript-doctor/compare/v1.14.2...v2.0.1) (2020-09-06) + + +### Features + +* nativescript 7 support ([6b88f4c](https://github.com/NativeScript/nativescript-doctor/commit/6b88f4c2195cf15e20e9df043270b1cf105093fe)) + + + ## [1.14.2](https://github.com/NativeScript/nativescript-doctor/compare/v1.14.1...v1.14.2) (2020-06-25) From 9db60b64970d229c539e03b888b1e93195367da4 Mon Sep 17 00:00:00 2001 From: Pavitra Golchha Date: Wed, 6 Jan 2021 00:10:49 +0530 Subject: [PATCH 157/169] fix(windows): handle paths correctly (#64) --- .travis.yml | 2 +- lib/wrappers/file-system.ts | 13 +------------ test/wrappers/file-system.ts | 6 +++--- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7b3076749..7494adcd45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- '8' +- '14' git: submodules: false before_script: diff --git a/lib/wrappers/file-system.ts b/lib/wrappers/file-system.ts index 57549a24c8..ccae7c94f3 100644 --- a/lib/wrappers/file-system.ts +++ b/lib/wrappers/file-system.ts @@ -1,12 +1,8 @@ import * as fs from "fs"; import * as path from "path"; import * as yauzl from "yauzl"; -import * as util from "util"; import * as shelljs from "shelljs"; -const access = util.promisify(fs.access); -const mkdir = util.promisify(fs.mkdir); - export class FileSystem { public exists(filePath: string): boolean { return fs.existsSync(path.resolve(filePath)); @@ -66,12 +62,5 @@ export class FileSystem { } function createParentDirsIfNeeded(filePath: string) { - const dirs = path.dirname(filePath).split(path.sep); - return dirs.reduce((p, dir) => p.then(parent => { - const current = `${parent}${path.sep}${dir}`; - - return access(current) - .catch(e => mkdir(current)) - .then(() => current); - }), Promise.resolve('')); + return fs.promises.mkdir(path.dirname(filePath), {recursive: true}); } diff --git a/test/wrappers/file-system.ts b/test/wrappers/file-system.ts index 97754017be..e2b0708439 100644 --- a/test/wrappers/file-system.ts +++ b/test/wrappers/file-system.ts @@ -18,7 +18,7 @@ describe('FileSystem', () => { ].join(''); const tmpDir = `${tmpdir()}/${datetime}`; const testFilePath = `${__dirname}/example.zip`; - const filesThatNeedToExtsit = [ + const filesThatNeedToExist = [ `${tmpDir}/test/android-local-build-requirements.ts`, `${tmpDir}/test/android-tools-info.ts`, `${tmpDir}/test/ios-local-build-requirements.ts`, @@ -27,11 +27,11 @@ describe('FileSystem', () => { ]; it('should extract in example zip archive in tmp folder', done => { - const fs = new FileSystem(); + const fs = new FileSystem(); fs.extractZip(testFilePath, tmpDir) .then(() => { - const allExists = filesThatNeedToExtsit + const allExists = filesThatNeedToExist .map(fs.exists) .reduce((acc, r) => acc && r, true); From cf6888c0d807bb360c7c1de75697cd3b9d3e08b3 Mon Sep 17 00:00:00 2001 From: Pavitra Golchha Date: Wed, 6 Jan 2021 00:14:05 +0530 Subject: [PATCH 158/169] chore: simplify npm scripts (#66) * Make npm scripts Windows compatible * Update package.json Co-authored-by: Igor Randjelovic --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ff628f5b76..3dd6752b8c 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,11 @@ "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", "scripts": { - "clean": "npx rimraf node_modules package-lock.json && npm i && ./node_modules/.bin/grunt clean", - "build": "./node_modules/.bin/grunt", - "build.all": "./node_modules/.bin/grunt ts:devall", - "pack": "./node_modules/.bin/grunt pack", - "test": "node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive", + "clean": "npx rimraf node_modules package-lock.json && npm i && grunt clean", + "build": "grunt", + "build.all": "grunt ts:devall", + "pack": "grunt pack", + "test": "istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" }, "repository": { From f2d9e32e32ab3ce897e4654ed61577fd67d0292a Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 5 Jan 2021 21:04:45 +0100 Subject: [PATCH 159/169] ci: add release workflow --- .github/workflows/npm_release.yml | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/npm_release.yml diff --git a/.github/workflows/npm_release.yml b/.github/workflows/npm_release.yml new file mode 100644 index 0000000000..fdcdff2975 --- /dev/null +++ b/.github/workflows/npm_release.yml @@ -0,0 +1,37 @@ +name: '@nativescript/doctor -> npm' + +on: + push: + branches: [ 'master' ] + +env: + NPM_TAG: 'next' + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Setup + run: npm install + + - name: Generate Version + run: | + echo NPM_VERSION=$(node -e "console.log(require('./package.json').version);")-$NPM_TAG-$(date +"%m-%d-%Y")-$GITHUB_RUN_ID >> $GITHUB_ENV + + - name: Bump Version + run: npm version $NPM_VERSION + + - name: Build @nativescript/doctor + run: npm run pack + + - name: Publish @nativescript/core + working-directory: dist/packages + env: + NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} + run: | + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ../../.npmrc + echo "Publishing @nativescript/doctor@$NPM_VERSION to NPM with tag $NPM_TAG..." + npm publish nativescript-doctor-$NPM_VERSION.tgz --tag $NPM_TAG From cfcb3f4cb075c5434c8392f14ff28f9478d58957 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 5 Jan 2021 21:08:03 +0100 Subject: [PATCH 160/169] ci: disable git tag/commit --- .github/workflows/npm_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm_release.yml b/.github/workflows/npm_release.yml index fdcdff2975..93dc1d20fd 100644 --- a/.github/workflows/npm_release.yml +++ b/.github/workflows/npm_release.yml @@ -22,7 +22,7 @@ jobs: echo NPM_VERSION=$(node -e "console.log(require('./package.json').version);")-$NPM_TAG-$(date +"%m-%d-%Y")-$GITHUB_RUN_ID >> $GITHUB_ENV - name: Bump Version - run: npm version $NPM_VERSION + run: npm --no-git-tag-version version $NPM_VERSION - name: Build @nativescript/doctor run: npm run pack From 2cc23a32794354293974e2b0e2fac06b24cb65c6 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 5 Jan 2021 21:09:49 +0100 Subject: [PATCH 161/169] ci: append to npmrc in cwd --- .github/workflows/npm_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm_release.yml b/.github/workflows/npm_release.yml index 93dc1d20fd..4857b98655 100644 --- a/.github/workflows/npm_release.yml +++ b/.github/workflows/npm_release.yml @@ -32,6 +32,6 @@ jobs: env: NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} run: | - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ../../.npmrc + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc echo "Publishing @nativescript/doctor@$NPM_VERSION to NPM with tag $NPM_TAG..." npm publish nativescript-doctor-$NPM_VERSION.tgz --tag $NPM_TAG From e56b78ca6bf31bac7e0fdebe1a89e22805d60946 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 5 Jan 2021 21:14:58 +0100 Subject: [PATCH 162/169] ci: remove working-directory --- .github/workflows/npm_release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/npm_release.yml b/.github/workflows/npm_release.yml index 4857b98655..4140571413 100644 --- a/.github/workflows/npm_release.yml +++ b/.github/workflows/npm_release.yml @@ -28,7 +28,6 @@ jobs: run: npm run pack - name: Publish @nativescript/core - working-directory: dist/packages env: NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} run: | From f9a86ef934b90e8f96fbb413b03e9fc09079a0d6 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 8 Jan 2021 16:19:21 +0100 Subject: [PATCH 163/169] ci: fix typo [ci skip] --- .github/workflows/npm_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm_release.yml b/.github/workflows/npm_release.yml index 4140571413..9b0c0a5ea5 100644 --- a/.github/workflows/npm_release.yml +++ b/.github/workflows/npm_release.yml @@ -27,7 +27,7 @@ jobs: - name: Build @nativescript/doctor run: npm run pack - - name: Publish @nativescript/core + - name: Publish @nativescript/doctor env: NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} run: | From 3e96ec16298f5205ed2511baf94b23d36d80c454 Mon Sep 17 00:00:00 2001 From: Ken Southerland Date: Fri, 5 Feb 2021 11:29:53 -0800 Subject: [PATCH 164/169] fix: removed max java version limitation (#67) --- lib/android-tools-info.ts | 17 ++++++++++++++--- test/android-tools-info.ts | 19 +++++++++---------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 0f0cae94bd..2681cfc94c 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -41,7 +41,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23"; private static VERSION_REGEX = /((\d+\.){2}\d+)/; private static MIN_JAVA_VERSION = "1.8.0"; - private static MAX_JAVA_VERSION = "13.0.0"; + // If some java release breaks the code then set this version to the breaking release (e.g. "13.0.0") + private static MAX_JAVA_VERSION = null as string; private toolsInfo: NativeScriptDoctor.IAndroidToolsInfoData; public get androidHome(): string { @@ -107,6 +108,16 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { return errors; } + public static unsupportedJavaMessage(installedJavaCompilerVersion: string): string { + return `Javac version ${installedJavaCompilerVersion} is not supported. You must install a java version greater than ${ + AndroidToolsInfo.MIN_JAVA_VERSION + }${ + AndroidToolsInfo.MAX_JAVA_VERSION + ? ` and less than ${AndroidToolsInfo.MAX_JAVA_VERSION}` + : "" + }.`; + } + public validateJavacVersion(installedJavaCompilerVersion: string, projectDir?: string, runtimeVersion?: string): NativeScriptDoctor.IWarning[] { const errors: NativeScriptDoctor.IWarning[] = []; @@ -123,8 +134,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "^10.0.0": "4.1.0-2018.5.18.1" }; - if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION) || semver.gte(installedJavaCompilerSemverVersion, AndroidToolsInfo.MAX_JAVA_VERSION)) { - warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION} and below ${AndroidToolsInfo.MAX_JAVA_VERSION}.`; + if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION) || (AndroidToolsInfo.MAX_JAVA_VERSION ? semver.gte(installedJavaCompilerSemverVersion, AndroidToolsInfo.MAX_JAVA_VERSION) : false)) { + warning = AndroidToolsInfo.unsupportedJavaMessage(installedJavaCompilerVersion); } else { runtimeVersion = this.getRuntimeVersion({ runtimeVersion, projectDir }); if (runtimeVersion) { diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index a25d538ed7..c156ee1547 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -115,20 +115,19 @@ describe("androidToolsInfo", () => { }, { javacVersion: "1.7.0", - warnings: ["Javac version 1.7.0 is not supported. You have to install at least 1.8.0 and below 13.0.0."] + warnings: [AndroidToolsInfo.unsupportedJavaMessage("1.7.0")] }, { javacVersion: "1.7.0_132", - warnings: ["Javac version 1.7.0_132 is not supported. You have to install at least 1.8.0 and below 13.0.0."] - }, - { - javacVersion: "13.0.0", - warnings: ["Javac version 13.0.0 is not supported. You have to install at least 1.8.0 and below 13.0.0."] - }, - { - javacVersion: "14.1.0", - warnings: ["Javac version 14.1.0 is not supported. You have to install at least 1.8.0 and below 13.0.0."] + warnings: [AndroidToolsInfo.unsupportedJavaMessage("1.7.0_132")] }, + // + // Reinstate this test if there is some future max java version found to be not supported. + // + // { + // javacVersion: "14.1.0", + // warnings: [AndroidToolsInfo.unsupportedJavaMessage("14.1.0")] + // }, { javacVersion: null, warnings: ["Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable."] From b7c7278b1425950a3168784293090617c021303f Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 8 Oct 2021 16:05:50 +0200 Subject: [PATCH 165/169] fix: android-31 target version (#71) * chore: add android-31 to supported targets * test: update test --- lib/android-tools-info.ts | 3 ++- test/android-tools-info.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/android-tools-info.ts b/lib/android-tools-info.ts index 2681cfc94c..9430076e6a 100644 --- a/lib/android-tools-info.ts +++ b/lib/android-tools-info.ts @@ -26,7 +26,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "android-27", "android-28", "android-29", - "android-30" + "android-30", + "android-31", ]; if (runtimeVersion && semver.lt(semver.coerce(runtimeVersion), "6.1.0")) { diff --git a/test/android-tools-info.ts b/test/android-tools-info.ts index c156ee1547..6468a5480f 100644 --- a/test/android-tools-info.ts +++ b/test/android-tools-info.ts @@ -79,9 +79,9 @@ describe("androidToolsInfo", () => { }); describe("supportedAndroidSdks", () => { - it("should support android-17 - android-30", () => { + it("should support android-17 - android-31", () => { const min = 17; - const max = 30; + const max = 31; let cnt = 0; const androidToolsInfo = getAndroidToolsInfo("6.5.0"); const supportedTargets = androidToolsInfo.getSupportedTargets("test"); From c6344042bad1547172739f74dd5f141eb58883c9 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 8 Oct 2021 16:07:08 +0200 Subject: [PATCH 166/169] chore(release): 2.0.5 --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fa18e0ce1..0c404e1b54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [2.0.5](https://github.com/NativeScript/nativescript-doctor/compare/v2.0.4...v2.0.5) (2021-10-08) + + +### Bug Fixes + +* android-31 target version ([#71](https://github.com/NativeScript/nativescript-doctor/issues/71)) ([b7c7278](https://github.com/NativeScript/nativescript-doctor/commit/b7c7278b1425950a3168784293090617c021303f)) +* removed max java version limitation ([#67](https://github.com/NativeScript/nativescript-doctor/issues/67)) ([3e96ec1](https://github.com/NativeScript/nativescript-doctor/commit/3e96ec16298f5205ed2511baf94b23d36d80c454)) +* **windows:** handle paths correctly ([#64](https://github.com/NativeScript/nativescript-doctor/issues/64)) ([9db60b6](https://github.com/NativeScript/nativescript-doctor/commit/9db60b64970d229c539e03b888b1e93195367da4)) + + + ## [2.0.4](https://github.com/NativeScript/nativescript-doctor/compare/v2.0.3...v2.0.4) (2020-09-06) diff --git a/package.json b/package.json index 3dd6752b8c..0a5bd2f4d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/doctor", - "version": "2.0.4", + "version": "2.0.5", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From f534630bf687b160a70d8baffdf1cda10a94dfd9 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Mon, 11 Oct 2021 17:51:01 +0200 Subject: [PATCH 167/169] chore(release): 2.0.6 2.0.5 had a packing issue and is missing files. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a5bd2f4d4..5ea19f042d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/doctor", - "version": "2.0.5", + "version": "2.0.6", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "lib/index.js", "types": "./typings/nativescript-doctor.d.ts", From 8e154c80a5ef91f07ce0f8790b764d8b3fd5657a Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Mon, 7 Feb 2022 18:10:07 +0100 Subject: [PATCH 168/169] move doctor sources to packages/doctor --- .../doctor/.github}/workflows/npm_release.yml | 0 .gitignore => packages/doctor/.gitignore | 0 .npmignore => packages/doctor/.npmignore | 0 .travis.yml => packages/doctor/.travis.yml | 0 CHANGELOG.md => packages/doctor/CHANGELOG.md | 0 Gruntfile.js => packages/doctor/Gruntfile.js | 0 LICENSE => packages/doctor/LICENSE | 0 NOTICE.txt => packages/doctor/NOTICE.txt | 0 README.md => packages/doctor/README.md | 0 {lib => packages/doctor/lib}/android-tools-info.ts | 0 {lib => packages/doctor/lib}/constants.ts | 0 {lib => packages/doctor/lib}/declarations.d.ts | 0 {lib => packages/doctor/lib}/definitions/osenv.d.ts | 0 {lib => packages/doctor/lib}/definitions/unzip.d.ts | 0 {lib => packages/doctor/lib}/doctor.ts | 0 {lib => packages/doctor/lib}/helpers.ts | 0 {lib => packages/doctor/lib}/host-info.ts | 0 {lib => packages/doctor/lib}/index.ts | 0 .../android-local-build-requirements.ts | 0 .../ios-local-build-requirements.ts | 0 {lib => packages/doctor/lib}/sys-info.ts | 0 {lib => packages/doctor/lib}/winreg.ts | 0 .../doctor/lib}/wrappers/child-process.ts | 0 .../doctor/lib}/wrappers/file-system.ts | 0 package.json => packages/doctor/package.json | 0 .../resources}/cocoapods-verification/cocoapods.zip | Bin .../test}/android-local-build-requirements.ts | 0 .../doctor/test}/android-tools-info.ts | 0 .../doctor/test}/ios-local-build-requirements.ts | 0 {test => packages/doctor/test}/sys-info.ts | 0 {test => packages/doctor/test}/wrappers/example.zip | Bin .../doctor/test}/wrappers/file-system.ts | 0 tsconfig.json => packages/doctor/tsconfig.json | 0 tslint.json => packages/doctor/tslint.json | 0 {typings => packages/doctor/typings}/interfaces.ts | 0 .../doctor/typings}/nativescript-doctor.d.ts | 0 36 files changed, 0 insertions(+), 0 deletions(-) rename {.github => packages/doctor/.github}/workflows/npm_release.yml (100%) rename .gitignore => packages/doctor/.gitignore (100%) rename .npmignore => packages/doctor/.npmignore (100%) rename .travis.yml => packages/doctor/.travis.yml (100%) rename CHANGELOG.md => packages/doctor/CHANGELOG.md (100%) rename Gruntfile.js => packages/doctor/Gruntfile.js (100%) rename LICENSE => packages/doctor/LICENSE (100%) rename NOTICE.txt => packages/doctor/NOTICE.txt (100%) rename README.md => packages/doctor/README.md (100%) rename {lib => packages/doctor/lib}/android-tools-info.ts (100%) rename {lib => packages/doctor/lib}/constants.ts (100%) rename {lib => packages/doctor/lib}/declarations.d.ts (100%) rename {lib => packages/doctor/lib}/definitions/osenv.d.ts (100%) rename {lib => packages/doctor/lib}/definitions/unzip.d.ts (100%) rename {lib => packages/doctor/lib}/doctor.ts (100%) rename {lib => packages/doctor/lib}/helpers.ts (100%) rename {lib => packages/doctor/lib}/host-info.ts (100%) rename {lib => packages/doctor/lib}/index.ts (100%) rename {lib => packages/doctor/lib}/local-build-requirements/android-local-build-requirements.ts (100%) rename {lib => packages/doctor/lib}/local-build-requirements/ios-local-build-requirements.ts (100%) rename {lib => packages/doctor/lib}/sys-info.ts (100%) rename {lib => packages/doctor/lib}/winreg.ts (100%) rename {lib => packages/doctor/lib}/wrappers/child-process.ts (100%) rename {lib => packages/doctor/lib}/wrappers/file-system.ts (100%) rename package.json => packages/doctor/package.json (100%) rename {resources => packages/doctor/resources}/cocoapods-verification/cocoapods.zip (100%) rename {test => packages/doctor/test}/android-local-build-requirements.ts (100%) rename {test => packages/doctor/test}/android-tools-info.ts (100%) rename {test => packages/doctor/test}/ios-local-build-requirements.ts (100%) rename {test => packages/doctor/test}/sys-info.ts (100%) rename {test => packages/doctor/test}/wrappers/example.zip (100%) rename {test => packages/doctor/test}/wrappers/file-system.ts (100%) rename tsconfig.json => packages/doctor/tsconfig.json (100%) rename tslint.json => packages/doctor/tslint.json (100%) rename {typings => packages/doctor/typings}/interfaces.ts (100%) rename {typings => packages/doctor/typings}/nativescript-doctor.d.ts (100%) diff --git a/.github/workflows/npm_release.yml b/packages/doctor/.github/workflows/npm_release.yml similarity index 100% rename from .github/workflows/npm_release.yml rename to packages/doctor/.github/workflows/npm_release.yml diff --git a/.gitignore b/packages/doctor/.gitignore similarity index 100% rename from .gitignore rename to packages/doctor/.gitignore diff --git a/.npmignore b/packages/doctor/.npmignore similarity index 100% rename from .npmignore rename to packages/doctor/.npmignore diff --git a/.travis.yml b/packages/doctor/.travis.yml similarity index 100% rename from .travis.yml rename to packages/doctor/.travis.yml diff --git a/CHANGELOG.md b/packages/doctor/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/doctor/CHANGELOG.md diff --git a/Gruntfile.js b/packages/doctor/Gruntfile.js similarity index 100% rename from Gruntfile.js rename to packages/doctor/Gruntfile.js diff --git a/LICENSE b/packages/doctor/LICENSE similarity index 100% rename from LICENSE rename to packages/doctor/LICENSE diff --git a/NOTICE.txt b/packages/doctor/NOTICE.txt similarity index 100% rename from NOTICE.txt rename to packages/doctor/NOTICE.txt diff --git a/README.md b/packages/doctor/README.md similarity index 100% rename from README.md rename to packages/doctor/README.md diff --git a/lib/android-tools-info.ts b/packages/doctor/lib/android-tools-info.ts similarity index 100% rename from lib/android-tools-info.ts rename to packages/doctor/lib/android-tools-info.ts diff --git a/lib/constants.ts b/packages/doctor/lib/constants.ts similarity index 100% rename from lib/constants.ts rename to packages/doctor/lib/constants.ts diff --git a/lib/declarations.d.ts b/packages/doctor/lib/declarations.d.ts similarity index 100% rename from lib/declarations.d.ts rename to packages/doctor/lib/declarations.d.ts diff --git a/lib/definitions/osenv.d.ts b/packages/doctor/lib/definitions/osenv.d.ts similarity index 100% rename from lib/definitions/osenv.d.ts rename to packages/doctor/lib/definitions/osenv.d.ts diff --git a/lib/definitions/unzip.d.ts b/packages/doctor/lib/definitions/unzip.d.ts similarity index 100% rename from lib/definitions/unzip.d.ts rename to packages/doctor/lib/definitions/unzip.d.ts diff --git a/lib/doctor.ts b/packages/doctor/lib/doctor.ts similarity index 100% rename from lib/doctor.ts rename to packages/doctor/lib/doctor.ts diff --git a/lib/helpers.ts b/packages/doctor/lib/helpers.ts similarity index 100% rename from lib/helpers.ts rename to packages/doctor/lib/helpers.ts diff --git a/lib/host-info.ts b/packages/doctor/lib/host-info.ts similarity index 100% rename from lib/host-info.ts rename to packages/doctor/lib/host-info.ts diff --git a/lib/index.ts b/packages/doctor/lib/index.ts similarity index 100% rename from lib/index.ts rename to packages/doctor/lib/index.ts diff --git a/lib/local-build-requirements/android-local-build-requirements.ts b/packages/doctor/lib/local-build-requirements/android-local-build-requirements.ts similarity index 100% rename from lib/local-build-requirements/android-local-build-requirements.ts rename to packages/doctor/lib/local-build-requirements/android-local-build-requirements.ts diff --git a/lib/local-build-requirements/ios-local-build-requirements.ts b/packages/doctor/lib/local-build-requirements/ios-local-build-requirements.ts similarity index 100% rename from lib/local-build-requirements/ios-local-build-requirements.ts rename to packages/doctor/lib/local-build-requirements/ios-local-build-requirements.ts diff --git a/lib/sys-info.ts b/packages/doctor/lib/sys-info.ts similarity index 100% rename from lib/sys-info.ts rename to packages/doctor/lib/sys-info.ts diff --git a/lib/winreg.ts b/packages/doctor/lib/winreg.ts similarity index 100% rename from lib/winreg.ts rename to packages/doctor/lib/winreg.ts diff --git a/lib/wrappers/child-process.ts b/packages/doctor/lib/wrappers/child-process.ts similarity index 100% rename from lib/wrappers/child-process.ts rename to packages/doctor/lib/wrappers/child-process.ts diff --git a/lib/wrappers/file-system.ts b/packages/doctor/lib/wrappers/file-system.ts similarity index 100% rename from lib/wrappers/file-system.ts rename to packages/doctor/lib/wrappers/file-system.ts diff --git a/package.json b/packages/doctor/package.json similarity index 100% rename from package.json rename to packages/doctor/package.json diff --git a/resources/cocoapods-verification/cocoapods.zip b/packages/doctor/resources/cocoapods-verification/cocoapods.zip similarity index 100% rename from resources/cocoapods-verification/cocoapods.zip rename to packages/doctor/resources/cocoapods-verification/cocoapods.zip diff --git a/test/android-local-build-requirements.ts b/packages/doctor/test/android-local-build-requirements.ts similarity index 100% rename from test/android-local-build-requirements.ts rename to packages/doctor/test/android-local-build-requirements.ts diff --git a/test/android-tools-info.ts b/packages/doctor/test/android-tools-info.ts similarity index 100% rename from test/android-tools-info.ts rename to packages/doctor/test/android-tools-info.ts diff --git a/test/ios-local-build-requirements.ts b/packages/doctor/test/ios-local-build-requirements.ts similarity index 100% rename from test/ios-local-build-requirements.ts rename to packages/doctor/test/ios-local-build-requirements.ts diff --git a/test/sys-info.ts b/packages/doctor/test/sys-info.ts similarity index 100% rename from test/sys-info.ts rename to packages/doctor/test/sys-info.ts diff --git a/test/wrappers/example.zip b/packages/doctor/test/wrappers/example.zip similarity index 100% rename from test/wrappers/example.zip rename to packages/doctor/test/wrappers/example.zip diff --git a/test/wrappers/file-system.ts b/packages/doctor/test/wrappers/file-system.ts similarity index 100% rename from test/wrappers/file-system.ts rename to packages/doctor/test/wrappers/file-system.ts diff --git a/tsconfig.json b/packages/doctor/tsconfig.json similarity index 100% rename from tsconfig.json rename to packages/doctor/tsconfig.json diff --git a/tslint.json b/packages/doctor/tslint.json similarity index 100% rename from tslint.json rename to packages/doctor/tslint.json diff --git a/typings/interfaces.ts b/packages/doctor/typings/interfaces.ts similarity index 100% rename from typings/interfaces.ts rename to packages/doctor/typings/interfaces.ts diff --git a/typings/nativescript-doctor.d.ts b/packages/doctor/typings/nativescript-doctor.d.ts similarity index 100% rename from typings/nativescript-doctor.d.ts rename to packages/doctor/typings/nativescript-doctor.d.ts From 1abf10696340224eaa602168dd32367a1d9f7b33 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Mon, 7 Feb 2022 18:19:07 +0100 Subject: [PATCH 169/169] chore: cleanup workflows --- .../workflows/{npm_release.yml => npm_release_cli.yml} | 2 ++ .../workflows/npm_release_doctor.yml | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) rename .github/workflows/{npm_release.yml => npm_release_cli.yml} (95%) rename packages/doctor/.github/workflows/npm_release.yml => .github/workflows/npm_release_doctor.yml (82%) diff --git a/.github/workflows/npm_release.yml b/.github/workflows/npm_release_cli.yml similarity index 95% rename from .github/workflows/npm_release.yml rename to .github/workflows/npm_release_cli.yml index bde0281f64..5643eed201 100644 --- a/.github/workflows/npm_release.yml +++ b/.github/workflows/npm_release_cli.yml @@ -3,6 +3,8 @@ name: 'nativescript -> npm' on: push: branches: [ 'master' ] + paths-ignore: + - 'packages/**' workflow_dispatch: env: diff --git a/packages/doctor/.github/workflows/npm_release.yml b/.github/workflows/npm_release_doctor.yml similarity index 82% rename from packages/doctor/.github/workflows/npm_release.yml rename to .github/workflows/npm_release_doctor.yml index 9b0c0a5ea5..2d2eda1c2a 100644 --- a/packages/doctor/.github/workflows/npm_release.yml +++ b/.github/workflows/npm_release_doctor.yml @@ -3,6 +3,13 @@ name: '@nativescript/doctor -> npm' on: push: branches: [ 'master' ] + paths: + - 'packages/doctor' + workflow_dispatch: + +defaults: + run: + working-directory: packages/doctor env: NPM_TAG: 'next' @@ -33,4 +40,4 @@ jobs: run: | echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc echo "Publishing @nativescript/doctor@$NPM_VERSION to NPM with tag $NPM_TAG..." - npm publish nativescript-doctor-$NPM_VERSION.tgz --tag $NPM_TAG + # npm publish nativescript-doctor-$NPM_VERSION.tgz --tag $NPM_TAG