@unisphere/nx 3.24.0 → 4.1.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 (43) hide show
  1. package/README.md +195 -0
  2. package/dist/generators/add-application/add-application.d.ts.map +1 -1
  3. package/dist/generators/add-application/add-application.js +29 -0
  4. package/dist/generators/add-application/schema.json +7 -24
  5. package/dist/generators/add-documentation/add-documentation.d.ts.map +1 -1
  6. package/dist/generators/add-documentation/add-documentation.js +27 -24
  7. package/dist/generators/add-package/add-package.d.ts.map +1 -1
  8. package/dist/generators/add-package/add-package.js +37 -0
  9. package/dist/generators/add-package/schema.json +4 -53
  10. package/dist/generators/add-runtime/add-runtime.d.ts.map +1 -1
  11. package/dist/generators/add-runtime/add-runtime.js +33 -70
  12. package/dist/generators/add-runtime/schema.d.ts +1 -1
  13. package/dist/generators/add-runtime/schema.json +9 -34
  14. package/dist/generators/add-runtime/templates/new-runtime/src/lib/runtime.tsx.template +1 -1
  15. package/dist/generators/add-visual/add-visual.d.ts.map +1 -1
  16. package/dist/generators/add-visual/add-visual.js +41 -49
  17. package/dist/generators/add-visual/schema.json +18 -2
  18. package/dist/generators/change-package-scope/change-package-scope.d.ts.map +1 -1
  19. package/dist/generators/change-package-scope/change-package-scope.js +29 -0
  20. package/dist/generators/change-package-scope/schema.json +2 -4
  21. package/dist/generators/remove/remove.d.ts.map +1 -1
  22. package/dist/generators/remove/remove.js +11 -0
  23. package/dist/generators/remove/schema.json +1 -2
  24. package/dist/generators/rename-package/rename-package.d.ts.map +1 -1
  25. package/dist/generators/rename-package/rename-package.js +23 -0
  26. package/dist/generators/rename-package/schema.json +2 -4
  27. package/dist/generators/utils/index.d.ts +2 -0
  28. package/dist/generators/utils/index.d.ts.map +1 -0
  29. package/dist/generators/utils/index.js +4 -0
  30. package/dist/generators/utils/validation.d.ts +9 -0
  31. package/dist/generators/utils/validation.d.ts.map +1 -0
  32. package/dist/generators/utils/validation.js +38 -0
  33. package/dist/migrations/3-24-0/add-server-runtimes-setup.d.ts +11 -0
  34. package/dist/migrations/3-24-0/add-server-runtimes-setup.d.ts.map +1 -0
  35. package/dist/migrations/3-24-0/add-server-runtimes-setup.js +160 -0
  36. package/dist/migrations/3-24-0/remove-runtime-js-patch.d.ts +9 -0
  37. package/dist/migrations/3-24-0/remove-runtime-js-patch.d.ts.map +1 -0
  38. package/dist/migrations/3-24-0/remove-runtime-js-patch.js +29 -0
  39. package/dist/migrations/3-24-0/update-runtime-logger-call.d.ts +9 -0
  40. package/dist/migrations/3-24-0/update-runtime-logger-call.d.ts.map +1 -0
  41. package/dist/migrations/3-24-0/update-runtime-logger-call.js +44 -0
  42. package/migrations.json +24 -0
  43. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,199 @@
1
1
  # Unisphere Workspace NX Plugin
2
2
 
3
+ Official Nx plugin for Unisphere workspace development. This plugin provides generators and executors for creating and managing Unisphere runtimes, visuals, applications, and packages.
3
4
 
5
+ ## Features
4
6
 
