@nx/js 23.2.0-beta.1 → 23.2.0-beta.11

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 (85) hide show
  1. package/README.md +2 -2
  2. package/dist/internal.d.ts +9 -3
  3. package/dist/internal.js +28 -17
  4. package/dist/src/executors/copy-workspace-modules/copy-workspace-modules.js +122 -21
  5. package/dist/src/executors/node/lib/output-file.js +4 -4
  6. package/dist/src/executors/node/node.impl.js +9 -10
  7. package/dist/src/executors/prune-lockfile/prune-lockfile.d.ts +1 -1
  8. package/dist/src/executors/prune-lockfile/prune-lockfile.js +40 -33
  9. package/dist/src/executors/tsc/lib/batch/watch.js +3 -3
  10. package/dist/src/executors/tsc/lib/typescript-compilation.js +1 -1
  11. package/dist/src/executors/tsc/tsc.batch-impl.d.ts +1 -1
  12. package/dist/src/executors/tsc/tsc.batch-impl.js +2 -2
  13. package/dist/src/executors/verdaccio/verdaccio.impl.js +8 -1
  14. package/dist/src/generators/init/init.js +32 -15
  15. package/dist/src/generators/init/schema.d.ts +1 -1
  16. package/dist/src/generators/init/schema.json +1 -1
  17. package/dist/src/generators/library/library.d.ts +1 -1
  18. package/dist/src/generators/library/library.js +34 -20
  19. package/dist/src/generators/library/schema.d.ts +12 -5
  20. package/dist/src/generators/library/schema.json +15 -4
  21. package/dist/src/generators/library/utils/add-release-config.js +2 -2
  22. package/dist/src/generators/setup-build/generator.js +2 -7
  23. package/dist/src/generators/typescript-sync/typescript-sync.d.ts +1 -1
  24. package/dist/src/generators/typescript-sync/typescript-sync.js +2 -2
  25. package/dist/src/index.d.ts +3 -2
  26. package/dist/src/index.js +8 -8
  27. package/dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6.d.ts +3 -2
  28. package/dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6.js +17 -11
  29. package/dist/src/migrations/update-23-2-0/add-pnpm-deploy-output-cache-inputs.d.ts +14 -0
  30. package/dist/src/migrations/update-23-2-0/add-pnpm-deploy-output-cache-inputs.js +242 -0
  31. package/dist/src/migrations/update-23-2-0/add-pnpm-deploy-output-cache-inputs.md +64 -0
  32. package/dist/src/migrations/update-23-2-0/add-pnpm-prune-lockfile-cache-config.d.ts +2 -0
  33. package/dist/src/migrations/update-23-2-0/add-pnpm-prune-lockfile-cache-config.js +305 -0
  34. package/dist/src/migrations/update-23-2-0/add-pnpm-prune-lockfile-cache-config.md +59 -0
  35. package/dist/src/plugins/typescript/plugin.js +9 -14
  36. package/dist/src/plugins/typescript/util.d.ts +1 -1
  37. package/dist/src/release/utils/update-lock-file.js +47 -8
  38. package/dist/src/release/version-actions.d.ts +12 -3
  39. package/dist/src/release/version-actions.js +236 -76
  40. package/dist/src/utils/add-linting-to-project.d.ts +46 -0
  41. package/dist/src/utils/add-linting-to-project.js +112 -0
  42. package/dist/src/utils/assets/copy-assets-handler.d.ts +1 -1
  43. package/dist/src/utils/assets/copy-assets-handler.js +2 -2
  44. package/dist/src/utils/buildable-libs-utils.js +10 -13
  45. package/dist/src/utils/find-npm-dependencies.js +7 -10
  46. package/dist/src/utils/formatter-setup.d.ts +26 -0
  47. package/dist/src/utils/formatter-setup.js +43 -0
  48. package/dist/src/utils/generate-globs.js +11 -14
  49. package/dist/src/utils/generator-prompts.d.ts +2 -1
  50. package/dist/src/utils/generator-prompts.js +23 -22
  51. package/dist/src/utils/get-main-file-dir.js +2 -2
  52. package/dist/src/utils/linter.d.ts +30 -0
  53. package/dist/src/utils/linter.js +43 -0
  54. package/dist/src/utils/npm-config.d.ts +1 -1
  55. package/dist/src/utils/nx-formatter-internals.d.ts +8 -0
  56. package/dist/src/utils/nx-formatter-internals.js +18 -0
  57. package/dist/src/utils/oxfmt.d.ts +4 -0
  58. package/dist/src/utils/oxfmt.js +35 -0
  59. package/dist/src/utils/package-json/update-package-json.d.ts +1 -1
  60. package/dist/src/utils/package-json/update-package-json.js +11 -22
  61. package/dist/src/utils/package-manager-workspaces.js +2 -2
  62. package/dist/src/utils/pnpm-deploy-output-cache-inputs.d.ts +29 -0
  63. package/dist/src/utils/pnpm-deploy-output-cache-inputs.js +177 -0
  64. package/dist/src/utils/pnpm-install-settings-inputs.d.ts +45 -0
  65. package/dist/src/utils/pnpm-install-settings-inputs.js +77 -0
  66. package/dist/src/utils/prettier.js +14 -33
  67. package/dist/src/utils/schema.d.ts +1 -2
  68. package/dist/src/utils/target-defaults-matching.d.ts +57 -0
  69. package/dist/src/utils/target-defaults-matching.js +126 -0
  70. package/dist/src/utils/typescript/configuration.js +3 -5
  71. package/dist/src/utils/typescript/create-ts-config.d.ts +1 -1
  72. package/dist/src/utils/typescript/create-ts-config.js +5 -5
  73. package/dist/src/utils/typescript/plugin.js +2 -2
  74. package/dist/src/utils/typescript/run-type-check.js +2 -2
  75. package/dist/src/utils/typescript/ts-config.d.ts +51 -1
  76. package/dist/src/utils/typescript/ts-config.js +114 -0
  77. package/dist/src/utils/typescript/ts-solution-setup.d.ts +1 -1
  78. package/dist/src/utils/typescript/ts-solution-setup.js +3 -3
  79. package/dist/src/utils/versions.d.ts +1 -0
  80. package/dist/src/utils/versions.js +2 -1
  81. package/dist/src/utils/watch-for-single-file-changes.js +2 -2
  82. package/dist/src/utils/workspace-module-sections.d.ts +16 -0
  83. package/dist/src/utils/workspace-module-sections.js +24 -0
  84. package/migrations.json +13 -1
  85. package/package.json +12 -5
