@nx/jest 23.0.0-beta.2 → 23.0.0-beta.20

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 (135) hide show
  1. package/{index.d.ts → dist/index.d.ts} +0 -5
  2. package/{index.js → dist/index.js} +1 -6
  3. package/dist/internal.d.ts +2 -0
  4. package/dist/internal.js +13 -0
  5. package/{plugin.d.ts → dist/plugin.d.ts} +0 -1
  6. package/dist/plugins/resolver.d.ts +1 -0
  7. package/{plugins → dist/plugins}/resolver.js +1 -1
  8. package/{preset → dist/preset}/index.d.ts +0 -1
  9. package/{preset → dist/preset}/jest-preset.d.ts +0 -1
  10. package/{preset → dist/preset}/jest-preset.js +1 -0
  11. package/{preset.d.ts → dist/preset.d.ts} +0 -1
  12. package/{src → dist/src}/executors/jest/jest.impl.d.ts +0 -1
  13. package/{src → dist/src}/executors/jest/jest.impl.js +4 -2
  14. package/{src → dist/src}/executors/jest/schema.json +1 -0
  15. package/{src → dist/src}/executors/jest/summary.d.ts +0 -1
  16. package/{src → dist/src}/generators/configuration/configuration.d.ts +0 -1
  17. package/{src → dist/src}/generators/configuration/configuration.js +22 -8
  18. package/{src → dist/src}/generators/configuration/lib/check-for-test-target.d.ts +0 -1
  19. package/{src → dist/src}/generators/configuration/lib/create-files.d.ts +0 -1
  20. package/{src → dist/src}/generators/configuration/lib/create-files.js +2 -2
  21. package/{src → dist/src}/generators/configuration/lib/create-jest-config.d.ts +0 -1
  22. package/{src → dist/src}/generators/configuration/lib/create-jest-config.js +2 -2
  23. package/{src → dist/src}/generators/configuration/lib/ensure-dependencies.d.ts +0 -1
  24. package/{src → dist/src}/generators/configuration/lib/update-tsconfig.d.ts +0 -1
  25. package/{src → dist/src}/generators/configuration/lib/update-tsconfig.js +2 -2
  26. package/{src → dist/src}/generators/configuration/lib/update-vscode-recommended-extensions.d.ts +0 -1
  27. package/{src → dist/src}/generators/configuration/lib/update-workspace.d.ts +0 -1
  28. package/{src → dist/src}/generators/convert-to-inferred/convert-to-inferred.d.ts +0 -1
  29. package/{src → dist/src}/generators/convert-to-inferred/convert-to-inferred.js +13 -14
  30. package/{src → dist/src}/generators/init/init.d.ts +0 -1
  31. package/{src → dist/src}/generators/init/init.js +60 -21
  32. package/{src → dist/src}/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.d.ts +0 -1
  33. package/{src/migrations/update-21-0-0 → dist/src/migrations/update-20-0-0}/replace-getJestProjects-with-getJestProjectsAsync.js +2 -2
  34. package/dist/src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.md +25 -0
  35. package/{src → dist/src}/migrations/update-21-0-0/remove-tsconfig-option-from-jest-executor.d.ts +0 -1
  36. package/dist/src/migrations/update-21-0-0/remove-tsconfig-option-from-jest-executor.js +97 -0
  37. package/dist/src/migrations/update-21-0-0/remove-tsconfig-option-from-jest-executor.md +102 -0
  38. package/{src → dist/src}/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.d.ts +0 -1
  39. package/{src/migrations/update-20-0-0 → dist/src/migrations/update-21-0-0}/replace-getJestProjects-with-getJestProjectsAsync.js +2 -2
  40. package/dist/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.md +25 -0
  41. package/{src → dist/src}/migrations/update-21-3-0/rename-test-path-pattern.d.ts +0 -1
  42. package/{src → dist/src}/migrations/update-21-3-0/rename-test-path-pattern.js +27 -11
  43. package/dist/src/migrations/update-21-3-0/rename-test-path-pattern.md +147 -0
  44. package/{src → dist/src}/migrations/update-21-3-0/replace-removed-matcher-aliases.d.ts +0 -1
  45. package/dist/src/migrations/update-21-3-0/replace-removed-matcher-aliases.md +51 -0
  46. package/{src → dist/src}/migrations/update-22-2-0/convert-jest-config-to-cjs.d.ts +0 -1
  47. package/dist/src/migrations/update-22-2-0/convert-jest-config-to-cjs.md +33 -0
  48. package/dist/src/migrations/update-23-0-0/rewrite-internal-subpath-imports.d.ts +3 -0
  49. package/dist/src/migrations/update-23-0-0/rewrite-internal-subpath-imports.js +201 -0
  50. package/dist/src/migrations/update-23-0-0/rewrite-jest-project-generator.d.ts +3 -0
  51. package/dist/src/migrations/update-23-0-0/rewrite-jest-project-generator.js +121 -0
  52. package/dist/src/migrations/update-23-0-0/update-snapshot-guide-link.d.ts +2 -0
  53. package/dist/src/migrations/update-23-0-0/update-snapshot-guide-link.js +28 -0
  54. package/dist/src/migrations/update-23-0-0/update-snapshot-guide-link.md +21 -0
  55. package/{src → dist/src}/plugins/plugin.d.ts +0 -1
  56. package/{src → dist/src}/plugins/plugin.js +18 -25
  57. package/{src → dist/src}/utils/ast-utils.d.ts +0 -1
  58. package/{src → dist/src}/utils/config/config-file.d.ts +0 -1
  59. package/{src → dist/src}/utils/config/functions.d.ts +0 -1
  60. package/{src → dist/src}/utils/config/functions.js +7 -7
  61. package/{src → dist/src}/utils/config/get-jest-projects.d.ts +0 -1
  62. package/{src → dist/src}/utils/config/get-jest-projects.js +2 -2
  63. package/{src → dist/src}/utils/config/update-config.d.ts +0 -1
  64. package/dist/src/utils/deprecation.d.ts +3 -0
  65. package/dist/src/utils/deprecation.js +15 -0
  66. package/{src → dist/src}/utils/version-utils.d.ts +0 -1
  67. package/{src → dist/src}/utils/versions.d.ts +0 -1
  68. package/{src → dist/src}/utils/versions.js +11 -5
  69. package/executors.json +3 -3
  70. package/generators.json +6 -6
  71. package/migrations.json +45 -7
  72. package/package.json +65 -10
  73. package/index.d.ts.map +0 -1
  74. package/plugin.d.ts.map +0 -1
  75. package/plugins/resolver.d.ts +0 -2
  76. package/plugins/resolver.d.ts.map +0 -1
  77. package/preset/index.d.ts.map +0 -1
  78. package/preset/jest-preset.d.ts.map +0 -1
  79. package/preset.d.ts.map +0 -1
  80. package/src/executors/jest/jest.impl.d.ts.map +0 -1
  81. package/src/executors/jest/summary.d.ts.map +0 -1
  82. package/src/generators/configuration/configuration.d.ts.map +0 -1
  83. package/src/generators/configuration/lib/check-for-test-target.d.ts.map +0 -1
  84. package/src/generators/configuration/lib/create-files.d.ts.map +0 -1
  85. package/src/generators/configuration/lib/create-jest-config.d.ts.map +0 -1
  86. package/src/generators/configuration/lib/ensure-dependencies.d.ts.map +0 -1
  87. package/src/generators/configuration/lib/update-tsconfig.d.ts.map +0 -1
  88. package/src/generators/configuration/lib/update-vscode-recommended-extensions.d.ts.map +0 -1
  89. package/src/generators/configuration/lib/update-workspace.d.ts.map +0 -1
  90. package/src/generators/convert-to-inferred/convert-to-inferred.d.ts.map +0 -1
  91. package/src/generators/init/init.d.ts.map +0 -1
  92. package/src/migrations/update-20-0-0/replace-getJestProjects-with-getJestProjectsAsync.d.ts.map +0 -1
  93. package/src/migrations/update-21-0-0/remove-tsconfig-option-from-jest-executor.d.ts.map +0 -1
  94. package/src/migrations/update-21-0-0/remove-tsconfig-option-from-jest-executor.js +0 -65
  95. package/src/migrations/update-21-0-0/replace-getJestProjects-with-getJestProjectsAsync.d.ts.map +0 -1
  96. package/src/migrations/update-21-3-0/rename-test-path-pattern.d.ts.map +0 -1
  97. package/src/migrations/update-21-3-0/replace-removed-matcher-aliases.d.ts.map +0 -1
  98. package/src/migrations/update-22-2-0/convert-jest-config-to-cjs.d.ts.map +0 -1
  99. package/src/plugins/plugin.d.ts.map +0 -1
  100. package/src/utils/ast-utils.d.ts.map +0 -1
  101. package/src/utils/config/config-file.d.ts.map +0 -1
  102. package/src/utils/config/functions.d.ts.map +0 -1
  103. package/src/utils/config/get-jest-projects.d.ts.map +0 -1
  104. package/src/utils/config/update-config.d.ts.map +0 -1
  105. package/src/utils/version-utils.d.ts.map +0 -1
  106. package/src/utils/versions.d.ts.map +0 -1
  107. /package/{LICENSE → dist/LICENSE} +0 -0
  108. /package/{PLUGIN.md → dist/PLUGIN.md} +0 -0
  109. /package/{plugin.js → dist/plugin.js} +0 -0
  110. /package/{preset → dist/preset}/index.js +0 -0
  111. /package/{preset.js → dist/preset.js} +0 -0
  112. /package/{src → dist/src}/executors/jest/schema.d.ts +0 -0
  113. /package/{src → dist/src}/executors/jest/summary.js +0 -0
  114. /package/{src → dist/src}/generators/configuration/files/common/src/test-setup.ts__tmpl__ +0 -0
  115. /package/{src → dist/src}/generators/configuration/files/common/tsconfig.spec.json__tmpl__ +0 -0
  116. /package/{src → dist/src}/generators/configuration/files/jest-config-non-ts-solution/jest.config.ts__tmpl__ +0 -0
  117. /package/{src → dist/src}/generators/configuration/files/jest-config-ts-solution/jest.config.ts__tmpl__ +0 -0
  118. /package/{src → dist/src}/generators/configuration/files-angular/jest.config.ts__tmpl__ +0 -0
  119. /package/{src → dist/src}/generators/configuration/files-angular/src/test-setup.ts__tmpl__ +0 -0
  120. /package/{src → dist/src}/generators/configuration/files-angular/tsconfig.spec.json__tmpl__ +0 -0
  121. /package/{src → dist/src}/generators/configuration/lib/check-for-test-target.js +0 -0
  122. /package/{src → dist/src}/generators/configuration/lib/ensure-dependencies.js +0 -0
  123. /package/{src → dist/src}/generators/configuration/lib/update-vscode-recommended-extensions.js +0 -0
  124. /package/{src → dist/src}/generators/configuration/lib/update-workspace.js +0 -0
  125. /package/{src → dist/src}/generators/configuration/schema.d.ts +0 -0
  126. /package/{src → dist/src}/generators/configuration/schema.json +0 -0
  127. /package/{src → dist/src}/generators/convert-to-inferred/schema.json +0 -0
  128. /package/{src → dist/src}/generators/init/schema.d.ts +0 -0
  129. /package/{src → dist/src}/generators/init/schema.json +0 -0
  130. /package/{src → dist/src}/migrations/update-21-3-0/replace-removed-matcher-aliases.js +0 -0
  131. /package/{src → dist/src}/migrations/update-22-2-0/convert-jest-config-to-cjs.js +0 -0
  132. /package/{src → dist/src}/utils/ast-utils.js +0 -0
  133. /package/{src → dist/src}/utils/config/config-file.js +0 -0
  134. /package/{src → dist/src}/utils/config/update-config.js +0 -0
  135. /package/{src → dist/src}/utils/version-utils.js +0 -0
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = rewriteInternalSubpathImports;
4
+ exports.rewriteSubpathImports = rewriteSubpathImports;
5
+ const devkit_1 = require("@nx/devkit");
6
+ const TS_EXTENSIONS = ['.ts', '.tsx', '.cts', '.mts'];
7
+ const FROM_PREFIX = '@nx/jest/src/';
8
+ const TO_PUBLIC = '@nx/jest';
9
+ const TO_INTERNAL = '@nx/jest/internal';
10
+ // Symbols exported from `@nx/jest`'s public entry (packages/jest/index.ts).
11
+ // A named import/export of one of these from `@nx/jest/src/*` is routed to
12
+ // the public `@nx/jest` entry; everything else goes to `@nx/jest/internal`.
13
+ const PUBLIC_SYMBOLS = new Set([
14
+ 'configurationGenerator',
15
+ 'jestInitGenerator',
16
+ 'addPropertyToJestConfig',
17
+ 'removePropertyFromJestConfig',
18
+ 'jestConfigObjectAst',
19
+ 'getJestProjectsAsync',
20
+ 'findJestConfig',
21
+ ]);
22
+ // Methods on `jest` and `vi` that take a module specifier as their first arg.
23
+ const MOCK_HELPER_METHODS = new Set([
24
+ 'mock',
25
+ 'unmock',
26
+ 'doMock',
27
+ 'dontMock',
28
+ 'requireActual',
29
+ 'requireMock',
30
+ 'importActual',
31
+ 'importMock',
32
+ ]);
33
+ let ts;
34
+ async function rewriteInternalSubpathImports(tree) {
35
+ let touchedCount = 0;
36
+ (0, devkit_1.visitNotIgnoredFiles)(tree, '.', (filePath) => {
37
+ if (!TS_EXTENSIONS.some((ext) => filePath.endsWith(ext))) {
38
+ return;
39
+ }
40
+ const original = tree.read(filePath, 'utf-8');
41
+ if (!original || !original.includes(FROM_PREFIX)) {
42
+ return;
43
+ }
44
+ const updated = rewriteSubpathImports(original);
45
+ if (updated !== original) {
46
+ tree.write(filePath, updated);
47
+ touchedCount += 1;
48
+ }
49
+ });
50
+ if (touchedCount > 0) {
51
+ devkit_1.logger.info(`Rewrote @nx/jest/src/* imports in ${touchedCount} file(s) ` +
52
+ `(public symbols to @nx/jest, internals to @nx/jest/internal).`);
53
+ }
54
+ await (0, devkit_1.formatFiles)(tree);
55
+ }
56
+ function rewriteSubpathImports(source) {
57
+ ts ??= (0, devkit_1.ensurePackage)('typescript', '*');
58
+ const sourceFile = ts.createSourceFile('tmp.ts', source, ts.ScriptTarget.Latest,
59
+ /* setParentNodes */ true, ts.ScriptKind.TSX);
60
+ const changes = [];
61
+ for (const stmt of sourceFile.statements) {
62
+ if (ts.isImportDeclaration(stmt)) {
63
+ collectImportRewrite(sourceFile, stmt, changes);
64
+ }
65
+ else if (ts.isExportDeclaration(stmt)) {
66
+ collectExportRewrite(sourceFile, stmt, changes);
67
+ }
68
+ }
69
+ collectCallExpressionRewrites(sourceFile, changes);
70
+ return changes.length > 0 ? (0, devkit_1.applyChangesToString)(source, changes) : source;
71
+ }
72
+ function isSubpathSpecifier(node) {
73
+ return ts.isStringLiteral(node) && node.text.startsWith(FROM_PREFIX);
74
+ }
75
+ function collectImportRewrite(sourceFile, stmt, changes) {
76
+ if (!isSubpathSpecifier(stmt.moduleSpecifier)) {
77
+ return;
78
+ }
79
+ const clause = stmt.importClause;
80
+ // Pure named imports (`import { a, b } from '...'`) can be split by symbol.
81
+ // A default or namespace import grabs the whole module, so it can't be
82
+ // split — route it wholesale to the internal entry.
83
+ if (clause &&
84
+ !clause.name &&
85
+ clause.namedBindings &&
86
+ ts.isNamedImports(clause.namedBindings)) {
87
+ rewriteNamedDeclaration(sourceFile, stmt, stmt.moduleSpecifier, clause.isTypeOnly, clause.namedBindings.elements, 'import', changes);
88
+ return;
89
+ }
90
+ replaceSpecifier(sourceFile, stmt.moduleSpecifier, TO_INTERNAL, changes);
91
+ }
92
+ function collectExportRewrite(sourceFile, stmt, changes) {
93
+ if (!stmt.moduleSpecifier || !isSubpathSpecifier(stmt.moduleSpecifier)) {
94
+ return;
95
+ }
96
+ // `export { a, b } from '...'` can be split; `export * from '...'` cannot.
97
+ if (stmt.exportClause && ts.isNamedExports(stmt.exportClause)) {
98
+ rewriteNamedDeclaration(sourceFile, stmt, stmt.moduleSpecifier, stmt.isTypeOnly, stmt.exportClause.elements, 'export', changes);
99
+ return;
100
+ }
101
+ replaceSpecifier(sourceFile, stmt.moduleSpecifier, TO_INTERNAL, changes);
102
+ }
103
+ /**
104
+ * Partition the named bindings of an import/export declaration into the ones
105
+ * that resolve to `@nx/jest`'s public entry and the ones that don't. If both
106
+ * groups are non-empty, the single declaration is split into two.
107
+ */
108
+ function rewriteNamedDeclaration(sourceFile, decl, specifier, isTypeOnly, elements, keyword, changes) {
109
+ const publicEls = [];
110
+ const internalEls = [];
111
+ for (const el of elements) {
112
+ // `propertyName` is the original name in `orig as alias`; fall back to
113
+ // `name` for the plain `orig` form.
114
+ const importedName = (el.propertyName ?? el.name).text;
115
+ (PUBLIC_SYMBOLS.has(importedName) ? publicEls : internalEls).push(el);
116
+ }
117
+ if (publicEls.length === 0) {
118
+ replaceSpecifier(sourceFile, specifier, TO_INTERNAL, changes);
119
+ return;
120
+ }
121
+ if (internalEls.length === 0) {
122
+ replaceSpecifier(sourceFile, specifier, TO_PUBLIC, changes);
123
+ return;
124
+ }
125
+ // Mixed — replace the whole declaration with one statement per target.
126
+ const quote = sourceFile.text.charAt(specifier.getStart(sourceFile));
127
+ const start = decl.getStart(sourceFile);
128
+ const end = decl.getEnd();
129
+ const semicolon = sourceFile.text.charAt(end - 1) === ';' ? ';' : '';
130
+ const prefix = isTypeOnly ? `${keyword} type` : keyword;
131
+ const render = (els, target) => `${prefix} { ${els
132
+ .map((el) => el.getText(sourceFile))
133
+ .join(', ')} } from ${quote}${target}${quote}${semicolon}`;
134
+ changes.push({ type: devkit_1.ChangeType.Delete, start, length: end - start }, {
135
+ type: devkit_1.ChangeType.Insert,
136
+ index: start,
137
+ text: `${render(publicEls, TO_PUBLIC)}\n${render(internalEls, TO_INTERNAL)}`,
138
+ });
139
+ }
140
+ function collectCallExpressionRewrites(sourceFile, changes) {
141
+ const visit = (node) => {
142
+ if (ts.isCallExpression(node) &&
143
+ shouldRewriteCallExpression(node) &&
144
+ node.arguments.length >= 1 &&
145
+ isSubpathSpecifier(node.arguments[0])) {
146
+ // `require(...)`, dynamic `import(...)` and `jest.mock(...)` reference
147
+ // the module as a whole and can't be symbol-split, so they go to the
148
+ // internal entry.
149
+ replaceSpecifier(sourceFile, node.arguments[0], TO_INTERNAL, changes);
150
+ }
151
+ else if (ts.isImportTypeNode(node)) {
152
+ // `typeof import('...')` parses as an `ImportTypeNode`, not a
153
+ // CallExpression — its argument is `LiteralTypeNode<StringLiteral>`.
154
+ // The whole module is referenced, so it can't be symbol-split.
155
+ const literal = getImportTypeStringLiteral(node);
156
+ if (literal && literal.text.startsWith(FROM_PREFIX)) {
157
+ replaceSpecifier(sourceFile, literal, TO_INTERNAL, changes);
158
+ }
159
+ }
160
+ ts.forEachChild(node, visit);
161
+ };
162
+ visit(sourceFile);
163
+ }
164
+ function getImportTypeStringLiteral(node) {
165
+ const arg = node.argument;
166
+ if (arg && ts.isLiteralTypeNode(arg) && ts.isStringLiteral(arg.literal)) {
167
+ return arg.literal;
168
+ }
169
+ return undefined;
170
+ }
171
+ function shouldRewriteCallExpression(call) {
172
+ const callee = call.expression;
173
+ // `require('...')`
174
+ if (ts.isIdentifier(callee) && callee.text === 'require')
175
+ return true;
176
+ // dynamic `import('...')` (runtime form parses as a CallExpression whose
177
+ // callee is the `import` keyword). The `typeof import('...')` type-position
178
+ // form is an `ImportTypeNode` (handled in `collectCallExpressionRewrites`).
179
+ if (callee.kind === ts.SyntaxKind.ImportKeyword)
180
+ return true;
181
+ // `jest.mock(...)` / `vi.mock(...)` and friends.
182
+ if (ts.isPropertyAccessExpression(callee)) {
183
+ const obj = callee.expression;
184
+ if (ts.isIdentifier(obj) &&
185
+ (obj.text === 'jest' || obj.text === 'vi') &&
186
+ MOCK_HELPER_METHODS.has(callee.name.text)) {
187
+ return true;
188
+ }
189
+ }
190
+ return false;
191
+ }
192
+ function replaceSpecifier(sourceFile, literal, target, changes) {
193
+ const start = literal.getStart(sourceFile);
194
+ const end = literal.getEnd();
195
+ const quote = sourceFile.text.charAt(start);
196
+ changes.push({ type: devkit_1.ChangeType.Delete, start, length: end - start }, {
197
+ type: devkit_1.ChangeType.Insert,
198
+ index: start,
199
+ text: `${quote}${target}${quote}`,
200
+ });
201
+ }
@@ -0,0 +1,3 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function rewriteJestProjectGenerator(tree: Tree): Promise<void>;
3
+ export declare function rewriteJestProjectGeneratorUsage(source: string): string;
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = rewriteJestProjectGenerator;
4
+ exports.rewriteJestProjectGeneratorUsage = rewriteJestProjectGeneratorUsage;
5
+ const devkit_1 = require("@nx/devkit");
6
+ const TS_EXTENSIONS = ['.ts', '.tsx', '.cts', '.mts'];
7
+ const PACKAGE = '@nx/jest';
8
+ const OLD_NAME = 'jestProjectGenerator';
9
+ const NEW_NAME = 'configurationGenerator';
10
+ let ts;
11
+ async function rewriteJestProjectGenerator(tree) {
12
+ let touchedCount = 0;
13
+ (0, devkit_1.visitNotIgnoredFiles)(tree, '.', (filePath) => {
14
+ if (!TS_EXTENSIONS.some((ext) => filePath.endsWith(ext))) {
15
+ return;
16
+ }
17
+ const original = tree.read(filePath, 'utf-8');
18
+ if (!original ||
19
+ !original.includes(OLD_NAME) ||
20
+ !original.includes(PACKAGE)) {
21
+ return;
22
+ }
23
+ const updated = rewriteJestProjectGeneratorUsage(original);
24
+ if (updated !== original) {
25
+ tree.write(filePath, updated);
26
+ touchedCount += 1;
27
+ }
28
+ });
29
+ if (touchedCount > 0) {
30
+ devkit_1.logger.info(`Replaced the deprecated \`${OLD_NAME}\` with \`${NEW_NAME}\` in ${touchedCount} file(s).`);
31
+ }
32
+ await (0, devkit_1.formatFiles)(tree);
33
+ }
34
+ function rewriteJestProjectGeneratorUsage(source) {
35
+ ts ??= (0, devkit_1.ensurePackage)('typescript', '*');
36
+ const sourceFile = ts.createSourceFile('tmp.ts', source, ts.ScriptTarget.Latest,
37
+ /* setParentNodes */ true, ts.ScriptKind.TSX);
38
+ // `jestProjectGenerator as alias` — only the imported name changes.
39
+ let aliasedSpecifier;
40
+ // `jestProjectGenerator` — the local binding is the old name itself.
41
+ let plainSpecifier;
42
+ // Whether `configurationGenerator` is already a binding in the file, which
43
+ // means a plain rename would produce a duplicate import specifier.
44
+ let newNameAlreadyBound = false;
45
+ for (const stmt of sourceFile.statements) {
46
+ if (!ts.isImportDeclaration(stmt))
47
+ continue;
48
+ if (!ts.isStringLiteral(stmt.moduleSpecifier) ||
49
+ stmt.moduleSpecifier.text !== PACKAGE) {
50
+ continue;
51
+ }
52
+ const named = stmt.importClause?.namedBindings;
53
+ if (!named || !ts.isNamedImports(named))
54
+ continue;
55
+ for (const spec of named.elements) {
56
+ const importedName = (spec.propertyName ?? spec.name).text;
57
+ if (importedName === OLD_NAME) {
58
+ if (spec.propertyName) {
59
+ aliasedSpecifier = spec;
60
+ }
61
+ else {
62
+ plainSpecifier = spec;
63
+ }
64
+ }
65
+ if (importedName === NEW_NAME || spec.name.text === NEW_NAME) {
66
+ newNameAlreadyBound = true;
67
+ }
68
+ }
69
+ }
70
+ if (!aliasedSpecifier && !plainSpecifier) {
71
+ return source;
72
+ }
73
+ const changes = [];
74
+ // `jestProjectGenerator as alias` -> `configurationGenerator as alias`.
75
+ // Call sites use `alias`, so only the imported name is rewritten.
76
+ if (aliasedSpecifier?.propertyName) {
77
+ replaceNode(sourceFile, aliasedSpecifier.propertyName, NEW_NAME, changes);
78
+ }
79
+ if (plainSpecifier) {
80
+ if (newNameAlreadyBound) {
81
+ // A plain rename would collide with the existing `configurationGenerator`
82
+ // binding, so alias the import and leave the call sites untouched.
83
+ replaceNode(sourceFile, plainSpecifier.name, `${NEW_NAME} as ${OLD_NAME}`, changes);
84
+ }
85
+ else {
86
+ // Rename the import binding and every bare-identifier usage in the file.
87
+ for (const id of collectBareIdentifiers(sourceFile)) {
88
+ replaceNode(sourceFile, id, NEW_NAME, changes);
89
+ }
90
+ }
91
+ }
92
+ return changes.length > 0 ? (0, devkit_1.applyChangesToString)(source, changes) : source;
93
+ }
94
+ /**
95
+ * Collect every `jestProjectGenerator` identifier that is a standalone
96
+ * reference — the import binding and its call sites — while skipping member
97
+ * accesses like `someObject.jestProjectGenerator`, which are unrelated.
98
+ */
99
+ function collectBareIdentifiers(sourceFile) {
100
+ const found = [];
101
+ const visit = (node) => {
102
+ if (ts.isIdentifier(node) && node.text === OLD_NAME) {
103
+ const parent = node.parent;
104
+ const isMemberName = parent &&
105
+ ts.isPropertyAccessExpression(parent) &&
106
+ parent.name === node;
107
+ const isQualifiedName = parent && ts.isQualifiedName(parent) && parent.right === node;
108
+ if (!isMemberName && !isQualifiedName) {
109
+ found.push(node);
110
+ }
111
+ }
112
+ ts.forEachChild(node, visit);
113
+ };
114
+ visit(sourceFile);
115
+ return found;
116
+ }
117
+ function replaceNode(sourceFile, node, text, changes) {
118
+ const start = node.getStart(sourceFile);
119
+ const end = node.getEnd();
120
+ changes.push({ type: devkit_1.ChangeType.Delete, start, length: end - start }, { type: devkit_1.ChangeType.Insert, index: start, text });
121
+ }
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function updateSnapshotGuideLink(tree: Tree): Promise<void>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = updateSnapshotGuideLink;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const OLD_HEADER = '// Jest Snapshot v1, https://goo.gl/fbAQLP';
6
+ const NEW_HEADER = '// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing';
7
+ async function updateSnapshotGuideLink(tree) {
8
+ const snapshotFiles = await (0, devkit_1.globAsync)(tree, ['**/__snapshots__/*.snap']);
9
+ for (const snapshotFile of snapshotFiles) {
10
+ const content = tree.read(snapshotFile, 'utf-8');
11
+ if (!content) {
12
+ continue;
13
+ }
14
+ const newlineMatch = content.match(/\r?\n/);
15
+ if (!newlineMatch) {
16
+ continue;
17
+ }
18
+ const newline = newlineMatch[0];
19
+ const firstNewlineIndex = content.indexOf(newline);
20
+ const firstLine = content.slice(0, firstNewlineIndex);
21
+ if (firstLine !== OLD_HEADER) {
22
+ continue;
23
+ }
24
+ const updated = NEW_HEADER + content.slice(firstNewlineIndex);
25
+ tree.write(snapshotFile, updated);
26
+ }
27
+ await (0, devkit_1.formatFiles)(tree);
28
+ }
@@ -0,0 +1,21 @@
1
+ #### Update Jest Snapshot Guide Link
2
+
3
+ Updates the snapshot guide link at the top of every `.snap` file from the legacy `https://goo.gl/fbAQLP` to `https://jestjs.io/docs/snapshot-testing`. Jest v30 errors out at test setup time if it sees the old link, so existing snapshot files need to be rewritten before tests can run. Read more at the [Jest v30 migration notes](https://jestjs.io/docs/upgrading-to-jest30).
4
+
5
+ #### Examples
6
+
7
+ ##### Before
8
+
9
+ ```text title="apps/myapp/src/__snapshots__/example.spec.ts.snap"
10
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
11
+
12
+ exports[`renders correctly 1`] = `"hello"`;
13
+ ```
14
+
15
+ ##### After
16
+
17
+ ```text title="apps/myapp/src/__snapshots__/example.spec.ts.snap"
18
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
19
+
20
+ exports[`renders correctly 1`] = `"hello"`;
21
+ ```
@@ -25,4 +25,3 @@ export interface JestPluginOptions {
25
25
  }
26
26
  export declare const createNodes: CreateNodesV2<JestPluginOptions>;
27
27
  export declare const createNodesV2: CreateNodesV2<JestPluginOptions>;
28
- //# sourceMappingURL=plugin.d.ts.map
@@ -1,10 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createNodesV2 = exports.createNodes = void 0;
4
+ const internal_1 = require("@nx/devkit/internal");
4
5
  const devkit_1 = require("@nx/devkit");
5
- const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
6
- const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
7
- const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
8
6
  const minimatch_1 = require("minimatch");
9
7
  const node_fs_1 = require("node:fs");
10
8
  const node_path_1 = require("node:path");
@@ -16,24 +14,16 @@ const installation_directory_1 = require("nx/src/utils/installation-directory");
16
14
  const plugins_1 = require("nx/src/utils/plugins");
17
15
  const workspace_context_1 = require("nx/src/utils/workspace-context");
18
16
  const js_1 = require("@nx/js");
19
- const internal_1 = require("@nx/js/src/internal");
17
+ const internal_2 = require("@nx/js/internal");
20
18
  const versions_1 = require("../utils/versions");
21
19
  const REPORTER_BUILTINS = new Set(['default', 'github-actions', 'summary']);
22
- function readTargetsCache(cachePath) {
23
- return process.env.NX_CACHE_PROJECT_GRAPH !== 'false' && (0, node_fs_1.existsSync)(cachePath)
24
- ? (0, devkit_1.readJsonFile)(cachePath)
25
- : {};
26
- }
27
- function writeTargetsToCache(cachePath, results) {
28
- (0, devkit_1.writeJsonFile)(cachePath, results);
29
- }
30
20
  const jestConfigGlob = '**/jest.config.{cjs,mjs,js,cts,mts,ts}';
31
21
  exports.createNodes = [
32
22
  jestConfigGlob,
33
23
  async (configFiles, options, context) => {
34
24
  const optionsHash = (0, devkit_internals_1.hashObject)(options);
35
25
  const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `jest-${optionsHash}.hash`);
36
- const targetsCache = readTargetsCache(cachePath);
26
+ const targetsCache = new internal_1.PluginCache(cachePath);
37
27
  // Cache jest preset(s) to avoid penalties of module load times. Most of jest configs will use the same preset.
38
28
  const presetCache = {};
39
29
  // Cache tsconfig reads + isolatedModules resolution. Many projects share
@@ -70,10 +60,10 @@ exports.createNodes = [
70
60
  const projectRoot = projectRoots[i];
71
61
  const absConfigFilePath = (0, node_path_1.resolve)(context.workspaceRoot, configFilePath);
72
62
  if (!requireCacheCleared && require.cache[absConfigFilePath]) {
73
- (0, config_utils_1.clearRequireCache)();
63
+ (0, internal_1.clearRequireCache)();
74
64
  requireCacheCleared = true;
75
65
  }
76
- const rawConfig = await (0, config_utils_1.loadConfigFile)(absConfigFilePath, [
66
+ const rawConfig = await (0, internal_1.loadConfigFile)(absConfigFilePath, [
77
67
  'tsconfig.spec.json',
78
68
  'tsconfig.test.json',
79
69
  'tsconfig.jest.json',
@@ -87,7 +77,7 @@ exports.createNodes = [
87
77
  });
88
78
  return { rawConfig, externalFiles, needsDtsInputs };
89
79
  }));
90
- const hashes = await (0, calculate_hash_for_create_nodes_1.calculateHashesForCreateNodes)(projectRoots, options, context, loadedConfigs.map(({ externalFiles }) => [
80
+ const hashes = await (0, internal_1.calculateHashesForCreateNodes)(projectRoots, options, context, loadedConfigs.map(({ externalFiles }) => [
91
81
  lockFilePattern,
92
82
  ...externalFiles,
93
83
  ]));
@@ -96,8 +86,10 @@ exports.createNodes = [
96
86
  const projectRoot = projectRoots[idx];
97
87
  const hash = hashes[idx];
98
88
  const { rawConfig, needsDtsInputs } = loadedConfigs[idx];
99
- targetsCache[hash] ??= await buildJestTargets(rawConfig, needsDtsInputs, configFilePath, projectRoot, options, context, presetCache, pmc);
100
- const { targets, metadata } = targetsCache[hash];
89
+ if (!targetsCache.has(hash)) {
90
+ targetsCache.set(hash, await buildJestTargets(rawConfig, needsDtsInputs, configFilePath, projectRoot, options, context, presetCache, pmc));
91
+ }
92
+ const { targets, metadata } = targetsCache.get(hash);
101
93
  return {
102
94
  projects: {
103
95
  [projectRoot]: {
@@ -110,7 +102,7 @@ exports.createNodes = [
110
102
  }, validConfigFiles, options, context);
111
103
  }
112
104
  finally {
113
- writeTargetsToCache(cachePath, targetsCache);
105
+ targetsCache.writeToDisk();
114
106
  }
115
107
  },
116
108
  ];
@@ -149,7 +141,7 @@ function checkIfConfigFileShouldBeProject(configFilePath, projectRoot, isInPacka
149
141
  async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, projectRoot, options, context, presetCache, pmc) {
150
142
  const absConfigFilePath = (0, node_path_1.resolve)(context.workspaceRoot, configFilePath);
151
143
  const targets = {};
152
- const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
144
+ const namedInputs = (0, internal_1.getNamedInputs)(projectRoot, context);
153
145
  const tsNodeCompilerOptions = JSON.stringify({
154
146
  moduleResolution: 'node10',
155
147
  module: 'commonjs',
@@ -222,7 +214,6 @@ async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, proje
222
214
  const targetName = `${options.ciTargetName}--${relativePath}`;
223
215
  dependsOn.push({
224
216
  target: targetName,
225
- projects: 'self',
226
217
  params: 'forward',
227
218
  options: 'forward',
228
219
  });
@@ -303,7 +294,10 @@ async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, proje
303
294
  ? await source.getTestPaths(config.globalConfig, config.projectConfig)
304
295
  : // @ts-expect-error Jest v29 doesn't have the projectConfig parameter
305
296
  await source.getTestPaths(config.globalConfig);
306
- const testPaths = new Set(specs.tests.map(({ path }) => path));
297
+ // Sort to keep atomized target name insertion order stable.
298
+ // jest.SearchSource.getTestPaths walks via jest-haste-map's
299
+ // parallel workers, so its output order isn't guaranteed.
300
+ const testPaths = new Set(specs.tests.map(({ path }) => path).sort());
307
301
  if (testPaths.size > 0) {
308
302
  const targetGroup = [];
309
303
  metadata = {
@@ -326,7 +320,6 @@ async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, proje
326
320
  const targetName = `${options.ciTargetName}--${relativePath}`;
327
321
  dependsOn.push({
328
322
  target: targetName,
329
- projects: 'self',
330
323
  params: 'forward',
331
324
  options: 'forward',
332
325
  });
@@ -721,7 +714,7 @@ async function loadPresetConfig(rawConfig, rootDir, presetCache) {
721
714
  }
722
715
  try {
723
716
  if (!presetCache[presetPath]) {
724
- presetCache[presetPath] = (0, config_utils_1.loadConfigFile)(presetPath);
717
+ presetCache[presetPath] = (0, internal_1.loadConfigFile)(presetPath);
725
718
  }
726
719
  return (await presetCache[presetPath]);
727
720
  }
@@ -885,7 +878,7 @@ function resolveIsolatedModules(tsconfigPath, jsonCache, resultCache) {
885
878
  return cached;
886
879
  let value;
887
880
  const visitedFiles = new Set();
888
- (0, internal_1.walkTsconfigExtendsChain)(tsconfigPath, (absPath, rawJson) => {
881
+ (0, internal_2.walkTsconfigExtendsChain)(tsconfigPath, (absPath, rawJson) => {
889
882
  visitedFiles.add(absPath);
890
883
  const opts = rawJson?.compilerOptions;
891
884
  if (opts?.isolatedModules !== undefined) {
@@ -7,4 +7,3 @@ export declare const TEST_FILE_PATTERN: RegExp;
7
7
  */
8
8
  export declare const TS_QUERY_JEST_CONFIG_PREFIX = ":matches(ExportAssignment, BinaryExpression:has(Identifier[name=\"module\"]):has(Identifier[name=\"exports\"]))";
9
9
  export declare function addTransformerToConfig(configContents: string, transformer: string): string;
10
- //# sourceMappingURL=ast-utils.d.ts.map
@@ -7,4 +7,3 @@ export declare function getPresetExt(tree: Tree): JestPresetExtension;
7
7
  export declare function findRootJestConfig(tree: Tree): string | null;
8
8
  export declare function findJestConfig(tree: Tree, projectPath: string): string | null;
9
9
  export declare function findRootJestPreset(tree: Tree): string | null;
10
- //# sourceMappingURL=config-file.d.ts.map
@@ -15,4 +15,3 @@ export declare function jestConfigObjectAst(fileContent: string): ts.ObjectLiter
15
15
  export declare function jestConfigObject(host: Tree, path: string): Partial<Config.InitialOptions> & {
16
16
  [index: string]: any;
17
17
  };
18
- //# sourceMappingURL=functions.d.ts.map
@@ -7,14 +7,14 @@ exports.jestConfigObject = jestConfigObject;
7
7
  const devkit_1 = require("@nx/devkit");
8
8
  const vm_1 = require("vm");
9
9
  const path_1 = require("path");
10
- const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
10
+ const internal_1 = require("@nx/js/internal");
11
11
  let tsModule;
12
12
  function makeTextToInsert(value, precedingCommaNeeded) {
13
13
  return `${precedingCommaNeeded ? ',' : ''}${value}`;
14
14
  }
15
15
  function findPropertyAssignment(object, propertyName) {
16
16
  if (!tsModule) {
17
- tsModule = (0, ensure_typescript_1.ensureTypescript)();
17
+ tsModule = (0, internal_1.ensureTypescript)();
18
18
  }
19
19
  return object.properties.find((prop) => {
20
20
  if (!tsModule.isPropertyAssignment(prop)) {
@@ -29,7 +29,7 @@ function findPropertyAssignment(object, propertyName) {
29
29
  }
30
30
  function addOrUpdateProperty(tree, object, properties, value, path) {
31
31
  if (!tsModule) {
32
- tsModule = (0, ensure_typescript_1.ensureTypescript)();
32
+ tsModule = (0, internal_1.ensureTypescript)();
33
33
  }
34
34
  const { SyntaxKind } = tsModule;
35
35
  const propertyName = properties.shift();
@@ -109,7 +109,7 @@ function addOrUpdateProperty(tree, object, properties, value, path) {
109
109
  }
110
110
  function removeProperty(object, properties) {
111
111
  if (!tsModule) {
112
- tsModule = (0, ensure_typescript_1.ensureTypescript)();
112
+ tsModule = (0, internal_1.ensureTypescript)();
113
113
  }
114
114
  const propertyName = properties.shift();
115
115
  const propertyAssignment = findPropertyAssignment(object, propertyName);
@@ -127,7 +127,7 @@ function removeProperty(object, properties) {
127
127
  }
128
128
  function isModuleExport(node) {
129
129
  if (!tsModule) {
130
- tsModule = (0, ensure_typescript_1.ensureTypescript)();
130
+ tsModule = (0, internal_1.ensureTypescript)();
131
131
  }
132
132
  return (tsModule.isExpressionStatement(node) &&
133
133
  node.expression?.kind &&
@@ -137,7 +137,7 @@ function isModuleExport(node) {
137
137
  }
138
138
  function isDefaultExport(node) {
139
139
  if (!tsModule) {
140
- tsModule = (0, ensure_typescript_1.ensureTypescript)();
140
+ tsModule = (0, internal_1.ensureTypescript)();
141
141
  }
142
142
  return (tsModule.isExportAssignment(node) &&
143
143
  node.expression?.kind &&
@@ -149,7 +149,7 @@ function isDefaultExport(node) {
149
149
  */
150
150
  function jestConfigObjectAst(fileContent) {
151
151
  if (!tsModule) {
152
- tsModule = (0, ensure_typescript_1.ensureTypescript)();
152
+ tsModule = (0, internal_1.ensureTypescript)();
153
153
  }
154
154
  const sourceFile = tsModule.createSourceFile('jest.config.ts', fileContent, tsModule.ScriptTarget.Latest, true);
155
155
  const exportStatement = sourceFile.statements.find((statement) => isModuleExport(statement) || isDefaultExport(statement));
@@ -12,4 +12,3 @@
12
12
  *
13
13
  **/
14
14
  export declare function getJestProjectsAsync(): Promise<string[]>;
15
- //# sourceMappingURL=get-jest-projects.d.ts.map
@@ -4,7 +4,7 @@ exports.getJestProjectsAsync = getJestProjectsAsync;
4
4
  const tslib_1 = require("tslib");
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const path_1 = require("path");
7
- const yargs = tslib_1.__importStar(require("yargs-parser"));
7
+ const yargs_parser_1 = tslib_1.__importDefault(require("yargs-parser"));
8
8
  function getJestConfigProjectPath(projectJestConfigPath) {
9
9
  return (0, path_1.join)('<rootDir>', projectJestConfigPath);
10
10
  }
@@ -98,7 +98,7 @@ function collectJestConfigFromCommand(command, cwd, jestConfigurations) {
98
98
  return;
99
99
  }
100
100
  for (const match of matches) {
101
- const parsed = yargs(match, {
101
+ const parsed = (0, yargs_parser_1.default)(match, {
102
102
  configuration: { 'strip-dashed': true },
103
103
  string: ['config'],
104
104
  });
@@ -18,4 +18,3 @@ export declare function addPropertyToJestConfig(host: Tree, path: string, proper
18
18
  */
19
19
  export declare function removePropertyFromJestConfig(host: Tree, path: string, propertyName: string | string[]): void;
20
20
  export declare function addImportStatementToJestConfig(host: Tree, path: string, importStatement: string): void;
21
- //# sourceMappingURL=update-config.d.ts.map
@@ -0,0 +1,3 @@
1
+ export declare const JEST_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/jest:jest` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/jest:convert-to-inferred` to migrate to the `@nx/jest/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
2
+ export declare function warnJestExecutorDeprecation(): void;
3
+ export declare function warnJestExecutorGenerating(): void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JEST_EXECUTOR_DEPRECATION_MESSAGE = void 0;
4
+ exports.warnJestExecutorDeprecation = warnJestExecutorDeprecation;
5
+ exports.warnJestExecutorGenerating = warnJestExecutorGenerating;
6
+ const devkit_1 = require("@nx/devkit");
7
+ // TODO(v24): Remove the @nx/jest:jest executor. The inferred plugin
8
+ // (@nx/jest/plugin) and the convert-to-inferred generator stay supported.
9
+ exports.JEST_EXECUTOR_DEPRECATION_MESSAGE = 'The `@nx/jest:jest` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/jest:convert-to-inferred` to migrate to the `@nx/jest/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.';
10
+ function warnJestExecutorDeprecation() {
11
+ devkit_1.logger.warn(exports.JEST_EXECUTOR_DEPRECATION_MESSAGE);
12
+ }
13
+ function warnJestExecutorGenerating() {
14
+ devkit_1.logger.warn('Generating a target that uses the deprecated `@nx/jest:jest` executor. The executor will be removed in Nx v24. Run `nx g @nx/jest:convert-to-inferred` next to migrate this target to the `@nx/jest/plugin` inferred plugin and prevent future generators from emitting executor targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.');
15
+ }
@@ -1,3 +1,2 @@
1
1
  export declare function getInstalledJestVersion(): string | null;
2
2
  export declare function getInstalledJestMajorVersion(): number | null;
3
- //# sourceMappingURL=version-utils.d.ts.map