7
+ - Create and manage Unisphere runtimes
8
+ - Add visuals to existing runtimes
9
+ - Generate development applications
10
+ - Create shared packages
11
+ - Documentation site generation
12
+ - Package management utilities
13
+
14
+ ## Installation
15
+
16
+ This plugin is typically installed as part of a Unisphere workspace. If you need to install it manually:
17
+
18
+ ```bash
19
+ npm install @unisphere/nx --save-dev
20
+ ```
21
+
22
+ ## Generators
23
+
24
+ All generators are non-interactive and require explicit flags. Run any generator without flags to see available options and examples.
25
+
26
+ ### add-runtime
27
+
28
+ Creates a new Unisphere runtime package.
29
+
30
+ **Required flags:**
31
+ - `--name`: The name of the runtime to create
32
+ - `--consumer`: Runtime consumer type (`external` or `internal`)
33
+
34
+ **Optional flags:**
35
+ - `--dependencies`: Packages to install (comma-separated: `react`, `ds`, `mui`)
36
+ - `--analyticsAppId`: Analytics app ID (number)
37
+
38
+ **Example:**
39
+ ```bash
40
+ nx g @unisphere/nx:add-runtime \
41
+ --name=my-runtime \
42
+ --consumer=external \
43
+ --dependencies=react,ds
44
+ ```
45
+
46
+ ### add-visual
47
+
48
+ Adds a visual component to an existing runtime.
49
+
50
+ **Required flags:**
51
+ - `--runtimeName`: The name of the runtime to add the visual to
52
+ - `--visualName`: The name of the visual to create
53
+
54
+ **Optional flags:**
55
+ - `--isSingleOccurrence`: Whether this visual is limited to single occurrence (default: `false`)
56
+
57
+ **Example:**
58
+ ```bash
59
+ nx g @unisphere/nx:add-visual \
60
+ --runtimeName=my-runtime \
61
+ --visualName=my-visual
62
+ ```
63
+
64
+ ### add-application
65
+
66
+ Creates a development application for testing runtimes.
67
+
68
+ **Required flags:**
69
+ - `--name`: The name of the application to create
70
+ - `--servingType`: How the app should be served
71
+ - `local-dev-playground`: Local development playground (default)
72
+ - `self-hosted`: Self-hosted application
73
+ - `iframe-with-post-messages`: iframe with post messages
74
+ - `assets-only`: Assets only
75
+
76
+ **Optional flags:**
77
+ - `--runtimeName`: Which runtime should the playground load
78
+ - `--htmlPageTitle`: The HTML page title for your app
79
+ - `--dependencies`: Packages to install (comma-separated: `ds`, `mui`, `react-hook-form`)
80
+
81
+ **Example:**
82
+ ```bash
83
+ nx g @unisphere/nx:add-application \
84
+ --name=my-dev-app \
85
+ --servingType=local-dev-playground \
86
+ --runtimeName=my-runtime
87
+ ```
88
+
89
+ ### add-package
90
+
91
+ Creates a new shared package in the workspace.
92
+
93
+ **Required flags:**
94
+ - `--name`: The name of the package to create
95
+ - `--type`: Package type
96
+ - `library`: Shared library
97
+ - `types`: TypeScript types package
98
+ - `configuration`: Configuration package
99
+
100
+ **Optional flags:**
101
+ - `--dependencies`: Packages to install (comma-separated: `react`, `ds`, `mui`)
102
+
103
+ **Example:**
104
+ ```bash
105
+ nx g @unisphere/nx:add-package \
106
+ --name=shared-utils \
107
+ --type=library \
108
+ --dependencies=react
109
+ ```
110
+
111
+ ### add-documentation
112
+
113
+ Generates a documentation site for your workspace.
114
+
115
+ **Required flags:**
116
+ - `--title`: The title for the documentation site
117
+
118
+ **Example:**
119
+ ```bash
120
+ nx g @unisphere/nx:add-documentation \
121
+ --title="My Project Documentation"
122
+ ```
123
+
124
+ ### remove
125
+
126
+ Removes a package from the workspace and cleans up all references.
127
+
128
+ **Required flags:**
129
+ - `--name`: The name of the package to remove
130
+
131
+ **Example:**
132
+ ```bash
133
+ nx g @unisphere/nx:remove --name=my-package
134
+ ```
135
+
136
+ ### rename-package
137
+
138
+ Renames an existing package and updates all references.
139
+
140
+ **Required flags:**
141
+ - `--currentName`: Current package name
142
+ - `--newName`: New package name
143
+
144
+ **Example:**
145
+ ```bash
146
+ nx g @unisphere/nx:rename-package \
147
+ --currentName=old-name \
148
+ --newName=new-name
149
+ ```
150
+
151
+ ### change-package-scope
152
+
153
+ Changes the scope of a package (e.g., from `@company` to `@newcompany`).
154
+
155
+ **Required flags:**
156
+ - `--name`: Package name to update
157
+ - `--newScope`: New scope (without `@` prefix)
158
+
159
+ **Example:**
160
+ ```bash
161
+ nx g @unisphere/nx:change-package-scope \
162
+ --name=my-package \
163
+ --newScope=newcompany
164
+ ```
165
+
166
+ ## Getting Help
167
+
168
+ Forgot what flags are required? Just run any generator without flags and you'll get a helpful error message with examples:
169
+
170
+ ```bash
171
+ $ nx g @unisphere/nx:add-runtime
172
+
173
+ Error: Missing required option: 'name'
174
+ Description: The name of the runtime to create
175
+ Example: nx g @unisphere/nx:add-runtime --name=my-runtime --consumer=external
176
+ ```
177
+
178
+ ## Migration from Interactive Generators
179
+
180
+ If you're upgrading from an older version that had interactive prompts, see the [Migration Guide](../../docs/migration/non-interactive-generators.md) for details on the changes and how to update your workflows.
181
+
182
+ ## Development
183
+
184
+ ### Testing Generators
185
+
186
+ Run all generator tests:
187
+ ```bash
188
+ npm test -- packages/nx/src/generators/
189
+ ```
190
+
191
+ ### Building the Plugin
192
+
193
+ ```bash
194
+ nx build @unisphere/nx
195
+ ```
196
+
197
+ ## License
198
+
199
+ See the root [LICENSE](../../LICENSE) file for details.
@@ -1 +1 @@
1
- {"version":3,"file":"add-application.d.ts","sourceRoot":"","sources":["../../../src/generators/add-application/add-application.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAgD,MAAM,YAAY,CAAC;AAE5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAkHzD,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,6BAA6B,uBAoLvC;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"add-application.d.ts","sourceRoot":"","sources":["../../../src/generators/add-application/add-application.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAgD,MAAM,YAAY,CAAC;AAE5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAyJzD,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,6BAA6B,uBAuLvC;AAED,eAAe,uBAAuB,CAAC"}
@@ -6,6 +6,33 @@ const devkit_1 = require("@nx/devkit");
6
6
  const path = tslib_1.__importStar(require("path"));
7
7
  const utils_1 = require("../utils");
8
8
  const dependency_config_1 = require("../dependency-config");
9
+ function validateOptions(options) {
10
+ if (!options.name || options.name.trim() === '') {
11
+ throw new Error(`Missing required option: 'name'\n` +
12
+ ` Description: The name of the application to create\n` +
13
+ ` Type: string\n` +
14
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
15
+ ` Example: nx g @unisphere/nx:add-application --name=my-app --servingType=self-hosted`);
16
+ }
17
+ const namePattern = /^[a-zA-Z][a-zA-Z0-9\-\s]*$/;
18
+ if (!namePattern.test(options.name)) {
19
+ throw new Error(`Invalid value '${options.name}' for option 'name'\n` +
20
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
21
+ ` Received: ${options.name}`);
22
+ }
23
+ if (!options.servingType) {
24
+ throw new Error(`Missing required option: 'servingType'\n` +
25
+ ` Description: How should this app be served?\n` +
26
+ ` Allowed values: local-dev-playground, self-hosted, iframe-with-post-messages, assets-only\n` +
27
+ ` Example: nx g @unisphere/nx:add-application --name=my-app --servingType=self-hosted`);
28
+ }
29
+ const allowedServingTypes = ['local-dev-playground', 'self-hosted', 'iframe-with-post-messages', 'assets-only'];
30
+ if (!allowedServingTypes.includes(options.servingType)) {
31
+ throw new Error(`Invalid value '${options.servingType}' for option 'servingType'\n` +
32
+ ` Allowed values: local-dev-playground, self-hosted, iframe-with-post-messages, assets-only\n` +
33
+ ` Received: ${options.servingType}`);
34
+ }
35
+ }
9
36
  async function getEnquirerPrompt() {
10
37
  const enquirer = await import('enquirer');
11
38
  // Handle both CommonJS and ESM exports
@@ -74,6 +101,8 @@ async function promptForDependencies(_isPlayground) {
74
101
  return response.dependencies;
75
102
  }
76
103
  async function addApplicationGenerator(tree, options) {
104
+ // Validate options
105
+ validateOptions(options);
77
106
  // Validate iframe-with-post-messages is not supported
78
107
  if (options.servingType === 'iframe-with-post-messages') {
79
108
  throw new Error('iframe-with-post-messages serving type is not currently supported. Please choose a different serving type.');
@@ -11,35 +11,18 @@
11
11
  "$default": {
12
12
  "$source": "argv",
13
13
  "index": 0
14
- },
15
- "x-prompt": "What is the application name? (letters, numbers, dashes and spaces allowed)"
14
+ }
16
15
  },
17
16
  "servingType": {
18
17
  "type": "string",
19
18
  "description": "How should this app be served?",
20
19
  "default": "local-dev-playground",
21
- "x-prompt": {
22
- "message": "Which serving type do you want?",
23
- "type": "list",
24
- "items": [
25
- {
26
- "value": "local-dev-playground",
27
- "label": "Runtime Dev Playground (for development purposes)"
28
- },
29
- {
30
- "value": "self-hosted",
31
- "label": "Standalone Application"
32
- },
33
- {
34
- "value": "iframe-with-post-messages",
35
- "label": "Iframe + Post Messages (suitible to applications that gets required configuration from post messages)"
36
- },
37
- {
38
- "value": "assets-only",
39
- "label": "Assets Only (static assets served via CDN, no application logic)"
40
- }
41
- ]
42
- }
20
+ "enum": [
21
+ "local-dev-playground",
22
+ "self-hosted",
23
+ "iframe-with-post-messages",
24
+ "assets-only"
25
+ ]
43
26
  },
44
27
  "runtimeName": {
45
28
  "type": "string",
@@ -1 +1 @@
1
- {"version":3,"file":"add-documentation.d.ts","sourceRoot":"","sources":["../../../src/generators/add-documentation/add-documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAiB,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AAa3D,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,+BAA+B,qCA+JzC;AAED,eAAe,yBAAyB,CAAC"}
1
+ {"version":3,"file":"add-documentation.d.ts","sourceRoot":"","sources":["../../../src/generators/add-documentation/add-documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAiB,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AA0C3D,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,+BAA+B,qCA6IzC;AAED,eAAe,yBAAyB,CAAC"}
@@ -7,11 +7,34 @@ const child_process_1 = require("child_process");
7
7
  const path = tslib_1.__importStar(require("path"));
8
8
  const utils_1 = require("../utils");
9
9
  const discover_typedoc_plugins_1 = require("./discover-typedoc-plugins");
10
- async function getEnquirerPrompt() {
11
- const enquirer = await import('enquirer');
12
- return enquirer.prompt || enquirer.default?.prompt || enquirer;
10
+ function validateOptions(options) {
11
+ if (options.name) {
12
+ const namePattern = /^[a-zA-Z][a-zA-Z0-9\-\s]*$/;
13
+ if (!namePattern.test(options.name)) {
14
+ throw new Error(`Invalid value '${options.name}' for option 'name'\n` +
15
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
16
+ ` Received: ${options.name}`);
17
+ }
18
+ }
19
+ if (!options.isExperienceLevel && options.subName) {
20
+ const subNamePattern = /^[a-zA-Z][a-zA-Z0-9\-\s]*$/;
21
+ if (!subNamePattern.test(options.subName)) {
22
+ throw new Error(`Invalid value '${options.subName}' for option 'subName'\n` +
23
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
24
+ ` Received: ${options.subName}`);
25
+ }
26
+ }
27
+ if (!options.isExperienceLevel && !options.subName) {
28
+ throw new Error(`Missing required option: 'subName'\n` +
29
+ ` Description: Sub-name for the documentation site (used when not experience-level)\n` +
30
+ ` Type: string\n` +
31
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
32
+ ` Example: nx g @unisphere/nx:add-documentation --subName=api-docs`);
33
+ }
13
34
  }
14
35
  async function addDocumentationGenerator(tree, options) {
36
+ // Validate options
37
+ validateOptions(options);
15
38
  // Validate .unisphere configuration exists
16
39
  const unisphereConfig = (0, utils_1.validateUnisphereConfig)(tree);
17
40
  // Check workspace pattern for documentation apps
@@ -35,28 +58,8 @@ async function addDocumentationGenerator(tree, options) {
35
58
  const documentationName = options.name || unisphereConfig.name;
36
59
  const documentationNameAsLowerDashCase = (0, devkit_1.names)(documentationName).fileName;
37
60
  devkit_1.logger.info(`Using experience name: ${documentationNameAsLowerDashCase}`);
38
- // If not experience-level, prompt for sub-name
39
- let subName = options.subName;
40
- if (!options.isExperienceLevel && !subName) {
41
- const prompt = await getEnquirerPrompt();
42
- const response = await prompt({
43
- type: 'input',
44
- name: 'subName',
45
- message: 'What is the documentation sub-name? (letters, numbers, dashes and spaces allowed)',
46
- validate: (value) => {
47
- if (!value || !value.trim()) {
48
- return 'Sub-name is required for non-experience-level documentation sites';
49
- }
50
- if (!/^[a-zA-Z][a-zA-Z0-9\-\s]*$/.test(value)) {
51
- return 'Sub-name must start with a letter and contain only letters, numbers, dashes and spaces';
52
- }
53
- return true;
54
- },
55
- });
56
- subName = response.subName;
57
- }
58
61
  // Build the full documentation name
59
- const subNameAsLowerDashCase = subName ? (0, devkit_1.names)(subName).fileName : null;
62
+ const subNameAsLowerDashCase = options.subName ? (0, devkit_1.names)(options.subName).fileName : null;
60
63
  const fullDocumentationName = subNameAsLowerDashCase
61
64
  ? `${documentationNameAsLowerDashCase}-${subNameAsLowerDashCase}`
62
65
  : documentationNameAsLowerDashCase;
@@ -1 +1 @@
1
- {"version":3,"file":"add-package.d.ts","sourceRoot":"","sources":["../../../src/generators/add-package/add-package.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAgD,MAAM,YAAY,CAAC;AAE5G,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AA4DrD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,yBAAyB,uBAqHnC;AAED,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"add-package.d.ts","sourceRoot":"","sources":["../../../src/generators/add-package/add-package.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAgD,MAAM,YAAY,CAAC;AAE5G,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AA8GrD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,yBAAyB,uBAwHnC;AAED,eAAe,mBAAmB,CAAC"}
@@ -6,6 +6,41 @@ const devkit_1 = require("@nx/devkit");
6
6
  const path = tslib_1.__importStar(require("path"));
7
7
  const utils_1 = require("../utils");
8
8
  const dependency_config_1 = require("../dependency-config");
9
+ function validateOptions(options) {
10
+ if (!options.packageName || options.packageName.trim() === '') {
11
+ throw new Error(`Missing required option: 'packageName'\n` +
12
+ ` Description: The name of the package to create\n` +
13
+ ` Type: string\n` +
14
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
15
+ ` Example: nx g @unisphere/nx:add-package --packageName=my-package --scope=local`);
16
+ }
17
+ const namePattern = /^[a-zA-Z][a-zA-Z0-9\-\s]*$/;
18
+ if (!namePattern.test(options.packageName)) {
19
+ throw new Error(`Invalid value '${options.packageName}' for option 'packageName'\n` +
20
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
21
+ ` Received: ${options.packageName}`);
22
+ }
23
+ if (!options.scope) {
24
+ throw new Error(`Missing required option: 'scope'\n` +
25
+ ` Description: The distribution scope of the package\n` +
26
+ ` Allowed values: local, kaltura-corp, unisphere, kaltura-ui, kaltura-apps, kaltura-sdk\n` +
27
+ ` Example: nx g @unisphere/nx:add-package --packageName=my-package --scope=local`);
28
+ }
29
+ const allowedScopes = ['local', 'kaltura-corp', 'unisphere', 'kaltura-ui', 'kaltura-apps', 'kaltura-sdk'];
30
+ if (!allowedScopes.includes(options.scope)) {
31
+ throw new Error(`Invalid value '${options.scope}' for option 'scope'\n` +
32
+ ` Allowed values: ${allowedScopes.join(', ')}\n` +
33
+ ` Received: ${options.scope}`);
34
+ }
35
+ if (options.dependencies) {
36
+ const allowedDeps = ['react', 'ds', 'mui'];
37
+ const invalidDeps = options.dependencies.filter(dep => !allowedDeps.includes(dep));
38
+ if (invalidDeps.length > 0) {
39
+ throw new Error(`Invalid dependencies: ${invalidDeps.join(', ')}\n` +
40
+ ` Allowed values: ${allowedDeps.join(', ')}`);
41
+ }
42
+ }
43
+ }
9
44
  /**
10
45
  * Resolves the @unisphere/runtime version from the workspace's root package.json
11
46
  * Falls back to a default version if not found
@@ -37,6 +72,8 @@ function resolveUnisphereRuntimeVersion(tree) {
37
72
  }
38
73
  }
39
74
  async function addPackageGenerator(tree, options) {
75
+ // Validate options
76
+ validateOptions(options);
40
77
  // Validate and read .unisphere configuration
41
78
  const unisphereConfig = (0, utils_1.validateUnisphereConfig)(tree);
42
79
  // Validate dependencies
@@ -7,43 +7,13 @@
7
7
  "packageName": {
8
8
  "type": "string",
9
9
  "description": "The name of the package to create",
10
- "pattern": "^[a-zA-Z][a-zA-Z0-9\\-\\s]*$",
11
- "x-prompt": "What is the package name? (alphanumeric with dashes and spaces allowed)"
10
+ "pattern": "^[a-zA-Z][a-zA-Z0-9\\-\\s]*$"
12
11
  },
13
12
  "scope": {
14
13
  "type": "string",
15
14
  "description": "The distribution scope of the package",
16
- "default": "local",
17
- "x-prompt": {
18
- "message": "What scope should this package have? If you're unsure, choose Local.",
19
- "type": "list",
20
- "items": [
21
- {
22
- "value": "local",
23
- "label": "Local – This repository only (not published to npm)"
24
- },
25
- {
26
- "value": "kaltura-corp",
27
- "label": "Kaltura Corp – For Kaltura repositories only (jfrog scope: @kaltura-corp/...)"
28
- },
29
- {
30
- "value": "unisphere",
31
- "label": "Unisphere – For all Unisphere workspace consumers (npm scope: @unisphere/...)"
32
- },
33
- {
34
- "value": "kaltura-ui",
35
- "label": "Kaltura UI – UI components for standalone use (npm scope: @kaltura-ui/...)"
36
- },
37
- {
38
- "value": "kaltura-apps",
39
- "label": "Kaltura Apps – Application packages for standalone use (npm scope: @kaltura-apps/...)"
40
- },
41
- {
42
- "value": "kaltura-sdk",
43
- "label": "Kaltura SDK – SDK packages for standalone use (npm scope: @kaltura-sdk/...)"
44
- }
45
- ]
46
- }
15
+ "enum": ["local", "kaltura-corp", "unisphere", "kaltura-ui", "kaltura-apps", "kaltura-sdk"],
16
+ "default": "local"
47
17
  },
48
18
  "dependencies": {
49
19
  "type": "array",
@@ -56,26 +26,7 @@
56
26
  "mui"
57
27
  ]
58
28
  },
59
- "default": [],
60
- "x-prompt": {
61
- "message": "Select dependencies to install (use space to select, enter to confirm):",
62
- "type": "list",
63
- "multiselect": true,
64
- "items": [
65
- {
66
- "value": "react",
67
- "label": "React - UI library for building components"
68
- },
69
- {
70
- "value": "ds",
71
- "label": "Kaltura DS - Design System (requires GIT_TOKEN)"
72
- },
73
- {
74
- "value": "mui",
75
- "label": "Material UI - Component library"
76
- }
77
- ]
78
- }
29
+ "default": []
79
30
  }
80
31
  },
81
32
  "required": [
@@ -1 +1 @@
1
- {"version":3,"file":"add-runtime.d.ts","sourceRoot":"","sources":["../../../src/generators/add-runtime/add-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAsC,MAAM,YAAY,CAAC;AAElG,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAqFrD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,yBAAyB,uBA6InC;AAED,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"add-runtime.d.ts","sourceRoot":"","sources":["../../../src/generators/add-runtime/add-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,IAAI,EAAsC,MAAM,YAAY,CAAC;AAElG,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAgFrD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,yBAAyB,uBA+GnC;AAED,eAAe,mBAAmB,CAAC"}
@@ -6,41 +6,31 @@ const devkit_1 = require("@nx/devkit");
6
6
  const path = tslib_1.__importStar(require("path"));
7
7
  const utils_1 = require("../utils");
8
8
  const dependency_config_1 = require("../dependency-config");
9
- const add_application_1 = require("../add-application/add-application");
10
- const add_visual_1 = require("../add-visual/add-visual");
11
- async function getEnquirerPrompt() {
12
- const enquirer = await import('enquirer');
13
- // Handle both CommonJS and ESM exports
14
- return enquirer.prompt || enquirer.default?.prompt || enquirer;
15
- }
16
- async function promptForAddVisual() {
17
- const prompt = await getEnquirerPrompt();
18
- const response = await prompt({
19
- type: 'confirm',
20
- name: 'addVisual',
21
- message: 'Would you like to add a visual to this runtime?',
22
- initial: true,
23
- });
24
- return response.addVisual;
25
- }
26
- async function promptForAnalyticsAppId(existingValue) {
27
- if (existingValue !== undefined) {
28
- return existingValue;
9
+ function validateOptions(options) {
10
+ if (!options.name || options.name.trim() === '') {
11
+ throw new Error(`Missing required option: 'name'\n` +
12
+ ` Description: The name of the runtime to create\n` +
13
+ ` Type: string\n` +
14
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
15
+ ` Example: nx g @unisphere/nx:add-runtime --name=my-runtime --consumer=external`);
16
+ }
17
+ const namePattern = /^[a-zA-Z][a-zA-Z0-9\-\s]*$/;
18
+ if (!namePattern.test(options.name)) {
19
+ throw new Error(`Invalid value '${options.name}' for option 'name'\n` +
20
+ ` Pattern: ^[a-zA-Z][a-zA-Z0-9\\-\\s]*$\n` +
21
+ ` Received: ${options.name}`);
22
+ }
23
+ if (!options.consumer) {
24
+ throw new Error(`Missing required option: 'consumer'\n` +
25
+ ` Description: Is this runtime loaded from within the same experience or by an external consumer?\n` +
26
+ ` Allowed values: external, internal\n` +
27
+ ` Example: nx g @unisphere/nx:add-runtime --name=my-runtime --consumer=external`);
28
+ }
29
+ if (!['external', 'internal'].includes(options.consumer)) {
30
+ throw new Error(`Invalid value '${options.consumer}' for option 'consumer'\n` +
31
+ ` Allowed values: external, internal\n` +
32
+ ` Received: ${options.consumer}`);
29
33
  }
30
- const prompt = await getEnquirerPrompt();
31
- const response = await prompt({
32
- type: 'input',
33
- name: 'analyticsAppId',
34
- message: 'Provide the analytics app id (number). If you are not certain, leave it empty and later update the runtime constructor.',
35
- validate: (input) => {
36
- if (input === '')
37
- return true; // Allow empty
38
- const num = Number(input);
39
- return !isNaN(num) && Number.isInteger(num) ? true : 'Please enter a valid integer or leave empty';
40
- },
41
- });
42
- const value = response.analyticsAppId;
43
- return value === '' ? undefined : Number(value);
44
34
  }
45
35
  function updateTypesIndexExport(tree, runtimeName, basePath) {
46
36
  const indexPath = `${basePath}/src/index.ts`;
@@ -61,6 +51,7 @@ function updateTypesIndexExport(tree, runtimeName, basePath) {
61
51
  tree.write(indexPath, updatedContent);
62
52
  }
63
53
  async function addRuntimeGenerator(tree, options) {
54
+ validateOptions(options);
64
55
  // Normalize consumer option - Nx list prompts may return string labels instead of boolean values
65
56
  let isExternal = options?.consumer === 'external' ? true : false;
66
57
  // Validate and read .unisphere configuration
@@ -74,10 +65,7 @@ async function addRuntimeGenerator(tree, options) {
74
65
  let userInputRuntimeName = (0, devkit_1.names)(options.name).fileName;
75
66
  // Find types package (or fallback to core)
76
67
  const typesPackageInfo = (0, utils_1.findTypesOrCorePackageInfo)(tree);
77
- // Prompt for analyticsAppId only if isExternal is true
78
- const analyticsAppId = isExternal
79
- ? await promptForAnalyticsAppId(options.analyticsAppId)
80
- : options.analyticsAppId;
68
+ const analyticsAppId = options.analyticsAppId;
81
69
  // Prepare template variables
82
70
  const templateVariables = {
83
71
  companyName,
@@ -116,31 +104,6 @@ async function addRuntimeGenerator(tree, options) {
116
104
  const runtimePathKey = `unisphere-runtime-${userInputRuntimeName}`;
117
105
  const runtimePathValue = `unisphere/runtimes/${userInputRuntimeName}/src/index.ts`;
118
106
  (0, utils_1.updateTsConfigPaths)(tree, runtimePathKey, runtimePathValue);
119
- // Prompt to add a visual to the new runtime
120
- const shouldAddVisual = await promptForAddVisual();
121
- let visualName = '';
122
- if (shouldAddVisual) {
123
- const visualTask = await (0, add_visual_1.addVisualGenerator)(tree, {
124
- runtimeName: userInputRuntimeName,
125
- });
126
- const visualResponse = await visualTask();
127
- visualName = visualResponse.visualName;
128
- }
129
- let applicationScriptName = '';
130
- // Handle internal usage - create dev application
131
- if (!!isExternal) {
132
- // Create a dev application without prompts
133
- const appTask = await (0, add_application_1.addApplicationGenerator)(tree, {
134
- name: `${userInputRuntimeName}-dev`,
135
- servingType: 'local-dev-playground',
136
- runtimeName: userInputRuntimeName,
137
- visualName,
138
- skipDynamicRuntimeVisualPrompt: true, // Skip the runtime/visual selection prompts since we already have the info
139
- dependencies: selectedDependencies, // Pass same dependencies as runtime
140
- });
141
- applicationScriptName = `serve:${userInputRuntimeName}-dev`;
142
- await appTask();
143
- }
144
107
  // Install selected dependencies
145
108
  (0, dependency_config_1.installSelectedDependencies)(tree, selectedDependencies);
146
109
  await (0, devkit_1.formatFiles)(tree);
@@ -152,14 +115,14 @@ async function addRuntimeGenerator(tree, options) {
152
115
  devkit_1.logger.info('');
153
116
  devkit_1.logger.info(`🚀 Runtime Name: ${userInputRuntimeName}`);
154
117
  devkit_1.logger.info(`📁 Location: ${projectRoot}`);
155
- devkit_1.logger.info(`Analytics App ID: ${analyticsAppId}`);
156
- devkit_1.logger.info(`🔧 Consumer: ${isExternal ? 'External' : 'Internal'}`);
157
- if (applicationScriptName) {
158
- devkit_1.logger.info('');
159
- devkit_1.logger.info('📦 Additional components created:');
160
- devkit_1.logger.info(` • Dev Application: ${userInputRuntimeName}-dev`);
161
- devkit_1.logger.info(`. 📜 To run the dev application locally: npm run ${applicationScriptName}`);
118
+ if (analyticsAppId) {
119
+ devkit_1.logger.info(`📊 Analytics App ID: ${analyticsAppId}`);
162
120
  }
121
+ devkit_1.logger.info(`🔧 Consumer: ${isExternal ? 'External' : 'Internal'}`);
122
+ devkit_1.logger.info('');
123
+ devkit_1.logger.info('📝 Next steps:');
124
+ devkit_1.logger.info(` 1. Add a visual: nx g @unisphere/nx:add-visual --runtimeName=${userInputRuntimeName}`);
125
+ devkit_1.logger.info(` 2. Add a dev app: nx g @unisphere/nx:add-application --name=${userInputRuntimeName}-dev --runtimeName=${userInputRuntimeName}`);
163
126
  devkit_1.logger.info('');
164
127
  };
165
128
  }
@@ -1,6 +1,6 @@
1
1
  export interface AddRuntimeGeneratorSchema {
2
2
  name: string;
3
- consumer: string;
3
+ consumer: 'external' | 'internal';
4
4
  dependencies?: string[];
5
5
  analyticsAppId?: number;
6
6
  }