@akylas/nativescript-cli 8.9.4 → 8.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/config/test-deps-versions-generated.json +10 -10
  2. package/docs/build-jekyll-md.sh +1 -1
  3. package/docs/man_pages/config/config-get.md +36 -0
  4. package/docs/man_pages/config/config-set.md +40 -0
  5. package/docs/man_pages/config/config.md +39 -0
  6. package/docs/man_pages/project/hooks/hooks.md +35 -0
  7. package/docs/man_pages/start.md +1 -0
  8. package/lib/.d.ts +8 -3
  9. package/lib/bootstrap.js +3 -1
  10. package/lib/color.js +38 -7
  11. package/lib/commands/build.js +18 -2
  12. package/lib/commands/clean.js +1 -2
  13. package/lib/commands/config.js +1 -1
  14. package/lib/commands/embedding/embed.js +1 -1
  15. package/lib/commands/hooks/common.js +79 -0
  16. package/lib/commands/hooks/hooks-lock.js +100 -0
  17. package/lib/commands/hooks/hooks.js +71 -0
  18. package/lib/commands/post-install.js +2 -2
  19. package/lib/commands/typings.js +29 -18
  20. package/lib/common/definitions/extensibility.d.ts +2 -2
  21. package/lib/common/definitions/mobile.d.ts +72 -72
  22. package/lib/common/header.js +3 -3
  23. package/lib/common/logger/layouts/cli-layout.js +1 -1
  24. package/lib/common/logger/logger.js +3 -3
  25. package/lib/common/mobile/android/android-device.js +1 -1
  26. package/lib/common/mobile/android/android-emulator-services.js +8 -6
  27. package/lib/common/mobile/device-log-provider.js +3 -4
  28. package/lib/common/project-helper.js +15 -2
  29. package/lib/common/verify-node-version.js +1 -1
  30. package/lib/constants.js +7 -4
  31. package/lib/controllers/migrate-controller.js +3 -4
  32. package/lib/controllers/prepare-controller.js +9 -9
  33. package/lib/controllers/run-controller.js +1 -1
  34. package/lib/declarations.d.ts +5 -0
  35. package/lib/definitions/hooks.d.ts +1 -0
  36. package/lib/definitions/nativescript-dev-xcode.d.ts +25 -1
  37. package/lib/definitions/project.d.ts +52 -1
  38. package/lib/definitions/temp-service.d.ts +6 -2
  39. package/lib/helpers/key-command-helper.js +2 -1
  40. package/lib/nativescript-cli.js +28 -0
  41. package/lib/options.js +4 -0
  42. package/lib/project-data.js +10 -4
  43. package/lib/services/analytics/analytics-broker-process.js +1 -1
  44. package/lib/services/analytics-settings-service.js +2 -1
  45. package/lib/services/android/gradle-build-args-service.js +7 -3
  46. package/lib/services/android/gradle-build-service.js +4 -1
  47. package/lib/services/android-project-service.js +12 -10
  48. package/lib/services/{webpack/webpack-compiler-service.js → bundler/bundler-compiler-service.js} +254 -85
  49. package/lib/services/bundler/bundler.js +2 -0
  50. package/lib/services/extensibility-service.js +1 -1
  51. package/lib/services/ios/spm-service.js +13 -2
  52. package/lib/services/ios/xcodebuild-args-service.js +7 -5
  53. package/lib/services/ios-project-service.js +0 -1
  54. package/lib/services/ios-watch-app-service.js +540 -16
  55. package/lib/services/livesync/android-livesync-tool.js +3 -1
  56. package/lib/services/plugins-service.js +1 -0
  57. package/lib/services/project-changes-service.js +1 -1
  58. package/lib/services/temp-service.js +16 -4
  59. package/lib/services/versions-service.js +2 -1
  60. package/package.json +35 -36
  61. package/vendor/aab-tool/README.txt +1 -1
  62. package/vendor/aab-tool/bundletool.jar +0 -0
  63. package/vendor/gradle-app/app/build.gradle +20 -13
  64. package/vendor/gradle-app/app/gradle.properties +45 -0
  65. package/vendor/gradle-plugin/build.gradle +7 -6
  66. package/lib/services/webpack/webpack.d.ts +0 -227
