@nx/js 19.0.0-beta.0 → 19.0.0-beta.10
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/babel.js +1 -1
- package/generators.json +6 -0
- package/migrations.json +0 -18
- package/package.json +4 -5
- package/src/executors/node/node.impl.js +1 -1
- package/src/executors/verdaccio/verdaccio.impl.js +28 -17
- package/src/generators/sync/schema.d.ts +1 -0
- package/src/generators/sync/schema.json +8 -0
- package/src/generators/sync/sync.d.ts +3 -0
- package/src/generators/sync/sync.js +76 -0
- package/src/plugins/typescript/plugin.d.ts +13 -0
- package/src/plugins/typescript/plugin.js +348 -0
- package/src/utils/assets/copy-assets-handler.js +1 -1
- package/typescript.d.ts +1 -0
- package/typescript.js +6 -0
- package/src/migrations/update-15-8-0/rename-swcrc-config.d.ts +0 -2
- package/src/migrations/update-15-8-0/rename-swcrc-config.js +0 -77
package/babel.js
CHANGED
|
@@ -13,7 +13,7 @@ module.exports = function (api, options = {}) {
|
|
|
13
13
|
const emitDecoratorMetadata = api.caller((caller) => caller?.emitDecoratorMetadata ?? true);
|
|
14
14
|
// Determine settings for `@babel//babel-plugin-transform-class-properties`,
|
|
15
15
|
// so that we can sync the `loose` option with `@babel/preset-env`.
|
|
16
|
-
// TODO(
|
|
16
|
+
// TODO(v20): Remove classProperties since it's no longer needed, now that the class props transform is in preset-env.
|
|
17
17
|
const loose = options.classProperties?.loose ?? options.loose ?? true;
|
|
18
18
|
if (options.classProperties) {
|
|
19
19
|
devkit_1.logger.warn(`Use =\`loose\` option instead of \`classProperties.loose\`. The \`classProperties\` option will be removed in Nx 19`);
|
package/generators.json
CHANGED
|
@@ -41,6 +41,12 @@
|
|
|
41
41
|
"schema": "./src/generators/setup-build/schema.json",
|
|
42
42
|
"alias": ["build"],
|
|
43
43
|
"description": "setup-build generator"
|
|
44
|
+
},
|
|
45
|
+
"sync": {
|
|
46
|
+
"factory": "./src/generators/sync/sync#syncGenerator",
|
|
47
|
+
"schema": "./src/generators/sync/schema.json",
|
|
48
|
+
"description": "Synchronize TypeScript project references based on the project graph",
|
|
49
|
+
"hidden": true
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
}
|
package/migrations.json
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generators": {
|
|
3
|
-
"rename-swcrc-config": {
|
|
4
|
-
"cli": "nx",
|
|
5
|
-
"version": "15.8.0-beta.0",
|
|
6
|
-
"description": "Rename .lib.swcrc to .swcrc for better SWC support throughout the workspace",
|
|
7
|
-
"factory": "./src/migrations/update-15-8-0/rename-swcrc-config"
|
|
8
|
-
},
|
|
9
3
|
"update-16-0-0-add-nx-packages": {
|
|
10
4
|
"cli": "nx",
|
|
11
5
|
"version": "16.0.0-beta.1",
|
|
@@ -32,18 +26,6 @@
|
|
|
32
26
|
}
|
|
33
27
|
},
|
|
34
28
|
"packageJsonUpdates": {
|
|
35
|
-
"15.8.0": {
|
|
36
|
-
"version": "15.8.0-beta.2",
|
|
37
|
-
"x-prompt": "Do you want to update to TypeScript v4.9?",
|
|
38
|
-
"requires": {
|
|
39
|
-
"typescript": ">=4.8.2 <4.9.0"
|
|
40
|
-
},
|
|
41
|
-
"packages": {
|
|
42
|
-
"typescript": {
|
|
43
|
-
"version": "~4.9.5"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
29
|
"16.0.0": {
|
|
48
30
|
"version": "16.0.0-beta.3",
|
|
49
31
|
"packages": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/js",
|
|
3
|
-
"version": "19.0.0-beta.
|
|
3
|
+
"version": "19.0.0-beta.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The JS plugin for Nx contains executors and generators that provide the best experience for developing JavaScript and TypeScript projects. ",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"@babel/preset-env": "^7.23.2",
|
|
38
38
|
"@babel/preset-typescript": "^7.22.5",
|
|
39
39
|
"@babel/runtime": "^7.22.6",
|
|
40
|
-
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
41
40
|
"babel-plugin-const-enum": "^1.0.1",
|
|
42
41
|
"babel-plugin-macros": "^2.8.0",
|
|
43
42
|
"babel-plugin-transform-typescript-metadata": "^0.3.1",
|
|
@@ -57,9 +56,9 @@
|
|
|
57
56
|
"semver": "^7.5.3",
|
|
58
57
|
"source-map-support": "0.5.19",
|
|
59
58
|
"tslib": "^2.3.0",
|
|
60
|
-
"@nx/devkit": "19.0.0-beta.
|
|
61
|
-
"@nx/workspace": "19.0.0-beta.
|
|
62
|
-
"@nrwl/js": "19.0.0-beta.
|
|
59
|
+
"@nx/devkit": "19.0.0-beta.10",
|
|
60
|
+
"@nx/workspace": "19.0.0-beta.10",
|
|
61
|
+
"@nrwl/js": "19.0.0-beta.10"
|
|
63
62
|
},
|
|
64
63
|
"peerDependencies": {
|
|
65
64
|
"verdaccio": "^5.0.4"
|
|
@@ -297,7 +297,7 @@ function getFileToRun(context, project, buildOptions, buildTargetExecutor) {
|
|
|
297
297
|
function fileToRunCorrectPath(fileToRun) {
|
|
298
298
|
if ((0, fileutils_1.fileExists)(fileToRun))
|
|
299
299
|
return fileToRun;
|
|
300
|
-
const extensionsToTry = ['.cjs', '.mjs', 'cjs.js', '.esm.js'];
|
|
300
|
+
const extensionsToTry = ['.cjs', '.mjs', '.cjs.js', '.esm.js'];
|
|
301
301
|
for (const ext of extensionsToTry) {
|
|
302
302
|
const file = fileToRun.replace(/\.js$/, ext);
|
|
303
303
|
if ((0, fileutils_1.fileExists)(file))
|
|
@@ -8,6 +8,10 @@ const detectPort = require("detect-port");
|
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const semver_1 = require("semver");
|
|
10
10
|
let childProcess;
|
|
11
|
+
let env = {
|
|
12
|
+
SKIP_YARN_COREPACK_CHECK: 'true',
|
|
13
|
+
...process.env,
|
|
14
|
+
};
|
|
11
15
|
/**
|
|
12
16
|
* - set npm and yarn to use local registry
|
|
13
17
|
* - start verdaccio
|
|
@@ -104,19 +108,19 @@ function createVerdaccioOptions(options, workspaceRoot) {
|
|
|
104
108
|
}
|
|
105
109
|
function setupNpm(options) {
|
|
106
110
|
try {
|
|
107
|
-
(0, child_process_1.execSync)('npm --version');
|
|
111
|
+
(0, child_process_1.execSync)('npm --version', { env });
|
|
108
112
|
}
|
|
109
113
|
catch (e) {
|
|
110
114
|
return () => { };
|
|
111
115
|
}
|
|
112
116
|
let npmRegistryPath;
|
|
113
117
|
try {
|
|
114
|
-
npmRegistryPath = (0, child_process_1.execSync)(`npm config get registry --location ${options.location}
|
|
118
|
+
npmRegistryPath = (0, child_process_1.execSync)(`npm config get registry --location ${options.location}`, { env })
|
|
115
119
|
?.toString()
|
|
116
120
|
?.trim()
|
|
117
121
|
?.replace('\u001b[2K\u001b[1G', ''); // strip out ansi codes
|
|
118
|
-
(0, child_process_1.execSync)(`npm config set registry http://localhost:${options.port}/ --location ${options.location}
|
|
119
|
-
(0, child_process_1.execSync)(`npm config set //localhost:${options.port}/:_authToken="secretVerdaccioToken" --location ${options.location}
|
|
122
|
+
(0, child_process_1.execSync)(`npm config set registry http://localhost:${options.port}/ --location ${options.location}`, { env });
|
|
123
|
+
(0, child_process_1.execSync)(`npm config set //localhost:${options.port}/:_authToken="secretVerdaccioToken" --location ${options.location}`, { env });
|
|
120
124
|
devkit_1.logger.info(`Set npm registry to http://localhost:${options.port}/`);
|
|
121
125
|
}
|
|
122
126
|
catch (e) {
|
|
@@ -124,19 +128,21 @@ function setupNpm(options) {
|
|
|
124
128
|
}
|
|
125
129
|
return () => {
|
|
126
130
|
try {
|
|
127
|
-
const currentNpmRegistryPath = (0, child_process_1.execSync)(`npm config get registry --location ${options.location}
|
|
131
|
+
const currentNpmRegistryPath = (0, child_process_1.execSync)(`npm config get registry --location ${options.location}`, { env })
|
|
128
132
|
?.toString()
|
|
129
133
|
?.trim()
|
|
130
134
|
?.replace('\u001b[2K\u001b[1G', ''); // strip out ansi codes
|
|
131
135
|
if (npmRegistryPath && currentNpmRegistryPath.includes('localhost')) {
|
|
132
|
-
(0, child_process_1.execSync)(`npm config set registry ${npmRegistryPath} --location ${options.location}
|
|
136
|
+
(0, child_process_1.execSync)(`npm config set registry ${npmRegistryPath} --location ${options.location}`, { env });
|
|
133
137
|
devkit_1.logger.info(`Reset npm registry to ${npmRegistryPath}`);
|
|
134
138
|
}
|
|
135
139
|
else {
|
|
136
|
-
(0, child_process_1.execSync)(`npm config delete registry --location ${options.location}
|
|
140
|
+
(0, child_process_1.execSync)(`npm config delete registry --location ${options.location}`, {
|
|
141
|
+
env,
|
|
142
|
+
});
|
|
137
143
|
devkit_1.logger.info('Cleared custom npm registry');
|
|
138
144
|
}
|
|
139
|
-
(0, child_process_1.execSync)(`npm config delete //localhost:${options.port}/:_authToken --location ${options.location}
|
|
145
|
+
(0, child_process_1.execSync)(`npm config delete //localhost:${options.port}/:_authToken --location ${options.location}`, { env });
|
|
140
146
|
}
|
|
141
147
|
catch (e) {
|
|
142
148
|
throw new Error(`Failed to reset npm registry: ${e.message}`);
|
|
@@ -145,22 +151,25 @@ function setupNpm(options) {
|
|
|
145
151
|
}
|
|
146
152
|
function getYarnUnsafeHttpWhitelist(isYarnV1) {
|
|
147
153
|
return !isYarnV1
|
|
148
|
-
? new Set(JSON.parse((0, child_process_1.execSync)(`yarn config get unsafeHttpWhitelist --json
|
|
154
|
+
? new Set(JSON.parse((0, child_process_1.execSync)(`yarn config get unsafeHttpWhitelist --json`, {
|
|
155
|
+
env,
|
|
156
|
+
}).toString()))
|
|
149
157
|
: null;
|
|
150
158
|
}
|
|
151
159
|
function setYarnUnsafeHttpWhitelist(currentWhitelist, options) {
|
|
152
160
|
if (currentWhitelist.size > 0) {
|
|
153
|
-
(0, child_process_1.execSync)(`yarn config set unsafeHttpWhitelist --json '${JSON.stringify(Array.from(currentWhitelist))}'` + (options.location === 'user' ? ' --home' : ''));
|
|
161
|
+
(0, child_process_1.execSync)(`yarn config set unsafeHttpWhitelist --json '${JSON.stringify(Array.from(currentWhitelist))}'` + (options.location === 'user' ? ' --home' : ''), { env });
|
|
154
162
|
}
|
|
155
163
|
else {
|
|
156
164
|
(0, child_process_1.execSync)(`yarn config unset unsafeHttpWhitelist` +
|
|
157
|
-
(options.location === 'user' ? ' --home' : ''));
|
|
165
|
+
(options.location === 'user' ? ' --home' : ''), { env });
|
|
158
166
|
}
|
|
159
167
|
}
|
|
160
168
|
function setupYarn(options) {
|
|
161
169
|
let isYarnV1;
|
|
162
170
|
try {
|
|
163
|
-
isYarnV1 =
|
|
171
|
+
isYarnV1 =
|
|
172
|
+
(0, semver_1.major)((0, child_process_1.execSync)('yarn --version', { env }).toString().trim()) === 1;
|
|
164
173
|
}
|
|
165
174
|
catch {
|
|
166
175
|
// This would fail if yarn is not installed which is okay
|
|
@@ -168,12 +177,14 @@ function setupYarn(options) {
|
|
|
168
177
|
}
|
|
169
178
|
try {
|
|
170
179
|
const registryConfigName = isYarnV1 ? 'registry' : 'npmRegistryServer';
|
|
171
|
-
const yarnRegistryPath = (0, child_process_1.execSync)(`yarn config get ${registryConfigName}
|
|
180
|
+
const yarnRegistryPath = (0, child_process_1.execSync)(`yarn config get ${registryConfigName}`, {
|
|
181
|
+
env,
|
|
182
|
+
})
|
|
172
183
|
?.toString()
|
|
173
184
|
?.trim()
|
|
174
185
|
?.replace('\u001b[2K\u001b[1G', ''); // strip out ansi codes
|
|
175
186
|
(0, child_process_1.execSync)(`yarn config set ${registryConfigName} http://localhost:${options.port}/` +
|
|
176
|
-
(options.location === 'user' ? ' --home' : ''));
|
|
187
|
+
(options.location === 'user' ? ' --home' : ''), { env });
|
|
177
188
|
devkit_1.logger.info(`Set yarn registry to http://localhost:${options.port}/`);
|
|
178
189
|
const currentWhitelist = getYarnUnsafeHttpWhitelist(isYarnV1);
|
|
179
190
|
let whitelistedLocalhost = false;
|
|
@@ -185,18 +196,18 @@ function setupYarn(options) {
|
|
|
185
196
|
}
|
|
186
197
|
return () => {
|
|
187
198
|
try {
|
|
188
|
-
const currentYarnRegistryPath = (0, child_process_1.execSync)(`yarn config get ${registryConfigName}
|
|
199
|
+
const currentYarnRegistryPath = (0, child_process_1.execSync)(`yarn config get ${registryConfigName}`, { env })
|
|
189
200
|
?.toString()
|
|
190
201
|
?.trim()
|
|
191
202
|
?.replace('\u001b[2K\u001b[1G', ''); // strip out ansi codes
|
|
192
203
|
if (yarnRegistryPath && currentYarnRegistryPath.includes('localhost')) {
|
|
193
204
|
(0, child_process_1.execSync)(`yarn config set ${registryConfigName} ${yarnRegistryPath}` +
|
|
194
|
-
(options.location === 'user' ? ' --home' : ''));
|
|
205
|
+
(options.location === 'user' ? ' --home' : ''), { env });
|
|
195
206
|
devkit_1.logger.info(`Reset yarn ${registryConfigName} to ${yarnRegistryPath}`);
|
|
196
207
|
}
|
|
197
208
|
else {
|
|
198
209
|
(0, child_process_1.execSync)(`yarn config ${isYarnV1 ? 'delete' : 'unset'} ${registryConfigName}` +
|
|
199
|
-
(options.location === 'user' ? ' --home' : ''));
|
|
210
|
+
(options.location === 'user' ? ' --home' : ''), { env });
|
|
200
211
|
devkit_1.logger.info(`Cleared custom yarn ${registryConfigName}`);
|
|
201
212
|
}
|
|
202
213
|
if (whitelistedLocalhost) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export interface SyncSchema {}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.syncGenerator = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const plugin_1 = require("../../plugins/typescript/plugin");
|
|
7
|
+
async function syncGenerator(tree, options) {
|
|
8
|
+
// Ensure that the plugin has been wired up in nx.json
|
|
9
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
10
|
+
let tscPluginConfig = nxJson.plugins.find((p) => {
|
|
11
|
+
if (typeof p === 'string') {
|
|
12
|
+
return p === plugin_1.PLUGIN_NAME;
|
|
13
|
+
}
|
|
14
|
+
return p.plugin === plugin_1.PLUGIN_NAME;
|
|
15
|
+
});
|
|
16
|
+
if (!tscPluginConfig) {
|
|
17
|
+
throw new Error(`The ${plugin_1.PLUGIN_NAME} plugin must be added to the "plugins" array in nx.json before syncing tsconfigs`);
|
|
18
|
+
}
|
|
19
|
+
const projectGraph = await (0, devkit_1.createProjectGraphAsync)();
|
|
20
|
+
const firstPartyDeps = Object.entries(projectGraph.dependencies).filter(([name, data]) => !name.startsWith('npm:') && data.length > 0);
|
|
21
|
+
// Root tsconfig containing project references for the whole workspace
|
|
22
|
+
const rootTsconfigPath = 'tsconfig.json';
|
|
23
|
+
const rootTsconfig = (0, devkit_1.readJson)(tree, rootTsconfigPath);
|
|
24
|
+
const tsconfigProjectNodeValues = Object.values(projectGraph.nodes).filter((node) => {
|
|
25
|
+
const projectTsconfigPath = (0, devkit_1.joinPathFragments)(node.data.root, 'tsconfig.json');
|
|
26
|
+
return tree.exists(projectTsconfigPath);
|
|
27
|
+
});
|
|
28
|
+
if (tsconfigProjectNodeValues.length > 0) {
|
|
29
|
+
// Sync the root tsconfig references from the project graph (do not destroy existing references)
|
|
30
|
+
rootTsconfig.references = rootTsconfig.references || [];
|
|
31
|
+
const referencesSet = new Set(rootTsconfig.references.map((ref) => normalizeReferencePath(ref.path)));
|
|
32
|
+
for (const node of tsconfigProjectNodeValues) {
|
|
33
|
+
const normalizedPath = normalizeReferencePath(node.data.root);
|
|
34
|
+
// Skip the root tsconfig itself
|
|
35
|
+
if (node.data.root !== '.' && !referencesSet.has(normalizedPath)) {
|
|
36
|
+
rootTsconfig.references.push({ path: `./${normalizedPath}` });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
(0, devkit_1.writeJson)(tree, rootTsconfigPath, rootTsconfig);
|
|
40
|
+
}
|
|
41
|
+
for (const [name, data] of firstPartyDeps) {
|
|
42
|
+
// Get the source project nodes for the source and target
|
|
43
|
+
const sourceProjectNode = projectGraph.nodes[name];
|
|
44
|
+
// Find the relevant tsconfig files for the source project
|
|
45
|
+
const sourceProjectTsconfigPath = (0, devkit_1.joinPathFragments)(sourceProjectNode.data.root, 'tsconfig.json');
|
|
46
|
+
if (!tree.exists(sourceProjectTsconfigPath)) {
|
|
47
|
+
console.warn(`Skipping project "${name}" as there is no tsconfig.json file found in the project root "${sourceProjectNode.data.root}"`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const sourceTsconfig = (0, devkit_1.readJson)(tree, sourceProjectTsconfigPath);
|
|
51
|
+
for (const dep of data) {
|
|
52
|
+
// Get the target project node
|
|
53
|
+
const targetProjectNode = projectGraph.nodes[dep.target];
|
|
54
|
+
if (!targetProjectNode) {
|
|
55
|
+
// It's an external dependency
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Set defaults only in the case where we have at least one dependency so that we don't patch files when not necessary
|
|
59
|
+
sourceTsconfig.references = sourceTsconfig.references || [];
|
|
60
|
+
// Ensure the project reference for the target is set
|
|
61
|
+
const relativePathToTargetRoot = (0, node_path_1.relative)(sourceProjectNode.data.root, targetProjectNode.data.root);
|
|
62
|
+
if (!sourceTsconfig.references.some((ref) => ref.path === relativePathToTargetRoot)) {
|
|
63
|
+
// Make sure we unshift rather than push so that dependencies are built in the right order by TypeScript when it is run directly from the root of the workspace
|
|
64
|
+
sourceTsconfig.references.unshift({ path: relativePathToTargetRoot });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Update the source tsconfig files
|
|
68
|
+
(0, devkit_1.writeJson)(tree, sourceProjectTsconfigPath, sourceTsconfig);
|
|
69
|
+
}
|
|
70
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
71
|
+
}
|
|
72
|
+
exports.syncGenerator = syncGenerator;
|
|
73
|
+
// Normalize the paths to strip leading `./` and trailing `/tsconfig.json`
|
|
74
|
+
function normalizeReferencePath(path) {
|
|
75
|
+
return path.replace(/\/tsconfig.json$/, '').replace(/^\.\//, '');
|
|
76
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CreateDependencies, type CreateNodes } from '@nx/devkit';
|
|
2
|
+
export interface TscPluginOptions {
|
|
3
|
+
typecheck?: boolean | {
|
|
4
|
+
targetName?: string;
|
|
5
|
+
};
|
|
6
|
+
build?: boolean | {
|
|
7
|
+
targetName?: string;
|
|
8
|
+
configName?: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare const createDependencies: CreateDependencies;
|
|
12
|
+
export declare const PLUGIN_NAME = "@nx/js/typescript";
|
|
13
|
+
export declare const createNodes: CreateNodes<TscPluginOptions>;
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodes = exports.PLUGIN_NAME = exports.createDependencies = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
|
|
6
|
+
const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const minimatch_1 = require("minimatch");
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
|
11
|
+
const lock_file_1 = require("nx/src/plugins/js/lock-file/lock-file");
|
|
12
|
+
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
13
|
+
const ts_config_1 = require("../../utils/typescript/ts-config");
|
|
14
|
+
const cachePath = (0, node_path_1.join)(cache_directory_1.projectGraphCacheDirectory, 'tsc.hash');
|
|
15
|
+
const targetsCache = (0, node_fs_1.existsSync)(cachePath) ? readTargetsCache() : {};
|
|
16
|
+
const calculatedTargets = {};
|
|
17
|
+
function readTargetsCache() {
|
|
18
|
+
return (0, devkit_1.readJsonFile)(cachePath);
|
|
19
|
+
}
|
|
20
|
+
function writeTargetsToCache(targets) {
|
|
21
|
+
(0, devkit_1.writeJsonFile)(cachePath, targets);
|
|
22
|
+
}
|
|
23
|
+
const createDependencies = () => {
|
|
24
|
+
writeTargetsToCache(calculatedTargets);
|
|
25
|
+
return [];
|
|
26
|
+
};
|
|
27
|
+
exports.createDependencies = createDependencies;
|
|
28
|
+
exports.PLUGIN_NAME = '@nx/js/typescript';
|
|
29
|
+
exports.createNodes = [
|
|
30
|
+
'**/tsconfig*.json',
|
|
31
|
+
(configFilePath, options, context) => {
|
|
32
|
+
const pluginOptions = normalizePluginOptions(options);
|
|
33
|
+
const projectRoot = (0, node_path_1.dirname)(configFilePath);
|
|
34
|
+
const fullConfigPath = (0, devkit_1.joinPathFragments)(context.workspaceRoot, configFilePath);
|
|
35
|
+
// Do not create a project if package.json and project.json isn't there.
|
|
36
|
+
const siblingFiles = (0, node_fs_1.readdirSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot));
|
|
37
|
+
if (!siblingFiles.includes('package.json') &&
|
|
38
|
+
!siblingFiles.includes('project.json')) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
// Do not create a project if it's not a tsconfig.json and there is no tsconfig.json in the same directory
|
|
42
|
+
if ((0, node_path_1.basename)(configFilePath) !== 'tsconfig.json' &&
|
|
43
|
+
!siblingFiles.includes('tsconfig.json')) {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
const nodeHash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, pluginOptions, context, [(0, lock_file_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot))]);
|
|
47
|
+
// The hash is calculated at the node/project level, so we add the config file path to avoid conflicts when caching
|
|
48
|
+
const cacheKey = `${nodeHash}_${configFilePath}`;
|
|
49
|
+
const targets = targetsCache[cacheKey]
|
|
50
|
+
? targetsCache[cacheKey]
|
|
51
|
+
: buildTscTargets(fullConfigPath, projectRoot, pluginOptions, context);
|
|
52
|
+
calculatedTargets[cacheKey] = targets;
|
|
53
|
+
return {
|
|
54
|
+
projects: {
|
|
55
|
+
[projectRoot]: {
|
|
56
|
+
projectType: 'library',
|
|
57
|
+
targets,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
64
|
+
const targets = {};
|
|
65
|
+
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
66
|
+
const tsConfig = readCachedTsConfig(configFilePath);
|
|
67
|
+
// TODO: check whether we want to always run with --pretty --verbose, it makes replacing scripts harder
|
|
68
|
+
// `--verbose` conflicts with `tsc -b --clean`, might be another reason for not using it, it would
|
|
69
|
+
// prevent users from running the task with `--clean` flag.
|
|
70
|
+
// Should we consider creating a different optional target for `--clean`?
|
|
71
|
+
// Should we consider having a plugin option to disable `--pretty` and `--verbose`?
|
|
72
|
+
let internalProjectReferences;
|
|
73
|
+
// Typecheck target
|
|
74
|
+
if ((0, node_path_1.basename)(configFilePath) === 'tsconfig.json' && options.typecheck) {
|
|
75
|
+
internalProjectReferences = resolveInternalProjectReferences(configFilePath, tsConfig);
|
|
76
|
+
const targetName = options.typecheck.targetName;
|
|
77
|
+
if (!targets[targetName]) {
|
|
78
|
+
let command = `tsc --build --emitDeclarationOnly --pretty --verbose`;
|
|
79
|
+
if (tsConfig.options.noEmit ||
|
|
80
|
+
Object.values(internalProjectReferences).some((ref) => ref.options.noEmit)) {
|
|
81
|
+
// `--emitDeclarationOnly` and `--noEmit` are mutually exclusive, so
|
|
82
|
+
// we remove `--emitDeclarationOnly` if `--noEmit` is set.
|
|
83
|
+
command = `tsc --build --pretty --verbose`;
|
|
84
|
+
}
|
|
85
|
+
targets[targetName] = {
|
|
86
|
+
dependsOn: [`^${targetName}`],
|
|
87
|
+
command,
|
|
88
|
+
options: { cwd: projectRoot },
|
|
89
|
+
cache: true,
|
|
90
|
+
inputs: getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
|
|
91
|
+
outputs: getOutputs(configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Build target
|
|
96
|
+
if (options.build && (0, node_path_1.basename)(configFilePath) === options.build.configName) {
|
|
97
|
+
internalProjectReferences ??= resolveInternalProjectReferences(configFilePath, tsConfig);
|
|
98
|
+
const targetName = options.build.targetName;
|
|
99
|
+
targets[targetName] = {
|
|
100
|
+
dependsOn: [`^${targetName}`],
|
|
101
|
+
command: `tsc --build ${options.build.configName} --pretty --verbose`,
|
|
102
|
+
options: { cwd: projectRoot },
|
|
103
|
+
cache: true,
|
|
104
|
+
inputs: getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
|
|
105
|
+
outputs: getOutputs(configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return targets;
|
|
109
|
+
}
|
|
110
|
+
function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
|
|
111
|
+
const configFiles = new Set();
|
|
112
|
+
const includePaths = new Set();
|
|
113
|
+
const excludePaths = new Set();
|
|
114
|
+
const extendedConfigFiles = getExtendedConfigFiles(configFilePath, tsConfig);
|
|
115
|
+
extendedConfigFiles.forEach((configPath) => {
|
|
116
|
+
configFiles.add(configPath);
|
|
117
|
+
});
|
|
118
|
+
const projectTsConfigFiles = [
|
|
119
|
+
[configFilePath, tsConfig],
|
|
120
|
+
...Object.entries(internalProjectReferences),
|
|
121
|
+
];
|
|
122
|
+
projectTsConfigFiles.forEach(([configPath, config]) => {
|
|
123
|
+
configFiles.add(configPath);
|
|
124
|
+
(config.raw?.include ?? []).forEach((p) => includePaths.add(p));
|
|
125
|
+
if (config.raw?.exclude) {
|
|
126
|
+
/**
|
|
127
|
+
* We need to filter out the exclude paths that are already included in
|
|
128
|
+
* other tsconfig files. If they are not included in other tsconfig files,
|
|
129
|
+
* they still correctly apply to the current file and we should keep them.
|
|
130
|
+
*/
|
|
131
|
+
const otherFilesInclude = [];
|
|
132
|
+
projectTsConfigFiles.forEach(([path, c]) => {
|
|
133
|
+
if (path !== configPath) {
|
|
134
|
+
otherFilesInclude.push(...(c.raw?.include ?? []));
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const normalize = (p) => (p.startsWith('./') ? p.slice(2) : p);
|
|
138
|
+
config.raw.exclude.forEach((excludePath) => {
|
|
139
|
+
if (!otherFilesInclude.some((includePath) => (0, minimatch_1.minimatch)(normalize(includePath), normalize(excludePath)) ||
|
|
140
|
+
(0, minimatch_1.minimatch)(normalize(excludePath), normalize(includePath)))) {
|
|
141
|
+
excludePaths.add(excludePath);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
const inputs = [];
|
|
147
|
+
if (includePaths.size) {
|
|
148
|
+
inputs.push(...Array.from(configFiles).map((p) => pathToInputOrOutput(p, workspaceRoot, projectRoot)), ...Array.from(includePaths).map((p) => (0, devkit_1.joinPathFragments)('{projectRoot}', p)));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// If we couldn't identify any include paths, we default to the default
|
|
152
|
+
// named inputs.
|
|
153
|
+
inputs.push('production' in namedInputs ? 'production' : 'default');
|
|
154
|
+
}
|
|
155
|
+
if (excludePaths.size) {
|
|
156
|
+
inputs.push(...Array.from(excludePaths).map((p) => `!${(0, devkit_1.joinPathFragments)('{projectRoot}', p)}`));
|
|
157
|
+
}
|
|
158
|
+
if (hasExternalProjectReferences(configFilePath, tsConfig)) {
|
|
159
|
+
// Importing modules from a referenced project will load its output declaration files (d.ts)
|
|
160
|
+
// https://www.typescriptlang.org/docs/handbook/project-references.html#what-is-a-project-reference
|
|
161
|
+
inputs.push({ dependentTasksOutputFiles: '**/*.d.ts' });
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
inputs.push('production' in namedInputs ? '^production' : '^default');
|
|
165
|
+
}
|
|
166
|
+
inputs.push({ externalDependencies: ['typescript'] });
|
|
167
|
+
return inputs;
|
|
168
|
+
}
|
|
169
|
+
function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
|
|
170
|
+
const outputs = new Set();
|
|
171
|
+
// We could have more surgical outputs based on the tsconfig options, but the
|
|
172
|
+
// user could override them through the command line and that wouldn't be
|
|
173
|
+
// reflected in the outputs. So, we just include everything that could be
|
|
174
|
+
// produced by the tsc command.
|
|
175
|
+
[tsConfig, ...Object.values(internalProjectReferences)].forEach((config) => {
|
|
176
|
+
if (config.options.outFile) {
|
|
177
|
+
const outFileName = (0, node_path_1.basename)(config.options.outFile, '.js');
|
|
178
|
+
const outFileDir = (0, node_path_1.dirname)(config.options.outFile);
|
|
179
|
+
outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', (0, node_path_1.relative)(workspaceRoot, config.options.outFile)));
|
|
180
|
+
// outFile is not be used with .cjs, .mjs, .jsx, so the list is simpler
|
|
181
|
+
const outDir = (0, node_path_1.relative)(workspaceRoot, outFileDir);
|
|
182
|
+
outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.js.map`));
|
|
183
|
+
outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.d.ts`));
|
|
184
|
+
outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.d.ts.map`));
|
|
185
|
+
// https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
|
|
186
|
+
outputs.add(tsConfig.options.tsBuildInfoFile
|
|
187
|
+
? pathToInputOrOutput(tsConfig.options.tsBuildInfoFile, workspaceRoot, projectRoot)
|
|
188
|
+
: (0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.tsbuildinfo`));
|
|
189
|
+
}
|
|
190
|
+
else if (config.options.outDir) {
|
|
191
|
+
outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', (0, node_path_1.relative)(workspaceRoot, config.options.outDir)));
|
|
192
|
+
}
|
|
193
|
+
else if (config.fileNames.length) {
|
|
194
|
+
// tsc produce files in place when no outDir or outFile is set
|
|
195
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.js'));
|
|
196
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.cjs'));
|
|
197
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.mjs'));
|
|
198
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.jsx'));
|
|
199
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.js.map')); // should also include .cjs and .mjs data
|
|
200
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.jsx.map'));
|
|
201
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.d.ts'));
|
|
202
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.d.cts'));
|
|
203
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.d.mts'));
|
|
204
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.d.ts.map'));
|
|
205
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.d.cts.map'));
|
|
206
|
+
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.d.mts.map'));
|
|
207
|
+
// https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
|
|
208
|
+
const name = (0, node_path_1.basename)(configFilePath, '.json');
|
|
209
|
+
outputs.add(tsConfig.options.tsBuildInfoFile
|
|
210
|
+
? pathToInputOrOutput(tsConfig.options.tsBuildInfoFile, workspaceRoot, projectRoot)
|
|
211
|
+
: (0, devkit_1.joinPathFragments)('{projectRoot}', `${name}.tsbuildinfo`));
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
return Array.from(outputs);
|
|
215
|
+
}
|
|
216
|
+
function pathToInputOrOutput(path, workspaceRoot, projectRoot) {
|
|
217
|
+
const pathRelativeToProjectRoot = (0, devkit_1.normalizePath)((0, node_path_1.relative)(projectRoot, path));
|
|
218
|
+
if (pathRelativeToProjectRoot.startsWith('..')) {
|
|
219
|
+
return (0, devkit_1.joinPathFragments)('{workspaceRoot}', (0, node_path_1.relative)(workspaceRoot, path));
|
|
220
|
+
}
|
|
221
|
+
return (0, devkit_1.joinPathFragments)('{projectRoot}', pathRelativeToProjectRoot);
|
|
222
|
+
}
|
|
223
|
+
function getExtendedConfigFiles(tsConfigPath, tsConfig) {
|
|
224
|
+
const extendedConfigFiles = new Set();
|
|
225
|
+
let currentConfigPath = tsConfigPath;
|
|
226
|
+
let currentConfig = tsConfig;
|
|
227
|
+
while (currentConfig.raw?.extends) {
|
|
228
|
+
const extendedConfigPath = (0, node_path_1.join)((0, node_path_1.dirname)(currentConfigPath), currentConfig.raw.extends);
|
|
229
|
+
extendedConfigFiles.add(extendedConfigPath);
|
|
230
|
+
const extendedConfig = readCachedTsConfig(extendedConfigPath);
|
|
231
|
+
currentConfigPath = extendedConfigPath;
|
|
232
|
+
currentConfig = extendedConfig;
|
|
233
|
+
}
|
|
234
|
+
return Array.from(extendedConfigFiles);
|
|
235
|
+
}
|
|
236
|
+
function resolveInternalProjectReferences(configFilePath, tsConfig, projectReferences = {}) {
|
|
237
|
+
if (!tsConfig.projectReferences?.length) {
|
|
238
|
+
return projectReferences;
|
|
239
|
+
}
|
|
240
|
+
const basePath = getTsConfigBasePath(configFilePath);
|
|
241
|
+
for (const ref of tsConfig.projectReferences) {
|
|
242
|
+
let refConfigPath = ref.path;
|
|
243
|
+
if (projectReferences[refConfigPath]) {
|
|
244
|
+
// Already resolved
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (isExternalProjectReference(refConfigPath, basePath)) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (!refConfigPath.endsWith('.json')) {
|
|
251
|
+
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
252
|
+
}
|
|
253
|
+
const refTsConfig = readCachedTsConfig(refConfigPath);
|
|
254
|
+
projectReferences[refConfigPath] = refTsConfig;
|
|
255
|
+
resolveInternalProjectReferences(refConfigPath, refTsConfig, projectReferences);
|
|
256
|
+
}
|
|
257
|
+
return projectReferences;
|
|
258
|
+
}
|
|
259
|
+
function hasExternalProjectReferences(tsConfigPath, tsConfig, seen = new Set()) {
|
|
260
|
+
if (!tsConfig.projectReferences?.length) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
seen.add(tsConfigPath);
|
|
264
|
+
const basePath = getTsConfigBasePath(tsConfigPath);
|
|
265
|
+
for (const ref of tsConfig.projectReferences) {
|
|
266
|
+
let refConfigPath = ref.path;
|
|
267
|
+
if (seen.has(refConfigPath)) {
|
|
268
|
+
// Already seen
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (isExternalProjectReference(refConfigPath, basePath)) {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
if (!refConfigPath.endsWith('.json')) {
|
|
275
|
+
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
276
|
+
}
|
|
277
|
+
const refTsConfig = readCachedTsConfig(refConfigPath);
|
|
278
|
+
const result = hasExternalProjectReferences(refConfigPath, refTsConfig);
|
|
279
|
+
if (result) {
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
function isExternalProjectReference(refTsConfigPath, basePath) {
|
|
286
|
+
const refBasePath = getTsConfigBasePath(refTsConfigPath);
|
|
287
|
+
// TODO: there could be internal project references in nested dirs (e.g.
|
|
288
|
+
// our storybook generator generates a nested `.storybook/tsconfig.json`),
|
|
289
|
+
// which would be considered an external project reference but it's not.
|
|
290
|
+
// We could instead check if the referenced tsconfig is outside the project
|
|
291
|
+
// root, but that would cause issues with standalone workspaces with nested
|
|
292
|
+
// projects.
|
|
293
|
+
return refBasePath !== basePath;
|
|
294
|
+
}
|
|
295
|
+
function getTsConfigBasePath(tsConfigPath) {
|
|
296
|
+
return (0, node_fs_1.statSync)(tsConfigPath).isFile() ? (0, node_path_1.dirname)(tsConfigPath) : tsConfigPath;
|
|
297
|
+
}
|
|
298
|
+
// TODO: we could probably persist this to disk to avoid reading the same
|
|
299
|
+
// tsconfig files over multiple runs
|
|
300
|
+
const tsConfigCache = new Map();
|
|
301
|
+
function readCachedTsConfig(tsConfigPath) {
|
|
302
|
+
const cacheKey = getTsConfigCacheKey(tsConfigPath);
|
|
303
|
+
if (tsConfigCache.has(cacheKey)) {
|
|
304
|
+
return tsConfigCache.get(cacheKey);
|
|
305
|
+
}
|
|
306
|
+
const tsConfig = (0, ts_config_1.readTsConfig)(tsConfigPath);
|
|
307
|
+
tsConfigCache.set(cacheKey, tsConfig);
|
|
308
|
+
return tsConfig;
|
|
309
|
+
}
|
|
310
|
+
function getTsConfigCacheKey(tsConfigPath) {
|
|
311
|
+
const timestamp = (0, node_fs_1.statSync)(tsConfigPath).mtimeMs;
|
|
312
|
+
return `${tsConfigPath}-${timestamp}`;
|
|
313
|
+
}
|
|
314
|
+
function normalizePluginOptions(pluginOptions = {}) {
|
|
315
|
+
const defaultTypecheckTargetName = 'typecheck';
|
|
316
|
+
let typecheck = {
|
|
317
|
+
targetName: defaultTypecheckTargetName,
|
|
318
|
+
};
|
|
319
|
+
if (pluginOptions.typecheck === false) {
|
|
320
|
+
typecheck = false;
|
|
321
|
+
}
|
|
322
|
+
else if (pluginOptions.typecheck &&
|
|
323
|
+
typeof pluginOptions.typecheck !== 'boolean') {
|
|
324
|
+
typecheck = {
|
|
325
|
+
targetName: pluginOptions.typecheck.targetName ?? defaultTypecheckTargetName,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
const defaultBuildTargetName = 'build';
|
|
329
|
+
const defaultBuildConfigName = 'tsconfig.lib.json';
|
|
330
|
+
let build = {
|
|
331
|
+
targetName: defaultBuildTargetName,
|
|
332
|
+
configName: defaultBuildConfigName,
|
|
333
|
+
};
|
|
334
|
+
// Build target is not enabled by default
|
|
335
|
+
if (!pluginOptions.build) {
|
|
336
|
+
build = false;
|
|
337
|
+
}
|
|
338
|
+
else if (pluginOptions.build && typeof pluginOptions.build !== 'boolean') {
|
|
339
|
+
build = {
|
|
340
|
+
targetName: pluginOptions.build.targetName ?? defaultBuildTargetName,
|
|
341
|
+
configName: pluginOptions.build.configName ?? defaultBuildConfigName,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
typecheck,
|
|
346
|
+
build,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CopyAssetsHandler = exports.defaultFileEventHandler = void 0;
|
|
4
4
|
const minimatch_1 = require("minimatch");
|
|
5
|
-
const path = require("path");
|
|
5
|
+
const path = require("node:path/posix");
|
|
6
6
|
const fse = require("fs-extra");
|
|
7
7
|
const ignore_1 = require("ignore");
|
|
8
8
|
const fg = require("fast-glob");
|
package/typescript.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createDependencies, createNodes, } from './src/plugins/typescript/plugin';
|
package/typescript.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodes = exports.createDependencies = void 0;
|
|
4
|
+
var plugin_1 = require("./src/plugins/typescript/plugin");
|
|
5
|
+
Object.defineProperty(exports, "createDependencies", { enumerable: true, get: function () { return plugin_1.createDependencies; } });
|
|
6
|
+
Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return plugin_1.createNodes; } });
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
|
|
5
|
-
const tsquery_1 = require("@phenomnomnominal/tsquery");
|
|
6
|
-
async function default_1(tree) {
|
|
7
|
-
let changesMade = false;
|
|
8
|
-
const projects = (0, devkit_1.getProjects)(tree);
|
|
9
|
-
(0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nrwl/js:swc', (_, projectName, target, configurationName) => {
|
|
10
|
-
const projectConfiguration = projects.get(projectName);
|
|
11
|
-
const executorOptions = configurationName
|
|
12
|
-
? projectConfiguration.targets[target].configurations[configurationName]
|
|
13
|
-
: projectConfiguration.targets[target].options;
|
|
14
|
-
// if the project uses a custom path to swcrc file
|
|
15
|
-
// and only if it's the default name
|
|
16
|
-
if (executorOptions.swcrc &&
|
|
17
|
-
executorOptions.swcrc.includes('.lib.swcrc')) {
|
|
18
|
-
const newSwcrc = executorOptions.swcrc.replace('.lib.swcrc', '.swcrc');
|
|
19
|
-
// rename the swcrc file first
|
|
20
|
-
tree.rename(executorOptions.swcrc, newSwcrc);
|
|
21
|
-
// then update the executor options
|
|
22
|
-
executorOptions.swcrc = newSwcrc;
|
|
23
|
-
changesMade = true;
|
|
24
|
-
}
|
|
25
|
-
const libSwcrcPath = (0, devkit_1.joinPathFragments)(projectConfiguration.root, '.lib.swcrc') ||
|
|
26
|
-
(0, devkit_1.joinPathFragments)(projectConfiguration.sourceRoot, '.lib.swcrc');
|
|
27
|
-
const isLibSwcrcExist = tree.exists(libSwcrcPath);
|
|
28
|
-
if (isLibSwcrcExist) {
|
|
29
|
-
tree.rename(libSwcrcPath, libSwcrcPath.replace('.lib.swcrc', '.swcrc'));
|
|
30
|
-
changesMade = true;
|
|
31
|
-
}
|
|
32
|
-
(0, devkit_1.updateProjectConfiguration)(tree, projectName, projectConfiguration);
|
|
33
|
-
});
|
|
34
|
-
(0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nrwl/jest:jest', (_, projectName, target, configurationName) => {
|
|
35
|
-
const projectConfiguration = projects.get(projectName);
|
|
36
|
-
const executorOptions = configurationName
|
|
37
|
-
? projectConfiguration.targets[target].configurations[configurationName]
|
|
38
|
-
: projectConfiguration.targets[target].options;
|
|
39
|
-
const isJestConfigExist = executorOptions.jestConfig && tree.exists(executorOptions.jestConfig);
|
|
40
|
-
if (isJestConfigExist) {
|
|
41
|
-
const jestConfig = tree.read(executorOptions.jestConfig, 'utf-8');
|
|
42
|
-
const jsonParseNodes = tsquery_1.tsquery.query(jestConfig, ':matches(CallExpression:has(Identifier[name="JSON"]):has(Identifier[name="parse"]))');
|
|
43
|
-
if (jsonParseNodes.length) {
|
|
44
|
-
// if we already assign false to swcrc, skip
|
|
45
|
-
if (jestConfig.includes('.swcrc = false')) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
let updatedJestConfig = tsquery_1.tsquery.replace(jestConfig, 'CallExpression:has(Identifier[name="JSON"]):has(Identifier[name="parse"]) TemplateSpan', (templateSpan) => {
|
|
49
|
-
if (templateSpan.literal.text === '/.lib.swcrc') {
|
|
50
|
-
return templateSpan
|
|
51
|
-
.getFullText()
|
|
52
|
-
.replace('.lib.swcrc', '.swcrc');
|
|
53
|
-
}
|
|
54
|
-
return '';
|
|
55
|
-
});
|
|
56
|
-
updatedJestConfig = tsquery_1.tsquery.replace(updatedJestConfig, ':matches(ExportAssignment, BinaryExpression:has(Identifier[name="module"]):has(Identifier[name="exports"]))', (node) => {
|
|
57
|
-
return `
|
|
58
|
-
|
|
59
|
-
// disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves.
|
|
60
|
-
// If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude"
|
|
61
|
-
if (swcJestConfig.swcrc === undefined) {
|
|
62
|
-
swcJestConfig.swcrc = false;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
${node.getFullText()}
|
|
66
|
-
`;
|
|
67
|
-
});
|
|
68
|
-
tree.write(executorOptions.jestConfig, updatedJestConfig);
|
|
69
|
-
changesMade = true;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
if (changesMade) {
|
|
74
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
exports.default = default_1;
|