@unisphere/nx 3.3.0 → 3.4.1

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-env-to-application-gitignore.d.ts","sourceRoot":"","sources":["../../../src/migrations/3-0-0/add-env-to-application-gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAoB,MAAM,YAAY,CAAC;AAsDpD,wBAA8B,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAkF9D"}
1
+ {"version":3,"file":"add-env-to-application-gitignore.d.ts","sourceRoot":"","sources":["../../../src/migrations/3-0-0/add-env-to-application-gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAU,MAAM,YAAY,CAAC;AAE1C,wBAA8B,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B9D"}
@@ -2,116 +2,30 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = update;
4
4
  const devkit_1 = require("@nx/devkit");
5
- const path_1 = require("path");
6
- const ENV_GITIGNORE_ENTRIES = `.env`;
7
- /**
8
- * Add .env entries to .gitignore for a given element
9
- * Returns: 'updated' | 'created' | 'skipped'
10
- */
11
- function addEnvToGitignore(tree, elementName, elementPath) {
12
- const gitignorePath = (0, path_1.join)(elementPath, '.gitignore');
13
- if (tree.exists(gitignorePath)) {
14
- // Read existing .gitignore
15
- const existingContent = tree.read(gitignorePath, 'utf-8') || '';
16
- // Check if .env is already in gitignore
17
- if (existingContent.includes('.env')) {
18
- devkit_1.logger.info(` ✅ ${elementName}: .gitignore already contains .env`);
19
- return 'skipped';
20
- }
21
- // Append .env entries to existing .gitignore
22
- const newContent = existingContent.trimEnd() + '\n\n# Environment files\n' + ENV_GITIGNORE_ENTRIES + '\n';
23
- tree.write(gitignorePath, newContent);
24
- devkit_1.logger.info(` ✅ ${elementName}: Added .env to existing .gitignore`);
25
- return 'updated';
26
- }
27
- else {
28
- // Create new .gitignore with .env entries
29
- const newContent = '# Environment files\n' + ENV_GITIGNORE_ENTRIES + '\n';
30
- tree.write(gitignorePath, newContent);
31
- devkit_1.logger.info(` ✅ ${elementName}: Created .gitignore with .env`);
32
- return 'created';
33
- }
34
- }
35
5
  async function update(tree) {
36
- devkit_1.logger.info('🔄 Adding .env to .gitignore files for all elements');
6
+ devkit_1.logger.info('🔄 Updating .gitignore to add migration-related entries...');
7
+ const gitignorePath = '.gitignore';
8
+ if (!tree.exists(gitignorePath)) {
9
+ devkit_1.logger.warn('⚠️ .gitignore file not found, creating one');
10
+ tree.write(gitignorePath, '');
11
+ }
37
12
  try {
38
- // Read .unisphere config
39
- if (!tree.exists('.unisphere')) {
40
- devkit_1.logger.warn('⚠️ No .unisphere file found, skipping');
41
- return;
42
- }
43
- const unisphereConfig = (0, devkit_1.readJson)(tree, '.unisphere');
44
- const elements = unisphereConfig.elements;
45
- if (!elements) {
46
- devkit_1.logger.info('ℹ️ No elements found, skipping');
47
- return;
48
- }
49
- let totalUpdated = 0;
50
- let totalCreated = 0;
51
- // Process applications
52
- const applications = elements.applications || {};
53
- if (Object.keys(applications).length > 0) {
54
- devkit_1.logger.info('\n📦 Processing applications...');
55
- for (const [name, config] of Object.entries(applications)) {
56
- const result = addEnvToGitignore(tree, name, config.sourceRoot);
57
- if (result === 'updated')
58
- totalUpdated++;
59
- if (result === 'created')
60
- totalCreated++;
61
- }
62
- }
63
- // Process packages
64
- const packages = elements.packages || {};
65
- if (Object.keys(packages).length > 0) {
66
- devkit_1.logger.info('\n📦 Processing packages...');
67
- for (const [name, config] of Object.entries(packages)) {
68
- const result = addEnvToGitignore(tree, name, config.sourceRoot);
69
- if (result === 'updated')
70
- totalUpdated++;
71
- if (result === 'created')
72
- totalCreated++;
73
- }
74
- }
75
- // Process runtimes
76
- const runtimes = elements.runtimes || {};
77
- if (Object.keys(runtimes).length > 0) {
78
- devkit_1.logger.info('\n📦 Processing runtimes...');
79
- for (const [name, config] of Object.entries(runtimes)) {
80
- const result = addEnvToGitignore(tree, name, config.sourceRoot);
81
- if (result === 'updated')
82
- totalUpdated++;
83
- if (result === 'created')
84
- totalCreated++;
85
- }
86
- }
87
- // Process workspace elements
88
- const workspace = elements.workspace || {};
89
- if (Object.keys(workspace).length > 0) {
90
- devkit_1.logger.info('\n📦 Processing workspace elements...');
91
- for (const [name, config] of Object.entries(workspace)) {
92
- const result = addEnvToGitignore(tree, name, config.sourceRoot);
93
- if (result === 'updated')
94
- totalUpdated++;
95
- if (result === 'created')
96
- totalCreated++;
97
- }
98
- }
99
- // Process loader elements
100
- const loader = elements.loader || {};
101
- if (Object.keys(loader).length > 0) {
102
- devkit_1.logger.info('\n📦 Processing loader elements...');
103
- for (const [name, config] of Object.entries(loader)) {
104
- const result = addEnvToGitignore(tree, name, config.sourceRoot);
105
- if (result === 'updated')
106
- totalUpdated++;
107
- if (result === 'created')
108
- totalCreated++;
109
- }
13
+ const currentContent = tree.read(gitignorePath, 'utf-8') || '';
14
+ let updatedContent = currentContent;
15
+ // Check if migrations.json is already in .gitignore
16
+ const migrationsJsonRegex = /^\.env$/gm;
17
+ if (!migrationsJsonRegex.test(updatedContent)) {
18
+ updatedContent += '.env\n';
19
+ tree.write(gitignorePath, updatedContent);
20
+ devkit_1.logger.info(`✅ Successfully updated .gitignore (added .env entry)`);
21
+ }
22
+ else {
23
+ devkit_1.logger.info('ℹ️ .env entry already exists in .gitignore');
110
24
  }
111
- devkit_1.logger.info(`\n✅ Done: ${totalUpdated} updated, ${totalCreated} created`);
112
25
  }
113
26
  catch (error) {
114
- devkit_1.logger.error(`❌ Failed to update .gitignore files: ${error?.message || 'Unknown error'}`);
115
- throw error;
27
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
28
+ devkit_1.logger.error(`❌ Failed to update .gitignore: ${errorMessage}`);
29
+ throw new Error(`Failed to update .gitignore: ${errorMessage}`);
116
30
  }
117
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reorganize-applications-by-distribution-channel.d.ts","sourceRoot":"","sources":["../../../src/migrations/3-0-0/reorganize-applications-by-distribution-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;EAQE;AAEF,OAAO,EACL,IAAI,EAOL,MAAM,YAAY,CAAC;AA8oBpB;;GAEG;AACH,wBAA8B,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAyE9D"}
1
+ {"version":3,"file":"reorganize-applications-by-distribution-channel.d.ts","sourceRoot":"","sources":["../../../src/migrations/3-0-0/reorganize-applications-by-distribution-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;EAQE;AAEF,OAAO,EACL,IAAI,EAML,MAAM,YAAY,CAAC;AAsmBpB;;GAEG;AACH,wBAA8B,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAyE9D"}
@@ -11,49 +11,10 @@
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.default = update;
13
13
  const devkit_1 = require("@nx/devkit");
14
+ const generators_1 = require("@nx/workspace/generators");
14
15
  const child_process_1 = require("child_process");
15
- /**
16
- * Manually move all files from source to destination directory.
17
- * This avoids using moveGenerator which relies on the Nx project graph cache.
18
- * The project graph is read from disk, but during migrations the Tree (virtual FS)
19
- * may have changes that aren't flushed to disk yet, causing stale data issues.
20
- * Using manual move with Tree APIs ensures we always work with the correct state.
21
- */
22
- function moveProjectFiles(tree, sourcePath, destPath) {
23
- const filesToMove = [];
24
- // Collect all files to move
25
- (0, devkit_1.visitNotIgnoredFiles)(tree, sourcePath, (filePath) => {
26
- const relativePath = filePath.substring(sourcePath.length);
27
- const newPath = `${destPath}${relativePath}`;
28
- filesToMove.push({ source: filePath, dest: newPath });
29
- });
30
- // Move files (create at dest, delete at source)
31
- for (const { source, dest } of filesToMove) {
32
- const content = tree.read(source);
33
- if (content !== null) {
34
- tree.write(dest, content);
35
- tree.delete(source);
36
- }
37
- }
38
- devkit_1.logger.info(` Moved ${filesToMove.length} files from ${sourcePath} to ${destPath}`);
39
- }
40
- /**
41
- * Update project.json after moving to new location
42
- */
43
- function updateProjectJsonAfterMove(tree, newPath, newProjectName) {
44
- const projectJsonPath = `${newPath}/project.json`;
45
- if (!tree.exists(projectJsonPath)) {
46
- return;
47
- }
48
- const projectJson = (0, devkit_1.readJson)(tree, projectJsonPath);
49
- // Update name if different
50
- if (projectJson.name !== newProjectName) {
51
- projectJson.name = newProjectName;
52
- }
53
- // Update sourceRoot to match new location
54
- projectJson.sourceRoot = `${newPath}/src`;
55
- (0, devkit_1.writeJson)(tree, projectJsonPath, projectJson);
56
- }
16
+ const fs_1 = require("fs");
17
+ const path_1 = require("path");
57
18
  /**
58
19
  * Reset Nx cache to ensure fresh project graph
59
20
  * This is important before moving projects, as Nx caches project locations
@@ -454,22 +415,33 @@ async function migrateApplication(tree, target) {
454
415
  devkit_1.logger.warn(` Source project.json not found at ${sourceProjectJson}, skipping`);
455
416
  return;
456
417
  }
457
- // Step 1: Manually move files using Tree APIs
458
- // We avoid moveGenerator because it relies on the Nx project graph cache,
459
- // which reads from disk. During migrations, the packages migration may have
460
- // already moved packages in the Tree but those changes aren't flushed to disk
461
- // yet, causing moveGenerator to use stale project locations.
462
- // Since applications don't need import path updates (they're entry points),
463
- // manual move is safe and reliable.
418
+ // Step 0: Clean node_modules from destination on disk if present.
419
+ // npm install may create node_modules/ at the target path (e.g. for workspace
420
+ // dependency resolution). tree.delete() only records a virtual deletion and
421
+ // doesn't remove on-disk children, so moveGenerator's checkDestination
422
+ // (which uses tree.children() -> readdirSync) would see node_modules and
423
+ // throw "Path is not empty". We must remove it from the real filesystem.
424
+ const destNodeModules = (0, path_1.join)(newPath, 'node_modules');
425
+ if ((0, fs_1.existsSync)(destNodeModules)) {
426
+ devkit_1.logger.info(` Removing leftover node_modules at destination: ${destNodeModules}`);
427
+ (0, fs_1.rmSync)(destNodeModules, { recursive: true, force: true });
428
+ }
429
+ // Step 1: Use Nx moveGenerator for the heavy lifting
464
430
  try {
465
- moveProjectFiles(tree, app.currentPath, newPath);
466
- updateProjectJsonAfterMove(tree, newPath, newNxProjectName);
467
- devkit_1.logger.info(` Project moved successfully`);
431
+ await (0, generators_1.moveGenerator)(tree, {
432
+ projectName: app.currentNxProjectName,
433
+ destination: newPath,
434
+ newProjectName: newNxProjectName,
435
+ updateImportPath: false, // Applications are entry points, not libraries
436
+ skipFormat: true,
437
+ });
438
+ devkit_1.logger.info(` Nx moved project successfully`);
468
439
  // Reset Nx cache after move to ensure fresh project graph for next operations
440
+ // This is important because moveGenerator uses the project graph, and it can become stale
469
441
  resetNxCache();
470
442
  }
471
443
  catch (error) {
472
- devkit_1.logger.error(` Failed to move project: ${error}`);
444
+ devkit_1.logger.error(` Failed to move project with Nx: ${error}`);
473
445
  devkit_1.logger.error(` Source path: ${app.currentPath}`);
474
446
  devkit_1.logger.error(` Destination path: ${newPath}`);
475
447
  devkit_1.logger.error(` Project name: ${app.currentNxProjectName}`);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Migration: Update .gitignore to exclude Claude Code local settings
3
+ *
4
+ * Adds .claude/settings.local.json to .gitignore to prevent local Claude Code
5
+ * settings from being committed to the repository.
6
+ */
7
+ import { Tree } from '@nx/devkit';
8
+ export default function update(tree: Tree): Promise<void>;
9
+ //# sourceMappingURL=update-gitignore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-gitignore.d.ts","sourceRoot":"","sources":["../../../src/migrations/3-4-0/update-gitignore.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAU,MAAM,YAAY,CAAC;AAE1C,wBAA8B,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C9D"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * Migration: Update .gitignore to exclude Claude Code local settings
4
+ *
5
+ * Adds .claude/settings.local.json to .gitignore to prevent local Claude Code
6
+ * settings from being committed to the repository.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.default = update;
10
+ const devkit_1 = require("@nx/devkit");
11
+ async function update(tree) {
12
+ devkit_1.logger.info('🔄 Updating .gitignore to exclude Claude Code local settings...');
13
+ const gitignorePath = '.gitignore';
14
+ if (!tree.exists(gitignorePath)) {
15
+ devkit_1.logger.warn('⚠️ .gitignore file not found, creating one');
16
+ tree.write(gitignorePath, '');
17
+ }
18
+ try {
19
+ const currentContent = tree.read(gitignorePath, 'utf-8') || '';
20
+ let updatedContent = currentContent;
21
+ // Check if .claude/settings.local.json is already in .gitignore
22
+ const claudeSettingsRegex = /^\.claude\/settings\.local\.json\s*$/gm;
23
+ if (!claudeSettingsRegex.test(updatedContent)) {
24
+ // Add Claude Code local settings section and entry
25
+ if (!updatedContent.includes('# Claude Code local settings')) {
26
+ updatedContent =
27
+ updatedContent.trim() + '\n\n# Claude Code local settings\n';
28
+ }
29
+ if (!updatedContent.includes('.claude/settings.local.json')) {
30
+ updatedContent += '.claude/settings.local.json\n';
31
+ devkit_1.logger.info('📝 Added .claude/settings.local.json to .gitignore');
32
+ }
33
+ tree.write(gitignorePath, updatedContent);
34
+ devkit_1.logger.info('✅ Successfully updated .gitignore');
35
+ }
36
+ else {
37
+ devkit_1.logger.info('ℹ️ .claude/settings.local.json already exists in .gitignore');
38
+ }
39
+ }
40
+ catch (error) {
41
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
42
+ devkit_1.logger.error(`❌ Failed to update .gitignore: ${errorMessage}`);
43
+ throw new Error(`Failed to update .gitignore: ${errorMessage}`);
44
+ }
45
+ }
package/migrations.json CHANGED
@@ -282,6 +282,14 @@
282
282
  "cli": {
283
283
  "postUpdateMessage": "✅ npm workspaces pattern updated to use explicit includes. Documentation apps can now have their own node_modules."
284
284
  }
285
+ },
286
+ "3-4-0-update-gitignore": {
287
+ "version": "3.4.0",
288
+ "description": "Updates .gitignore to exclude Claude Code local settings",
289
+ "factory": "./dist/migrations/3-4-0/update-gitignore.js",
290
+ "cli": {
291
+ "postUpdateMessage": "✅ .gitignore updated to exclude .claude/settings.local.json"
292
+ }
285
293
  }
286
294
  },
287
295
  "packageJsonUpdates": {
@@ -439,4 +447,4 @@
439
447
  }
440
448
  }
441
449
  }
442
- }
450
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unisphere/nx",
3
- "version": "3.3.0",
3
+ "version": "3.4.1",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -91,4 +91,4 @@
91
91
  "nx-migrations": {
92
92
  "migrations": "./migrations.json"
93
93
  }
94
- }
94
+ }