@nx/plugin 23.2.0-beta.1 → 23.2.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/src/generators/create-package/create-package.js +6 -4
- package/dist/src/generators/create-package/files/create-framework-package/bin/index.ts__tmpl__ +1 -1
- package/dist/src/generators/create-package/files/e2e/__cliName__.spec.ts__tmpl__ +3 -1
- package/dist/src/generators/create-package/schema.d.ts +2 -2
- package/dist/src/generators/create-package/schema.json +2 -2
- package/dist/src/generators/create-package/utils/normalize-schema.d.ts +1 -1
- package/dist/src/generators/e2e-project/e2e.d.ts +1 -1
- package/dist/src/generators/e2e-project/e2e.js +118 -7
- package/dist/src/generators/e2e-project/files/src/__simplePluginName__.spec.ts__tmpl__ +5 -2
- package/dist/src/generators/e2e-project/schema.d.ts +3 -2
- package/dist/src/generators/e2e-project/schema.json +8 -2
- package/dist/src/generators/lint-checks/generator.d.ts +1 -1
- package/dist/src/generators/lint-checks/generator.js +5 -6
- package/dist/src/generators/migration/migration.js +1 -2
- package/dist/src/generators/plugin/files/plugin/src/index.ts__tmpl__ +1 -0
- package/dist/src/generators/plugin/plugin.js +6 -0
- package/dist/src/generators/plugin/schema.d.ts +7 -3
- package/dist/src/generators/plugin/schema.json +11 -5
- package/dist/src/generators/plugin/utils/normalize-schema.d.ts +1 -1
- package/dist/src/generators/preset/generator.js +8 -4
- package/dist/src/generators/preset/schema.d.ts +5 -2
- package/dist/src/generators/preset/schema.json +5 -0
- package/dist/src/utils/testing-utils/nx-project.js +3 -4
- package/dist/src/utils/testing-utils/utils.d.ts +1 -1
- package/dist/src/utils/testing-utils/utils.js +4 -4
- package/package.json +14 -6
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
<div style="text-align: center;">
|
|
9
9
|
|
|
10
|
-
[]()
|
|
10
|
+
[](<>)
|
|
11
11
|
[](https://www.npmjs.com/package/nx)
|
|
12
|
-
[]()
|
|
12
|
+
[](<>)
|
|
13
13
|
[](http://commitizen.github.io/cz-cli/)
|
|
14
14
|
[](https://go.nx.dev/community)
|
|
15
15
|
[](https://nx.dev/docs/features/ci-features/sandboxing)
|
|
@@ -5,11 +5,11 @@ exports.createPackageGeneratorInternal = createPackageGeneratorInternal;
|
|
|
5
5
|
const devkit_1 = require("@nx/devkit");
|
|
6
6
|
const js_1 = require("@nx/js");
|
|
7
7
|
const internal_1 = require("@nx/js/internal");
|
|
8
|
-
const versions_1 = require("nx/src/utils/versions");
|
|
9
8
|
const path_1 = require("path");
|
|
10
9
|
const has_generator_1 = require("../../utils/has-generator");
|
|
11
10
|
const generator_1 = require("../generator/generator");
|
|
12
11
|
const normalize_schema_1 = require("./utils/normalize-schema");
|
|
12
|
+
const internal_2 = require("@nx/devkit/internal");
|
|
13
13
|
async function createPackageGenerator(host, schema) {
|
|
14
14
|
return await createPackageGeneratorInternal(host, {
|
|
15
15
|
useProjectJson: true,
|
|
@@ -25,7 +25,7 @@ async function createPackageGeneratorInternal(host, schema) {
|
|
|
25
25
|
tasks.push((0, js_1.addTsLibDependencies)(host));
|
|
26
26
|
}
|
|
27
27
|
const installTask = (0, devkit_1.addDependenciesToPackageJson)(host, {
|
|
28
|
-
'create-nx-workspace':
|
|
28
|
+
'create-nx-workspace': internal_2.nxVersion,
|
|
29
29
|
}, {});
|
|
30
30
|
tasks.push(installTask);
|
|
31
31
|
const cliPackageTask = await createCliPackage(host, options, pluginPackageName);
|
|
@@ -52,7 +52,9 @@ async function addPresetGenerator(host, schema) {
|
|
|
52
52
|
path: (0, path_1.join)(projectRoot, 'src/generators/preset/generator'),
|
|
53
53
|
unitTestRunner: schema.unitTestRunner,
|
|
54
54
|
skipFormat: true,
|
|
55
|
-
|
|
55
|
+
// Lint checks are an ESLint-only feature; asking for them under any other
|
|
56
|
+
// linter makes `pluginLintCheckGenerator` log an error and do nothing.
|
|
57
|
+
skipLintChecks: schema.linter !== 'eslint',
|
|
56
58
|
});
|
|
57
59
|
}
|
|
58
60
|
return (0, devkit_1.readJson)(host, (0, devkit_1.joinPathFragments)(projectRoot, 'package.json'))?.name;
|
|
@@ -86,7 +88,7 @@ async function createCliPackage(host, options, pluginPackageName) {
|
|
|
86
88
|
delete packageJson.exports;
|
|
87
89
|
}
|
|
88
90
|
packageJson.dependencies = {
|
|
89
|
-
'create-nx-workspace':
|
|
91
|
+
'create-nx-workspace': internal_2.nxVersion,
|
|
90
92
|
...(options.bundler === 'tsc' && { tslib: internal_1.tsLibVersion }),
|
|
91
93
|
};
|
|
92
94
|
return packageJson;
|
package/dist/src/generators/create-package/files/create-framework-package/bin/index.ts__tmpl__
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { createWorkspace } from 'create-nx-workspace';
|
|
4
4
|
|
|
5
5
|
async function main() {
|
|
6
|
-
const name = process.argv[2]; // TODO: use libraries like yargs
|
|
6
|
+
const name = process.argv[2]; // TODO: use libraries like yargs, <%= unitTestRunner === 'jest' ? 'enquirer' : '@clack/prompts' %>, or another prompting library to set your workspace name
|
|
7
7
|
if (!name) {
|
|
8
8
|
throw new Error('Please provide a name for the workspace');
|
|
9
9
|
}
|
|
@@ -16,6 +16,8 @@ describe('<%= cliName %>', () => {
|
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
// This test shells out synchronously, so its budget has to cover a cold
|
|
20
|
+
// package manager cache. Otherwise work that succeeded still fails on return.
|
|
19
21
|
it('should be installed', () => {
|
|
20
22
|
projectDirectory = createTestProject();
|
|
21
23
|
|
|
@@ -24,7 +26,7 @@ describe('<%= cliName %>', () => {
|
|
|
24
26
|
cwd: projectDirectory,
|
|
25
27
|
stdio: 'inherit',
|
|
26
28
|
});
|
|
27
|
-
});
|
|
29
|
+
}, 180_000);
|
|
28
30
|
});
|
|
29
31
|
|
|
30
32
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LinterType } from '@nx/js';
|
|
2
2
|
|
|
3
3
|
export interface CreatePackageSchema {
|
|
4
4
|
name: string;
|
|
@@ -9,7 +9,7 @@ export interface CreatePackageSchema {
|
|
|
9
9
|
skipFormat?: boolean;
|
|
10
10
|
tags?: string;
|
|
11
11
|
unitTestRunner?: 'jest' | 'vitest' | 'none';
|
|
12
|
-
linter?:
|
|
12
|
+
linter?: LinterType;
|
|
13
13
|
compiler?: 'swc' | 'tsc';
|
|
14
14
|
|
|
15
15
|
// options to create e2e project, passed to e2e project generator
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"description": "Test runner to use for unit tests."
|
|
38
38
|
},
|
|
39
39
|
"linter": {
|
|
40
|
-
"description": "The tool to use for running lint checks.",
|
|
40
|
+
"description": "The tool to use for running lint checks. Defaults to the linter the workspace already uses.",
|
|
41
41
|
"type": "string",
|
|
42
|
-
"enum": ["none", "eslint"]
|
|
42
|
+
"enum": ["none", "eslint", "oxlint"]
|
|
43
43
|
},
|
|
44
44
|
"tags": {
|
|
45
45
|
"type": "string",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tree, type GeneratorCallback } from '@nx/devkit';
|
|
2
2
|
import type { Schema } from './schema';
|
|
3
3
|
export declare function e2eProjectGenerator(host: Tree, schema: Schema): Promise<GeneratorCallback>;
|
|
4
4
|
export declare function e2eProjectGeneratorInternal(host: Tree, schema: Schema): Promise<GeneratorCallback>;
|
|
@@ -4,11 +4,11 @@ exports.e2eProjectGenerator = e2eProjectGenerator;
|
|
|
4
4
|
exports.e2eProjectGeneratorInternal = e2eProjectGeneratorInternal;
|
|
5
5
|
const internal_1 = require("@nx/devkit/internal");
|
|
6
6
|
const devkit_1 = require("@nx/devkit");
|
|
7
|
-
const eslint_1 = require("@nx/eslint");
|
|
8
7
|
const jest_1 = require("@nx/jest");
|
|
9
8
|
const js_1 = require("@nx/js");
|
|
10
9
|
const internal_2 = require("@nx/js/internal");
|
|
11
10
|
const path_1 = require("path");
|
|
11
|
+
const versions_1 = require("../../utils/versions");
|
|
12
12
|
async function normalizeOptions(host, options) {
|
|
13
13
|
const linter = await (0, internal_2.normalizeLinterOption)(host, options.linter);
|
|
14
14
|
const projectName = options.rootProject ? 'e2e' : `${options.pluginName}-e2e`;
|
|
@@ -112,19 +112,122 @@ async function addJest(host, options) {
|
|
|
112
112
|
}
|
|
113
113
|
return jestTask;
|
|
114
114
|
}
|
|
115
|
+
async function addVitest(host, options) {
|
|
116
|
+
const projectConfiguration = {
|
|
117
|
+
name: options.projectName,
|
|
118
|
+
root: options.projectRoot,
|
|
119
|
+
projectType: 'application',
|
|
120
|
+
sourceRoot: `${options.projectRoot}/src`,
|
|
121
|
+
implicitDependencies: [options.pluginName],
|
|
122
|
+
};
|
|
123
|
+
if (options.isTsSolutionSetup) {
|
|
124
|
+
(0, devkit_1.writeJson)(host, (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json'), {
|
|
125
|
+
name: options.projectName,
|
|
126
|
+
version: '0.0.1',
|
|
127
|
+
private: true,
|
|
128
|
+
});
|
|
129
|
+
(0, devkit_1.updateProjectConfiguration)(host, options.projectName, projectConfiguration);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
projectConfiguration.targets = {};
|
|
133
|
+
(0, devkit_1.addProjectConfiguration)(host, options.projectName, projectConfiguration);
|
|
134
|
+
}
|
|
135
|
+
(0, devkit_1.ensurePackage)('@nx/vitest', versions_1.nxVersion);
|
|
136
|
+
// Use `require` rather than a dynamic `import()`: `ensurePackage` makes the
|
|
137
|
+
// on-demand-installed package resolvable via CJS resolution only, so a true
|
|
138
|
+
// ESM dynamic import cannot see the temp install.
|
|
139
|
+
const { configurationGenerator: vitestConfigurationGenerator, } = require('@nx/vitest/generators');
|
|
140
|
+
const vitestTask = await vitestConfigurationGenerator(host, {
|
|
141
|
+
project: options.projectName,
|
|
142
|
+
testTarget: 'e2e',
|
|
143
|
+
skipFormat: true,
|
|
144
|
+
addPlugin: options.addPlugin,
|
|
145
|
+
testEnvironment: 'node',
|
|
146
|
+
coverageProvider: 'none',
|
|
147
|
+
});
|
|
148
|
+
(0, internal_2.addLocalRegistryScripts)(host);
|
|
149
|
+
// Vitest has no `globalTeardown` option. Its `globalSetup` file must export
|
|
150
|
+
// both `setup` and `teardown`, so wire the local registry scripts through a
|
|
151
|
+
// wrapper module. Without the teardown, the verdaccio process started in
|
|
152
|
+
// setup outlives the test run.
|
|
153
|
+
const vitestGlobalSetupPath = 'tools/scripts/vitest-global-setup.ts';
|
|
154
|
+
if (!host.exists(vitestGlobalSetupPath)) {
|
|
155
|
+
host.write(vitestGlobalSetupPath, `/**
|
|
156
|
+
* This script adapts the local registry scripts to vitest's globalSetup
|
|
157
|
+
* lifecycle: vitest calls the exported setup and teardown functions around
|
|
158
|
+
* the test run.
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
export { default as setup } from './start-local-registry';
|
|
162
|
+
export { default as teardown } from './stop-local-registry';
|
|
163
|
+
`);
|
|
164
|
+
}
|
|
165
|
+
// Add globalSetup to vitest config
|
|
166
|
+
// Check for both .mts and .ts extensions (mts is checked first as it's the default created by @nx/vitest)
|
|
167
|
+
const vitestConfigExtensions = ['mts', 'ts'];
|
|
168
|
+
let vitestConfigPath;
|
|
169
|
+
for (const ext of vitestConfigExtensions) {
|
|
170
|
+
const configPath = (0, devkit_1.joinPathFragments)(options.projectRoot, `vitest.config.${ext}`);
|
|
171
|
+
if (host.exists(configPath)) {
|
|
172
|
+
vitestConfigPath = configPath;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (vitestConfigPath) {
|
|
177
|
+
let vitestConfig = host.read(vitestConfigPath, 'utf-8');
|
|
178
|
+
const globalSetupPath = (0, path_1.join)((0, devkit_1.offsetFromRoot)(options.projectRoot), vitestGlobalSetupPath);
|
|
179
|
+
// Insert globalSetup in the test config
|
|
180
|
+
// Look for 'test: {' and insert our properties right after the opening brace
|
|
181
|
+
const testConfigRegex = /(test:\s*\{\s*)/;
|
|
182
|
+
const match = testConfigRegex.exec(vitestConfig);
|
|
183
|
+
if (match) {
|
|
184
|
+
// Extract the indentation from the next line to maintain consistent formatting
|
|
185
|
+
const afterMatch = vitestConfig.slice(match.index + match[0].length);
|
|
186
|
+
const nextLineMatch = afterMatch.match(/\n(\s*)/);
|
|
187
|
+
const indent = nextLineMatch ? nextLineMatch[1] : ' ';
|
|
188
|
+
vitestConfig = vitestConfig.replace(testConfigRegex, `$1\n${indent}globalSetup: '${globalSetupPath}',`);
|
|
189
|
+
host.write(vitestConfigPath, vitestConfig);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// If we can't find the test config block, log a warning
|
|
193
|
+
throw new Error(`Could not find test configuration block in ${vitestConfigPath}. Please manually add the globalSetup property.`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
// This should not happen as the vitest configuration generator should create the config file
|
|
198
|
+
throw new Error(`Could not find Vitest config for project ${options.projectName} at ${options.projectRoot}`);
|
|
199
|
+
}
|
|
200
|
+
const project = (0, devkit_1.readProjectConfiguration)(host, options.projectName);
|
|
201
|
+
project.targets ??= {};
|
|
202
|
+
if (project.targets.e2e) {
|
|
203
|
+
const e2eTarget = project.targets.e2e;
|
|
204
|
+
// The suites share a single tmp/test-project directory, so they have to run
|
|
205
|
+
// one at a time. Vitest 4 removed `poolOptions`, and nested options do not
|
|
206
|
+
// survive the executor's argv round-trip anyway, so use the scalar options.
|
|
207
|
+
project.targets.e2e = {
|
|
208
|
+
...e2eTarget,
|
|
209
|
+
dependsOn: [`^build`],
|
|
210
|
+
options: {
|
|
211
|
+
...e2eTarget.options,
|
|
212
|
+
maxWorkers: 1,
|
|
213
|
+
isolate: false,
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
(0, devkit_1.updateProjectConfiguration)(host, options.projectName, project);
|
|
217
|
+
}
|
|
218
|
+
return vitestTask;
|
|
219
|
+
}
|
|
115
220
|
async function addLintingToApplication(tree, options) {
|
|
116
|
-
|
|
221
|
+
return (0, internal_2.addLintingToProject)(tree, {
|
|
117
222
|
linter: options.linter,
|
|
118
223
|
project: options.projectName,
|
|
119
224
|
tsConfigPaths: [
|
|
120
225
|
(0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.app.json'),
|
|
121
226
|
],
|
|
122
|
-
unitTestRunner: 'jest',
|
|
123
|
-
|
|
124
|
-
setParserOptionsProject: false,
|
|
227
|
+
unitTestRunner: options.testRunner ?? 'jest',
|
|
228
|
+
enableTypedLinting: false,
|
|
125
229
|
addPlugin: options.addPlugin,
|
|
126
230
|
});
|
|
127
|
-
return lintTask;
|
|
128
231
|
}
|
|
129
232
|
function updatePluginPackageJson(tree, options) {
|
|
130
233
|
const { root } = (0, devkit_1.readProjectConfiguration)(tree, options.pluginName);
|
|
@@ -145,11 +248,19 @@ async function e2eProjectGeneratorInternal(host, schema) {
|
|
|
145
248
|
const tasks = [];
|
|
146
249
|
validatePlugin(host, schema.pluginName);
|
|
147
250
|
const options = await normalizeOptions(host, schema);
|
|
251
|
+
// Default to jest if no testRunner is specified
|
|
252
|
+
options.testRunner = options.testRunner ?? 'jest';
|
|
148
253
|
addFiles(host, options);
|
|
149
254
|
tasks.push(await (0, js_1.setupVerdaccio)(host, {
|
|
150
255
|
skipFormat: true,
|
|
151
256
|
}));
|
|
152
|
-
|
|
257
|
+
// Add test runner based on the testRunner option
|
|
258
|
+
if (options.testRunner === 'vitest') {
|
|
259
|
+
tasks.push(await addVitest(host, options));
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
tasks.push(await addJest(host, options));
|
|
263
|
+
}
|
|
153
264
|
updatePluginPackageJson(host, options);
|
|
154
265
|
if (options.linter !== 'none') {
|
|
155
266
|
tasks.push(await addLintingToApplication(host, {
|
|
@@ -5,17 +5,20 @@ import { mkdirSync, rmSync } from 'fs';
|
|
|
5
5
|
describe('<%= pluginName %>', () => {
|
|
6
6
|
let projectDirectory: string;
|
|
7
7
|
|
|
8
|
+
// This hook shells out synchronously twice, so its budget has to cover both
|
|
9
|
+
// installs on a cold package manager cache. Otherwise work that succeeded
|
|
10
|
+
// still fails on return.
|
|
8
11
|
beforeAll(() => {
|
|
9
12
|
projectDirectory = createTestProject();
|
|
10
13
|
|
|
11
|
-
// The plugin has been built and published to a local registry in the
|
|
14
|
+
// The plugin has been built and published to a local registry in the globalSetup
|
|
12
15
|
// Install the plugin built with the latest source code into the test repo
|
|
13
16
|
execSync(`<%= packageManagerCommands.addDev %> <%= pluginPackageName %>@e2e`, {
|
|
14
17
|
cwd: projectDirectory,
|
|
15
18
|
stdio: 'inherit',
|
|
16
19
|
env: process.env,
|
|
17
20
|
});
|
|
18
|
-
});
|
|
21
|
+
}, 300_000);
|
|
19
22
|
|
|
20
23
|
afterAll(() => {
|
|
21
24
|
if (projectDirectory) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LinterType } from '@nx/js';
|
|
2
2
|
|
|
3
3
|
export interface Schema {
|
|
4
4
|
pluginName: string;
|
|
@@ -6,7 +6,8 @@ export interface Schema {
|
|
|
6
6
|
projectDirectory?: string;
|
|
7
7
|
pluginOutputPath?: string;
|
|
8
8
|
jestConfig?: string;
|
|
9
|
-
|
|
9
|
+
testRunner?: 'jest' | 'vitest';
|
|
10
|
+
linter?: LinterType;
|
|
10
11
|
skipFormat?: boolean;
|
|
11
12
|
rootProject?: boolean;
|
|
12
13
|
useProjectJson?: boolean;
|
|
@@ -30,10 +30,16 @@
|
|
|
30
30
|
"type": "string",
|
|
31
31
|
"description": "Jest config file."
|
|
32
32
|
},
|
|
33
|
+
"testRunner": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"enum": ["jest", "vitest"],
|
|
36
|
+
"description": "Test runner to use for the e2e tests.",
|
|
37
|
+
"default": "jest"
|
|
38
|
+
},
|
|
33
39
|
"linter": {
|
|
34
|
-
"description": "The tool to use for running lint checks.",
|
|
40
|
+
"description": "The tool to use for running lint checks. Defaults to the linter the workspace already uses.",
|
|
35
41
|
"type": "string",
|
|
36
|
-
"enum": ["none", "eslint"]
|
|
42
|
+
"enum": ["none", "eslint", "oxlint"]
|
|
37
43
|
},
|
|
38
44
|
"minimal": {
|
|
39
45
|
"type": "boolean",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ProjectConfiguration, TargetConfiguration, Tree } from '@nx/devkit';
|
|
2
2
|
import type { Schema as EsLintExecutorOptions } from '@nx/eslint/internal';
|
|
3
3
|
import { PluginLintChecksGeneratorSchema } from './schema';
|
|
4
|
-
import { PackageJson } from 'nx/
|
|
4
|
+
import { PackageJson } from '@nx/devkit/internal';
|
|
5
5
|
export default function pluginLintCheckGenerator(host: Tree, options: PluginLintChecksGeneratorSchema): Promise<void>;
|
|
6
6
|
export declare function addMigrationJsonChecks(host: Tree, options: PluginLintChecksGeneratorSchema, packageJson: PackageJson): void;
|
|
7
7
|
export declare function getEsLintOptions(project: ProjectConfiguration): [target: string, configuration: TargetConfiguration<EsLintExecutorOptions>];
|
|
@@ -4,9 +4,8 @@ exports.default = pluginLintCheckGenerator;
|
|
|
4
4
|
exports.addMigrationJsonChecks = addMigrationJsonChecks;
|
|
5
5
|
exports.getEsLintOptions = getEsLintOptions;
|
|
6
6
|
const devkit_1 = require("@nx/devkit");
|
|
7
|
-
const logger_1 = require("nx/src/utils/logger");
|
|
8
|
-
const package_json_1 = require("nx/src/utils/package-json");
|
|
9
7
|
const internal_1 = require("@nx/eslint/internal");
|
|
8
|
+
const internal_2 = require("@nx/devkit/internal");
|
|
10
9
|
async function pluginLintCheckGenerator(host, options) {
|
|
11
10
|
const project = (0, devkit_1.readProjectConfiguration)(host, options.projectName);
|
|
12
11
|
const packageJson = (0, devkit_1.readJson)(host, (0, devkit_1.joinPathFragments)(project.root, 'package.json'));
|
|
@@ -21,7 +20,7 @@ async function pluginLintCheckGenerator(host, options) {
|
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
22
|
else {
|
|
24
|
-
devkit_1.logger.error(`${
|
|
23
|
+
devkit_1.logger.error(`${internal_2.NX_PREFIX} plugin lint checks can only be added to plugins which use eslint for linting`);
|
|
25
24
|
}
|
|
26
25
|
if (!options.skipFormat) {
|
|
27
26
|
await (0, devkit_1.formatFiles)(host);
|
|
@@ -33,7 +32,7 @@ function addMigrationJsonChecks(host, options, packageJson) {
|
|
|
33
32
|
return;
|
|
34
33
|
}
|
|
35
34
|
const [eslintTarget, eslintTargetConfiguration] = getEsLintOptions(projectConfiguration) ?? [];
|
|
36
|
-
const relativeMigrationsJsonPath = (0,
|
|
35
|
+
const relativeMigrationsJsonPath = (0, internal_2.readNxMigrateConfig)(packageJson).migrations;
|
|
37
36
|
if (!relativeMigrationsJsonPath) {
|
|
38
37
|
return;
|
|
39
38
|
}
|
|
@@ -129,7 +128,7 @@ function updateProjectEslintConfig(host, options, packageJson) {
|
|
|
129
128
|
packageJson.executors,
|
|
130
129
|
packageJson.schematics,
|
|
131
130
|
packageJson.builders,
|
|
132
|
-
(0,
|
|
131
|
+
(0, internal_2.readNxMigrateConfig)(packageJson).migrations,
|
|
133
132
|
].filter((f) => !!f);
|
|
134
133
|
const parser = (0, internal_1.useFlatConfig)(host)
|
|
135
134
|
? { languageOptions: { parser: 'jsonc-eslint-parser' } }
|
|
@@ -195,7 +194,7 @@ function setupVsCodeLintingForJsonFiles(host) {
|
|
|
195
194
|
existing = (0, devkit_1.readJson)(host, '.vscode/settings.json');
|
|
196
195
|
}
|
|
197
196
|
else {
|
|
198
|
-
devkit_1.logger.info(`${
|
|
197
|
+
devkit_1.logger.info(`${internal_2.NX_PREFIX} We've updated the vscode settings for this repository to ensure that plugin lint checks show up inside your IDE. This created .vscode/settings.json. To read more about this file, check vscode's documentation. It is frequently not committed, so other developers may need to add similar settings if they'd like to see the lint checks in the IDE rather than only during linting.`);
|
|
199
198
|
}
|
|
200
199
|
// setup eslint validation for json files
|
|
201
200
|
const eslintValidate = existing['eslint.validate'] ?? [];
|
|
@@ -5,7 +5,6 @@ const internal_1 = require("@nx/devkit/internal");
|
|
|
5
5
|
const devkit_1 = require("@nx/devkit");
|
|
6
6
|
const internal_2 = require("@nx/js/internal");
|
|
7
7
|
const node_path_1 = require("node:path");
|
|
8
|
-
const package_json_1 = require("nx/src/utils/package-json");
|
|
9
8
|
const paths_1 = require("../../utils/paths");
|
|
10
9
|
const versions_1 = require("../../utils/versions");
|
|
11
10
|
const generator_1 = require("../lint-checks/generator");
|
|
@@ -38,7 +37,7 @@ function addFiles(host, options) {
|
|
|
38
37
|
});
|
|
39
38
|
}
|
|
40
39
|
function updateMigrationsJson(host, options) {
|
|
41
|
-
const configuredMigrationPath = (0,
|
|
40
|
+
const configuredMigrationPath = (0, internal_1.readNxMigrateConfig)((0, devkit_1.readJson)(host, (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json'))).migrations;
|
|
42
41
|
const migrationsPath = (0, devkit_1.joinPathFragments)(options.projectRoot, configuredMigrationPath ?? 'migrations.json');
|
|
43
42
|
const migrations = host.exists(migrationsPath)
|
|
44
43
|
? (0, devkit_1.readJson)(host, migrationsPath)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -83,6 +83,11 @@ async function pluginGeneratorInternal(host, schema) {
|
|
|
83
83
|
'@nx/devkit': nxVersion,
|
|
84
84
|
}, {
|
|
85
85
|
[options.unitTestRunner === 'vitest' ? '@nx/vitest' : '@nx/jest']: nxVersion,
|
|
86
|
+
...(options.e2eTestRunner === 'vitest'
|
|
87
|
+
? { '@nx/vitest': nxVersion }
|
|
88
|
+
: options.e2eTestRunner === 'jest'
|
|
89
|
+
? { '@nx/jest': nxVersion }
|
|
90
|
+
: {}),
|
|
86
91
|
'@nx/js': nxVersion,
|
|
87
92
|
'@nx/plugin': nxVersion,
|
|
88
93
|
}));
|
|
@@ -103,6 +108,7 @@ async function pluginGeneratorInternal(host, schema) {
|
|
|
103
108
|
linter: options.linter,
|
|
104
109
|
useProjectJson: options.useProjectJson,
|
|
105
110
|
addPlugin: options.addPlugin,
|
|
111
|
+
testRunner: options.e2eTestRunner,
|
|
106
112
|
}));
|
|
107
113
|
}
|
|
108
114
|
if (options.linter === 'eslint' && !options.skipLintChecks) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LinterType } from '@nx/js';
|
|
2
2
|
|
|
3
3
|
export interface Schema {
|
|
4
4
|
directory: string;
|
|
@@ -7,11 +7,15 @@ export interface Schema {
|
|
|
7
7
|
skipTsConfig?: boolean; // default is false
|
|
8
8
|
skipFormat?: boolean; // default is false
|
|
9
9
|
skipLintChecks?: boolean; // default is false
|
|
10
|
-
e2eTestRunner?: 'jest' | 'none';
|
|
10
|
+
e2eTestRunner?: 'jest' | 'vitest' | 'none';
|
|
11
11
|
e2eProjectDirectory?: string;
|
|
12
12
|
tags?: string;
|
|
13
13
|
unitTestRunner?: 'jest' | 'vitest' | 'none';
|
|
14
|
-
linter?:
|
|
14
|
+
linter?: LinterType;
|
|
15
|
+
enableTypedLinting?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Use `enableTypedLinting` instead. This option will be removed in Nx v24.
|
|
18
|
+
*/
|
|
15
19
|
setParserOptionsProject?: boolean;
|
|
16
20
|
compiler?: 'swc' | 'tsc';
|
|
17
21
|
rootProject?: boolean;
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"x-priority": "important"
|
|
33
33
|
},
|
|
34
34
|
"linter": {
|
|
35
|
-
"description": "The tool to use for running lint checks.",
|
|
35
|
+
"description": "The tool to use for running lint checks. Defaults to the linter the workspace already uses.",
|
|
36
36
|
"type": "string",
|
|
37
|
-
"enum": ["none", "eslint"],
|
|
37
|
+
"enum": ["none", "eslint", "oxlint"],
|
|
38
38
|
"x-priority": "important"
|
|
39
39
|
},
|
|
40
40
|
"unitTestRunner": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
"e2eTestRunner": {
|
|
69
69
|
"type": "string",
|
|
70
|
-
"enum": ["jest", "none"],
|
|
70
|
+
"enum": ["jest", "vitest", "none"],
|
|
71
71
|
"description": "Test runner to use for end to end (E2E) tests.",
|
|
72
72
|
"default": "none"
|
|
73
73
|
},
|
|
@@ -75,11 +75,17 @@
|
|
|
75
75
|
"type": "string",
|
|
76
76
|
"description": "A directory where the plugin E2E project is placed."
|
|
77
77
|
},
|
|
78
|
-
"
|
|
78
|
+
"enableTypedLinting": {
|
|
79
79
|
"type": "boolean",
|
|
80
|
-
"description": "Whether
|
|
80
|
+
"description": "Whether to enable typed linting. For flat configs, this configures the recommended `parserOptions.projectService` and `tsconfigRootDir`. For legacy `.eslintrc` configs, this configures `parserOptions.project`. We do not enable this by default for lint performance reasons.",
|
|
81
81
|
"default": false
|
|
82
82
|
},
|
|
83
|
+
"setParserOptionsProject": {
|
|
84
|
+
"type": "boolean",
|
|
85
|
+
"description": "Deprecated alias for `enableTypedLinting`.",
|
|
86
|
+
"default": false,
|
|
87
|
+
"x-deprecated": "Use `enableTypedLinting` instead. This option will be removed in Nx v24."
|
|
88
|
+
},
|
|
83
89
|
"compiler": {
|
|
84
90
|
"type": "string",
|
|
85
91
|
"enum": ["tsc", "swc"],
|
|
@@ -5,6 +5,7 @@ exports.presetGeneratorInternal = presetGeneratorInternal;
|
|
|
5
5
|
const devkit_1 = require("@nx/devkit");
|
|
6
6
|
const create_package_1 = require("../create-package/create-package");
|
|
7
7
|
const plugin_1 = require("../plugin/plugin");
|
|
8
|
+
const internal_1 = require("@nx/js/internal");
|
|
8
9
|
async function presetGenerator(tree, rawOptions) {
|
|
9
10
|
return await presetGeneratorInternal(tree, {
|
|
10
11
|
addPlugin: false,
|
|
@@ -14,10 +15,10 @@ async function presetGenerator(tree, rawOptions) {
|
|
|
14
15
|
}
|
|
15
16
|
async function presetGeneratorInternal(tree, rawOptions) {
|
|
16
17
|
const tasks = [];
|
|
17
|
-
const options = normalizeOptions(rawOptions);
|
|
18
|
+
const options = await normalizeOptions(tree, rawOptions);
|
|
18
19
|
const pluginTask = await (0, plugin_1.pluginGenerator)(tree, {
|
|
19
20
|
compiler: 'tsc',
|
|
20
|
-
linter:
|
|
21
|
+
linter: options.linter,
|
|
21
22
|
skipFormat: true,
|
|
22
23
|
unitTestRunner: 'jest',
|
|
23
24
|
importPath: options.pluginName,
|
|
@@ -42,7 +43,7 @@ async function presetGeneratorInternal(tree, rawOptions) {
|
|
|
42
43
|
project: options.pluginName,
|
|
43
44
|
skipFormat: true,
|
|
44
45
|
unitTestRunner: 'jest',
|
|
45
|
-
linter:
|
|
46
|
+
linter: options.linter,
|
|
46
47
|
compiler: 'tsc',
|
|
47
48
|
useProjectJson: options.useProjectJson,
|
|
48
49
|
addPlugin: options.addPlugin,
|
|
@@ -62,7 +63,7 @@ function moveNxPluginToDevDeps(tree) {
|
|
|
62
63
|
return json;
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
|
-
function normalizeOptions(options) {
|
|
66
|
+
async function normalizeOptions(tree, options) {
|
|
66
67
|
return {
|
|
67
68
|
...options,
|
|
68
69
|
pluginName: (0, devkit_1.names)(options.pluginName.includes('/')
|
|
@@ -71,6 +72,9 @@ function normalizeOptions(options) {
|
|
|
71
72
|
createPackageName: options.createPackageName === 'false' // for command line in e2e, it is passed as a string
|
|
72
73
|
? undefined
|
|
73
74
|
: options.createPackageName,
|
|
75
|
+
// Resolved once here rather than left to the two child generators, which
|
|
76
|
+
// each prompt on their own and would ask the same question twice.
|
|
77
|
+
linter: await (0, internal_1.normalizeLinterOption)(tree, options.linter),
|
|
74
78
|
};
|
|
75
79
|
}
|
|
76
80
|
exports.default = presetGenerator;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import type { LinterType } from '@nx/js';
|
|
2
|
+
|
|
1
3
|
export interface PresetGeneratorSchema {
|
|
2
4
|
pluginName: string;
|
|
3
5
|
createPackageName?: string;
|
|
4
6
|
useProjectJson?: boolean;
|
|
5
7
|
addPlugin?: boolean;
|
|
8
|
+
linter?: LinterType;
|
|
6
9
|
}
|
|
7
10
|
|
|
8
|
-
export interface NormalizedPresetGeneratorOptions
|
|
9
|
-
extends PresetGeneratorSchema {
|
|
11
|
+
export interface NormalizedPresetGeneratorOptions extends PresetGeneratorSchema {
|
|
10
12
|
createPackageName: string;
|
|
13
|
+
linter: LinterType;
|
|
11
14
|
}
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
"type": "string",
|
|
26
26
|
"description": "Name of package which creates a workspace"
|
|
27
27
|
},
|
|
28
|
+
"linter": {
|
|
29
|
+
"description": "The tool to use for running lint checks. Defaults to the linter the workspace already uses.",
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": ["none", "eslint", "oxlint"]
|
|
32
|
+
},
|
|
28
33
|
"useProjectJson": {
|
|
29
34
|
"type": "boolean",
|
|
30
35
|
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
|
@@ -6,7 +6,6 @@ exports.runPackageManagerInstall = runPackageManagerInstall;
|
|
|
6
6
|
exports.newNxProject = newNxProject;
|
|
7
7
|
exports.ensureNxProject = ensureNxProject;
|
|
8
8
|
const devkit_1 = require("@nx/devkit");
|
|
9
|
-
const devkit_2 = require("@nx/devkit");
|
|
10
9
|
const child_process_1 = require("child_process");
|
|
11
10
|
const node_fs_1 = require("node:fs");
|
|
12
11
|
const path_1 = require("path");
|
|
@@ -22,9 +21,9 @@ function runNxNewCommand(args, silent) {
|
|
|
22
21
|
}
|
|
23
22
|
function patchPackageJsonForPlugin(npmPackageName, distPath) {
|
|
24
23
|
const path = (0, paths_1.tmpProjPath)('package.json');
|
|
25
|
-
const json = (0,
|
|
24
|
+
const json = (0, devkit_1.readJsonFile)(path);
|
|
26
25
|
json.devDependencies[npmPackageName] = `file:${devkit_1.workspaceRoot}/${distPath}`;
|
|
27
|
-
(0,
|
|
26
|
+
(0, devkit_1.writeJsonFile)(path, json);
|
|
28
27
|
}
|
|
29
28
|
/**
|
|
30
29
|
* Generate a unique name for running CLI commands
|
|
@@ -41,7 +40,7 @@ function uniq(prefix) {
|
|
|
41
40
|
*/
|
|
42
41
|
function runPackageManagerInstall(silent = true) {
|
|
43
42
|
const cwd = (0, paths_1.tmpProjPath)();
|
|
44
|
-
const pmc = (0,
|
|
43
|
+
const pmc = (0, devkit_1.getPackageManagerCommand)((0, devkit_1.detectPackageManager)(cwd));
|
|
45
44
|
const install = (0, child_process_1.execSync)(pmc.install, {
|
|
46
45
|
cwd,
|
|
47
46
|
...(silent ? { stdio: ['ignore', 'ignore', 'ignore'] } : {}),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { JsonParseOptions } from '@nx/devkit';
|
|
2
|
-
import { directoryExists, fileExists } from 'nx/
|
|
2
|
+
import { directoryExists, fileExists } from '@nx/devkit/internal';
|
|
3
3
|
export { directoryExists, fileExists };
|
|
4
4
|
/**
|
|
5
5
|
* Copies module folders from the working directory to the e2e directory
|
|
@@ -19,9 +19,9 @@ const node_fs_1 = require("node:fs");
|
|
|
19
19
|
const path_1 = require("path");
|
|
20
20
|
const paths_1 = require("./paths");
|
|
21
21
|
const devkit_1 = require("@nx/devkit");
|
|
22
|
-
const
|
|
23
|
-
Object.defineProperty(exports, "directoryExists", { enumerable: true, get: function () { return
|
|
24
|
-
Object.defineProperty(exports, "fileExists", { enumerable: true, get: function () { return
|
|
22
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
23
|
+
Object.defineProperty(exports, "directoryExists", { enumerable: true, get: function () { return internal_1.directoryExists; } });
|
|
24
|
+
Object.defineProperty(exports, "fileExists", { enumerable: true, get: function () { return internal_1.fileExists; } });
|
|
25
25
|
/**
|
|
26
26
|
* Copies module folders from the working directory to the e2e directory
|
|
27
27
|
* @param modules a list of module names or scopes to copy
|
|
@@ -136,7 +136,7 @@ function getCwd() {
|
|
|
136
136
|
* @param path Path to file or directory
|
|
137
137
|
*/
|
|
138
138
|
function exists(path) {
|
|
139
|
-
return (0,
|
|
139
|
+
return (0, internal_1.directoryExists)(path) || (0, internal_1.fileExists)(path);
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* Get the size of a file on disk
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/plugin",
|
|
3
|
-
"version": "23.2.0-beta.
|
|
3
|
+
"version": "23.2.0-beta.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This plugin is used to create Nx plugins! It contains generators for generating common plugin features like generators, executors, migrations and more.",
|
|
6
6
|
"repository": {
|
|
@@ -36,13 +36,21 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"tslib": "^2.3.0",
|
|
39
|
-
"@nx/devkit": "23.2.0-beta.
|
|
40
|
-
"@nx/jest": "23.2.0-beta.
|
|
41
|
-
"@nx/js": "23.2.0-beta.
|
|
42
|
-
"@nx/eslint": "23.2.0-beta.
|
|
39
|
+
"@nx/devkit": "23.2.0-beta.11",
|
|
40
|
+
"@nx/jest": "23.2.0-beta.11",
|
|
41
|
+
"@nx/js": "23.2.0-beta.11",
|
|
42
|
+
"@nx/eslint": "23.2.0-beta.11"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"nx": "23.2.0-beta.
|
|
45
|
+
"nx": "23.2.0-beta.11"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@nx/vitest": "23.2.0-beta.11"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"@nx/vitest": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
46
54
|
},
|
|
47
55
|
"publishConfig": {
|
|
48
56
|
"access": "public"
|