@nx/js 20.0.0-beta.2 → 20.0.0-beta.4
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/generators.json +1 -1
- package/package.json +5 -4
- package/src/generators/init/files/ts-solution/tsconfig.base.json__tmpl__ +34 -0
- package/src/generators/init/files/ts-solution/tsconfig.json__tmpl__ +6 -0
- package/src/generators/init/init.js +52 -9
- package/src/generators/init/schema.d.ts +4 -1
- package/src/generators/init/schema.json +6 -6
- package/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ +4 -4
- package/src/generators/library/files/lib/src/lib/__fileName__.ts__tmpl__ +1 -1
- package/src/generators/library/files/readme/README.md +3 -11
- package/src/generators/library/files/tsconfig-lib/ts-solution/tsconfig.lib.json__tmpl__ +14 -0
- package/src/generators/library/library.d.ts +2 -11
- package/src/generators/library/library.js +294 -93
- package/src/generators/library/schema.d.ts +53 -0
- package/src/generators/library/schema.json +18 -17
- package/src/generators/library/utils/package-manager-workspaces.d.ts +3 -0
- package/src/generators/library/utils/package-manager-workspaces.js +52 -0
- package/src/generators/library/utils/plugin-registrations.d.ts +3 -0
- package/src/generators/library/utils/plugin-registrations.js +108 -0
- package/src/generators/setup-prettier/generator.js +3 -3
- package/src/generators/setup-verdaccio/generator.js +14 -10
- package/src/generators/typescript-sync/typescript-sync.d.ts +1 -1
- package/src/generators/typescript-sync/typescript-sync.js +9 -8
- package/src/plugins/typescript/plugin.js +8 -0
- package/src/utils/find-npm-dependencies.js +12 -0
- package/src/utils/package-manager-workspaces.d.ts +4 -0
- package/src/utils/package-manager-workspaces.js +19 -0
- package/src/utils/prettier.d.ts +1 -0
- package/src/utils/prettier.js +53 -0
- package/src/utils/schema.d.ts +0 -32
- package/src/utils/swc/add-swc-dependencies.d.ts +4 -0
- package/src/utils/swc/add-swc-dependencies.js +11 -4
- package/src/utils/typescript/configuration.d.ts +7 -0
- package/src/utils/typescript/configuration.js +64 -0
- package/src/utils/typescript/ts-solution-setup.d.ts +3 -0
- package/src/utils/typescript/ts-solution-setup.js +48 -0
- /package/src/generators/init/files/{__fileName__ → non-ts-solution/__fileName__} +0 -0
- /package/src/generators/library/files/{lib → tsconfig-lib/non-ts-solution}/tsconfig.lib.json__tmpl__ +0 -0
|
@@ -21,22 +21,28 @@
|
|
|
21
21
|
"description": "A directory where the lib is placed.",
|
|
22
22
|
"x-priority": "important"
|
|
23
23
|
},
|
|
24
|
-
"
|
|
25
|
-
"description": "
|
|
24
|
+
"bundler": {
|
|
25
|
+
"description": "The bundler to use. Choosing 'none' means this library is not buildable.",
|
|
26
26
|
"type": "string",
|
|
27
|
-
"enum": ["
|
|
27
|
+
"enum": ["swc", "tsc", "rollup", "vite", "esbuild", "none"],
|
|
28
|
+
"x-priority": "important"
|
|
28
29
|
},
|
|
29
30
|
"linter": {
|
|
30
31
|
"description": "The tool to use for running lint checks.",
|
|
31
32
|
"type": "string",
|
|
32
|
-
"enum": ["
|
|
33
|
-
"
|
|
33
|
+
"enum": ["none", "eslint"],
|
|
34
|
+
"x-priority": "important"
|
|
34
35
|
},
|
|
35
36
|
"unitTestRunner": {
|
|
36
|
-
"type": "string",
|
|
37
|
-
"enum": ["jest", "vitest", "none"],
|
|
38
37
|
"description": "Test runner to use for unit tests.",
|
|
39
|
-
"
|
|
38
|
+
"type": "string",
|
|
39
|
+
"enum": ["none", "jest", "vitest"],
|
|
40
|
+
"x-priority": "important"
|
|
41
|
+
},
|
|
42
|
+
"projectNameAndRootFormat": {
|
|
43
|
+
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
|
44
|
+
"type": "string",
|
|
45
|
+
"enum": ["as-provided", "derived"]
|
|
40
46
|
},
|
|
41
47
|
"tags": {
|
|
42
48
|
"type": "string",
|
|
@@ -112,18 +118,9 @@
|
|
|
112
118
|
"compiler": {
|
|
113
119
|
"type": "string",
|
|
114
120
|
"enum": ["tsc", "swc"],
|
|
115
|
-
"default": "tsc",
|
|
116
121
|
"description": "The compiler used by the build and test targets",
|
|
117
122
|
"x-deprecated": "Use the `bundler` option for greater control (swc, tsc, rollup, vite, esbuild, none)."
|
|
118
123
|
},
|
|
119
|
-
"bundler": {
|
|
120
|
-
"description": "The bundler to use. Choosing 'none' means this library is not buildable.",
|
|
121
|
-
"type": "string",
|
|
122
|
-
"enum": ["swc", "tsc", "rollup", "vite", "esbuild", "none"],
|
|
123
|
-
"default": "tsc",
|
|
124
|
-
"x-prompt": "Which bundler would you like to use to build the library? Choose 'none' to skip build setup.",
|
|
125
|
-
"x-priority": "important"
|
|
126
|
-
},
|
|
127
124
|
"skipTypeCheck": {
|
|
128
125
|
"type": "boolean",
|
|
129
126
|
"description": "Whether to skip TypeScript type checking for SWC compiler.",
|
|
@@ -138,6 +135,10 @@
|
|
|
138
135
|
"description": "Don't include the directory in the generated file name.",
|
|
139
136
|
"type": "boolean",
|
|
140
137
|
"default": false
|
|
138
|
+
},
|
|
139
|
+
"useProjectJson": {
|
|
140
|
+
"type": "boolean",
|
|
141
|
+
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
|
141
142
|
}
|
|
142
143
|
},
|
|
143
144
|
"required": ["name"],
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type GeneratorCallback } from '@nx/devkit';
|
|
2
|
+
import type { ProjectPackageManagerWorkspaceState } from '../../../utils/package-manager-workspaces';
|
|
3
|
+
export declare function getProjectPackageManagerWorkspaceStateWarningTask(projectPackageManagerWorkspaceState: ProjectPackageManagerWorkspaceState, workspaceRoot: string): GeneratorCallback;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProjectPackageManagerWorkspaceStateWarningTask = getProjectPackageManagerWorkspaceStateWarningTask;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const semver_1 = require("semver");
|
|
6
|
+
function getProjectPackageManagerWorkspaceStateWarningTask(projectPackageManagerWorkspaceState, workspaceRoot) {
|
|
7
|
+
return () => {
|
|
8
|
+
const packageManager = (0, devkit_1.detectPackageManager)(workspaceRoot);
|
|
9
|
+
let packageManagerWorkspaceSetupDocs;
|
|
10
|
+
if (packageManager === 'pnpm') {
|
|
11
|
+
packageManagerWorkspaceSetupDocs =
|
|
12
|
+
'https://pnpm.io/workspaces and https://pnpm.io/pnpm-workspace_yaml';
|
|
13
|
+
}
|
|
14
|
+
else if (packageManager === 'yarn') {
|
|
15
|
+
const yarnVersion = (0, devkit_1.getPackageManagerVersion)(packageManager, workspaceRoot);
|
|
16
|
+
if ((0, semver_1.lt)(yarnVersion, '2.0.0')) {
|
|
17
|
+
packageManagerWorkspaceSetupDocs =
|
|
18
|
+
'https://classic.yarnpkg.com/lang/en/docs/workspaces/';
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
packageManagerWorkspaceSetupDocs =
|
|
22
|
+
'https://yarnpkg.com/features/workspaces';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (packageManager === 'npm') {
|
|
26
|
+
packageManagerWorkspaceSetupDocs =
|
|
27
|
+
'https://docs.npmjs.com/cli/v10/using-npm/workspaces';
|
|
28
|
+
}
|
|
29
|
+
else if (packageManager === 'bun') {
|
|
30
|
+
packageManagerWorkspaceSetupDocs =
|
|
31
|
+
'https://bun.sh/docs/install/workspaces';
|
|
32
|
+
}
|
|
33
|
+
if (projectPackageManagerWorkspaceState === 'no-workspaces') {
|
|
34
|
+
devkit_1.output.warn({
|
|
35
|
+
title: `The package manager workspaces feature is not enabled in the workspace`,
|
|
36
|
+
bodyLines: [
|
|
37
|
+
'You must enable the package manager workspaces feature to use the "@nx/js/typescript" plugin.',
|
|
38
|
+
`Read more about the ${packageManager} workspaces feature and how to set it up at ${packageManagerWorkspaceSetupDocs}.`,
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else if (projectPackageManagerWorkspaceState === 'excluded') {
|
|
43
|
+
devkit_1.output.warn({
|
|
44
|
+
title: `The project is not included in the package manager workspaces configuration`,
|
|
45
|
+
bodyLines: [
|
|
46
|
+
'Please add it to the workspace configuration to use the "@nx/js/typescript" plugin.',
|
|
47
|
+
`Read more about the ${packageManager} workspaces feature and how to set it up at ${packageManagerWorkspaceSetupDocs}.`,
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NxJsonConfiguration } from '@nx/devkit';
|
|
2
|
+
export declare function ensureProjectIsIncludedInPluginRegistrations(nxJson: NxJsonConfiguration, projectRoot: string): void;
|
|
3
|
+
export declare function ensureProjectIsExcludedFromPluginRegistrations(nxJson: NxJsonConfiguration, projectRoot: string): void;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureProjectIsIncludedInPluginRegistrations = ensureProjectIsIncludedInPluginRegistrations;
|
|
4
|
+
exports.ensureProjectIsExcludedFromPluginRegistrations = ensureProjectIsExcludedFromPluginRegistrations;
|
|
5
|
+
const devkit_internals_1 = require("nx/src/devkit-internals");
|
|
6
|
+
function ensureProjectIsIncludedInPluginRegistrations(nxJson, projectRoot) {
|
|
7
|
+
if (!nxJson.plugins?.length ||
|
|
8
|
+
!nxJson.plugins.some(isTypeScriptPluginRegistration)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
let isIncluded = false;
|
|
12
|
+
let index = 0;
|
|
13
|
+
for (const registration of nxJson.plugins) {
|
|
14
|
+
if (!isTypeScriptPluginRegistration(registration)) {
|
|
15
|
+
index++;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (typeof registration === 'string') {
|
|
19
|
+
// if it's a string all projects are included but the are no user-specified options
|
|
20
|
+
// and the `build` task is not inferred by default, so we need to exclude it
|
|
21
|
+
nxJson.plugins[index] = {
|
|
22
|
+
plugin: '@nx/js/typescript',
|
|
23
|
+
exclude: [`${projectRoot}/*`],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// check if the project would be included by the plugin registration
|
|
28
|
+
const matchingConfigFiles = (0, devkit_internals_1.findMatchingConfigFiles)([`${projectRoot}/tsconfig.json`], '**/tsconfig.json', registration.include, registration.exclude);
|
|
29
|
+
if (matchingConfigFiles.length) {
|
|
30
|
+
// it's included by the plugin registration, check if the user-specified options would result
|
|
31
|
+
// in a `build` task being inferred, if not, we need to exclude it
|
|
32
|
+
if (registration.options?.typecheck && registration.options?.build) {
|
|
33
|
+
// it has the desired options, do nothing
|
|
34
|
+
isIncluded = true;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// it would not have the `build` task inferred, so we need to exclude it
|
|
38
|
+
registration.exclude ??= [];
|
|
39
|
+
registration.exclude.push(`${projectRoot}/*`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (registration.options?.typecheck &&
|
|
43
|
+
registration.options?.build &&
|
|
44
|
+
!registration.exclude?.length) {
|
|
45
|
+
// negative pattern are not supported by the `exclude` option so we
|
|
46
|
+
// can't update it to not exclude the project, so we only update the
|
|
47
|
+
// plugin registration if there's no `exclude` option, in which case
|
|
48
|
+
// the plugin registration should have an `include` options that doesn't
|
|
49
|
+
// include the project
|
|
50
|
+
isIncluded = true;
|
|
51
|
+
registration.include ??= [];
|
|
52
|
+
registration.include.push(`${projectRoot}/*`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
index++;
|
|
56
|
+
}
|
|
57
|
+
if (!isIncluded) {
|
|
58
|
+
// the project is not included by any plugin registration with an inferred `build` task,
|
|
59
|
+
// so we create a new plugin registration for it
|
|
60
|
+
nxJson.plugins.push({
|
|
61
|
+
plugin: '@nx/js/typescript',
|
|
62
|
+
include: [`${projectRoot}/*`],
|
|
63
|
+
options: {
|
|
64
|
+
typecheck: { targetName: 'typecheck' },
|
|
65
|
+
build: {
|
|
66
|
+
targetName: 'build',
|
|
67
|
+
configName: 'tsconfig.lib.json',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function ensureProjectIsExcludedFromPluginRegistrations(nxJson, projectRoot) {
|
|
74
|
+
if (!nxJson.plugins?.length ||
|
|
75
|
+
!nxJson.plugins.some(isTypeScriptPluginRegistration)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
let index = 0;
|
|
79
|
+
for (const registration of nxJson.plugins) {
|
|
80
|
+
if (!isTypeScriptPluginRegistration(registration)) {
|
|
81
|
+
index++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (typeof registration === 'string') {
|
|
85
|
+
// if it's a string, it includes all projects, so we need to exclude it
|
|
86
|
+
nxJson.plugins[index] = {
|
|
87
|
+
plugin: '@nx/js/typescript',
|
|
88
|
+
exclude: [`${projectRoot}/*`],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// check if the project would be included by the plugin registration
|
|
93
|
+
const matchingConfigFiles = (0, devkit_internals_1.findMatchingConfigFiles)([`${projectRoot}/tsconfig.json`], '**/tsconfig.json', registration.include, registration.exclude);
|
|
94
|
+
if (matchingConfigFiles.length &&
|
|
95
|
+
(registration.options?.typecheck !== false ||
|
|
96
|
+
registration.options?.build)) {
|
|
97
|
+
// the project is included by a plugin registration that infers any of the targets, so we need to exclude it
|
|
98
|
+
registration.exclude ??= [];
|
|
99
|
+
registration.exclude.push(`${projectRoot}/*`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
index++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function isTypeScriptPluginRegistration(plugin) {
|
|
106
|
+
return ((typeof plugin === 'string' && plugin === '@nx/js/typescript') ||
|
|
107
|
+
(typeof plugin !== 'string' && plugin.plugin === '@nx/js/typescript'));
|
|
108
|
+
}
|
|
@@ -8,10 +8,10 @@ async function setupPrettierGenerator(tree, options) {
|
|
|
8
8
|
const prettierTask = (0, prettier_1.generatePrettierSetup)(tree, {
|
|
9
9
|
skipPackageJson: options.skipPackageJson,
|
|
10
10
|
});
|
|
11
|
+
if (!options.skipPackageJson) {
|
|
12
|
+
(0, devkit_1.ensurePackage)('prettier', versions_1.prettierVersion);
|
|
13
|
+
}
|
|
11
14
|
if (!options.skipFormat) {
|
|
12
|
-
if (!options.skipPackageJson) {
|
|
13
|
-
(0, devkit_1.ensurePackage)('prettier', versions_1.prettierVersion);
|
|
14
|
-
}
|
|
15
15
|
// even if skipPackageJson === true, we can safely run formatFiles, prettier might
|
|
16
16
|
// have been installed earlier and if not, the formatFiles function still handles it
|
|
17
17
|
await (0, devkit_1.formatFiles)(tree);
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.setupVerdaccio = setupVerdaccio;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const path = require("path");
|
|
6
|
+
const ts_solution_setup_1 = require("../../utils/typescript/ts-solution-setup");
|
|
6
7
|
const versions_1 = require("../../utils/versions");
|
|
7
8
|
const child_process_1 = require("child_process");
|
|
8
9
|
async function setupVerdaccio(tree, options) {
|
|
@@ -24,21 +25,24 @@ async function setupVerdaccio(tree, options) {
|
|
|
24
25
|
},
|
|
25
26
|
};
|
|
26
27
|
if (!tree.exists('project.json')) {
|
|
28
|
+
const isUsingNewTsSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
|
|
27
29
|
const { name } = (0, devkit_1.readJson)(tree, 'package.json');
|
|
28
30
|
(0, devkit_1.updateJson)(tree, 'package.json', (json) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
json.nx ??= { includedScripts: [] };
|
|
32
|
+
if (isUsingNewTsSetup) {
|
|
33
|
+
json.nx.targets ??= {};
|
|
34
|
+
json.nx.targets['local-registry'] ??= verdaccioTarget;
|
|
33
35
|
}
|
|
34
36
|
return json;
|
|
35
37
|
});
|
|
36
|
-
(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
if (!isUsingNewTsSetup) {
|
|
39
|
+
(0, devkit_1.addProjectConfiguration)(tree, name, {
|
|
40
|
+
root: '.',
|
|
41
|
+
targets: {
|
|
42
|
+
['local-registry']: verdaccioTarget,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
else {
|
|
44
48
|
// use updateJson instead of updateProjectConfiguration due to unknown project name
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type Tree } from '@nx/devkit';
|
|
2
|
-
import type
|
|
2
|
+
import { type SyncGeneratorResult } from 'nx/src/utils/sync-generators';
|
|
3
3
|
export declare function syncGenerator(tree: Tree): Promise<SyncGeneratorResult>;
|
|
4
4
|
export default syncGenerator;
|
|
@@ -5,6 +5,7 @@ const devkit_1 = require("@nx/devkit");
|
|
|
5
5
|
const ignore_1 = require("ignore");
|
|
6
6
|
const jsonc_parser_1 = require("jsonc-parser");
|
|
7
7
|
const posix_1 = require("node:path/posix");
|
|
8
|
+
const sync_generators_1 = require("nx/src/utils/sync-generators");
|
|
8
9
|
const ts = require("typescript");
|
|
9
10
|
const plugin_1 = require("../../plugins/typescript/plugin");
|
|
10
11
|
const COMMON_RUNTIME_TS_CONFIG_FILE_NAMES = [
|
|
@@ -25,12 +26,16 @@ async function syncGenerator(tree) {
|
|
|
25
26
|
return p.plugin === plugin_1.PLUGIN_NAME;
|
|
26
27
|
});
|
|
27
28
|
if (!tscPluginConfig) {
|
|
28
|
-
throw new
|
|
29
|
+
throw new sync_generators_1.SyncError(`The "${plugin_1.PLUGIN_NAME}" plugin is not registered`, [
|
|
30
|
+
`The "${plugin_1.PLUGIN_NAME}" plugin must be added to the "plugins" array in "nx.json" in order to sync the project graph information to the TypeScript configuration files.`,
|
|
31
|
+
]);
|
|
29
32
|
}
|
|
30
33
|
// Root tsconfig containing project references for the whole workspace
|
|
31
34
|
const rootTsconfigPath = 'tsconfig.json';
|
|
32
35
|
if (!tree.exists(rootTsconfigPath)) {
|
|
33
|
-
throw new
|
|
36
|
+
throw new sync_generators_1.SyncError('Missing root "tsconfig.json"', [
|
|
37
|
+
`A "tsconfig.json" file must exist in the workspace root in order to sync the project graph information to the TypeScript configuration files.`,
|
|
38
|
+
]);
|
|
34
39
|
}
|
|
35
40
|
const rawTsconfigContentsCache = new Map();
|
|
36
41
|
const stringifiedRootJsonContents = readRawTsconfigContents(tree, rawTsconfigContentsCache, rootTsconfigPath);
|
|
@@ -93,8 +98,7 @@ async function syncGenerator(tree) {
|
|
|
93
98
|
const collectedDependencies = new Map();
|
|
94
99
|
for (const [projectName, data] of Object.entries(projectGraph.dependencies)) {
|
|
95
100
|
if (!projectGraph.nodes[projectName] ||
|
|
96
|
-
projectGraph.nodes[projectName].data.root === '.'
|
|
97
|
-
!data.length) {
|
|
101
|
+
projectGraph.nodes[projectName].data.root === '.') {
|
|
98
102
|
continue;
|
|
99
103
|
}
|
|
100
104
|
// Get the source project nodes for the source and target
|
|
@@ -109,9 +113,6 @@ async function syncGenerator(tree) {
|
|
|
109
113
|
}
|
|
110
114
|
// Collect the dependencies of the source project
|
|
111
115
|
const dependencies = collectProjectDependencies(tree, projectName, projectGraph, collectedDependencies);
|
|
112
|
-
if (!dependencies.length) {
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
116
|
for (const runtimeTsConfigFileName of runtimeTsConfigFileNames) {
|
|
116
117
|
const runtimeTsConfigPath = (0, devkit_1.joinPathFragments)(sourceProjectNode.data.root, runtimeTsConfigFileName);
|
|
117
118
|
if (!tsconfigExists(tree, rawTsconfigContentsCache, runtimeTsConfigPath)) {
|
|
@@ -128,7 +129,7 @@ async function syncGenerator(tree) {
|
|
|
128
129
|
if (hasChanges) {
|
|
129
130
|
await (0, devkit_1.formatFiles)(tree);
|
|
130
131
|
return {
|
|
131
|
-
outOfSyncMessage: 'Based on the workspace project graph, some TypeScript configuration files are missing project references to the projects they depend on.',
|
|
132
|
+
outOfSyncMessage: 'Based on the workspace project graph, some TypeScript configuration files are missing project references to the projects they depend on or contain outdated project references.',
|
|
132
133
|
};
|
|
133
134
|
}
|
|
134
135
|
}
|
|
@@ -292,6 +292,10 @@ function resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot,
|
|
|
292
292
|
// Already resolved
|
|
293
293
|
continue;
|
|
294
294
|
}
|
|
295
|
+
if (!(0, node_fs_1.existsSync)(refConfigPath)) {
|
|
296
|
+
// the referenced tsconfig doesn't exist, ignore it
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
295
299
|
if (isExternalProjectReference(refConfigPath, workspaceRoot, projectRoot)) {
|
|
296
300
|
continue;
|
|
297
301
|
}
|
|
@@ -315,6 +319,10 @@ function hasExternalProjectReferences(tsConfigPath, tsConfig, workspaceRoot, pro
|
|
|
315
319
|
// Already seen
|
|
316
320
|
continue;
|
|
317
321
|
}
|
|
322
|
+
if (!(0, node_fs_1.existsSync)(refConfigPath)) {
|
|
323
|
+
// the referenced tsconfig doesn't exist, ignore it
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
318
326
|
if (isExternalProjectReference(refConfigPath, workspaceRoot, projectRoot)) {
|
|
319
327
|
return true;
|
|
320
328
|
}
|
|
@@ -138,4 +138,16 @@ function collectHelperDependencies(workspaceRoot, sourceProject, projectGraph, b
|
|
|
138
138
|
projectGraph.externalNodes['npm:@swc/helpers'].data.version;
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
+
// For inferred targets or manually added run-commands, check if user is using `tsc` in build target.
|
|
142
|
+
if (target.executor === 'nx:run-commands' &&
|
|
143
|
+
/\btsc\b/.test(target.options.command)) {
|
|
144
|
+
const tsConfigFileName = (0, ts_config_1.getRootTsConfigFileName)();
|
|
145
|
+
if (tsConfigFileName) {
|
|
146
|
+
const tsConfig = (0, ts_config_1.readTsConfig)((0, path_1.join)(workspaceRoot, tsConfigFileName));
|
|
147
|
+
if (tsConfig?.options['importHelpers'] &&
|
|
148
|
+
projectGraph.externalNodes['npm:tslib']?.type === 'npm') {
|
|
149
|
+
npmDeps['tslib'] = projectGraph.externalNodes['npm:tslib'].data.version;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
141
153
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
export type ProjectPackageManagerWorkspaceState = 'included' | 'excluded' | 'no-workspaces';
|
|
3
|
+
export declare function getProjectPackageManagerWorkspaceState(tree: Tree, projectRoot: string): ProjectPackageManagerWorkspaceState;
|
|
4
|
+
export declare function isUsingPackageManagerWorkspaces(tree: Tree): boolean;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProjectPackageManagerWorkspaceState = getProjectPackageManagerWorkspaceState;
|
|
4
|
+
exports.isUsingPackageManagerWorkspaces = isUsingPackageManagerWorkspaces;
|
|
5
|
+
const devkit_1 = require("@nx/devkit");
|
|
6
|
+
const minimatch_1 = require("minimatch");
|
|
7
|
+
const posix_1 = require("node:path/posix");
|
|
8
|
+
const package_json_1 = require("nx/src/plugins/package-json");
|
|
9
|
+
function getProjectPackageManagerWorkspaceState(tree, projectRoot) {
|
|
10
|
+
if (!isUsingPackageManagerWorkspaces(tree)) {
|
|
11
|
+
return 'no-workspaces';
|
|
12
|
+
}
|
|
13
|
+
const patterns = (0, package_json_1.getGlobPatternsFromPackageManagerWorkspaces)(tree.root, (path) => (0, devkit_1.readJson)(tree, path, { expectComments: true }));
|
|
14
|
+
const isIncluded = patterns.some((p) => (0, minimatch_1.minimatch)((0, posix_1.join)(projectRoot, 'package.json'), p));
|
|
15
|
+
return isIncluded ? 'included' : 'excluded';
|
|
16
|
+
}
|
|
17
|
+
function isUsingPackageManagerWorkspaces(tree) {
|
|
18
|
+
return (0, devkit_1.isWorkspacesEnabled)((0, devkit_1.detectPackageManager)(tree.root), tree.root);
|
|
19
|
+
}
|
package/src/utils/prettier.d.ts
CHANGED
|
@@ -8,3 +8,4 @@ export declare function resolveUserExistingPrettierConfig(): Promise<ExistingPre
|
|
|
8
8
|
export declare function generatePrettierSetup(tree: Tree, options: {
|
|
9
9
|
skipPackageJson?: boolean;
|
|
10
10
|
}): GeneratorCallback;
|
|
11
|
+
export declare function resolvePrettierConfigPath(tree: Tree): Promise<string | null>;
|
package/src/utils/prettier.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveUserExistingPrettierConfig = resolveUserExistingPrettierConfig;
|
|
4
4
|
exports.generatePrettierSetup = generatePrettierSetup;
|
|
5
|
+
exports.resolvePrettierConfigPath = resolvePrettierConfigPath;
|
|
5
6
|
const devkit_1 = require("@nx/devkit");
|
|
6
7
|
const versions_1 = require("./versions");
|
|
7
8
|
async function resolveUserExistingPrettierConfig() {
|
|
@@ -74,3 +75,55 @@ function generatePrettierSetup(tree, options) {
|
|
|
74
75
|
? () => { }
|
|
75
76
|
: (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { prettier: versions_1.prettierVersion });
|
|
76
77
|
}
|
|
78
|
+
async function resolvePrettierConfigPath(tree) {
|
|
79
|
+
let prettier;
|
|
80
|
+
try {
|
|
81
|
+
prettier = require('prettier');
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
if (prettier) {
|
|
87
|
+
const filePath = await prettier.resolveConfigFile();
|
|
88
|
+
if (filePath) {
|
|
89
|
+
return filePath;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!tree) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
// if we haven't find a config file in the file system, we try to find it in the virtual tree
|
|
96
|
+
// https://prettier.io/docs/en/configuration.html
|
|
97
|
+
const prettierrcNameOptions = [
|
|
98
|
+
'.prettierrc',
|
|
99
|
+
'.prettierrc.json',
|
|
100
|
+
'.prettierrc.yml',
|
|
101
|
+
'.prettierrc.yaml',
|
|
102
|
+
'.prettierrc.json5',
|
|
103
|
+
'.prettierrc.js',
|
|
104
|
+
'.prettierrc.cjs',
|
|
105
|
+
'.prettierrc.mjs',
|
|
106
|
+
'.prettierrc.toml',
|
|
107
|
+
'prettier.config.js',
|
|
108
|
+
'prettier.config.cjs',
|
|
109
|
+
'prettier.config.mjs',
|
|
110
|
+
];
|
|
111
|
+
const filePath = prettierrcNameOptions.find((file) => tree.exists(file));
|
|
112
|
+
if (filePath) {
|
|
113
|
+
return filePath;
|
|
114
|
+
}
|
|
115
|
+
// check the package.json file
|
|
116
|
+
const packageJson = (0, devkit_1.readJson)(tree, 'package.json');
|
|
117
|
+
if (packageJson.prettier) {
|
|
118
|
+
return 'package.json';
|
|
119
|
+
}
|
|
120
|
+
// check the package.yaml file
|
|
121
|
+
if (tree.exists('package.yaml')) {
|
|
122
|
+
const { load } = await Promise.resolve().then(() => require('@zkochan/js-yaml'));
|
|
123
|
+
const packageYaml = load(tree.read('package.yaml', 'utf-8'));
|
|
124
|
+
if (packageYaml.prettier) {
|
|
125
|
+
return 'package.yaml';
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
package/src/utils/schema.d.ts
CHANGED
|
@@ -1,39 +1,7 @@
|
|
|
1
|
-
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
|
2
1
|
import type { AssetGlob, FileInputOutput } from './assets/assets';
|
|
3
2
|
import { TransformerEntry } from './typescript/types';
|
|
4
|
-
// nx-ignore-next-line
|
|
5
|
-
const { Linter, LinterType } = require('@nx/eslint'); // use require to import to avoid circular dependency
|
|
6
3
|
|
|
7
4
|
export type Compiler = 'tsc' | 'swc';
|
|
8
|
-
export type Bundler = 'swc' | 'tsc' | 'rollup' | 'vite' | 'esbuild' | 'none';
|
|
9
|
-
|
|
10
|
-
export interface LibraryGeneratorSchema {
|
|
11
|
-
name: string;
|
|
12
|
-
directory?: string;
|
|
13
|
-
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
|
14
|
-
skipFormat?: boolean;
|
|
15
|
-
tags?: string;
|
|
16
|
-
skipTsConfig?: boolean;
|
|
17
|
-
skipPackageJson?: boolean;
|
|
18
|
-
includeBabelRc?: boolean;
|
|
19
|
-
unitTestRunner?: 'jest' | 'vitest' | 'none';
|
|
20
|
-
linter?: Linter | LinterType;
|
|
21
|
-
testEnvironment?: 'jsdom' | 'node';
|
|
22
|
-
importPath?: string;
|
|
23
|
-
js?: boolean;
|
|
24
|
-
strict?: boolean;
|
|
25
|
-
publishable?: boolean;
|
|
26
|
-
buildable?: boolean;
|
|
27
|
-
setParserOptionsProject?: boolean;
|
|
28
|
-
config?: 'workspace' | 'project' | 'npm-scripts';
|
|
29
|
-
compiler?: Compiler;
|
|
30
|
-
bundler?: Bundler;
|
|
31
|
-
skipTypeCheck?: boolean;
|
|
32
|
-
minimal?: boolean;
|
|
33
|
-
rootProject?: boolean;
|
|
34
|
-
simpleName?: boolean;
|
|
35
|
-
addPlugin?: boolean;
|
|
36
|
-
}
|
|
37
5
|
|
|
38
6
|
export interface ExecutorOptions {
|
|
39
7
|
assets: Array<AssetGlob | string>;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { Tree } from '@nx/devkit';
|
|
2
|
+
export declare function getSwcDependencies(): {
|
|
3
|
+
dependencies: Record<string, string>;
|
|
4
|
+
devDependencies: Record<string, string>;
|
|
5
|
+
};
|
|
2
6
|
export declare function addSwcDependencies(tree: Tree): import("@nx/devkit").GeneratorCallback;
|
|
3
7
|
export declare function addSwcRegisterDependencies(tree: Tree): import("@nx/devkit").GeneratorCallback;
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSwcDependencies = getSwcDependencies;
|
|
3
4
|
exports.addSwcDependencies = addSwcDependencies;
|
|
4
5
|
exports.addSwcRegisterDependencies = addSwcRegisterDependencies;
|
|
5
6
|
const devkit_1 = require("@nx/devkit");
|
|
6
7
|
const versions_1 = require("../versions");
|
|
7
|
-
function
|
|
8
|
-
|
|
8
|
+
function getSwcDependencies() {
|
|
9
|
+
const dependencies = {
|
|
9
10
|
'@swc/helpers': versions_1.swcHelpersVersion,
|
|
10
|
-
}
|
|
11
|
+
};
|
|
12
|
+
const devDependencies = {
|
|
11
13
|
'@swc/core': versions_1.swcCoreVersion,
|
|
12
14
|
'@swc/cli': versions_1.swcCliVersion,
|
|
13
|
-
}
|
|
15
|
+
};
|
|
16
|
+
return { dependencies, devDependencies };
|
|
17
|
+
}
|
|
18
|
+
function addSwcDependencies(tree) {
|
|
19
|
+
const { dependencies, devDependencies } = getSwcDependencies();
|
|
20
|
+
return (0, devkit_1.addDependenciesToPackageJson)(tree, dependencies, devDependencies);
|
|
14
21
|
}
|
|
15
22
|
function addSwcRegisterDependencies(tree) {
|
|
16
23
|
return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@swc-node/register': versions_1.swcNodeVersion, '@swc/core': versions_1.swcCoreVersion });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Tree } from '@nx/devkit';
|
|
2
|
+
import type { CompilerOptions } from 'typescript';
|
|
3
|
+
/**
|
|
4
|
+
* Cleans up the provided compiler options to only include the options that are
|
|
5
|
+
* different or not set in the provided tsconfig file.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getNeededCompilerOptionOverrides(tree: Tree, compilerOptions: Record<keyof CompilerOptions, any>, tsConfigPath: string): Record<keyof CompilerOptions, any>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNeededCompilerOptionOverrides = getNeededCompilerOptionOverrides;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const ensure_typescript_1 = require("./ensure-typescript");
|
|
6
|
+
const optionEnumTypeMap = {
|
|
7
|
+
importsNotUsedAsValues: 'ImportsNotUsedAsValues',
|
|
8
|
+
jsx: 'JsxEmit',
|
|
9
|
+
module: 'ModuleKind',
|
|
10
|
+
moduleDetection: 'ModuleDetectionKind',
|
|
11
|
+
moduleResolution: 'ModuleResolutionKind',
|
|
12
|
+
newLine: 'NewLineKind',
|
|
13
|
+
target: 'ScriptTarget',
|
|
14
|
+
};
|
|
15
|
+
let ts;
|
|
16
|
+
/**
|
|
17
|
+
* Cleans up the provided compiler options to only include the options that are
|
|
18
|
+
* different or not set in the provided tsconfig file.
|
|
19
|
+
*/
|
|
20
|
+
function getNeededCompilerOptionOverrides(tree, compilerOptions, tsConfigPath) {
|
|
21
|
+
if (!ts) {
|
|
22
|
+
ts = (0, ensure_typescript_1.ensureTypescript)();
|
|
23
|
+
}
|
|
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));
|
|
29
|
+
// ModuleKind: { CommonJS: 'commonjs', ... } => ModuleKind: { commonjs: 'CommonJS', ... }
|
|
30
|
+
const reversedCompilerOptionsEnumValues = {
|
|
31
|
+
JsxEmit: reverseEnum(ts.server.protocol.JsxEmit),
|
|
32
|
+
ModuleKind: reverseEnum(ts.server.protocol.ModuleKind),
|
|
33
|
+
ModuleResolutionKind: reverseEnum(ts.server.protocol.ModuleResolutionKind),
|
|
34
|
+
NewLineKind: reverseEnum(ts.server.protocol.NewLineKind),
|
|
35
|
+
ScriptTarget: reverseEnum(ts.server.protocol.ScriptTarget),
|
|
36
|
+
};
|
|
37
|
+
const matchesValue = (key) => {
|
|
38
|
+
return (parsed.options[key] ===
|
|
39
|
+
ts[optionEnumTypeMap[key]][compilerOptions[key]] ||
|
|
40
|
+
parsed.options[key] ===
|
|
41
|
+
ts[optionEnumTypeMap[key]][reversedCompilerOptionsEnumValues[optionEnumTypeMap[key]][compilerOptions[key]]]);
|
|
42
|
+
};
|
|
43
|
+
let result = {};
|
|
44
|
+
for (const key of Object.keys(compilerOptions)) {
|
|
45
|
+
if (optionEnumTypeMap[key]) {
|
|
46
|
+
if (parsed.options[key] === undefined) {
|
|
47
|
+
result[key] = compilerOptions[key];
|
|
48
|
+
}
|
|
49
|
+
else if (!matchesValue(key)) {
|
|
50
|
+
result[key] = compilerOptions[key];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (parsed.options[key] !== compilerOptions[key]) {
|
|
54
|
+
result[key] = compilerOptions[key];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
function reverseEnum(enumObj) {
|
|
60
|
+
return Object.keys(enumObj).reduce((acc, key) => {
|
|
61
|
+
acc[enumObj[key]] = key;
|
|
62
|
+
return acc;
|
|
63
|
+
}, {});
|
|
64
|
+
}
|