@@ -1,16 +1,16 @@
1
1
  {
2
- "karma-jasmine": "4.0.2",
3
- "karma-chai": "0.1.0",
4
- "karma-coverage": "2.2.1",
2
+ "@jsdevtools/coverage-istanbul-loader": "3.0.5",
5
3
  "karma": "6.4.4",
4
+ "karma-coverage": "2.2.1",
5
+ "karma-nativescript-launcher": "1.0.0",
6
+ "mocha": "11.7.5",
6
7
  "karma-mocha": "2.0.1",
8
+ "karma-chai": "0.1.0",
9
+ "karma-jasmine": "4.0.2",
7
10
  "karma-qunit": "4.2.1",
8
- "mocha": "11.7.1",
9
- "nyc": "17.1.0",
10
- "@types/jasmine": "5.1.9",
11
+ "@types/karma-chai": "0.1.8",
11
12
  "@types/mocha": "10.0.10",
12
- "@jsdevtools/coverage-istanbul-loader": "3.0.5",
13
- "karma-nativescript-launcher": "1.0.0",
14
- "@types/karma-chai": "0.1.7",
15
- "@types/qunit": "2.19.13"
13
+ "@types/jasmine": "5.1.15",
14
+ "@types/qunit": "2.19.13",
15
+ "nyc": "17.1.0"
16
16
  }
@@ -4,4 +4,4 @@ set -e
4
4
  rm -rf docs-cli
5
5
  npm install --ignore-scripts
6
6
 
7
- grunt docs-jekyll
7
+ npx grunt docs-jekyll
@@ -0,0 +1,36 @@
1
+ <% if (isJekyll) { %>---
2
+ title: ns config get
3
+ position: 2
4
+ ---<% } %>
5
+
6
+ # ns config get
7
+
8
+ ### Description
9
+
10
+ Prints the value for a specific key from the project's NativeScript configuration.
11
+
12
+ ### Commands
13
+
14
+ Usage | Synopsis
15
+ ------|-------
16
+ General | `$ ns config get <key>`
17
+
18
+ ### Arguments
19
+
20
+ * `<key>` — The configuration key in dot-notation. Examples: `ios.id`, `android.codeCache`, `bundler`.
21
+
22
+ ### Examples
23
+
24
+ * `$ ns config get ios.id`
25
+ * `$ ns config get android.codeCache`
26
+ * `$ ns config get bundler`
27
+
28
+ <% if(isHtml) { %>
29
+
30
+ ### Related Commands
31
+
32
+ Command | Description
33
+ ----------|----------
34
+ [config](config.html) | Lists all configuration values for the current project.
35
+ [config set](config-set.html) | Sets the value for the specified configuration key.
36
+ <% } %>
@@ -0,0 +1,40 @@
1
+ <% if (isJekyll) { %>---
2
+ title: ns config set
3
+ position: 3
4
+ ---<% } %>
5
+
6
+ # ns config set
7
+
8
+ ### Description
9
+
10
+ Sets the value for a specific key in the project's NativeScript configuration.
11
+
12
+ ### Commands
13
+
14
+ Usage | Synopsis
15
+ ------|-------
16
+ General | `$ ns config set <key> <value>`
17
+
18
+ ### Arguments
19
+
20
+ * `<key>` — The configuration key in dot-notation. Examples: `ios.id`, `android.codeCache`, `bundler`.
21
+ * `<value>` — The value to set. Parsed as JSON when possible (e.g. `true`, `42`, `{ "foo": "bar" }`). Otherwise treated as a string.
22
+
23
+ ### Examples
24
+
25
+ * `$ ns config set ios.id org.nativescript.myapp`
26
+ * `$ ns config set android.codeCache true`
27
+ * `$ ns config set bundler vite`
28
+
29
+ ### Notes
30
+
31
+ * Setting whole objects is not supported. Update individual keys instead. For example, use:
32
+ `$ ns config set android.codeCache true`
33
+
34
+ ### Related Commands
35
+
36
+ Command | Description
37
+ ----------|----------
38
+ [config](config.html) | Lists all configuration values for the current project.
39
+ [config get](config-get.html) | Prints the value for the specified configuration key.
40
+ <% } %>
@@ -0,0 +1,39 @@
1
+ <% if (isJekyll) { %>---
2
+ title: ns config
3
+ position: 1
4
+ ---<% } %>
5
+
6
+ # ns config
7
+
8
+ ### Description
9
+
10
+ View and manage your project's NativeScript configuration stored in `nativescript.config.(js|ts)` (or legacy `nsconfig.json`).
11
+
12
+ ### Commands
13
+
14
+ Usage | Synopsis
15
+ ------|---------
16
+ List all config | `$ ns config`
17
+ Get a value | `$ ns config get <key>`
18
+ Set a value | `$ ns config set <key> <value>`
19
+
20
+ ### Examples
21
+
22
+ * `$ ns config` — prints all configuration values.
23
+ * `$ ns config get ios.id` — prints the iOS bundle identifier.
24
+ * `$ ns config set android.codeCache true` — enables Android V8 code cache.
25
+
26
+ ### Notes
27
+
28
+ * Keys use dot-notation, for example: `ios.id`, `android.codeCache`, `bundler`.
29
+ * Values are parsed as JSON when possible. Use quotes for strings with spaces.
30
+
31
+ <% if(isHtml) { %>
32
+
33
+ ### Related Commands
34
+
35
+ Command | Description
36
+ ----------|----------
37
+ [config get](config-get.html) | Prints the value for the specified configuration key.
38
+ [config set](config-set.html) | Sets the value for the specified configuration key.
39
+ <% } %>
@@ -0,0 +1,35 @@
1
+ <% if (isJekyll) { %>---
2
+ title: ns hooks
3
+ position: 1
4
+ ---<% } %>
5
+
6
+ # ns create
7
+
8
+ ### Description
9
+
10
+ Manages lifecycle hooks from installed plugins.
11
+
12
+ ### Commands
13
+
14
+ Usage | Synopsis
15
+ ---------|---------
16
+ Install | `$ ns hooks install`
17
+ List | `$ ns hooks list`
18
+ Lock | `$ ns hooks lock`
19
+ Verify | `$ ns hooks verify`
20
+
21
+ #### Install
22
+
23
+ Installs hooks from each installed plugin dependency.
24
+
25
+ #### List
26
+
27
+ Lists the plugins which have hooks and which scripts they install
28
+
29
+ #### Lock
30
+
31
+ Generates a `hooks-lock.json` containing the hooks that are in the current versions of the plugins.
32
+
33
+ #### Verify
34
+
35
+ Verifies that the hooks contained in the installed plugins match those listed in the `hooks-lock.json` file.
@@ -51,6 +51,7 @@ Command | Description
51
51
  [plugin](lib-management/plugin.html) | Lets you manage the plugins for your project.