@@ -0,0 +1,29 @@
1
+ import type { TargetDefaults } from '@nx/devkit';
2
+ import { type MatchedTargetRef } from './target-defaults-matching';
3
+ /**
4
+ * Adds the missing `PNPM_INSTALL_SETTINGS_INPUTS` to the layer whose `inputs`
5
+ * array the runtime actually uses for this target: the target's own `inputs`
6
+ * when it declares them (its array replaces the defaults' rather than merging
7
+ * with it), otherwise the matching `targetDefaults` entry supplying the array
8
+ * it inherits, and otherwise the target itself with nx's own default spelled
9
+ * out first, so nothing that was hashed stops being hashed. Sources the
10
+ * effective inputs already hash, including via a whole-file root package.json
11
+ * fileset or a `json` input covering the settings fields, are left alone; no
12
+ * `'...'` is ever authored. Returns which layer was mutated, or null when
13
+ * nothing was missing.
14
+ */
15
+ export declare function addPnpmDeployOutputCacheInputs(ref: MatchedTargetRef, targetDefaults: TargetDefaults | undefined, executor: string): 'target' | 'defaults' | null;
16
+ /**
17
+ * Variant for a plugin-inferred target, whose generated `inputs` already carry
18
+ * the settings sources (the runtime probe only while the root manifest has no
19
+ * valid pnpm pin): a repair is only needed when an overlay (a project-level
20
+ * target entry, exact or glob key, or a matching `targetDefaults` entry)
21
+ * supplies a replacing `inputs` array that discards them. The repair appends
22
+ * the full set, probe included, because it runs once and the pin can be
23
+ * removed later. The inferred layer is modeled as an array of exactly the
24
+ * settings inputs: enough for the missing check, and it makes an overlay-less
25
+ * target come back as nothing missing, so the fallback that would narrow the
26
+ * plugin's richer array to `DEFAULT_INPUTS` can never be reached: with no
27
+ * replacing supplier there is nothing to mutate.
28
+ */
29
+ export declare function addPnpmDeployOutputCacheInputsToInferredTargetOverlay(ref: MatchedTargetRef, targetDefaults: TargetDefaults | undefined): 'target' | 'defaults' | null;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addPnpmDeployOutputCacheInputs = addPnpmDeployOutputCacheInputs;
4
+ exports.addPnpmDeployOutputCacheInputsToInferredTargetOverlay = addPnpmDeployOutputCacheInputsToInferredTargetOverlay;
5
+ const internal_1 = require("@nx/devkit/internal");
6
+ const pnpm_install_settings_inputs_1 = require("./pnpm-install-settings-inputs");
7
+ const target_defaults_matching_1 = require("./target-defaults-matching");
8
+ const ROOT_MANIFEST = '{workspaceRoot}/package.json';
9
+ const MANIFEST_SETTINGS_FIELDS = new Set(pnpm_install_settings_inputs_1.PNPM_INSTALL_SETTINGS_INPUTS.filter((input) => typeof input !== 'string' && 'json' in input).flatMap((input) => input.fields ?? []));
10
+ /**
11
+ * Adds the missing `PNPM_INSTALL_SETTINGS_INPUTS` to the layer whose `inputs`
12
+ * array the runtime actually uses for this target: the target's own `inputs`
13
+ * when it declares them (its array replaces the defaults' rather than merging
14
+ * with it), otherwise the matching `targetDefaults` entry supplying the array
15
+ * it inherits, and otherwise the target itself with nx's own default spelled
16
+ * out first, so nothing that was hashed stops being hashed. Sources the
17
+ * effective inputs already hash, including via a whole-file root package.json
18
+ * fileset or a `json` input covering the settings fields, are left alone; no
19
+ * `'...'` is ever authored. Returns which layer was mutated, or null when
20
+ * nothing was missing.
21
+ */
22
+ function addPnpmDeployOutputCacheInputs(ref, targetDefaults, executor) {
23
+ const selectedKey = targetDefaults
24
+ ? (0, target_defaults_matching_1.selectDefaultsKey)(ref, targetDefaults, executor)
25
+ : null;
26
+ const entries = (0, target_defaults_matching_1.compatibleDefaultsEntries)(ref, selectedKey, targetDefaults);
27
+ const defaults = entries.length
28
+ ? (0, internal_1.readTargetDefaultsForTarget)(ref.targetName, { [selectedKey]: entries }, ref.matcherExecutor, {
29
+ projectName: ref.projectName,
30
+ projectNode: ref.projectNode,
31
+ sourcePlugin: ref.sourcePlugin,
32
+ })
33
+ : null;
34
+ const effective = (0, internal_1.mergeTargetConfigurations)(ref.target, defaults ?? {});
35
+ const missing = missingSettingsInputs(effective.inputs);
36
+ if (missing.length === 0) {
37
+ return null;
38
+ }
39
+ if (ref.target.inputs !== undefined) {
40
+ appendInputs(ref.target, missing);
41
+ return 'target';
42
+ }
43
+ const supplier = (0, target_defaults_matching_1.lastMatchingInputsSupplier)(ref, selectedKey, entries);
44
+ if (supplier) {
45
+ appendInputs(supplier, missing);
46
+ return 'defaults';
47
+ }
48
+ appendInputs(ref.target, missing);
49
+ return 'target';
50
+ }
51
+ /**
52
+ * Variant for a plugin-inferred target, whose generated `inputs` already carry
53
+ * the settings sources (the runtime probe only while the root manifest has no
54
+ * valid pnpm pin): a repair is only needed when an overlay (a project-level
55
+ * target entry, exact or glob key, or a matching `targetDefaults` entry)
56
+ * supplies a replacing `inputs` array that discards them. The repair appends
57
+ * the full set, probe included, because it runs once and the pin can be
58
+ * removed later. The inferred layer is modeled as an array of exactly the
59
+ * settings inputs: enough for the missing check, and it makes an overlay-less
60
+ * target come back as nothing missing, so the fallback that would narrow the
61
+ * plugin's richer array to `DEFAULT_INPUTS` can never be reached: with no
62
+ * replacing supplier there is nothing to mutate.
63
+ */
64
+ function addPnpmDeployOutputCacheInputsToInferredTargetOverlay(ref, targetDefaults) {
65
+ const selectedKey = targetDefaults
66
+ ? (0, target_defaults_matching_1.selectDefaultsKey)(ref, targetDefaults, ref.matcherExecutor)
67
+ : null;
68
+ const entries = (0, target_defaults_matching_1.compatibleDefaultsEntries)(ref, selectedKey, targetDefaults);
69
+ const defaults = entries.length
70
+ ? (0, internal_1.readTargetDefaultsForTarget)(ref.targetName, { [selectedKey]: entries }, ref.matcherExecutor, {
71
+ projectName: ref.projectName,
72
+ projectNode: ref.projectNode,
73
+ sourcePlugin: ref.sourcePlugin,
74
+ })
75
+ : null;
76
+ const inferredLayer = {
77
+ inputs: [...pnpm_install_settings_inputs_1.PNPM_INSTALL_SETTINGS_INPUTS],
78
+ };
79
+ const effective = (0, internal_1.mergeTargetConfigurations)(ref.target, (0, internal_1.mergeTargetConfigurations)(defaults ?? {}, inferredLayer));
80
+ const missing = missingSettingsInputs(effective.inputs);
81
+ if (missing.length === 0) {
82
+ return null;
83
+ }
84
+ if (ref.target.inputs !== undefined) {
85
+ appendInputs(ref.target, missing);
86
+ return 'target';
87
+ }
88
+ const supplier = (0, target_defaults_matching_1.lastMatchingInputsSupplier)(ref, selectedKey, entries);
89
+ if (supplier) {
90
+ appendInputs(supplier, missing);
91
+ return 'defaults';
92
+ }
93
+ return null;
94
+ }
95
+ /**
96
+ * The settings sources the effective inputs do not hash yet. The manifest
97
+ * counts as covered by a whole-file fileset no negative pattern can cancel,
98
+ * or by an existing `json` input that hashes all the settings fields (`json`
99
+ * inputs are immune to fileset negations); the workspace yaml by its fileset
100
+ * (a negative pattern cancelling that fileset has no input-level counter, so
101
+ * it is left to the author who wrote it); the runtime probe by an identical
102
+ * `runtime` entry.
103
+ */
104
+ function missingSettingsInputs(inputs) {
105
+ const filesets = (0, target_defaults_matching_1.namedFilesets)(inputs);
106
+ const missing = [];
107
+ for (const input of pnpm_install_settings_inputs_1.PNPM_INSTALL_SETTINGS_INPUTS) {
108
+ if (typeof input === 'string') {
109
+ if (!filesets.has(input)) {
110
+ missing.push(input);
111
+ }
112
+ }
113
+ else if ('runtime' in input) {
114
+ if (!(inputs ?? []).some((existing) => typeof existing === 'object' &&
115
+ existing !== null &&
116
+ 'runtime' in existing &&
117
+ existing.runtime === input.runtime)) {
118
+ missing.push(input);
119
+ }
120
+ }
121
+ else if (!(filesets.has(ROOT_MANIFEST) && !negationMayCancel(inputs)) &&
122
+ !(inputs ?? []).some((existing) => typeof existing === 'object' &&
123
+ existing !== null &&
124
+ 'json' in existing &&
125
+ existing.json === ROOT_MANIFEST &&
126
+ [...MANIFEST_SETTINGS_FIELDS].every((field) => jsonInputCoversField(existing, field)))) {
127
+ missing.push(input);
128
+ }
129
+ }
130
+ return missing;
131
+ }
132
+ /**
133
+ * Whether a negative fileset entry could remove the source from the hash. Any
134
+ * workspace-root-scoped negation counts, in the string or `{ fileset }` form:
135
+ * nx's pattern syntax (globs, extglobs) is not re-evaluated here, and an
136
+ * extra input for a source the negation does not actually touch is harmless.
137
+ * Project-relative negations never match a workspace-root file.
138
+ */
139
+ function negationMayCancel(inputs) {
140
+ return (inputs ?? []).some((existing) => {
141
+ const pattern = typeof existing === 'string'
142
+ ? existing
143
+ : typeof existing === 'object' &&
144
+ existing !== null &&
145
+ 'fileset' in existing
146
+ ? existing.fileset
147
+ : undefined;
148
+ return (typeof pattern === 'string' &&
149
+ pattern.startsWith('!') &&
150
+ pattern.includes('{workspaceRoot}'));
151
+ });
152
+ }
153
+ /**
154
+ * Whether an existing `json` input hashes `field`: selected by the allowlist
155
+ * (an entry covers its whole subtree) and not touched by the denylist, which
156
+ * the hasher applies after selection. A denylist entry below the field only
157
+ * removes part of its subtree, but that part is then unhashed, so it
158
+ * disqualifies coverage too.
159
+ */
160
+ function jsonInputCoversField(input, field) {
161
+ const selected = input.fields === undefined ||
162
+ input.fields.some((path) => path === field || field.startsWith(`${path}.`));
163
+ if (!selected) {
164
+ return false;
165
+ }
166
+ return !(input.excludeFields ?? []).some((path) => path === field ||
167
+ field.startsWith(`${path}.`) ||
168
+ path.startsWith(`${field}.`));
169
+ }
170
+ /**
171
+ * Appends to an array that already exists, or writes nx's default as the base
172
+ * when no layer declares one, so the configuration is never narrowed to the
173
+ * settings sources alone.
174
+ */
175
+ function appendInputs(config, missing) {
176
+ config.inputs = [...(config.inputs ?? target_defaults_matching_1.DEFAULT_INPUTS), ...missing];
177
+ }
@@ -0,0 +1,45 @@
1
+ import { type PackageManager } from '@nx/devkit';
2
+ import { type JsonInput } from '@nx/devkit/internal';
3
+ /**
4
+ * Task inputs covering the sources of the pnpm install settings a pruned
5
+ * deploy output carries (build-script approvals, `supportedArchitectures`,
6
+ * `patchedDependencies`). Nothing else in a build target's default hash moves
7
+ * when an approval is revoked, so a target that emits the deploy output must
8
+ * hash these or a cached run replays an output that still grants it. The
9
+ * manifest is narrowed to the fields the output is built from so dependency
10
+ * bumps in the root package.json do not invalidate every build.
11
+ *
12
+ * The pnpm major selects which emitted file carries the settings (pnpm 11+
13
+ * reads them from pnpm-workspace.yaml, pnpm <=10 from the emitted
14
+ * package.json). The manifest's `packageManager` field pins it when it
15
+ * parses to a pnpm version; the runtime probe covers the ambient binary that
16
+ * decides it otherwise, printing only the major so pnpm patch and minor
17
+ * releases do not move the hash, and a sentinel when the binary is missing
18
+ * (the hasher records the probe's output without checking its exit status,
19
+ * so a missing binary does not fail the hash). The full set keeps the probe
20
+ * even under a valid pin: the generator and the migrations write inputs
21
+ * once, and the pin can be removed later. Plugins re-infer on every graph
22
+ * build, so they use {@link pnpmInstallSettingsInputsForInferredTarget} to
23
+ * add the probe only while no valid pin exists.
24
+ *
25
+ * The contents of vendored non-workspace local-path dependencies also ship in
26
+ * the deploy output but are not covered: their set is derived from the
27
+ * lockfile at build time, so no static input list stays correct as
28
+ * dependencies change. Covering them needs content hashing at the graph level
29
+ * (the pnpm parser's directory/link external nodes hash only name and path).
30
+ */
31
+ export declare const PNPM_MAJOR_RUNTIME_INPUT: {
32
+ runtime: string;
33
+ };
34
+ export declare const PNPM_INSTALL_SETTINGS_INPUTS: (string | JsonInput | {
35
+ runtime: string;
36
+ })[];
37
+ export declare function pnpmInstallSettingsInputsForInferredTarget(includePnpmMajorRuntimeInput: boolean): (string | JsonInput | {
38
+ runtime: string;
39
+ })[];
40
+ /**
41
+ * Whether an inferred build target needs the runtime probe: the workspace uses
42
+ * pnpm and the root `packageManager` field does not pin a pnpm version. A
43
+ * missing or unreadable root manifest cannot pin one, so it counts as no pin.
44
+ */
45
+ export declare function shouldIncludePnpmMajorRuntimeInput(packageManager: PackageManager, workspaceRoot: string): boolean;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PNPM_INSTALL_SETTINGS_INPUTS = exports.PNPM_MAJOR_RUNTIME_INPUT = void 0;
4
+ exports.pnpmInstallSettingsInputsForInferredTarget = pnpmInstallSettingsInputsForInferredTarget;
5
+ exports.shouldIncludePnpmMajorRuntimeInput = shouldIncludePnpmMajorRuntimeInput;
6
+ const devkit_1 = require("@nx/devkit");
7
+ const internal_1 = require("@nx/devkit/internal");
8
+ const path_1 = require("path");
9
+ /**
10
+ * Task inputs covering the sources of the pnpm install settings a pruned
11
+ * deploy output carries (build-script approvals, `supportedArchitectures`,
12
+ * `patchedDependencies`). Nothing else in a build target's default hash moves
13
+ * when an approval is revoked, so a target that emits the deploy output must
14
+ * hash these or a cached run replays an output that still grants it. The
15
+ * manifest is narrowed to the fields the output is built from so dependency
16
+ * bumps in the root package.json do not invalidate every build.
17
+ *
18
+ * The pnpm major selects which emitted file carries the settings (pnpm 11+
19
+ * reads them from pnpm-workspace.yaml, pnpm <=10 from the emitted
20
+ * package.json). The manifest's `packageManager` field pins it when it
21
+ * parses to a pnpm version; the runtime probe covers the ambient binary that
22
+ * decides it otherwise, printing only the major so pnpm patch and minor
23
+ * releases do not move the hash, and a sentinel when the binary is missing
24
+ * (the hasher records the probe's output without checking its exit status,
25
+ * so a missing binary does not fail the hash). The full set keeps the probe
26
+ * even under a valid pin: the generator and the migrations write inputs
27
+ * once, and the pin can be removed later. Plugins re-infer on every graph
28
+ * build, so they use {@link pnpmInstallSettingsInputsForInferredTarget} to
29
+ * add the probe only while no valid pin exists.
30
+ *
31
+ * The contents of vendored non-workspace local-path dependencies also ship in
32
+ * the deploy output but are not covered: their set is derived from the
33
+ * lockfile at build time, so no static input list stays correct as
34
+ * dependencies change. Covering them needs content hashing at the graph level
35
+ * (the pnpm parser's directory/link external nodes hash only name and path).
36
+ */
37
+ exports.PNPM_MAJOR_RUNTIME_INPUT = {
38
+ runtime: `node -e "try{console.log('pnpm major '+require('child_process').execSync('pnpm --version',{stdio:['ignore','pipe','ignore']}).toString().trim().split('.')[0])}catch{console.log('pnpm major unavailable')}"`,
39
+ };
40
+ const PNPM_INSTALL_SETTINGS_FILE_INPUTS = [
41
+ '{workspaceRoot}/pnpm-workspace.yaml',
42
+ {
43
+ json: '{workspaceRoot}/package.json',
44
+ fields: [
45
+ 'packageManager',
46
+ 'pnpm.onlyBuiltDependencies',
47
+ 'pnpm.neverBuiltDependencies',
48
+ 'pnpm.allowBuilds',
49
+ 'pnpm.supportedArchitectures',
50
+ 'pnpm.patchedDependencies',
51
+ ],
52
+ },
53
+ ];
54
+ exports.PNPM_INSTALL_SETTINGS_INPUTS = [...PNPM_INSTALL_SETTINGS_FILE_INPUTS, exports.PNPM_MAJOR_RUNTIME_INPUT];
55
+ function pnpmInstallSettingsInputsForInferredTarget(includePnpmMajorRuntimeInput) {
56
+ return includePnpmMajorRuntimeInput
57
+ ? [...PNPM_INSTALL_SETTINGS_FILE_INPUTS, exports.PNPM_MAJOR_RUNTIME_INPUT]
58
+ : [...PNPM_INSTALL_SETTINGS_FILE_INPUTS];
59
+ }
60
+ /**
61
+ * Whether an inferred build target needs the runtime probe: the workspace uses
62
+ * pnpm and the root `packageManager` field does not pin a pnpm version. A
63
+ * missing or unreadable root manifest cannot pin one, so it counts as no pin.
64
+ */
65
+ function shouldIncludePnpmMajorRuntimeInput(packageManager, workspaceRoot) {
66
+ if (packageManager !== 'pnpm') {
67
+ return false;
68
+ }
69
+ let field;
70
+ try {
71
+ field = (0, devkit_1.readJsonFile)((0, path_1.join)(workspaceRoot, 'package.json'))?.packageManager;
72
+ }
73
+ catch {
74
+ field = undefined;
75
+ }
76
+ return ((0, internal_1.parseVersionFromPackageManagerField)('pnpm', typeof field === 'string' ? field : undefined) === null);
77
+ }
@@ -4,6 +4,8 @@ exports.resolveUserExistingPrettierConfig = resolveUserExistingPrettierConfig;
4
4
  exports.generatePrettierSetup = generatePrettierSetup;
