@nx/js 23.0.0 → 23.1.0-beta.0
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.
- package/README.md +1 -2
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +12 -5
- package/dist/src/generators/init/files/non-ts-solution/__fileName__ +2 -1
- package/dist/src/generators/init/init.js +2 -0
- package/dist/src/generators/library/library.js +1 -1
- package/dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6.d.ts +28 -0
- package/dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6.js +195 -0
- package/dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6.md +37 -0
- package/dist/src/utils/is-typescript-version-at-least.d.ts +37 -0
- package/dist/src/utils/is-typescript-version-at-least.js +86 -0
- package/dist/src/utils/typescript/create-ts-config.d.ts +17 -0
- package/dist/src/utils/typescript/create-ts-config.js +11 -0
- package/dist/src/utils/versions.d.ts +3 -3
- package/dist/src/utils/versions.js +3 -3
- package/migrations.json +24 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -7,13 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
<div style="text-align: center;">
|
|
9
9
|
|
|
10
|
-
[](https://circleci.com/gh/nrwl/nx)
|
|
11
10
|
[]()
|
|
12
11
|
[](https://www.npmjs.com/package/nx)
|
|
13
12
|
[]()
|
|
14
13
|
[](http://commitizen.github.io/cz-cli/)
|
|
15
|
-
[](https://gitter.im/nrwl-nx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
16
14
|
[](https://go.nx.dev/community)
|
|
15
|
+
[](https://nx.dev/docs/features/ci-features/sandboxing)
|
|
17
16
|
|
|
18
17
|
</div>
|
|
19
18
|
|
package/dist/internal.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ export { findProjectsNpmDependencies } from 'nx/src/plugins/js/package-json/crea
|
|
|
4
4
|
export { walkTsconfigExtendsChain, type RawTsconfigJsonCache, } from './src/utils/typescript/raw-tsconfig';
|
|
5
5
|
export { isEsmProject } from './src/utils/module-format/is-esm-project';
|
|
6
6
|
export { TS_SOLUTION_SETUP_TSCONFIG_INPUT, addProjectToTsSolutionWorkspace, assertNotUsingTsSolutionSetup, findRuntimeTsConfigName, getDefinedCustomConditionName, getProjectSourceRoot, getProjectType, isUsingTsSolutionSetup, shouldConfigureTsSolutionSetup, updateTsconfigFiles, } from './src/utils/typescript/ts-solution-setup';
|
|
7
|
+
export { getTsConfigBaseOptions } from './src/utils/typescript/create-ts-config';
|
|
7
8
|
export { ensureTypescript } from './src/utils/typescript/ensure-typescript';
|
|
9
|
+
export { getRangeMinimum, getTsConfigModuleResolution, isTypescriptVersionAtLeast, } from './src/utils/is-typescript-version-at-least';
|
|
8
10
|
export { getNeededCompilerOptionOverrides } from './src/utils/typescript/configuration';
|
|
9
11
|
export { compileTypeScript, type TypeScriptCompilationOptions, } from './src/utils/typescript/compilation';
|
|
10
12
|
export { calculateProjectBuildableDependencies, calculateProjectDependencies, computeCompilerOptionsPaths, createTmpTsConfig, type DependentBuildableProjectNode, } from './src/utils/buildable-libs-utils';
|
package/dist/internal.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
// internal consumers and may change without semver protection. Consider it
|
|
6
6
|
// the @nx/js equivalent of `@nx/devkit/internal`.
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.
|
|
9
|
-
exports.typesNodeVersion = exports.tsLibVersion = exports.swcNodeVersion = exports.swcHelpersVersion = exports.swcCoreVersion = exports.swcCliVersion = exports.prettierVersion = void 0;
|
|
8
|
+
exports.addReleaseConfigForNonTsSolution = exports.addLocalRegistryScripts = exports.stripGlobToBaseDir = exports.getImportPath = exports.createGlobPatternsForDependencies = exports.normalizeUnitTestRunnerOption = exports.normalizeLinterOption = exports.isValidPackageJsonBuildConfig = exports.addBuildAndWatchDepsTargets = exports.findNpmDependencies = exports.getProjectPackageManagerWorkspaceStateWarningTask = exports.getProjectPackageManagerWorkspaceState = exports.getNpmScope = exports.sortPackageJsonFields = exports.CopyAssetsHandler = exports.addSwcRegisterDependencies = exports.addSwcDependencies = exports.addSwcTestConfig = exports.addSwcConfig = exports.createTmpTsConfig = exports.computeCompilerOptionsPaths = exports.calculateProjectDependencies = exports.calculateProjectBuildableDependencies = exports.compileTypeScript = exports.getNeededCompilerOptionOverrides = exports.isTypescriptVersionAtLeast = exports.getTsConfigModuleResolution = exports.getRangeMinimum = exports.ensureTypescript = exports.getTsConfigBaseOptions = exports.updateTsconfigFiles = exports.shouldConfigureTsSolutionSetup = exports.isUsingTsSolutionSetup = exports.getProjectType = exports.getProjectSourceRoot = exports.getDefinedCustomConditionName = exports.findRuntimeTsConfigName = exports.assertNotUsingTsSolutionSetup = exports.addProjectToTsSolutionWorkspace = exports.TS_SOLUTION_SETUP_TSCONFIG_INPUT = exports.isEsmProject = exports.walkTsconfigExtendsChain = exports.findProjectsNpmDependencies = exports.isBuiltinModuleImport = exports.TargetProjectLocator = exports.requireWithTsconfigFallback = exports.registerTsConfigPaths = exports.registerTsProject = exports.loadTsFile = exports.forceRegisterEsmLoader = void 0;
|
|
9
|
+
exports.typesNodeVersion = exports.tsLibVersion = exports.swcNodeVersion = exports.swcHelpersVersion = exports.swcCoreVersion = exports.swcCliVersion = exports.prettierVersion = exports.esbuildVersion = exports.nxVersion = exports.releaseTasks = exports.addReleaseConfigForTsSolution = void 0;
|
|
10
10
|
// Re-exports of nx-source internals (need `no-restricted-imports` overrides).
|
|
11
11
|
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
|
12
12
|
var register_1 = require("nx/src/plugins/js/utils/register");
|
|
@@ -41,11 +41,18 @@ Object.defineProperty(exports, "getProjectType", { enumerable: true, get: functi
|
|
|
41
41
|
Object.defineProperty(exports, "isUsingTsSolutionSetup", { enumerable: true, get: function () { return ts_solution_setup_1.isUsingTsSolutionSetup; } });
|
|
42
42
|
Object.defineProperty(exports, "shouldConfigureTsSolutionSetup", { enumerable: true, get: function () { return ts_solution_setup_1.shouldConfigureTsSolutionSetup; } });
|
|
43
43
|
Object.defineProperty(exports, "updateTsconfigFiles", { enumerable: true, get: function () { return ts_solution_setup_1.updateTsconfigFiles; } });
|
|
44
|
-
// TypeScript helpers
|
|
45
|
-
// tsConfigBaseOptions, addTsLibDependencies, resolveModuleByImport
|
|
46
|
-
//
|
|
44
|
+
// TypeScript helpers. resolvePathsBaseUrl, extractTsConfigBase,
|
|
45
|
+
// tsConfigBaseOptions, addTsLibDependencies, and resolveModuleByImport ship via
|
|
46
|
+
// the public @nx/js entry. getTsConfigBaseOptions is public too, but is
|
|
47
|
+
// re-exported here so internal consumers can import it from @nx/js/internal.
|
|
48
|
+
var create_ts_config_1 = require("./src/utils/typescript/create-ts-config");
|
|
49
|
+
Object.defineProperty(exports, "getTsConfigBaseOptions", { enumerable: true, get: function () { return create_ts_config_1.getTsConfigBaseOptions; } });
|
|
47
50
|
var ensure_typescript_1 = require("./src/utils/typescript/ensure-typescript");
|
|
48
51
|
Object.defineProperty(exports, "ensureTypescript", { enumerable: true, get: function () { return ensure_typescript_1.ensureTypescript; } });
|
|
52
|
+
var is_typescript_version_at_least_1 = require("./src/utils/is-typescript-version-at-least");
|
|
53
|
+
Object.defineProperty(exports, "getRangeMinimum", { enumerable: true, get: function () { return is_typescript_version_at_least_1.getRangeMinimum; } });
|
|
54
|
+
Object.defineProperty(exports, "getTsConfigModuleResolution", { enumerable: true, get: function () { return is_typescript_version_at_least_1.getTsConfigModuleResolution; } });
|
|
55
|
+
Object.defineProperty(exports, "isTypescriptVersionAtLeast", { enumerable: true, get: function () { return is_typescript_version_at_least_1.isTypescriptVersionAtLeast; } });
|
|
49
56
|
var configuration_1 = require("./src/utils/typescript/configuration");
|
|
50
57
|
Object.defineProperty(exports, "getNeededCompilerOptionOverrides", { enumerable: true, get: function () { return configuration_1.getNeededCompilerOptionOverrides; } });
|
|
51
58
|
var compilation_1 = require("./src/utils/typescript/compilation");
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"rootDir": ".",
|
|
5
5
|
"sourceMap": true,
|
|
6
6
|
"declaration": false,
|
|
7
|
-
"moduleResolution": "
|
|
7
|
+
"moduleResolution": "<%= moduleResolution %>",
|
|
8
8
|
"emitDecoratorMetadata": true,
|
|
9
9
|
"experimentalDecorators": true,
|
|
10
10
|
"importHelpers": true,
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"lib": ["es2020", "dom"],
|
|
14
14
|
"skipLibCheck": true,
|
|
15
15
|
"skipDefaultLibCheck": true,
|
|
16
|
+
"strict": false,
|
|
16
17
|
"paths": {}
|
|
17
18
|
},
|
|
18
19
|
"exclude": ["node_modules", "tmp"]
|
|
@@ -8,6 +8,7 @@ const path_1 = require("path");
|
|
|
8
8
|
const plugin_1 = require("../../plugins/typescript/plugin");
|
|
9
9
|
const assert_supported_typescript_version_1 = require("../../utils/assert-supported-typescript-version");
|
|
10
10
|
const prettier_1 = require("../../utils/prettier");
|
|
11
|
+
const create_ts_config_1 = require("../../utils/typescript/create-ts-config");
|
|
11
12
|
const ts_config_1 = require("../../utils/typescript/ts-config");
|
|
12
13
|
const ts_solution_setup_1 = require("../../utils/typescript/ts-solution-setup");
|
|
13
14
|
const versions_1 = require("../../utils/versions");
|
|
@@ -70,6 +71,7 @@ async function initGeneratorInternal(tree, schema) {
|
|
|
70
71
|
else {
|
|
71
72
|
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, './files/non-ts-solution'), '.', {
|
|
72
73
|
fileName: schema.tsConfigName ?? 'tsconfig.base.json',
|
|
74
|
+
moduleResolution: (0, create_ts_config_1.getTsConfigBaseOptions)(tree).moduleResolution,
|
|
73
75
|
});
|
|
74
76
|
}
|
|
75
77
|
}
|
|
@@ -771,7 +771,7 @@ function createProjectTsConfigs(tree, options) {
|
|
|
771
771
|
? undefined
|
|
772
772
|
: (0, ts_config_1.getRelativePathToRootTsConfig)(tree, options.projectRoot),
|
|
773
773
|
compilerOptions: {
|
|
774
|
-
...(options.rootProject ? create_ts_config_1.
|
|
774
|
+
...(options.rootProject ? (0, create_ts_config_1.getTsConfigBaseOptions)(tree) : {}),
|
|
775
775
|
...compilerOptionOverrides,
|
|
776
776
|
},
|
|
777
777
|
files: [],
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* Two independent passes over every tsconfig*.json in the workspace:
|
|
4
|
+
*
|
|
5
|
+
* 1. ignoreDeprecations pass - adds `ignoreDeprecations: "6.0"` to any
|
|
6
|
+
* compilerOptions (or ts-node.compilerOptions) block that directly carries a
|
|
7
|
+
* TS6 hard-deprecated option value (moduleResolution node/node10/classic,
|
|
8
|
+
* baseUrl, target es5, esModuleInterop false, outFile, module
|
|
9
|
+
* amd/umd/system/none, alwaysStrict false, allowSyntheticDefaultImports
|
|
10
|
+
* false, downlevelIteration set to any value).
|
|
11
|
+
*
|
|
12
|
+
* 2. default-preserving pass - for every chain root (no "extends" key), pins
|
|
13
|
+
* the TS6 compiler-option defaults that flipped to a stricter value back to
|
|
14
|
+
* their pre-TS6 value, but only when the root does not set them explicitly:
|
|
15
|
+
* - "strict": false - TS6 treats an absent "strict" as true; TS5 as false.
|
|
16
|
+
* - "noUncheckedSideEffectImports": false - TS6 defaults it to true, which
|
|
17
|
+
* turns a bare side-effect import of an asset lacking an ambient
|
|
18
|
+
* declaration (e.g. `import './styles.css'`) into a hard TS2882 error; it
|
|
19
|
+
* is a semantic diagnostic, not a deprecation, so `ignoreDeprecations`
|
|
20
|
+
* cannot silence it.
|
|
21
|
+
* Files with "extends" inherit from their chain root and are left untouched.
|
|
22
|
+
* Pure solution-style containers (root has `"files": []` and no "include")
|
|
23
|
+
* select no source files, so pinning there is noise and they are skipped.
|
|
24
|
+
*
|
|
25
|
+
* Only runs on TS6 workspaces (gated by `requires` in migrations.json), because
|
|
26
|
+
* `ignoreDeprecations: "6.0"` is itself a hard error (TS5103) on TS 5.x.
|
|
27
|
+
*/
|
|
28
|
+
export default function (tree: Tree): Promise<void>;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = default_1;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const jsonc_parser_1 = require("jsonc-parser");
|
|
7
|
+
const FORMATTING_OPTIONS = {
|
|
8
|
+
formattingOptions: { keepLines: true, insertSpaces: true, tabSize: 2 },
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Two independent passes over every tsconfig*.json in the workspace:
|
|
12
|
+
*
|
|
13
|
+
* 1. ignoreDeprecations pass - adds `ignoreDeprecations: "6.0"` to any
|
|
14
|
+
* compilerOptions (or ts-node.compilerOptions) block that directly carries a
|
|
15
|
+
* TS6 hard-deprecated option value (moduleResolution node/node10/classic,
|
|
16
|
+
* baseUrl, target es5, esModuleInterop false, outFile, module
|
|
17
|
+
* amd/umd/system/none, alwaysStrict false, allowSyntheticDefaultImports
|
|
18
|
+
* false, downlevelIteration set to any value).
|
|
19
|
+
*
|
|
20
|
+
* 2. default-preserving pass - for every chain root (no "extends" key), pins
|
|
21
|
+
* the TS6 compiler-option defaults that flipped to a stricter value back to
|
|
22
|
+
* their pre-TS6 value, but only when the root does not set them explicitly:
|
|
23
|
+
* - "strict": false - TS6 treats an absent "strict" as true; TS5 as false.
|
|
24
|
+
* - "noUncheckedSideEffectImports": false - TS6 defaults it to true, which
|
|
25
|
+
* turns a bare side-effect import of an asset lacking an ambient
|
|
26
|
+
* declaration (e.g. `import './styles.css'`) into a hard TS2882 error; it
|
|
27
|
+
* is a semantic diagnostic, not a deprecation, so `ignoreDeprecations`
|
|
28
|
+
* cannot silence it.
|
|
29
|
+
* Files with "extends" inherit from their chain root and are left untouched.
|
|
30
|
+
* Pure solution-style containers (root has `"files": []` and no "include")
|
|
31
|
+
* select no source files, so pinning there is noise and they are skipped.
|
|
32
|
+
*
|
|
33
|
+
* Only runs on TS6 workspaces (gated by `requires` in migrations.json), because
|
|
34
|
+
* `ignoreDeprecations: "6.0"` is itself a hard error (TS5103) on TS 5.x.
|
|
35
|
+
*/
|
|
36
|
+
async function default_1(tree) {
|
|
37
|
+
let deprecationCount = 0;
|
|
38
|
+
let defaultsPinCount = 0;
|
|
39
|
+
(0, devkit_1.visitNotIgnoredFiles)(tree, '.', (filePath) => {
|
|
40
|
+
const name = (0, node_path_1.basename)(filePath);
|
|
41
|
+
if (!name.startsWith('tsconfig') || !name.endsWith('.json')) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (addIgnoreDeprecations(tree, filePath)) {
|
|
45
|
+
deprecationCount += 1;
|
|
46
|
+
}
|
|
47
|
+
if (pinPreTs6Defaults(tree, filePath)) {
|
|
48
|
+
defaultsPinCount += 1;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
if (deprecationCount > 0) {
|
|
52
|
+
devkit_1.logger.info(`Added "ignoreDeprecations": "6.0" to ${deprecationCount} tsconfig file(s) carrying TS6-deprecated options.`);
|
|
53
|
+
}
|
|
54
|
+
if (defaultsPinCount > 0) {
|
|
55
|
+
devkit_1.logger.info(`Pinned pre-TS6 compiler option defaults ("strict", "noUncheckedSideEffectImports") on ${defaultsPinCount} tsconfig chain root(s) to preserve existing behavior.`);
|
|
56
|
+
}
|
|
57
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
58
|
+
}
|
|
59
|
+
function addIgnoreDeprecations(tree, tsconfigPath) {
|
|
60
|
+
const original = tree.read(tsconfigPath, 'utf-8');
|
|
61
|
+
if (!original) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
// Each entry targets a distinct compilerOptions block within the same file.
|
|
65
|
+
const blocks = [
|
|
66
|
+
['compilerOptions'],
|
|
67
|
+
['ts-node', 'compilerOptions'],
|
|
68
|
+
];
|
|
69
|
+
let contents = original;
|
|
70
|
+
let changed = false;
|
|
71
|
+
for (const blockPath of blocks) {
|
|
72
|
+
// Re-parse each iteration: a prior edit shifts offsets in `contents`.
|
|
73
|
+
const root = (0, jsonc_parser_1.parseTree)(contents);
|
|
74
|
+
const blockNode = root && (0, jsonc_parser_1.findNodeAtLocation)(root, blockPath);
|
|
75
|
+
if (!blockNode || blockNode.type !== 'object') {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const compilerOptions = (0, jsonc_parser_1.getNodeValue)(blockNode);
|
|
79
|
+
if (!hasDeprecatedValue(compilerOptions)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// An existing non-"6.0" value (e.g. "5.0") does NOT silence 6.0-class
|
|
83
|
+
// deprecations, so upgrade it; only "6.0" is already correct.
|
|
84
|
+
if (compilerOptions.ignoreDeprecations === '6.0') {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const edits = (0, jsonc_parser_1.modify)(contents, [...blockPath, 'ignoreDeprecations'], '6.0', FORMATTING_OPTIONS);
|
|
88
|
+
contents = (0, jsonc_parser_1.applyEdits)(contents, edits);
|
|
89
|
+
changed = true;
|
|
90
|
+
}
|
|
91
|
+
if (changed) {
|
|
92
|
+
tree.write(tsconfigPath, contents);
|
|
93
|
+
}
|
|
94
|
+
return changed;
|
|
95
|
+
}
|
|
96
|
+
// Values that compile silently on TS 5.8 but are hard deprecation errors
|
|
97
|
+
// (TS5101/TS5107) on TS 6.0 - derived by differential 5.8-vs-6.0 probing.
|
|
98
|
+
function hasDeprecatedValue(compilerOptions) {
|
|
99
|
+
const moduleResolution = asLowerString(compilerOptions.moduleResolution);
|
|
100
|
+
if (moduleResolution === 'node' ||
|
|
101
|
+
moduleResolution === 'node10' ||
|
|
102
|
+
moduleResolution === 'classic') {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
// `baseUrl`/`outFile` only deprecate when set to a real value; `null`/unset
|
|
106
|
+
// is inert on TS6.
|
|
107
|
+
if (compilerOptions.baseUrl != null) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (asLowerString(compilerOptions.target) === 'es5') {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
if (compilerOptions.esModuleInterop === false) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (compilerOptions.outFile != null) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
const moduleValue = asLowerString(compilerOptions.module);
|
|
120
|
+
if (moduleValue === 'amd' ||
|
|
121
|
+
moduleValue === 'umd' ||
|
|
122
|
+
moduleValue === 'system' ||
|
|
123
|
+
moduleValue === 'none') {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
// Only the explicit `false` value triggers TS5107 for these two flags.
|
|
127
|
+
if (compilerOptions.alwaysStrict === false) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
if (compilerOptions.allowSyntheticDefaultImports === false) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
// A real boolean triggers TS5101; `null`/unset is inert. `!= null` also flags
|
|
134
|
+
// non-boolean JSON, but that only adds a harmless no-op `ignoreDeprecations`.
|
|
135
|
+
if (compilerOptions.downlevelIteration != null) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
// TS6 compiler-option defaults that flipped to a stricter value. We pin each
|
|
141
|
+
// back to its pre-TS6 value on chain roots that don't set it, so existing
|
|
142
|
+
// workspaces keep building without adopting a legit TS6 setup.
|
|
143
|
+
const DEFAULT_PRESERVING_PINS = [
|
|
144
|
+
['strict', false],
|
|
145
|
+
['noUncheckedSideEffectImports', false],
|
|
146
|
+
];
|
|
147
|
+
function pinPreTs6Defaults(tree, tsconfigPath) {
|
|
148
|
+
const original = tree.read(tsconfigPath, 'utf-8');
|
|
149
|
+
if (!original) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
const root = (0, jsonc_parser_1.parseTree)(original);
|
|
153
|
+
if (!root || root.type !== 'object') {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const rootValue = (0, jsonc_parser_1.getNodeValue)(root);
|
|
157
|
+
// Only touch chain roots - files with "extends" inherit from their ancestor.
|
|
158
|
+
if ('extends' in rootValue) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
// Skip pure solution-style containers: root has "files": [] and no "include".
|
|
162
|
+
// They select no source files, so pinning defaults there is noise.
|
|
163
|
+
const filesNode = (0, jsonc_parser_1.findNodeAtLocation)(root, ['files']);
|
|
164
|
+
const hasEmptyFiles = filesNode?.type === 'array' && filesNode.children?.length === 0;
|
|
165
|
+
if (hasEmptyFiles && !('include' in rootValue)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
const compilerOptionsNode = (0, jsonc_parser_1.findNodeAtLocation)(root, ['compilerOptions']);
|
|
169
|
+
// A present-but-non-object compilerOptions can't receive pinned keys; bailing
|
|
170
|
+
// avoids modify() throwing and aborting the whole migration.
|
|
171
|
+
if (compilerOptionsNode && compilerOptionsNode.type !== 'object') {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
const compilerOptions = compilerOptionsNode
|
|
175
|
+
? (0, jsonc_parser_1.getNodeValue)(compilerOptionsNode)
|
|
176
|
+
: {};
|
|
177
|
+
let contents = original;
|
|
178
|
+
let changed = false;
|
|
179
|
+
for (const [key, value] of DEFAULT_PRESERVING_PINS) {
|
|
180
|
+
// An explicit value (true or false) means the user opted in - leave it.
|
|
181
|
+
if (key in compilerOptions) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const edits = (0, jsonc_parser_1.modify)(contents, ['compilerOptions', key], value, FORMATTING_OPTIONS);
|
|
185
|
+
contents = (0, jsonc_parser_1.applyEdits)(contents, edits);
|
|
186
|
+
changed = true;
|
|
187
|
+
}
|
|
188
|
+
if (changed) {
|
|
189
|
+
tree.write(tsconfigPath, contents);
|
|
190
|
+
}
|
|
191
|
+
return changed;
|
|
192
|
+
}
|
|
193
|
+
function asLowerString(value) {
|
|
194
|
+
return typeof value === 'string' ? value.toLowerCase() : undefined;
|
|
195
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#### Keep Existing Workspaces Compiling on TypeScript 6
|
|
2
|
+
|
|
3
|
+
TypeScript 6 turns several long-deprecated compiler options into hard errors and flips a few option defaults to stricter values. So that an existing workspace keeps compiling on TypeScript 6 without being migrated to a full TypeScript 6 setup, this migration makes two edits to the `tsconfig*.json` files in the workspace:
|
|
4
|
+
|
|
5
|
+
- Adds `"ignoreDeprecations": "6.0"` to any `compilerOptions` (or `ts-node.compilerOptions`) block that directly sets a TypeScript 6 deprecated option - for example `moduleResolution` set to `node`/`node10`/`classic`, `baseUrl`, `target` set to `es5`, `esModuleInterop: false`, `outFile`, `module` set to `amd`/`umd`/`system`/`none`, `alwaysStrict: false`, `allowSyntheticDefaultImports: false`, or `downlevelIteration`.
|
|
6
|
+
- Pins `"strict": false` and `"noUncheckedSideEffectImports": false` on every chain-root tsconfig (one without an `extends`) that does not already set them. TypeScript 6 treats an absent `strict` as `true` (it was `false` when unset before) and defaults `noUncheckedSideEffectImports` to `true`, which turns a bare side-effect import such as `import './styles.css'` without an ambient module declaration into an error. Pinning both preserves the pre-TypeScript 6 behavior.
|
|
7
|
+
|
|
8
|
+
Files that use `extends` inherit these settings from their chain root and are left untouched, and pure solution-style tsconfigs (`"files": []` with no `include`) are skipped. The migration only runs when the workspace is on TypeScript 6.
|
|
9
|
+
|
|
10
|
+
#### Sample Code Changes
|
|
11
|
+
|
|
12
|
+
##### Before
|
|
13
|
+
|
|
14
|
+
```json title="tsconfig.json"
|
|
15
|
+
{
|
|
16
|
+
"compilerOptions": {
|
|
17
|
+
"target": "es5",
|
|
18
|
+
"module": "esnext",
|
|
19
|
+
"moduleResolution": "bundler"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
##### After
|
|
25
|
+
|
|
26
|
+
```json title="tsconfig.json" {6-8}
|
|
27
|
+
{
|
|
28
|
+
"compilerOptions": {
|
|
29
|
+
"target": "es5",
|
|
30
|
+
"module": "esnext",
|
|
31
|
+
"moduleResolution": "bundler",
|
|
32
|
+
"ignoreDeprecations": "6.0",
|
|
33
|
+
"strict": false,
|
|
34
|
+
"noUncheckedSideEffectImports": false
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether the workspace's `typescript` is at or above the given version.
|
|
4
|
+
*
|
|
5
|
+
* Resolution order:
|
|
6
|
+
* - When `typescript` is declared and the installed version satisfies that
|
|
7
|
+
* declared range, the installed version decides. This resolves open ranges
|
|
8
|
+
* (e.g. `>=5.8.0`, `^5 || ^6`) to what is actually installed.
|
|
9
|
+
* - Otherwise the declared range's minimum is used (e.g. `^5.9.2` -> `5.9.2`,
|
|
10
|
+
* `<6` -> `0.0.0`). This is the fresh-workspace path (nothing installed yet)
|
|
11
|
+
* and the case where a generator is mid-flight re-pinning `typescript` - the
|
|
12
|
+
* new range no longer satisfies the still-installed version, so intent wins.
|
|
13
|
+
* - When `typescript` is not declared at all, Nx's default install version is
|
|
14
|
+
* assumed; a transitively-hoisted install is ignored as it does not reflect
|
|
15
|
+
* a workspace choice.
|
|
16
|
+
*
|
|
17
|
+
* Dist-tags and unparseable ranges (e.g. `latest`, `next`) have no resolvable
|
|
18
|
+
* floor, so they are treated as meeting any version.
|
|
19
|
+
*
|
|
20
|
+
* Use from generators to emit version-appropriate config when a single value
|
|
21
|
+
* is not valid across the supported TypeScript range.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isTypescriptVersionAtLeast(tree: Tree, version: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The `moduleResolution` to emit in generated tsconfig files, chosen for the
|
|
26
|
+
* workspace's TypeScript version: `bundler` on TS >= 6, `node10` on TS < 6.
|
|
27
|
+
* node-family resolution is a TS5107 deprecation error on TS 6, and `bundler`
|
|
28
|
+
* is invalid in a commonjs setup on TS < 6 (TS5095); `node10` also preserves
|
|
29
|
+
* classic node resolution for pre-TS6 workspaces.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getTsConfigModuleResolution(tree: Tree): 'bundler' | 'node10';
|
|
32
|
+
/**
|
|
33
|
+
* Returns the minimum satisfying version for a semver range, stripping
|
|
34
|
+
* prerelease so `>=6.0.0-beta.1` still counts as 6.0. Falls back to coerce()
|
|
35
|
+
* for dist-tags and garbage inputs that minVersion() cannot parse.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getRangeMinimum(range: string): string | undefined;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isTypescriptVersionAtLeast = isTypescriptVersionAtLeast;
|
|
4
|
+
exports.getTsConfigModuleResolution = getTsConfigModuleResolution;
|
|
5
|
+
exports.getRangeMinimum = getRangeMinimum;
|
|
6
|
+
const devkit_1 = require("@nx/devkit");
|
|
7
|
+
const semver_1 = require("semver");
|
|
8
|
+
const versions_1 = require("./versions");
|
|
9
|
+
/**
|
|
10
|
+
* Checks whether the workspace's `typescript` is at or above the given version.
|
|
11
|
+
*
|
|
12
|
+
* Resolution order:
|
|
13
|
+
* - When `typescript` is declared and the installed version satisfies that
|
|
14
|
+
* declared range, the installed version decides. This resolves open ranges
|
|
15
|
+
* (e.g. `>=5.8.0`, `^5 || ^6`) to what is actually installed.
|
|
16
|
+
* - Otherwise the declared range's minimum is used (e.g. `^5.9.2` -> `5.9.2`,
|
|
17
|
+
* `<6` -> `0.0.0`). This is the fresh-workspace path (nothing installed yet)
|
|
18
|
+
* and the case where a generator is mid-flight re-pinning `typescript` - the
|
|
19
|
+
* new range no longer satisfies the still-installed version, so intent wins.
|
|
20
|
+
* - When `typescript` is not declared at all, Nx's default install version is
|
|
21
|
+
* assumed; a transitively-hoisted install is ignored as it does not reflect
|
|
22
|
+
* a workspace choice.
|
|
23
|
+
*
|
|
24
|
+
* Dist-tags and unparseable ranges (e.g. `latest`, `next`) have no resolvable
|
|
25
|
+
* floor, so they are treated as meeting any version.
|
|
26
|
+
*
|
|
27
|
+
* Use from generators to emit version-appropriate config when a single value
|
|
28
|
+
* is not valid across the supported TypeScript range.
|
|
29
|
+
*/
|
|
30
|
+
function isTypescriptVersionAtLeast(tree, version) {
|
|
31
|
+
const declared = (0, devkit_1.getDependencyVersionFromPackageJson)(tree, 'typescript');
|
|
32
|
+
if (declared) {
|
|
33
|
+
const installed = getInstalledTypescriptVersion(tree);
|
|
34
|
+
if (installed && (0, semver_1.satisfies)(installed, declared)) {
|
|
35
|
+
return (0, semver_1.gte)(installed, version);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const minimum = getRangeMinimum(declared ?? versions_1.typescriptVersion);
|
|
39
|
+
return !minimum || (0, semver_1.gte)(minimum, version);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reads the installed `typescript` version via the tree (not `require`), so it
|
|
43
|
+
* reflects in-flight tree changes and stays controllable in tests. Returns
|
|
44
|
+
* undefined when not resolvable.
|
|
45
|
+
*/
|
|
46
|
+
function getInstalledTypescriptVersion(tree) {
|
|
47
|
+
try {
|
|
48
|
+
const pkgJson = tree.read('node_modules/typescript/package.json', 'utf-8');
|
|
49
|
+
if (!pkgJson) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
// Strip any prerelease (e.g. `6.0.0-rc.1` -> `6.0.0`) so it compares
|
|
53
|
+
// consistently with getRangeMinimum's normalization.
|
|
54
|
+
return (0, semver_1.coerce)(JSON.parse(pkgJson).version)?.version;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The `moduleResolution` to emit in generated tsconfig files, chosen for the
|
|
62
|
+
* workspace's TypeScript version: `bundler` on TS >= 6, `node10` on TS < 6.
|
|
63
|
+
* node-family resolution is a TS5107 deprecation error on TS 6, and `bundler`
|
|
64
|
+
* is invalid in a commonjs setup on TS < 6 (TS5095); `node10` also preserves
|
|
65
|
+
* classic node resolution for pre-TS6 workspaces.
|
|
66
|
+
*/
|
|
67
|
+
function getTsConfigModuleResolution(tree) {
|
|
68
|
+
return isTypescriptVersionAtLeast(tree, '6.0.0') ? 'bundler' : 'node10';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns the minimum satisfying version for a semver range, stripping
|
|
72
|
+
* prerelease so `>=6.0.0-beta.1` still counts as 6.0. Falls back to coerce()
|
|
73
|
+
* for dist-tags and garbage inputs that minVersion() cannot parse.
|
|
74
|
+
*/
|
|
75
|
+
function getRangeMinimum(range) {
|
|
76
|
+
try {
|
|
77
|
+
const min = (0, semver_1.minVersion)(range);
|
|
78
|
+
if (min) {
|
|
79
|
+
return `${min.major}.${min.minor}.${min.patch}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// fall through to coerce for dist-tags and other unparseable inputs
|
|
84
|
+
}
|
|
85
|
+
return (0, semver_1.coerce)(range)?.version;
|
|
86
|
+
}
|
|
@@ -12,6 +12,23 @@ export declare const tsConfigBaseOptions: {
|
|
|
12
12
|
lib: string[];
|
|
13
13
|
skipLibCheck: boolean;
|
|
14
14
|
skipDefaultLibCheck: boolean;
|
|
15
|
+
strict: boolean;
|
|
15
16
|
paths: {};
|
|
16
17
|
};
|
|
18
|
+
export declare function getTsConfigBaseOptions(tree: Tree): {
|
|
19
|
+
rootDir: string;
|
|
20
|
+
sourceMap: boolean;
|
|
21
|
+
declaration: boolean;
|
|
22
|
+
emitDecoratorMetadata: boolean;
|
|
23
|
+
experimentalDecorators: boolean;
|
|
24
|
+
importHelpers: boolean;
|
|
25
|
+
target: string;
|
|
26
|
+
module: string;
|
|
27
|
+
lib: string[];
|
|
28
|
+
skipLibCheck: boolean;
|
|
29
|
+
skipDefaultLibCheck: boolean;
|
|
30
|
+
strict: boolean;
|
|
31
|
+
paths: {};
|
|
32
|
+
moduleResolution: "bundler" | "node10";
|
|
33
|
+
};
|
|
17
34
|
export declare function extractTsConfigBase(host: Tree): void;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.tsConfigBaseOptions = void 0;
|
|
4
|
+
exports.getTsConfigBaseOptions = getTsConfigBaseOptions;
|
|
4
5
|
exports.extractTsConfigBase = extractTsConfigBase;
|
|
5
6
|
const json_1 = require("nx/src/generators/utils/json");
|
|
7
|
+
const is_typescript_version_at_least_1 = require("../is-typescript-version-at-least");
|
|
6
8
|
exports.tsConfigBaseOptions = {
|
|
7
9
|
rootDir: '.',
|
|
8
10
|
sourceMap: true,
|
|
@@ -16,8 +18,17 @@ exports.tsConfigBaseOptions = {
|
|
|
16
18
|
lib: ['es2020', 'dom'],
|
|
17
19
|
skipLibCheck: true,
|
|
18
20
|
skipDefaultLibCheck: true,
|
|
21
|
+
// TS 6.0 flips the `strict` default to true; pin false to keep this base
|
|
22
|
+
// config's behavior identical on TS 5.8 and 6.0.
|
|
23
|
+
strict: false,
|
|
19
24
|
paths: {},
|
|
20
25
|
};
|
|
26
|
+
function getTsConfigBaseOptions(tree) {
|
|
27
|
+
return {
|
|
28
|
+
...exports.tsConfigBaseOptions,
|
|
29
|
+
moduleResolution: (0, is_typescript_version_at_least_1.getTsConfigModuleResolution)(tree),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
21
32
|
function extractTsConfigBase(host) {
|
|
22
33
|
if (host.exists('tsconfig.base.json'))
|
|
23
34
|
return;
|
|
@@ -8,10 +8,10 @@ export declare const swcNodeVersion = "~1.11.1";
|
|
|
8
8
|
export declare const tsLibVersion = "^2.3.0";
|
|
9
9
|
export declare const typesNodeVersion = "^22.0.0";
|
|
10
10
|
export declare const verdaccioVersion = "^6.3.2";
|
|
11
|
-
export declare const typescriptVersion = "~
|
|
11
|
+
export declare const typescriptVersion = "~6.0.3";
|
|
12
12
|
/**
|
|
13
13
|
* The minimum version is currently determined from the lowest version
|
|
14
14
|
* that's supported by the lowest Angular supported version, e.g.
|
|
15
|
-
* `npm view @angular/compiler-cli@
|
|
15
|
+
* `npm view @angular/compiler-cli@20.0.0 peerDependencies.typescript`
|
|
16
16
|
*/
|
|
17
|
-
export declare const minSupportedTypescriptVersion = "5.
|
|
17
|
+
export declare const minSupportedTypescriptVersion = "5.8.0";
|
|
@@ -13,10 +13,10 @@ exports.tsLibVersion = '^2.3.0';
|
|
|
13
13
|
exports.typesNodeVersion = '^22.0.0';
|
|
14
14
|
exports.verdaccioVersion = '^6.3.2';
|
|
15
15
|
// Typescript
|
|
16
|
-
exports.typescriptVersion = '~
|
|
16
|
+
exports.typescriptVersion = '~6.0.3';
|
|
17
17
|
/**
|
|
18
18
|
* The minimum version is currently determined from the lowest version
|
|
19
19
|
* that's supported by the lowest Angular supported version, e.g.
|
|
20
|
-
* `npm view @angular/compiler-cli@
|
|
20
|
+
* `npm view @angular/compiler-cli@20.0.0 peerDependencies.typescript`
|
|
21
21
|
*/
|
|
22
|
-
exports.minSupportedTypescriptVersion = '5.
|
|
22
|
+
exports.minSupportedTypescriptVersion = '5.8.0';
|
package/migrations.json
CHANGED
|
@@ -28,6 +28,15 @@
|
|
|
28
28
|
"description": "Rename imports of `createNodesV2` from `@nx/js/typescript` to the canonical `createNodes` export.",
|
|
29
29
|
"implementation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes",
|
|
30
30
|
"documentation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes.md"
|
|
31
|
+
},
|
|
32
|
+
"23-1-0-add-ignore-deprecations-for-ts6": {
|
|
33
|
+
"version": "23.1.0-beta.0",
|
|
34
|
+
"description": "Adds `\"ignoreDeprecations\": \"6.0\"` to tsconfig files whose compilerOptions (or ts-node.compilerOptions) directly carry a TypeScript 6 deprecated option value (e.g. moduleResolution node/node10/classic, baseUrl, target es5, esModuleInterop false, outFile, module amd/umd/system/none, alwaysStrict false, allowSyntheticDefaultImports false, downlevelIteration set). Also pins `\"strict\": false` and `\"noUncheckedSideEffectImports\": false` in chain-root tsconfigs (no \"extends\") that lack each key, preserving pre-TS6 behavior where their defaults were less strict.",
|
|
35
|
+
"requires": {
|
|
36
|
+
"typescript": ">=6.0.0"
|
|
37
|
+
},
|
|
38
|
+
"factory": "./dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6",
|
|
39
|
+
"documentation": "./dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6.md"
|
|
31
40
|
}
|
|
32
41
|
},
|
|
33
42
|
"packageJsonUpdates": {
|
|
@@ -106,6 +115,21 @@
|
|
|
106
115
|
"alwaysAddToPackageJson": false
|
|
107
116
|
}
|
|
108
117
|
}
|
|
118
|
+
},
|
|
119
|
+
"23.1.0-typescript": {
|
|
120
|
+
"version": "23.1.0-beta.0",
|
|
121
|
+
"incompatibleWith": {
|
|
122
|
+
"@remix-run/dev": "*"
|
|
123
|
+
},
|
|
124
|
+
"requires": {
|
|
125
|
+
"typescript": ">=5.9.0 <6.0.0"
|
|
126
|
+
},
|
|
127
|
+
"packages": {
|
|
128
|
+
"typescript": {
|
|
129
|
+
"version": "~6.0.3",
|
|
130
|
+
"alwaysAddToPackageJson": false
|
|
131
|
+
}
|
|
132
|
+
}
|
|
109
133
|
}
|
|
110
134
|
}
|
|
111
135
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/js",
|
|
3
|
-
"version": "23.0.0",
|
|
3
|
+
"version": "23.1.0-beta.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"files": [
|
|
@@ -144,11 +144,11 @@
|
|
|
144
144
|
"source-map-support": "0.5.19",
|
|
145
145
|
"tinyglobby": "^0.2.12",
|
|
146
146
|
"tslib": "^2.3.0",
|
|
147
|
-
"@nx/devkit": "23.0.0",
|
|
148
|
-
"@nx/workspace": "23.0.0"
|
|
147
|
+
"@nx/devkit": "23.1.0-beta.0",
|
|
148
|
+
"@nx/workspace": "23.1.0-beta.0"
|
|
149
149
|
},
|
|
150
150
|
"devDependencies": {
|
|
151
|
-
"nx": "23.0.0"
|
|
151
|
+
"nx": "23.1.0-beta.0"
|
|
152
152
|
},
|
|
153
153
|
"peerDependencies": {
|
|
154
154
|
"@swc/cli": ">=0.6.0 <0.9.0",
|