52
52
  [open](project/configuration/open.md) | Opens the native project in Xcode/Android Studio.
53
53
  [widget ios](project/configuration/widget.md) | Adds a new iOS widget to the project.
54
+ [hooks](project/hooks/hooks.html) | Installs lifecycle hooks from plugins.
54
55
  ## Publishing Commands
55
56
  Command | Description
56
57
  ---|---
package/lib/.d.ts CHANGED
@@ -23,6 +23,9 @@
23
23
  /// <reference path="commands/generate-assets.ts" />
24
24
  /// <reference path="commands/generate-help.ts" />
25
25
  /// <reference path="commands/generate.ts" />
26
+ /// <reference path="commands/hooks/common.ts" />
27
+ /// <reference path="commands/hooks/hooks-lock.ts" />
28
+ /// <reference path="commands/hooks/hooks.ts" />
26
29
  /// <reference path="commands/info.ts" />
27
30
  /// <reference path="commands/install.ts" />
28
31
  /// <reference path="commands/list-platforms.ts" />
@@ -257,6 +260,7 @@
257
260
  /// <reference path="definitions/files-hash-service.d.ts" />
258
261
  /// <reference path="definitions/gradle.d.ts" />
259
262
  /// <reference path="definitions/hmr-status-service.d.ts" />
263
+ /// <reference path="definitions/hooks.d.ts" />
260
264
  /// <reference path="definitions/initialize-service.d.ts" />
261
265
  /// <reference path="definitions/ios-debugger-port-service.d.ts" />
262
266
  /// <reference path="definitions/ios.d.ts" />
@@ -344,6 +348,8 @@
344
348
  /// <reference path="services/build-artifacts-service.ts" />
345
349
  /// <reference path="services/build-data-service.ts" />
346
350
  /// <reference path="services/build-info-file-service.ts" />
351
+ /// <reference path="services/bundler/bundler-compiler-service.ts" />
352
+ /// <reference path="services/bundler/bundler.ts" />
347
353
  /// <reference path="services/cleanup-service.ts" />
348
354
  /// <reference path="services/cocoapods-platform-manager.ts" />
349
355
  /// <reference path="services/cocoapods-service.ts" />
@@ -419,8 +425,6 @@
419
425
  /// <reference path="services/user-settings-service.ts" />
420
426
  /// <reference path="services/versions-service.ts" />
421
427
  /// <reference path="services/watch-ignore-list-service.ts" />
422
- /// <reference path="services/webpack/webpack-compiler-service.ts" />
423
- /// <reference path="services/webpack/webpack.d.ts" />
424
428
  /// <reference path="services/xcconfig-service.ts" />
425
429
  /// <reference path="services/xcproj-service.ts" />
