@nx/devkit 23.0.0-beta.6 → 23.0.0-beta.7

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.
@@ -61,7 +61,19 @@ exports.DEVKIT_INTERNAL_SYMBOLS = new Set([
61
61
  'classify',
62
62
  'dasherize',
63
63
  ]);
64
- const FALLBACK_RE = /(['"])@nx\/devkit\/src\/[^'"\n]+?\1/g;
64
+ // Methods on `jest` and `vi` that take a module specifier as their first
65
+ // argument. Calls like `jest.mock('@nx/devkit/src/...')` are rewritten so the
66
+ // mock target lines up with the rewritten import.
67
+ const MOCK_HELPER_METHODS = new Set([
68
+ 'mock',
69
+ 'unmock',
70
+ 'doMock',
71
+ 'dontMock',
72
+ 'requireActual',
73
+ 'requireMock',
74
+ 'importActual',
75
+ 'importMock',
76
+ ]);
65
77
  let ts;
66
78
  async function updateDevkitDeepImports(tree) {
67
79
  let touchedCount = 0;
@@ -107,13 +119,14 @@ function rewriteDevkitDeepImports(source) {
107
119
  text: replacement,
108
120
  });
109
121
  }
122
+ // Pass 2: rewrite `require('@nx/devkit/src/...')`, dynamic
123
+ // `import('@nx/devkit/src/...')`, and `jest.mock(...)` / `vi.mock(...)`-style
124
+ // calls. We can't bucket these by symbol (no named binding to inspect), so
125
+ // we route them at `/internal` as a best guess. Walking the AST instead of
126
+ // string-replacing keeps us out of unrelated string literals — template
127
+ // strings, `typeof import('...')` type queries, comments, etc.
128
+ collectCallExpressionRewrites(sourceFile, changes);
110
129
  let updated = changes.length > 0 ? (0, string_change_1.applyChangesToString)(source, changes) : source;
111
- // Fallback: any remaining `@nx/devkit/src/...` specifiers (default imports,
112
- // namespace imports, side-effect imports, dynamic `import(...)`, `require(...)`
113
- // calls, etc.) get rewritten to `/internal`. We can't bucket by symbol for
114
- // those forms, so `/internal` is the safe default since it re-exports every
115
- // symbol that was deep-importable.
116
- updated = updated.replace(FALLBACK_RE, (_match, quote) => `${quote}${INTERNAL_SPECIFIER}${quote}`);
117
130
  // Final pass: collapse any duplicate `@nx/devkit` and `@nx/devkit/internal`
118
131
  // named-only imports into a single declaration. This handles both the
119
132
  // imports we just emitted AND any that the user already had, so we never
@@ -259,3 +272,50 @@ function renderImport(specifiers, from, typeOnly) {
259
272
  function source(decl, sourceFile) {
260
273
  return sourceFile.text.slice(decl.getStart(sourceFile), decl.getEnd());
261
274
  }
275
+ function collectCallExpressionRewrites(sourceFile, changes) {
276
+ const visit = (node) => {
277
+ if (ts.isCallExpression(node) &&
278
+ shouldRewriteCallExpression(node) &&
279
+ node.arguments.length >= 1 &&
280
+ ts.isStringLiteral(node.arguments[0]) &&
281
+ node.arguments[0].text.startsWith(DEEP_IMPORT_PREFIX)) {
282
+ const arg = node.arguments[0];
283
+ const start = arg.getStart(sourceFile);
284
+ const end = arg.getEnd();
285
+ const quote = sourceFile.text.charAt(start);
286
+ changes.push({
287
+ type: string_change_1.ChangeType.Delete,
288
+ start,
289
+ length: end - start,
290
+ }, {
291
+ type: string_change_1.ChangeType.Insert,
292
+ index: start,
293
+ text: `${quote}${INTERNAL_SPECIFIER}${quote}`,
294
+ });
295
+ }
296
+ ts.forEachChild(node, visit);
297
+ };
298
+ visit(sourceFile);
299
+ }
300
+ function shouldRewriteCallExpression(call) {
301
+ const callee = call.expression;
302
+ // `require('...')`
303
+ if (ts.isIdentifier(callee) && callee.text === 'require')
304
+ return true;
305
+ // dynamic `import('...')` — the runtime form parses as a CallExpression
306
+ // whose callee is the `import` keyword. The type-position form
307
+ // (`typeof import('...')`) parses as `ImportTypeNode`, not a CallExpression,
308
+ // so we don't touch it.
309
+ if (callee.kind === ts.SyntaxKind.ImportKeyword)
310
+ return true;
311
+ // `jest.mock(...)` / `vi.mock(...)` and friends.
312
+ if (ts.isPropertyAccessExpression(callee)) {
313
+ const obj = callee.expression;
314
+ if (ts.isIdentifier(obj) &&
315
+ (obj.text === 'jest' || obj.text === 'vi') &&
316
+ MOCK_HELPER_METHODS.has(callee.name.text)) {
317
+ return true;
318
+ }
319
+ }
320
+ return false;
321
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/devkit",
3
- "version": "23.0.0-beta.6",
3
+ "version": "23.0.0-beta.7",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -60,7 +60,7 @@
60
60
  },
61
61
  "devDependencies": {
62
62
  "jest": "^30.0.2",
63
- "nx": "23.0.0-beta.6"
63
+ "nx": "23.0.0-beta.7"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "nx": ">= 22 <= 24 || ^23.0.0-0"