@unisphere/nx 3.2.3 → 3.2.4

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.
@@ -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,EAAsC,MAAM,YAAY,CAAC;AAElG,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAkHzD,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,6BAA6B,uBAoIvC;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,EAAsC,MAAM,YAAY,CAAC;AAIlG,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAkHzD,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,6BAA6B,uBAgQvC;AAED,eAAe,uBAAuB,CAAC"}
@@ -4,6 +4,8 @@ exports.addApplicationGenerator = addApplicationGenerator;
4
4
  const tslib_1 = require("tslib");
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const path = tslib_1.__importStar(require("path"));
7
+ const child_process_1 = require("child_process");
8
+ const fs = tslib_1.__importStar(require("fs"));
7
9
  const utils_1 = require("../utils");
8
10
  const dependency_config_1 = require("../dependency-config");
9
11
  async function getEnquirerPrompt() {
@@ -79,17 +81,50 @@ async function addApplicationGenerator(tree, options) {
79
81
  throw new Error('iframe-with-post-messages serving type is not currently supported. Please choose a different serving type.');
80
82
  }
81
83
  const isPlayground = options.servingType === 'local-dev-playground';
84
+ const isDocumentation = options.servingType === 'documentation';
85
+ // Check workspace pattern for documentation apps
86
+ if (isDocumentation) {
87
+ const rootPackageJsonPath = 'package.json';
88
+ if (tree.exists(rootPackageJsonPath)) {
89
+ const packageJson = JSON.parse(tree.read(rootPackageJsonPath, 'utf-8') || '{}');
90
+ const workspaces = packageJson.workspaces || [];
91
+ // Check if using the old catch-all pattern that doesn't work with documentation apps
92
+ const hasCatchAllPattern = workspaces.includes('unisphere/**');
93
+ const hasNegationPattern = workspaces.some((pattern) => pattern.startsWith('!'));
94
+ if (hasCatchAllPattern || hasNegationPattern) {
95
+ throw new Error('Documentation applications require @unisphere/nx version 3.1.0 or higher.\n\n' +
96
+ 'Your workspace is using an old npm workspaces pattern that prevents documentation apps ' +
97
+ 'from having their own node_modules.\n\n' +
98
+ 'Please upgrade by running:\n' +
99
+ ' npx nx migrate @unisphere/nx@latest\n' +
100
+ ' npx nx migrate --run-migrations\n\n' +
101
+ 'This will update your workspace pattern to support documentation apps.');
102
+ }
103
+ }
104
+ }
82
105
  // Validate and read .unisphere configuration
83
106
  const unisphereConfig = (0, utils_1.validateUnisphereConfig)(tree);
84
- const { runtimeName, visualName } = await promptForRuntimeName(unisphereConfig.runtimes, options.runtimeName || '', options.visualName || '', options.skipDynamicRuntimeVisualPrompt || false);
85
- if (!isPlayground && !options.htmlPageTitle) {
107
+ // Skip runtime/visual prompts for documentation sites
108
+ let runtimeName = '';
109
+ let visualName = '';
110
+ if (!isDocumentation) {
111
+ const promptResult = await promptForRuntimeName(unisphereConfig.runtimes, options.runtimeName || '', options.visualName || '', options.skipDynamicRuntimeVisualPrompt || false);
112
+ runtimeName = promptResult.runtimeName;
113
+ visualName = promptResult.visualName;
114
+ }
115
+ // Skip HTML page title prompt for documentation (Docusaurus has its own config)
116
+ if (!isPlayground && !isDocumentation && !options.htmlPageTitle) {
86
117
  options.htmlPageTitle = options.htmlPageTitle || await promptForHtmlPageTitle();
87
118
  }
88
- if (options.dependencies === undefined) {
89
- options.dependencies = await promptForDependencies(isPlayground);
119
+ // Skip dependencies prompt for documentation (Docusaurus has its own)
120
+ let selectedDependencies = [];
121
+ if (!isDocumentation) {
122
+ if (options.dependencies === undefined) {
123
+ options.dependencies = await promptForDependencies(isPlayground);
124
+ }
125
+ const baseDependencies = ['react'];
126
+ selectedDependencies = [...baseDependencies, ...(options.dependencies || [])];
90
127
  }
91
- const baseDependencies = ['react'];
92
- const selectedDependencies = [...baseDependencies, ...(options.dependencies || [])];
93
128
  // Validate runtime exists if runtimeName is provided
94
129
  if (runtimeName) {
95
130
  if (!(0, utils_1.checkIfRuntimeExists)(tree, runtimeName)) {
@@ -103,12 +138,83 @@ async function addApplicationGenerator(tree, options) {
103
138
  applicationName += '-dev';
104
139
  }
105
140
  const applicationNameAsLowerDashCase = (0, devkit_1.names)(applicationName).fileName;
106
- // Find types package (or fallback to core)
107
- const typesPackageInfo = (0, utils_1.findTypesOrCorePackageInfo)(tree);
141
+ // Find types package (or fallback to core) - skip for documentation
142
+ const typesPackageInfo = isDocumentation ? null : (0, utils_1.findTypesOrCorePackageInfo)(tree);
108
143
  // Determine subdirectory based on serving type
109
- // local-dev-playground -> local/, other types -> server/
110
- const subdirectory = isPlayground ? 'local' : 'server';
144
+ // local-dev-playground -> local/, documentation -> documentation/, other types -> server/
145
+ const subdirectory = isPlayground ? 'local' : isDocumentation ? 'documentation' : 'server';
111
146
  const projectRoot = `unisphere/applications/${subdirectory}/${applicationNameAsLowerDashCase}`;
147
+ // Handle documentation type separately
148
+ if (isDocumentation) {
149
+ // Check if the application already exists
150
+ if (tree.exists(projectRoot)) {
151
+ throw new Error(`Application "${applicationNameAsLowerDashCase}" already exists at ${projectRoot}.\n` +
152
+ 'Please choose a different application name or remove the existing application first.');
153
+ }
154
+ // Update .unisphere configuration (applicationType is derived from folder path)
155
+ (0, utils_1.updateUnisphereConfig)(tree, 'applications', applicationNameAsLowerDashCase, {
156
+ sourceRoot: projectRoot,
157
+ });
158
+ // Add documentation folder to .nxignore to prevent NX from scanning it
159
+ // Docusaurus has its own node_modules which can slow down NX
160
+ const nxIgnorePath = '.nxignore';
161
+ const ignoreEntry = `${projectRoot}/node_modules`;
162
+ let nxIgnoreContent = '';
163
+ if (tree.exists(nxIgnorePath)) {
164
+ nxIgnoreContent = tree.read(nxIgnorePath, 'utf-8') || '';
165
+ }
166
+ if (!nxIgnoreContent.includes(ignoreEntry)) {
167
+ const newContent = nxIgnoreContent
168
+ ? `${nxIgnoreContent.trimEnd()}\n\n# Documentation site (Docusaurus) - has its own node_modules\n${ignoreEntry}\n`
169
+ : `# Documentation site (Docusaurus) - has its own node_modules\n${ignoreEntry}\n`;
170
+ tree.write(nxIgnorePath, newContent);
171
+ }
172
+ // Documentation folders are automatically excluded from npm workspaces
173
+ // because the root package.json uses explicit workspace patterns that don't include
174
+ // unisphere/applications/documentation/**
175
+ // This allows documentation sites (like Docusaurus) to have their own node_modules
176
+ await (0, devkit_1.formatFiles)(tree);
177
+ // Return a function that will be executed after all file operations are complete
178
+ return () => {
179
+ const workspaceRoot = process.cwd();
180
+ const fullProjectPath = path.join(workspaceRoot, projectRoot);
181
+ devkit_1.logger.info('');
182
+ devkit_1.logger.info('📚 Setting up Docusaurus documentation site...');
183
+ devkit_1.logger.info('');
184
+ try {
185
+ // Create the parent directory if it doesn't exist
186
+ const parentDir = path.dirname(fullProjectPath);
187
+ if (!fs.existsSync(parentDir)) {
188
+ fs.mkdirSync(parentDir, { recursive: true });
189
+ }
190
+ // Run Docusaurus CLI to scaffold the project
191
+ // Docusaurus creates a self-contained project with its own package.json
192
+ // No NX integration needed - we just delegate to Docusaurus CLI for serve/build
193
+ // Use public npm registry explicitly (workspaces may have private registry configured)
194
+ devkit_1.logger.info('Running Docusaurus CLI...');
195
+ (0, child_process_1.execSync)(`npx --yes --registry https://registry.npmjs.org create-docusaurus@3 "${fullProjectPath}" classic --typescript`, {
196
+ stdio: 'inherit',
197
+ cwd: workspaceRoot,
198
+ });
199
+ devkit_1.logger.info('');
200
+ devkit_1.logger.info('✅ Documentation site generated successfully!');
201
+ devkit_1.logger.info('');
202
+ devkit_1.logger.info(`📚 Application Name: ${applicationNameAsLowerDashCase}`);
203
+ devkit_1.logger.info(`🔧 Type: Documentation Site (Docusaurus)`);
204
+ devkit_1.logger.info(`📁 Location: ${projectRoot}`);
205
+ devkit_1.logger.info('');
206
+ devkit_1.logger.info(`📜 To serve: npx unisphere application serve ${applicationNameAsLowerDashCase}`);
207
+ devkit_1.logger.info(`📦 To build: npx unisphere application build ${applicationNameAsLowerDashCase}`);
208
+ devkit_1.logger.info('');
209
+ }
210
+ catch (error) {
211
+ devkit_1.logger.error('Failed to create Docusaurus project:');
212
+ devkit_1.logger.error(error instanceof Error ? error.message : String(error));
213
+ throw error;
214
+ }
215
+ };
216
+ }
217
+ // Standard application flow (non-documentation)
112
218
  const hasDs = selectedDependencies.includes('ds');
113
219
  const templateVariables = {
114
220
  htmlPageTitle: options.servingType === 'local-dev-playground'
@@ -1,7 +1,7 @@
1
1
  export interface AddApplicationGeneratorSchema {
2
2
  name: string;
3
3
  htmlPageTitle?: string;
4
- servingType: 'local-dev-playground' | 'self-hosted' | 'iframe-with-post-messages';
4
+ servingType: 'local-dev-playground' | 'self-hosted' | 'iframe-with-post-messages' | 'documentation';
5
5
  runtimeName?: string;
6
6
  visualName?: string;
7
7
  skipDynamicRuntimeVisualPrompt?: boolean; // Internal option to skip the dynamic prompt for visual when runtime is selected
@@ -33,6 +33,10 @@
33
33
  {
34
34
  "value": "iframe-with-post-messages",
35
35
  "label": "Iframe + Post Messages (suitible to applications that gets required configuration from post messages)"
36
+ },
37
+ {
38
+ "value": "documentation",
39
+ "label": "Documentation Site (Docusaurus)"
36
40
  }
37
41
  ]
38
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/generators/internal-dev-runner/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAalC,wBAA8B,sBAAsB,CAAC,IAAI,EAAE,IAAI,iBAsC9D"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/generators/internal-dev-runner/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAclC,wBAA8B,sBAAsB,CAAC,IAAI,EAAE,IAAI,iBAuC9D"}
@@ -11,7 +11,8 @@ const tslib_1 = require("tslib");
11
11
  // import reorganizeApplicationsByDistributionChannel from '../../migrations/3-0-0/reorganize-applications-by-distribution-channel';
12
12
  // import upgradeSchemaTo2 from '../../migrations/3-0-0/upgrade-schema-to-2-0-0';
13
13
  // import postCleanupEmptyDirectories from '../../migrations/3-0-0/post-cleanup-empty-directories';
14
- const remove_private_from_applications_and_runtimes_1 = tslib_1.__importDefault(require("../../migrations/3-0-0/remove-private-from-applications-and-runtimes"));
14
+ // import removePrivateFromApplicationsAndRuntimes from '../../migrations/3-0-0/remove-private-from-applications-and-runtimes';
15
+ const fix_workspaces_pattern_1 = tslib_1.__importDefault(require("../../migrations/3-1-0/fix-workspaces-pattern"));
15
16
  async function testMigrationGenerator(tree) {
16
17
  // Collect all callbacks to run after all migrations complete
17
18
  // const callbacks: (() => void)[] = [];
@@ -29,7 +30,8 @@ async function testMigrationGenerator(tree) {
29
30
  // Upgrade schema to 2.0.0 and remove distributionChannel from packages
30
31
  // await upgradeSchemaTo2(tree);
31
32
  // Remove private field from applications, runtimes, and packages
32
- await (0, remove_private_from_applications_and_runtimes_1.default)(tree);
33
+ // await removePrivateFromApplicationsAndRuntimes(tree);
34
+ await (0, fix_workspaces_pattern_1.default)(tree);
33
35
  // Post-cleanup: Remove empty directories after reorganization
34
36
  // const postCleanupCallback = await postCleanupEmptyDirectories(tree);
35
37
  // if (postCleanupCallback) {
@@ -0,0 +1,23 @@
1
+ import { Tree } from '@nx/devkit';
2
+ /**
3
+ * Migration: Fix npm workspaces pattern to use explicit includes
4
+ *
5
+ * This migration updates the root package.json workspaces array to use
6
+ * explicit include patterns instead of a catch-all pattern with exclusions.
7
+ *
8
+ * The problem with "unisphere/**" + "!unisphere/applications/documentation/**"
9
+ * is that npm's negation patterns don't work reliably. This caused documentation
10
+ * apps (like Docusaurus) to be unable to have their own node_modules.
11
+ *
12
+ * The fix is to use explicit patterns that only include what should be workspaces:
13
+ * - unisphere/packages/**
14
+ * - unisphere/runtimes/**
15
+ * - unisphere/visuals/**
16
+ * - unisphere/applications/local/**
17
+ * - unisphere/applications/server/**
18
+ *
19
+ * This automatically excludes unisphere/applications/documentation/** without
20
+ * needing a negation pattern.
21
+ */
22
+ export default function update(tree: Tree): Promise<void>;
23
+ //# sourceMappingURL=fix-workspaces-pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix-workspaces-pattern.d.ts","sourceRoot":"","sources":["../../../src/migrations/3-1-0/fix-workspaces-pattern.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA+B,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAA8B,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D9D"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = update;
4
+ const devkit_1 = require("@nx/devkit");
5
+ /**
6
+ * Migration: Fix npm workspaces pattern to use explicit includes
7
+ *
8
+ * This migration updates the root package.json workspaces array to use
9
+ * explicit include patterns instead of a catch-all pattern with exclusions.
10
+ *
11
+ * The problem with "unisphere/**" + "!unisphere/applications/documentation/**"
12
+ * is that npm's negation patterns don't work reliably. This caused documentation
13
+ * apps (like Docusaurus) to be unable to have their own node_modules.
14
+ *
15
+ * The fix is to use explicit patterns that only include what should be workspaces:
16
+ * - unisphere/packages/**
17
+ * - unisphere/runtimes/**
18
+ * - unisphere/visuals/**
19
+ * - unisphere/applications/local/**
20
+ * - unisphere/applications/server/**
21
+ *
22
+ * This automatically excludes unisphere/applications/documentation/** without
23
+ * needing a negation pattern.
24
+ */
25
+ async function update(tree) {
26
+ devkit_1.logger.info('🔄 Fixing npm workspaces pattern to use explicit includes');
27
+ const packageJsonPath = 'package.json';
28
+ if (!tree.exists(packageJsonPath)) {
29
+ devkit_1.logger.warn('No package.json found, skipping migration');
30
+ return;
31
+ }
32
+ const packageJson = (0, devkit_1.readJson)(tree, packageJsonPath);
33
+ if (!packageJson.workspaces || !Array.isArray(packageJson.workspaces)) {
34
+ devkit_1.logger.warn('No workspaces array found in package.json, skipping migration');
35
+ return;
36
+ }
37
+ const oldWorkspaces = packageJson.workspaces;
38
+ // Check if using the old catch-all pattern
39
+ const hasCatchAllPattern = oldWorkspaces.includes('unisphere/**');
40
+ const hasNegationPattern = oldWorkspaces.some((pattern) => pattern.startsWith('!'));
41
+ if (!hasCatchAllPattern && !hasNegationPattern) {
42
+ // Check if already using explicit patterns
43
+ const expectedPatterns = [
44
+ 'unisphere/packages/**',
45
+ 'unisphere/runtimes/**',
46
+ 'unisphere/visuals/**',
47
+ 'unisphere/applications/local/**',
48
+ 'unisphere/applications/server/**',
49
+ ];
50
+ const hasAllExpectedPatterns = expectedPatterns.every(pattern => oldWorkspaces.includes(pattern));
51
+ if (hasAllExpectedPatterns) {
52
+ devkit_1.logger.info('Workspaces already using explicit patterns, skipping migration');
53
+ return;
54
+ }
55
+ }
56
+ // Replace with explicit patterns
57
+ const newWorkspaces = [
58
+ 'unisphere/packages/**',
59
+ 'unisphere/runtimes/**',
60
+ 'unisphere/visuals/**',
61
+ 'unisphere/applications/local/**',
62
+ 'unisphere/applications/server/**',
63
+ ];
64
+ packageJson.workspaces = newWorkspaces;
65
+ (0, devkit_1.writeJson)(tree, packageJsonPath, packageJson);
66
+ devkit_1.logger.info('✅ Updated workspaces from:');
67
+ devkit_1.logger.info(` ${JSON.stringify(oldWorkspaces)}`);
68
+ devkit_1.logger.info(' to:');
69
+ devkit_1.logger.info(` ${JSON.stringify(newWorkspaces)}`);
70
+ devkit_1.logger.info('');
71
+ devkit_1.logger.info('This allows documentation apps (like Docusaurus) to have their own node_modules.');
72
+ }
package/migrations.json CHANGED
@@ -273,7 +273,15 @@
273
273
  "3-0-0-remove-pre-install": {
274
274
  "version": "3.0.0",
275
275
  "description": "Removes kaltura-tools preinstall script from package.json",
276
- "factory": "./dist/migrations/3-0-0/remove-kaltura-tools-to-pre-install.js",
276
+ "factory": "./dist/migrations/3-0-0/remove-kaltura-tools-to-pre-install.js"
277
+ },
278
+ "3-1-0-fix-workspaces-pattern": {
279
+ "version": "3.1.0",
280
+ "description": "Fixes npm workspaces pattern to use explicit includes instead of catch-all with exclusions",
281
+ "factory": "./dist/migrations/3-1-0/fix-workspaces-pattern.js",
282
+ "cli": {
283
+ "postUpdateMessage": "✅ npm workspaces pattern updated to use explicit includes. Documentation apps can now have their own node_modules."
284
+ }
277
285
  }
278
286
  },
279
287
  "packageJsonUpdates": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unisphere/nx",
3
- "version": "3.2.3",
3
+ "version": "3.2.4",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",