426
430
  /// <reference path="shared-event-bus.ts" />
@@ -465,6 +469,7 @@
465
469
  /// <reference path="../test/services/android-plugin-build-service.ts" />
466
470
  /// <reference path="../test/services/android-project-service.ts" />
467
471
  /// <reference path="../test/services/android/gradle-build-args-service.ts" />
472
+ /// <reference path="../test/services/bundler/bundler-compiler-service.ts" />
468
473
  /// <reference path="../test/services/doctor-service.ts" />
469
474
  /// <reference path="../test/services/extensibility-service.ts" />
470
475
  /// <reference path="../test/services/ios-debugger-port-service.ts" />
@@ -487,7 +492,7 @@
487
492
  /// <reference path="../test/services/project-data-service.ts" />
488
493
  /// <reference path="../test/services/test-execution-service.ts" />
489
494
  /// <reference path="../test/services/user-settings-service.ts" />
490
- /// <reference path="../test/services/webpack/webpack-compiler-service.ts" />
495
+ /// <reference path="../test/spm-service.ts" />
491
496
  /// <reference path="../test/stubs.ts" />
492
497
  /// <reference path="../test/sys-info.ts" />
493
498
  /// <reference path="../test/test-bootstrap.ts" />
package/lib/bootstrap.js CHANGED
@@ -128,6 +128,8 @@ yok_1.injector.requireCommand("plugin|remove", "./commands/plugin/remove-plugin"
128
128
  yok_1.injector.requireCommand("plugin|update", "./commands/plugin/update-plugin");
129
129
  yok_1.injector.requireCommand("plugin|build", "./commands/plugin/build-plugin");
130
130
  yok_1.injector.requireCommand("plugin|create", "./commands/plugin/create-plugin");
131
+ yok_1.injector.requireCommand(["hooks|*list", "hooks|install"], "./commands/hooks/hooks");
132
+ yok_1.injector.requireCommand(["hooks|lock", "hooks|verify"], "./commands/hooks/hooks-lock");
131
133
  yok_1.injector.require("doctorService", "./services/doctor-service");
132
134
  yok_1.injector.require("xcprojService", "./services/xcproj-service");
133
135
  yok_1.injector.require("versionsService", "./services/versions-service");
@@ -185,7 +187,7 @@ yok_1.injector.require("qrCodeTerminalService", "./services/qr-code-terminal-ser
185
187
  yok_1.injector.require("testInitializationService", "./services/test-initialization-service");
186
188
  yok_1.injector.require("networkConnectivityValidator", "./helpers/network-connectivity-validator");
187
189
  yok_1.injector.requirePublic("cleanupService", "./services/cleanup-service");
188
- yok_1.injector.require("webpackCompilerService", "./services/webpack/webpack-compiler-service");
190
+ yok_1.injector.require("bundlerCompilerService", "./services/bundler/bundler-compiler-service");
189
191
  yok_1.injector.require("applePortalSessionService", "./services/apple-portal/apple-portal-session-service");
190
192
  yok_1.injector.require("applePortalCookieService", "./services/apple-portal/apple-portal-cookie-service");
191
193
  yok_1.injector.require("applePortalApplicationService", "./services/apple-portal/apple-portal-application-service");
package/lib/color.js CHANGED
@@ -1,10 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.color = void 0;
3
+ exports.stripColors = exports.color = void 0;
4
+ const node_util_1 = require("node:util");
5
+ exports.color = {
6
+ reset: (text) => (0, node_util_1.styleText)("reset", text),
7
+ bold: (text) => (0, node_util_1.styleText)("bold", text),
8
+ dim: (text) => (0, node_util_1.styleText)("dim", text),
9
+ italic: (text) => (0, node_util_1.styleText)("italic", text),
10
+ underline: (text) => (0, node_util_1.styleText)("underline", text),
11
+ inverse: (text) => (0, node_util_1.styleText)("inverse", text),
12
+ hidden: (text) => (0, node_util_1.styleText)("hidden", text),
13
+ strikethrough: (text) => (0, node_util_1.styleText)("strikethrough", text),
14
+ black: (text) => (0, node_util_1.styleText)("black", text),
15
+ red: (text) => (0, node_util_1.styleText)("red", text),
16
+ blue: (text) => (0, node_util_1.styleText)("blue", text),
17
+ magenta: (text) => (0, node_util_1.styleText)("magenta", text),
18
+ cyan: (text) => (0, node_util_1.styleText)("cyan", text),
19
+ white: (text) => (0, node_util_1.styleText)("white", text),
20
+ gray: (text) => (0, node_util_1.styleText)("gray", text),
21
+ yellow: (text) => (0, node_util_1.styleText)("yellow", text),
22
+ green: (text) => (0, node_util_1.styleText)("green", text),
23
+ grey: (text) => (0, node_util_1.styleText)("grey", text),
24
+ bgBlack: (text) => (0, node_util_1.styleText)("bgBlack", text),
25
+ bgBlackBright: (text) => (0, node_util_1.styleText)("bgBlackBright", text),
26
+ bgRed: (text) => (0, node_util_1.styleText)("bgRed", text),
27
+ bgGreen: (text) => (0, node_util_1.styleText)("bgGreen", text),
28
+ bgYellow: (text) => (0, node_util_1.styleText)("bgYellow", text),
29
+ bgBlue: (text) => (0, node_util_1.styleText)("bgBlue", text),
30
+ bgMagenta: (text) => (0, node_util_1.styleText)("bgMagenta", text),
31
+ bgCyan: (text) => (0, node_util_1.styleText)("bgCyan", text),
32
+ bgWhite: (text) => (0, node_util_1.styleText)("bgWhite", text),
33
+ cyanBright: (text) => (0, node_util_1.styleText)("cyanBright", text),
34
+ whiteBright: (text) => (0, node_util_1.styleText)("whiteBright", text),
35
+ greenBright: (text) => (0, node_util_1.styleText)("greenBright", text),
36
+ yellowBright: (text) => (0, node_util_1.styleText)("yellowBright", text),
37
+ redBright: (text) => (0, node_util_1.styleText)("redBright", text),
38
+ styleText: node_util_1.styleText,
39
+ };
40
+ const stripColors = (text) => (0, node_util_1.stripVTControlCharacters)(text);
4
41
  exports.stripColors = stripColors;
5
- const ansi = require("ansi-colors");
6
- const chalk = require("chalk");
7
- function stripColors(formatStr) {
8
- return ansi.stripColor(formatStr);
9
- }
10
- exports.color = chalk;
@@ -122,9 +122,25 @@ class BuildVisionOsCommand extends BuildIosCommand {
122
122
  this.$options = $options;
123
123
  this.$migrateController = $migrateController;
124
124
  }
125
+ async execute(args) {
126
+ await this.executeCore([
127
+ this.$devicePlatformsConstants.visionOS.toLowerCase(),
128
+ ]);
129
+ }
125
130
  async canExecute(args) {
126
- this.$errors.fail('Building for "visionOS" platform is not supported via the CLI. Please open the project in Xcode and build it from there.');
127
- return false;
131
+ const platform = this.$devicePlatformsConstants.visionOS;
132
+ if (!this.$options.force) {
133
+ await this.$migrateController.validate({
134
+ projectDir: this.$projectData.projectDir,
135
+ platforms: [platform],
136
+ });
137
+ }
138
+ super.validatePlatform(platform);
139
+ let canExecute = await super.canExecuteCommandBase(platform);
140
+ if (canExecute) {
141
+ canExecute = await super.validateArgs(args, platform);
142
+ }
143
+ return canExecute;
128
144
  }
129
145
  }
130
146
  exports.BuildVisionOsCommand = BuildVisionOsCommand;
@@ -70,7 +70,6 @@ class CleanCommand {
70
70
  constants.HOOKS_DIR_NAME,
71
71
  this.$projectData.getBuildRelativeDirectoryPath(),
72
72
  constants.NODE_MODULES_FOLDER_NAME,
73
- constants.PACKAGE_LOCK_JSON_FILE_NAME,
74
73
  ];
75
74
  try {
76
75
  const overridePathsToClean = this.$projectConfigService.getValue("cli.pathsToClean");
@@ -167,7 +166,7 @@ class CleanCommand {
167
166
  optionsPerPage: process.stdout.rows - 6,
168
167
  });
169
168
  this.$logger.clearScreen();
170
- spinner.warn(`This will run "${color_1.color.yellow(`ns clean`)}" in all the selected projects and ${color_1.color.red.bold("delete files from your system")}!`);
169
+ spinner.warn(`This will run "${color_1.color.yellow(`ns clean`)}" in all the selected projects and ${color_1.color.styleText(["red", "bold"], "delete files from your system")}!`);
171
170
  spinner.warn(`This action cannot be undone!`);
172
171
  let confirmed = await this.$prompter.confirm("Are you sure you want to clean the selected projects?");
173
172
  if (!confirmed) {
@@ -81,7 +81,7 @@ class ConfigSetCommand {
81
81
  const convertedValue = this.getConvertedValue(value);
82
82
  const existingKey = current !== undefined;
83
83
  const keyDisplay = color_1.color.green(key);
84
- const currentDisplay = color_1.color.yellow(current);
84
+ const currentDisplay = current ? color_1.color.yellow(current) : "";
85
85
  const updatedDisplay = color_1.color.cyan(convertedValue);
86
86
  this.$logger.info(`${existingKey ? "Updating" : "Setting"} ${keyDisplay}${existingKey ? ` from ${currentDisplay} ` : " "}to ${updatedDisplay}`);
87
87
  try {
@@ -31,7 +31,7 @@ class EmbedCommand extends prepare_1.PrepareCommand {
31
31
  const hostProjectPath = args[1];
32
32
  const resolvedHostProjectPath = this.resolveHostProjectPath(hostProjectPath);
33
33
  if (!this.$fs.exists(resolvedHostProjectPath)) {
34
- this.$logger.error(`The host project path ${color_1.color.yellow(hostProjectPath)} (resolved to: ${color_1.color.yellow.dim(resolvedHostProjectPath)}) does not exist.`);
34
+ this.$logger.error(`The host project path ${color_1.color.yellow(hostProjectPath)} (resolved to: ${color_1.color.styleText(["yellow", "dim"], resolvedHostProjectPath)}) does not exist.`);
35
35
  return;
36
36
  }
37
37
  this.$options["hostProjectPath"] = resolvedHostProjectPath;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HooksVerify = exports.LOCK_FILE_NAME = void 0;
4
+ const path = require("path");
5
+ const crypto = require("crypto");
6
+ exports.LOCK_FILE_NAME = "nativescript-lock.json";
7
+ class HooksVerify {
8
+ constructor($projectData, $errors, $fs, $logger) {
9
+ this.$projectData = $projectData;
10
+ this.$errors = $errors;
11
+ this.$fs = $fs;
12
+ this.$logger = $logger;
13
+ this.allowedParameters = [];
14
+ this.$projectData.initializeProjectData();
15
+ }
16
+ async verifyHooksLock(plugins, hooksLockPath) {
17
+ var _a;
18
+ let lockFileContent;
19
+ let hooksLock;
20
+ try {
21
+ lockFileContent = this.$fs.readText(hooksLockPath, "utf8");
22
+ hooksLock = JSON.parse(lockFileContent);
23
+ }
24
+ catch (err) {
25
+ this.$errors.fail(`❌ Failed to read or parse ${exports.LOCK_FILE_NAME} at ${hooksLockPath}`);
26
+ }
27
+ const lockMap = new Map();
28
+ for (const plugin of hooksLock) {
29
+ const hookMap = new Map();
30
+ for (const hook of plugin.hooks) {
31
+ hookMap.set(hook.type, hook.hash);
32
+ }
33
+ lockMap.set(plugin.name, hookMap);
34
+ }
35
+ let isValid = true;
36
+ for (const plugin of plugins) {
37
+ const pluginLockHooks = lockMap.get(plugin.name);
38
+ if (!pluginLockHooks) {
39
+ this.$logger.error(`❌ Plugin '${plugin.name}' not found in ${exports.LOCK_FILE_NAME}`);
40
+ isValid = false;
41
+ continue;
42
+ }
43
+ for (const hook of ((_a = plugin.nativescript) === null || _a === void 0 ? void 0 : _a.hooks) || []) {
44
+ const expectedHash = pluginLockHooks.get(hook.type);
45
+ if (!expectedHash) {
46
+ this.$logger.error(`❌ Missing hook '${hook.type}' for plugin '${plugin.name}' in ${exports.LOCK_FILE_NAME}`);
47
+ isValid = false;
48
+ continue;
49
+ }
50
+ let fileContent;
51
+ try {
52
+ fileContent = this.$fs.readFile(path.join(plugin.fullPath, hook.script));
53
+ }
54
+ catch (err) {
55
+ this.$logger.error(`❌ Cannot read script file '${hook.script}' for hook '${hook.type}' in plugin '${plugin.name}'`);
56
+ isValid = false;
57
+ continue;
58
+ }
59
+ const actualHash = crypto
60
+ .createHash("sha256")
61
+ .update(fileContent)
62
+ .digest("hex");
63
+ if (actualHash !== expectedHash) {
64
+ this.$logger.error(`❌ Hash mismatch for '${hook.script}' (${hook.type} in ${plugin.name}):`);
65
+ this.$logger.error(` Expected: ${expectedHash}`);
66
+ this.$logger.error(` Actual: ${actualHash}`);
67
+ isValid = false;
68
+ }
69
+ }
70
+ }
71
+ if (isValid) {
72
+ this.$logger.info("✅ All hooks verified successfully. No issues found.");
73
+ }
74
+ else {
75
+ this.$errors.fail("❌ One or more hooks failed verification.");
76
+ }
77
+ }
78
+ }
79
+ exports.HooksVerify = HooksVerify;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HooksVerifyPluginCommand = exports.HooksLockPluginCommand = void 0;
4
+ const yok_1 = require("../../common/yok");
5
+ const path = require("path");
6
+ const crypto = require("crypto");
7
+ const common_1 = require("./common");
8
+ class HooksLockPluginCommand {
9
+ constructor($pluginsService, $projectData, $errors, $fs, $logger) {
10
+ this.$pluginsService = $pluginsService;
11
+ this.$projectData = $projectData;
12
+ this.$errors = $errors;
13
+ this.$fs = $fs;
14
+ this.$logger = $logger;
15
+ this.allowedParameters = [];
16
+ this.$projectData.initializeProjectData();
17
+ }
18
+ async execute() {
19
+ var _a, _b;
20
+ const plugins = await this.$pluginsService.getAllInstalledPlugins(this.$projectData);
21
+ if (plugins && plugins.length > 0) {
22
+ const pluginsWithHooks = [];
23
+ for (const plugin of plugins) {
24
+ if (((_b = (_a = plugin.nativescript) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.length) > 0) {
25
+ pluginsWithHooks.push(plugin);
26
+ }
27
+ }
28
+ await this.writeHooksLockFile(pluginsWithHooks, this.$projectData.projectDir);
29
+ }
30
+ else {
31
+ this.$logger.info("No plugins with hooks found.");
32
+ }
33
+ }
34
+ async canExecute(args) {
35
+ return true;
36
+ }
37
+ async writeHooksLockFile(plugins, outputDir) {
38
+ var _a;
39
+ const output = [];
40
+ for (const plugin of plugins) {
41
+ const hooks = [];
42
+ for (const hook of ((_a = plugin.nativescript) === null || _a === void 0 ? void 0 : _a.hooks) || []) {
43
+ try {
44
+ const fileContent = this.$fs.readFile(path.join(plugin.fullPath, hook.script));
45
+ const hash = crypto
46
+ .createHash("sha256")
47
+ .update(fileContent)
48
+ .digest("hex");
49
+ hooks.push({
50
+ type: hook.type,
51
+ hash,
52
+ });
53
+ }
54
+ catch (err) {
55
+ this.$logger.warn(`Warning: Failed to read script '${hook.script}' for plugin '${plugin.name}'. Skipping this hook.`);
56
+ continue;
57
+ }
58
+ }
59
+ output.push({ name: plugin.name, hooks });
60
+ }
61
+ const filePath = path.resolve(outputDir, common_1.LOCK_FILE_NAME);
62
+ try {
63
+ this.$fs.writeFile(filePath, JSON.stringify(output, null, 2), "utf8");
64
+ this.$logger.info(`✅ ${common_1.LOCK_FILE_NAME} written to: ${filePath}`);
65
+ }
66
+ catch (err) {
67
+ this.$errors.fail(`❌ Failed to write ${common_1.LOCK_FILE_NAME}: ${err}`);
68
+ }
69
+ }
70
+ }
71
+ exports.HooksLockPluginCommand = HooksLockPluginCommand;
72
+ class HooksVerifyPluginCommand extends common_1.HooksVerify {
73
+ constructor($pluginsService, $projectData, $errors, $fs, $logger) {
74
+ super($projectData, $errors, $fs, $logger);
75
+ this.$pluginsService = $pluginsService;
76
+ this.allowedParameters = [];
77
+ }
78
+ async execute() {
79
+ var _a, _b;
80
+ const plugins = await this.$pluginsService.getAllInstalledPlugins(this.$projectData);
81
+ if (plugins && plugins.length > 0) {
82
+ const pluginsWithHooks = [];
83
+ for (const plugin of plugins) {
84
+ if (((_b = (_a = plugin.nativescript) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.length) > 0) {
85
+ pluginsWithHooks.push(plugin);
86
+ }
87
+ }
88
+ await this.verifyHooksLock(pluginsWithHooks, path.join(this.$projectData.projectDir, common_1.LOCK_FILE_NAME));
89
+ }
90
+ else {
91
+ this.$logger.info("No plugins with hooks found.");
92
+ }
93
+ }
94
+ async canExecute(args) {
95
+ return true;
96
+ }
97
+ }
98
+ exports.HooksVerifyPluginCommand = HooksVerifyPluginCommand;
99
+ yok_1.injector.registerCommand(["hooks|lock"], HooksLockPluginCommand);
100
+ yok_1.injector.registerCommand(["hooks|verify"], HooksVerifyPluginCommand);
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HooksListPluginCommand = exports.HooksPluginCommand = void 0;
4
+ const yok_1 = require("../../common/yok");
5
+ const path = require("path");
6
+ const constants_1 = require("../../constants");
7
+ const helpers_1 = require("../../common/helpers");
8
+ const nsHooks = require("@nativescript/hook");
9
+ const common_1 = require("./common");
10
+ class HooksPluginCommand extends common_1.HooksVerify {
11
+ constructor($pluginsService, $projectData, $errors, $fs, $logger) {
12
+ super($projectData, $errors, $fs, $logger);
13
+ this.$pluginsService = $pluginsService;
14
+ this.allowedParameters = [];
15
+ }
16
+ async execute(args) {
17
+ var _a, _b;
18
+ const isList = args.length > 0 && args[0] === "list" ? true : false;
19
+ const plugins = await this.$pluginsService.getAllInstalledPlugins(this.$projectData);
20
+ if (plugins && plugins.length > 0) {
21
+ const hooksDir = path.join(this.$projectData.projectDir, constants_1.HOOKS_DIR_NAME);
22
+ const pluginsWithHooks = [];
23
+ for (const plugin of plugins) {
24
+ if (((_b = (_a = plugin.nativescript) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.length) > 0) {
25
+ pluginsWithHooks.push(plugin);
26
+ }
27
+ }
28
+ if (isList) {
29
+ const headers = ["Plugin", "HookName", "HookPath"];
30
+ const hookDataData = pluginsWithHooks.flatMap((plugin) => plugin.nativescript.hooks.map((hook) => {
31
+ return [plugin.name, hook.type, hook.script];
32
+ }));
33
+ const hookDataTable = (0, helpers_1.createTable)(headers, hookDataData);
34
+ this.$logger.info("Hooks:");
35
+ this.$logger.info(hookDataTable.toString());
36
+ }
37
+ else {
38
+ if (this.$fs.exists(path.join(this.$projectData.projectDir, common_1.LOCK_FILE_NAME))) {
39
+ await this.verifyHooksLock(pluginsWithHooks, path.join(this.$projectData.projectDir, common_1.LOCK_FILE_NAME));
40
+ }
41
+ if (pluginsWithHooks.length === 0) {
42
+ if (!this.$fs.exists(hooksDir)) {
43
+ this.$fs.createDirectory(hooksDir);
44
+ }
45
+ }
46
+ for (const plugin of pluginsWithHooks) {
47
+ nsHooks(plugin.fullPath).postinstall();
48
+ }
49
+ }
50
+ }
51
+ }
52
+ async canExecute(args) {
53
+ if (args.length > 0 && args[0] !== "list") {
54
+ this.$errors.failWithHelp(`Invalid argument ${args[0]}. Supported argument is "list".`);
55
+ }
56
+ return true;
57
+ }
58
+ }
59
+ exports.HooksPluginCommand = HooksPluginCommand;
60
+ class HooksListPluginCommand extends HooksPluginCommand {
61
+ constructor($pluginsService, $projectData, $errors, $fs, $logger) {
62
+ super($pluginsService, $projectData, $errors, $fs, $logger);
63
+ this.allowedParameters = [];
64
+ }
65
+ async execute() {
66
+ await super.execute(["list"]);
67
+ }
68
+ }
69
+ exports.HooksListPluginCommand = HooksListPluginCommand;
70
+ yok_1.injector.registerCommand(["hooks|install"], HooksPluginCommand);
71
+ yok_1.injector.registerCommand(["hooks|*list"], HooksListPluginCommand);
@@ -32,10 +32,10 @@ class PostInstallCliCommand {
32
32
  }
33
33
  async postCommandAction(args) {
34
34
  this.$logger.info("");
35
- this.$logger.info(color_1.color.green.bold("You have successfully installed the NativeScript CLI!"));
35
+ this.$logger.info(color_1.color.styleText(["green", "bold"], "You have successfully installed the NativeScript CLI!"));
36
36
  this.$logger.info("");
37
37
  this.$logger.info("Your next step is to create a new project:");
38
- this.$logger.info(color_1.color.green.bold("ns create"));
38
+ this.$logger.info(color_1.color.styleText(["green", "bold"], "ns create"));
39
39
  this.$logger.info("");
40
40
  this.$logger.printMarkdown("If you have any questions, check Stack Overflow: `https://stackoverflow.com/questions/tagged/nativescript` and our public Discord channel: `https://nativescript.org/discord`");
41
41
  }