5
5
  exports.resolvePrettierConfigPath = resolvePrettierConfigPath;
6
6
  const devkit_1 = require("@nx/devkit");
7
+ const internal_1 = require("@nx/devkit/internal");
8
+ const nx_formatter_internals_1 = require("./nx-formatter-internals");
7
9
  const versions_1 = require("./versions");
8
10
  // Prettier v3 (ESM) exposes its API as named exports; v2 (CJS) exposes it under
9
11
  // `.default` when loaded via `import()`. Return whichever carries the API, or
@@ -44,22 +46,11 @@ async function resolveUserExistingPrettierConfig() {
44
46
  }
45
47
  }
46
48
  function generatePrettierSetup(tree, options) {
47
- // https://prettier.io/docs/en/configuration.html
48
- const prettierrcNameOptions = [
49
- '.prettierrc',
50
- '.prettierrc.json',
51
- '.prettierrc.yml',
52
- '.prettierrc.yaml',
53
- '.prettierrc.json5',
54
- '.prettierrc.js',
55
- '.prettierrc.cjs',
56
- '.prettierrc.mjs',
57
- '.prettierrc.toml',
58
- 'prettier.config.js',
59
- 'prettier.config.cjs',
60
- 'prettier.config.mjs',
61
- ];
62
- if (prettierrcNameOptions.every((name) => !tree.exists(name))) {
49
+ (0, nx_formatter_internals_1.assertNxSupportsFormatters)();
50
+ // Imported rather than copied: detection and setup have to agree on this
51
+ // list, or a workspace whose config format is missing from one side gets a
52
+ // second, redundant `.prettierrc` written beside the one it already has.
53
+ if (internal_1.prettierConfigFiles.every((name) => !tree.exists(name))) {
63
54
  (0, devkit_1.writeJson)(tree, '.prettierrc', { singleQuote: true });
64
55
  }
65
56
  if (!tree.exists('.prettierignore')) {
@@ -68,6 +59,7 @@ function generatePrettierSetup(tree, options) {
68
59
  /coverage
69
60
  /.nx/cache
70
61
  /.nx/workspace-data
62
+ ${(0, internal_1.getLockFileName)((0, devkit_1.detectPackageManager)(tree.root))}
71
63
  `);
72
64
  }
73
65
  if (tree.exists('.vscode/extensions.json')) {
@@ -85,6 +77,7 @@ function generatePrettierSetup(tree, options) {
85
77
  : (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { prettier: versions_1.prettierVersion });
86
78
  }
87
79
  async function resolvePrettierConfigPath(tree) {
80
+ (0, nx_formatter_internals_1.assertNxSupportsFormatters)();
88
81
  const prettier = await importPrettier();
89
82
  if (!prettier) {
90
83
  return null;
@@ -96,23 +89,11 @@ async function resolvePrettierConfigPath(tree) {
96
89
  if (!tree) {
97
90
  return null;
98
91
  }
99
- // if we haven't find a config file in the file system, we try to find it in the virtual tree
100
- // https://prettier.io/docs/en/configuration.html
101
- const prettierrcNameOptions = [
102
- '.prettierrc',
103
- '.prettierrc.json',
104
- '.prettierrc.yml',
105
- '.prettierrc.yaml',
106
- '.prettierrc.json5',
107
- '.prettierrc.js',
108
- '.prettierrc.cjs',
109
- '.prettierrc.mjs',
110
- '.prettierrc.toml',
111
- 'prettier.config.js',
112
- 'prettier.config.cjs',
113
- 'prettier.config.mjs',
114
- ];
115
- const filePath = prettierrcNameOptions.find((file) => tree.exists(file));
92
+ // Same shared list as the setup above, so a config this can't see is one the
93
+ // setup would overwrite. The copy this replaced was missing the `.ts`,
94
+ // `.mts` and `.cts` forms.
95
+ // https://prettier.io/docs/configuration
96
+ const filePath = internal_1.prettierConfigFiles.find((file) => tree.exists(file));
116
97
  if (filePath) {
117
98
  return filePath;
118
99
  }
@@ -47,8 +47,7 @@ export interface SwcCliOptions {
47
47
  stripLeadingPaths: boolean;
48
48
  }
49
49
 
50
- export interface NormalizedSwcExecutorOptions
51
- extends NormalizedExecutorOptions {
50
+ export interface NormalizedSwcExecutorOptions extends NormalizedExecutorOptions {
52
51
  originalProjectRoot: string;
53
52
  swcExclude: string[];
54
53
  skipTypeCheck: boolean;
@@ -0,0 +1,57 @@
1
+ import type { ProjectGraphProjectNode, TargetConfiguration, TargetDefaultArrayEntry, TargetDefaults } from '@nx/devkit';
2
+ export declare const DEFAULT_INPUTS: string[];
3
+ /** Everything the runtime's `targetDefaults` matcher needs to resolve a target. */
4
+ export interface DefaultsMatchContext {
5
+ targetName: string;
6
+ projectName: string;
7
+ projectNode: ProjectGraphProjectNode;
8
+ matcherExecutor: string | undefined;
9
+ sourcePlugin?: string;
10
+ }
11
+ export interface MatchedTargetRef extends DefaultsMatchContext {
12
+ target: TargetConfiguration;
13
+ }
14
+ /**
15
+ * A matched target with the `targetDefaults` key the runtime would resolve for
16
+ * it, carried together so the two cannot fall out of step.
17
+ */
18
+ export interface KeyedTargetRef {
19
+ ref: MatchedTargetRef;
20
+ selectedKey: string | null;
21
+ }
22
+ /**
23
+ * The `targetDefaults` entries under the selected key that survive nx's own
24
+ * per-entry compatibility guard. Graph construction selects the key, then drops
25
+ * each entry whose identity is incompatible with the target's *original* one and
26
+ * keeps the compatible siblings (`createTargetDefaultsResults` in nx's
27
+ * target-defaults). Reading the key unfiltered instead would let a
28
+ * foreign-executor entry contribute outputs the target never gets.
29
+ */
30
+ export declare function compatibleDefaultsEntries(ref: MatchedTargetRef, selectedKey: string | null, targetDefaults: TargetDefaults | undefined): TargetDefaultArrayEntry[];
31
+ /**
32
+ * The last entry under the selected key that both matches the target (the
33
+ * entry's own filter included) and declares `inputs`: the runtime merge makes
34
+ * that entry's array the one the target inherits. A later entry that declares
35
+ * `inputs` behind a filter not matching this target supplies some other
36
+ * target's array, so it cannot be the layer to mutate.
37
+ */
38
+ export declare function lastMatchingInputsSupplier(ref: MatchedTargetRef, selectedKey: string, entries: TargetDefaultArrayEntry[]): TargetDefaultArrayEntry | undefined;
39
+ /** The plain filesets an inputs array names, for a containment check. */
40
+ export declare function namedFilesets(inputs: TargetConfiguration['inputs']): ReadonlySet<string>;
41
+ /**
42
+ * The executor an executor-less target ends up with after its selected
43
+ * defaults key applies. Each matching entry's identity is resolved like the
44
+ * runtime does at merge time: a `command` payload means nx:run-commands, and
45
+ * a later entry's identity replaces an earlier, incompatible one (the reader's
46
+ * merged view keeps the first executor instead, so it cannot be used here).
47
+ */
48
+ export declare function resolveDefaultsExecutor(targetName: string, projectName: string, projectNode: ProjectGraphProjectNode, targetDefaults: TargetDefaults | undefined, executorKeyCandidate?: string): string | undefined;
49
+ /**
50
+ * The `targetDefaults` key nx's runtime would select for this target: keys
51
+ * are tried as the executor key, the exact-name key, then glob keys longest
52
+ * first, and the first whose entries produce a match wins; the rest are
53
+ * shadowed. Resolution per key goes through nx's own reader. Non-matching
54
+ * keys never resolve, so sorting all remaining keys by length stands in for
55
+ * the runtime's glob-only ordering.
56
+ */
57
+ export declare function selectDefaultsKey(ref: DefaultsMatchContext, targetDefaults: TargetDefaults, executorKeyCandidate?: string): string | null;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_INPUTS = void 0;
4
+ exports.compatibleDefaultsEntries = compatibleDefaultsEntries;
5
+ exports.lastMatchingInputsSupplier = lastMatchingInputsSupplier;
6
+ exports.namedFilesets = namedFilesets;
7
+ exports.resolveDefaultsExecutor = resolveDefaultsExecutor;
8
+ exports.selectDefaultsKey = selectDefaultsKey;
9
+ const internal_1 = require("@nx/devkit/internal");
10
+ // what nx hashes for a target that declares no `inputs`
11
+ exports.DEFAULT_INPUTS = ['default', '^default'];
12
+ /**
13
+ * The `targetDefaults` entries under the selected key that survive nx's own
14
+ * per-entry compatibility guard. Graph construction selects the key, then drops
15
+ * each entry whose identity is incompatible with the target's *original* one and
16
+ * keeps the compatible siblings (`createTargetDefaultsResults` in nx's
17
+ * target-defaults). Reading the key unfiltered instead would let a
18
+ * foreign-executor entry contribute outputs the target never gets.
19
+ */
20
+ function compatibleDefaultsEntries(ref, selectedKey, targetDefaults) {
21
+ if (!targetDefaults || selectedKey === null) {
22
+ return [];
23
+ }
24
+ const value = targetDefaults[selectedKey];
25
+ return (Array.isArray(value) ? value : [value]).filter((entry) =>
26
+ // `isCompatibleTarget` against the target's own executor. Falsy rather than
27
+ // nullish, matching `resolveCommandSyntacticSugar` and `isCompatibleTarget`,
28
+ // which read an empty string as no identity at all; an executor-less target
29
+ // has no identity to clash with, so every entry survives, as it does there.
30
+ !ref.matcherExecutor
31
+ ? true
32
+ : !entry.command &&
33
+ (!entry.executor || entry.executor === ref.matcherExecutor));
34
+ }
35
+ /**
36
+ * The last entry under the selected key that both matches the target (the
37
+ * entry's own filter included) and declares `inputs`: the runtime merge makes
38
+ * that entry's array the one the target inherits. A later entry that declares
39
+ * `inputs` behind a filter not matching this target supplies some other
40
+ * target's array, so it cannot be the layer to mutate.
41
+ */
42
+ function lastMatchingInputsSupplier(ref, selectedKey, entries) {
43
+ return [...entries].reverse().find((entry) => entry.inputs !== undefined &&
44
+ (0, internal_1.readTargetDefaultsForTarget)(ref.targetName, { [selectedKey]: [entry] }, ref.matcherExecutor, {
45
+ projectName: ref.projectName,
46
+ projectNode: ref.projectNode,
47
+ sourcePlugin: ref.sourcePlugin,
48
+ }) !== null);
49
+ }
50
+ /** The plain filesets an inputs array names, for a containment check. */
51
+ function namedFilesets(inputs) {
52
+ return new Set((inputs ?? []).filter((input) => typeof input === 'string'));
53
+ }
54
+ /**
55
+ * The executor an executor-less target ends up with after its selected
56
+ * defaults key applies. Each matching entry's identity is resolved like the
57
+ * runtime does at merge time: a `command` payload means nx:run-commands, and
58
+ * a later entry's identity replaces an earlier, incompatible one (the reader's
59
+ * merged view keeps the first executor instead, so it cannot be used here).
60
+ */
61
+ function resolveDefaultsExecutor(targetName, projectName, projectNode, targetDefaults, executorKeyCandidate) {
62
+ if (!targetDefaults) {
63
+ return undefined;
64
+ }
65
+ const ref = {
66
+ targetName,
67
+ projectName,
68
+ projectNode,
69
+ matcherExecutor: undefined,
70
+ };
71
+ const key = selectDefaultsKey(ref, targetDefaults, executorKeyCandidate);
72
+ if (key === null) {
73
+ return undefined;
74
+ }
75
+ // like the runtime merge, a later matching entry's identity (a `command`
76
+ // payload means nx:run-commands) replaces an earlier, incompatible one
77
+ const value = targetDefaults[key];
78
+ let executor;
79
+ for (const entry of Array.isArray(value) ? value : [value]) {
80
+ if ((0, internal_1.readTargetDefaultsForTarget)(targetName, { [key]: [entry] }, undefined, {
81
+ projectName,
82
+ projectNode,
83
+ }) === null) {
84
+ continue;
85
+ }
86
+ const identity = entry.command ? 'nx:run-commands' : entry.executor;
87
+ if (identity) {
88
+ executor = identity;
89
+ }
90
+ }
91
+ return executor;
92
+ }
93
+ /**
94
+ * The `targetDefaults` key nx's runtime would select for this target: keys
95
+ * are tried as the executor key, the exact-name key, then glob keys longest
96
+ * first, and the first whose entries produce a match wins; the rest are
97
+ * shadowed. Resolution per key goes through nx's own reader. Non-matching
98
+ * keys never resolve, so sorting all remaining keys by length stands in for
99
+ * the runtime's glob-only ordering.
100
+ */
101
+ function selectDefaultsKey(ref, targetDefaults, executorKeyCandidate) {
102
+ const resolves = (key) => (0, internal_1.readTargetDefaultsForTarget)(ref.targetName, { [key]: targetDefaults[key] }, ref.matcherExecutor, {
103
+ projectName: ref.projectName,
104
+ projectNode: ref.projectNode,
105
+ sourcePlugin: ref.sourcePlugin,
106
+ }) !== null;
107
+ if (executorKeyCandidate &&
108
+ targetDefaults[executorKeyCandidate] &&
109
+ resolves(executorKeyCandidate)) {
110
+ return executorKeyCandidate;
111
+ }
112
+ if (targetDefaults[ref.targetName] &&
113
+ ref.targetName !== executorKeyCandidate &&
114
+ resolves(ref.targetName)) {
115
+ return ref.targetName;
116
+ }
117
+ const globCandidates = Object.keys(targetDefaults)
118
+ .filter((key) => key !== executorKeyCandidate && key !== ref.targetName)
119
+ .sort((a, b) => b.length - a.length);
120
+ for (const key of globCandidates) {
121
+ if (resolves(key)) {
122
+ return key;
123
+ }
124
+ }
125
+ return null;
126
+ }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getNeededCompilerOptionOverrides = getNeededCompilerOptionOverrides;
4
4
  const path_1 = require("path");
5
5
  const ensure_typescript_1 = require("./ensure-typescript");
6
+ const ts_config_1 = require("./ts-config");
6
7
  const optionEnumTypeMap = {
7
8
  importsNotUsedAsValues: 'ImportsNotUsedAsValues',
8
9
  jsx: 'JsxEmit',
@@ -21,11 +22,8 @@ function getNeededCompilerOptionOverrides(tree, compilerOptions, tsConfigPath) {
21
22
  if (!ts) {
22
23
  ts = (0, ensure_typescript_1.ensureTypescript)();
23
24
  }
24
- const tsSysFromTree = {
25
- ...ts.sys,
26
- readFile: (path) => tree.read(path, 'utf-8'),
27
- };
28
- const parsed = ts.parseJsonConfigFileContent(ts.readConfigFile(tsConfigPath, tsSysFromTree.readFile).config, tsSysFromTree, (0, path_1.dirname)(tsConfigPath));
25
+ const host = (0, ts_config_1.createTreeParseConfigHost)(tree);
26
+ const parsed = ts.parseJsonConfigFileContent(ts.readConfigFile(tsConfigPath, host.readFile).config, host, (0, path_1.dirname)(tsConfigPath));
29
27
  // ModuleKind: { CommonJS: 'commonjs', ... } => ModuleKind: { commonjs: 'CommonJS', ... }
30
28
  const reversedCompilerOptionsEnumValues = {
31
29
  JsxEmit: reverseEnum(ts.server.protocol.JsxEmit),
@@ -1,4 +1,4 @@
1
- import { Tree } from 'nx/src/generators/tree';
1
+ import { Tree } from '@nx/devkit';
2
2
  export declare const tsConfigBaseOptions: {
3
3
  rootDir: string;
4
4
  sourceMap: boolean;