@nx/js 24.0.0-beta.1 → 24.0.0-beta.3
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/dist/internal.d.ts +2 -0
- package/dist/internal.js +8 -2
- package/dist/node.d.ts +1 -0
- package/dist/node.js +6 -0
- package/dist/src/generators/init/init.js +3 -33
- package/dist/src/generators/init/schema.d.ts +0 -1
- package/dist/src/generators/library/library.d.ts +1 -1
- package/dist/src/generators/library/library.js +3 -11
- package/dist/src/generators/library/schema.d.ts +0 -1
- package/dist/src/generators/setup-build/generator.js +0 -5
- package/dist/src/plugins/scripts/create-script-nodes.d.ts +24 -0
- package/dist/src/plugins/scripts/create-script-nodes.js +149 -0
- package/dist/src/plugins/scripts/node-plugin.d.ts +10 -0
- package/dist/src/plugins/scripts/node-plugin.js +52 -0
- package/dist/src/plugins/scripts/shebang.d.ts +19 -0
- package/dist/src/plugins/scripts/shebang.js +67 -0
- package/dist/src/plugins/scripts/target-name.d.ts +9 -0
- package/dist/src/plugins/scripts/target-name.js +19 -0
- package/dist/src/plugins/scripts/tsx-plugin.d.ts +3 -0
- package/dist/src/plugins/scripts/tsx-plugin.js +11 -0
- package/dist/src/plugins/typescript/build-typechecks.d.ts +8 -0
- package/dist/src/plugins/typescript/build-typechecks.js +45 -0
- package/dist/src/plugins/typescript/plugin.js +107 -38
- package/dist/src/plugins/typescript/typecheck-target.d.ts +54 -0
- package/dist/src/plugins/typescript/typecheck-target.js +81 -0
- package/dist/src/utils/add-linting-to-project.d.ts +0 -2
- package/dist/src/utils/add-linting-to-project.js +0 -3
- package/dist/src/utils/typescript/add-typescript-plugin.d.ts +22 -0
- package/dist/src/utils/typescript/add-typescript-plugin.js +145 -0
- package/dist/src/utils/typescript/ts-solution-setup.d.ts +1 -1
- package/dist/src/utils/typescript/ts-solution-setup.js +1 -10
- package/dist/tsx.d.ts +1 -0
- package/dist/tsx.js +6 -0
- package/package.json +27 -11
package/dist/internal.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { PNPM_INSTALL_SETTINGS_INPUTS, PNPM_MAJOR_RUNTIME_INPUT, pnpmInstallSett
|
|
|
7
7
|
export { addPnpmDeployOutputCacheInputs } from './src/utils/pnpm-deploy-output-cache-inputs';
|
|
8
8
|
export type { MatchedTargetRef } from './src/utils/target-defaults-matching';
|
|
9
9
|
export { TS_SOLUTION_SETUP_TSCONFIG_INPUT, addProjectToTsSolutionWorkspace, assertNotUsingTsSolutionSetup, findRuntimeTsConfigName, getDefinedCustomConditionName, getProjectSourceRoot, getProjectType, isUsingTsSolutionSetup, shouldConfigureTsSolutionSetup, updateTsconfigFiles, } from './src/utils/typescript/ts-solution-setup';
|
|
10
|
+
export { ensureTypescriptPlugin, registerTypescriptPluginForTypecheck, } from './src/utils/typescript/add-typescript-plugin';
|
|
10
11
|
export { getTsConfigBaseOptions } from './src/utils/typescript/create-ts-config';
|
|
11
12
|
export { createTreeParseConfigHost, type TreeParseConfigHost, } from './src/utils/typescript/ts-config';
|
|
12
13
|
export { ensureTypescript } from './src/utils/typescript/ensure-typescript';
|
|
@@ -23,6 +24,7 @@ export { getNpmScope } from './src/utils/package-json/get-npm-scope';
|
|
|
23
24
|
export { getProjectPackageManagerWorkspaceState, getProjectPackageManagerWorkspaceStateWarningTask, } from './src/utils/package-manager-workspaces';
|
|
24
25
|
export { findNpmDependencies } from './src/utils/find-npm-dependencies';
|
|
25
26
|
export { addBuildAndWatchDepsTargets, isValidPackageJsonBuildConfig, } from './src/plugins/typescript/util';
|
|
27
|
+
export { createTypecheckTarget, selectTypecheckTsConfig, type TypecheckTargetOptions, } from './src/plugins/typescript/typecheck-target';
|
|
26
28
|
export { normalizeLinterOption, normalizeUnitTestRunnerOption, } from './src/utils/generator-prompts';
|
|
27
29
|
export { detectLinters } from './src/utils/linter';
|
|
28
30
|
export { addLintingToProject, type AddLintingToProjectOptions, } from './src/utils/add-linting-to-project';
|
package/dist/internal.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
// internal consumers and may change without semver protection. Consider it
|
|
6
6
|
// the @nx/js equivalent of `@nx/devkit/internal`.
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.
|
|
9
|
-
exports.typesNodeVersion = exports.tsLibVersion = exports.swcNodeVersion = exports.swcHelpersVersion = exports.swcCoreVersion = exports.swcCliVersion = exports.prettierVersion = exports.esbuildVersion = exports.nxVersion = exports.releaseTasks = exports.addReleaseConfigForTsSolution = exports.addReleaseConfigForNonTsSolution = exports.addLocalRegistryScripts = exports.stripGlobToBaseDir = exports.getImportPath = exports.createGlobPatternsForDependencies = exports.addLintingToProject = exports.detectLinters = exports.normalizeUnitTestRunnerOption = exports.normalizeLinterOption = void 0;
|
|
8
|
+
exports.findNpmDependencies = exports.getProjectPackageManagerWorkspaceStateWarningTask = exports.getProjectPackageManagerWorkspaceState = exports.getNpmScope = exports.sortPackageJsonFields = exports.CopyAssetsHandler = exports.addSwcRegisterDependencies = exports.addSwcDependencies = exports.acknowledgeSwcBuildScripts = exports.addSwcTestConfig = exports.addSwcConfig = exports.createTmpTsConfig = exports.computeCompilerOptionsPaths = exports.calculateProjectDependencies = exports.calculateProjectBuildableDependencies = exports.compileTypeScript = exports.getNeededCompilerOptionOverrides = exports.isTypescriptVersionAtLeast = exports.getTsConfigModuleResolution = exports.getRangeMinimum = exports.ensureTypescript = exports.createTreeParseConfigHost = exports.getTsConfigBaseOptions = exports.registerTypescriptPluginForTypecheck = exports.ensureTypescriptPlugin = exports.updateTsconfigFiles = exports.shouldConfigureTsSolutionSetup = exports.isUsingTsSolutionSetup = exports.getProjectType = exports.getProjectSourceRoot = exports.getDefinedCustomConditionName = exports.findRuntimeTsConfigName = exports.assertNotUsingTsSolutionSetup = exports.addProjectToTsSolutionWorkspace = exports.TS_SOLUTION_SETUP_TSCONFIG_INPUT = exports.addPnpmDeployOutputCacheInputs = exports.shouldIncludePnpmMajorRuntimeInput = exports.pnpmInstallSettingsInputsForInferredTarget = exports.PNPM_MAJOR_RUNTIME_INPUT = exports.PNPM_INSTALL_SETTINGS_INPUTS = exports.isEsmProject = exports.walkTsconfigExtendsChain = exports.findProjectsNpmDependencies = exports.isBuiltinModuleImport = exports.TargetProjectLocator = exports.requireWithTsconfigFallback = exports.registerTsConfigPaths = exports.registerTsProject = exports.loadTsFile = exports.forceRegisterEsmLoader = void 0;
|
|
9
|
+
exports.typesNodeVersion = exports.tsLibVersion = exports.swcNodeVersion = exports.swcHelpersVersion = exports.swcCoreVersion = exports.swcCliVersion = exports.prettierVersion = exports.esbuildVersion = exports.nxVersion = exports.releaseTasks = exports.addReleaseConfigForTsSolution = exports.addReleaseConfigForNonTsSolution = exports.addLocalRegistryScripts = exports.stripGlobToBaseDir = exports.getImportPath = exports.createGlobPatternsForDependencies = exports.addLintingToProject = exports.detectLinters = exports.normalizeUnitTestRunnerOption = exports.normalizeLinterOption = exports.selectTypecheckTsConfig = exports.createTypecheckTarget = exports.isValidPackageJsonBuildConfig = exports.addBuildAndWatchDepsTargets = void 0;
|
|
10
10
|
// Re-exports of nx-source internals.
|
|
11
11
|
var internal_1 = require("@nx/devkit/internal");
|
|
12
12
|
Object.defineProperty(exports, "forceRegisterEsmLoader", { enumerable: true, get: function () { return internal_1.forceRegisterEsmLoader; } });
|
|
@@ -46,6 +46,9 @@ Object.defineProperty(exports, "getProjectType", { enumerable: true, get: functi
|
|
|
46
46
|
Object.defineProperty(exports, "isUsingTsSolutionSetup", { enumerable: true, get: function () { return ts_solution_setup_1.isUsingTsSolutionSetup; } });
|
|
47
47
|
Object.defineProperty(exports, "shouldConfigureTsSolutionSetup", { enumerable: true, get: function () { return ts_solution_setup_1.shouldConfigureTsSolutionSetup; } });
|
|
48
48
|
Object.defineProperty(exports, "updateTsconfigFiles", { enumerable: true, get: function () { return ts_solution_setup_1.updateTsconfigFiles; } });
|
|
49
|
+
var add_typescript_plugin_1 = require("./src/utils/typescript/add-typescript-plugin");
|
|
50
|
+
Object.defineProperty(exports, "ensureTypescriptPlugin", { enumerable: true, get: function () { return add_typescript_plugin_1.ensureTypescriptPlugin; } });
|
|
51
|
+
Object.defineProperty(exports, "registerTypescriptPluginForTypecheck", { enumerable: true, get: function () { return add_typescript_plugin_1.registerTypescriptPluginForTypecheck; } });
|
|
49
52
|
// TypeScript helpers. resolvePathsBaseUrl, extractTsConfigBase,
|
|
50
53
|
// tsConfigBaseOptions, addTsLibDependencies, and resolveModuleByImport ship via
|
|
51
54
|
// the public @nx/js entry. getTsConfigBaseOptions is public too, but is
|
|
@@ -94,6 +97,9 @@ Object.defineProperty(exports, "findNpmDependencies", { enumerable: true, get: f
|
|
|
94
97
|
var util_1 = require("./src/plugins/typescript/util");
|
|
95
98
|
Object.defineProperty(exports, "addBuildAndWatchDepsTargets", { enumerable: true, get: function () { return util_1.addBuildAndWatchDepsTargets; } });
|
|
96
99
|
Object.defineProperty(exports, "isValidPackageJsonBuildConfig", { enumerable: true, get: function () { return util_1.isValidPackageJsonBuildConfig; } });
|
|
100
|
+
var typecheck_target_1 = require("./src/plugins/typescript/typecheck-target");
|
|
101
|
+
Object.defineProperty(exports, "createTypecheckTarget", { enumerable: true, get: function () { return typecheck_target_1.createTypecheckTarget; } });
|
|
102
|
+
Object.defineProperty(exports, "selectTypecheckTsConfig", { enumerable: true, get: function () { return typecheck_target_1.selectTypecheckTsConfig; } });
|
|
97
103
|
// Generator helpers
|
|
98
104
|
var generator_prompts_1 = require("./src/utils/generator-prompts");
|
|
99
105
|
Object.defineProperty(exports, "normalizeLinterOption", { enumerable: true, get: function () { return generator_prompts_1.normalizeLinterOption; } });
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createNodes, createNodesV2, type NodeScriptsPluginOptions, } from './src/plugins/scripts/node-plugin';
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodesV2 = exports.createNodes = void 0;
|
|
4
|
+
var node_plugin_1 = require("./src/plugins/scripts/node-plugin");
|
|
5
|
+
Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return node_plugin_1.createNodes; } });
|
|
6
|
+
Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return node_plugin_1.createNodesV2; } });
|
|
@@ -5,8 +5,8 @@ exports.initGeneratorInternal = initGeneratorInternal;
|
|
|
5
5
|
const internal_1 = require("@nx/devkit/internal");
|
|
6
6
|
const devkit_1 = require("@nx/devkit");
|
|
7
7
|
const path_1 = require("path");
|
|
8
|
-
const plugin_1 = require("../../plugins/typescript/plugin");
|
|
9
8
|
const assert_supported_typescript_version_1 = require("../../utils/assert-supported-typescript-version");
|
|
9
|
+
const add_typescript_plugin_1 = require("../../utils/typescript/add-typescript-plugin");
|
|
10
10
|
const formatter_setup_1 = require("../../utils/formatter-setup");
|
|
11
11
|
const nx_formatter_internals_1 = require("../../utils/nx-formatter-internals");
|
|
12
12
|
const create_ts_config_1 = require("../../utils/typescript/create-ts-config");
|
|
@@ -36,39 +36,9 @@ async function initGenerator(tree, schema) {
|
|
|
36
36
|
async function initGeneratorInternal(tree, schema) {
|
|
37
37
|
(0, assert_supported_typescript_version_1.assertSupportedTypescriptVersion)(tree);
|
|
38
38
|
const tasks = [];
|
|
39
|
-
|
|
40
|
-
schema.addPlugin ??=
|
|
41
|
-
process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
42
|
-
nxJson.useInferencePlugins !== false;
|
|
43
|
-
schema.addTsPlugin ??= schema.addPlugin;
|
|
39
|
+
schema.addTsPlugin ??= true;
|
|
44
40
|
if (schema.addTsPlugin) {
|
|
45
|
-
await (0,
|
|
46
|
-
typecheck: [
|
|
47
|
-
{ targetName: 'typecheck' },
|
|
48
|
-
{ targetName: 'tsc:typecheck' },
|
|
49
|
-
{ targetName: 'tsc-typecheck' },
|
|
50
|
-
],
|
|
51
|
-
build: [
|
|
52
|
-
{
|
|
53
|
-
targetName: 'build',
|
|
54
|
-
configName: 'tsconfig.lib.json',
|
|
55
|
-
buildDepsName: 'build-deps',
|
|
56
|
-
watchDepsName: 'watch-deps',
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
targetName: 'tsc:build',
|
|
60
|
-
configName: 'tsconfig.lib.json',
|
|
61
|
-
buildDepsName: 'tsc:build-deps',
|
|
62
|
-
watchDepsName: 'tsc:watch-deps',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
targetName: 'tsc-build',
|
|
66
|
-
configName: 'tsconfig.lib.json',
|
|
67
|
-
buildDepsName: 'tsc-build-deps',
|
|
68
|
-
watchDepsName: 'tsc-watch-deps',
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
}, schema.updatePackageScripts);
|
|
41
|
+
await (0, add_typescript_plugin_1.addTypescriptPlugin)(tree, schema.updatePackageScripts);
|
|
72
42
|
}
|
|
73
43
|
if (schema.addTsConfigBase && !(0, ts_config_1.getRootTsConfigFileName)(tree)) {
|
|
74
44
|
if (schema.addTsPlugin) {
|
|
@@ -2,6 +2,6 @@ import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
|
2
2
|
import type { LibraryGeneratorSchema, NormalizedLibraryGeneratorOptions } from './schema';
|
|
3
3
|
export declare function libraryGenerator(tree: Tree, schema: LibraryGeneratorSchema): Promise<GeneratorCallback>;
|
|
4
4
|
export declare function libraryGeneratorInternal(tree: Tree, schema: LibraryGeneratorSchema): Promise<GeneratorCallback>;
|
|
5
|
-
export type AddLintOptions = Pick<NormalizedLibraryGeneratorOptions, 'name' | 'linter' | 'projectRoot' | 'unitTestRunner' | 'js' | 'enableTypedLinting' | 'setParserOptionsProject' | 'rootProject' | 'bundler' | '
|
|
5
|
+
export type AddLintOptions = Pick<NormalizedLibraryGeneratorOptions, 'name' | 'linter' | 'projectRoot' | 'unitTestRunner' | 'js' | 'enableTypedLinting' | 'setParserOptionsProject' | 'rootProject' | 'bundler' | 'isUsingTsSolutionConfig'>;
|
|
6
6
|
export declare function addLint(tree: Tree, options: AddLintOptions): Promise<GeneratorCallback>;
|
|
7
7
|
export default libraryGenerator;
|
|
@@ -26,7 +26,6 @@ const add_release_config_1 = require("./utils/add-release-config");
|
|
|
26
26
|
const defaultOutputDirectory = 'dist';
|
|
27
27
|
async function libraryGenerator(tree, schema) {
|
|
28
28
|
return await libraryGeneratorInternal(tree, {
|
|
29
|
-
addPlugin: false,
|
|
30
29
|
useProjectJson: true,
|
|
31
30
|
...schema,
|
|
32
31
|
});
|
|
@@ -34,7 +33,7 @@ async function libraryGenerator(tree, schema) {
|
|
|
34
33
|
async function libraryGeneratorInternal(tree, schema) {
|
|
35
34
|
(0, assert_supported_typescript_version_1.assertSupportedTypescriptVersion)(tree);
|
|
36
35
|
const tasks = [];
|
|
37
|
-
const addTsPlugin = (0, ts_solution_setup_1.shouldConfigureTsSolutionSetup)(tree
|
|
36
|
+
const addTsPlugin = (0, ts_solution_setup_1.shouldConfigureTsSolutionSetup)(tree);
|
|
38
37
|
tasks.push(await (0, init_1.default)(tree, {
|
|
39
38
|
...schema,
|
|
40
39
|
skipFormat: true,
|
|
@@ -72,7 +71,6 @@ async function libraryGeneratorInternal(tree, schema) {
|
|
|
72
71
|
includeLib: true,
|
|
73
72
|
skipFormat: true,
|
|
74
73
|
testEnvironment: options.testEnvironment,
|
|
75
|
-
addPlugin: options.addPlugin,
|
|
76
74
|
});
|
|
77
75
|
tasks.push(viteTask);
|
|
78
76
|
createOrEditViteConfig(tree, {
|
|
@@ -111,7 +109,6 @@ async function libraryGeneratorInternal(tree, schema) {
|
|
|
111
109
|
compiler: options.compiler === 'swc' ? 'swc' : 'babel',
|
|
112
110
|
passWithNoTests: options.passWithNoTests,
|
|
113
111
|
skipPackageJson: options.skipPackageJson,
|
|
114
|
-
addPlugin: options.addPlugin,
|
|
115
112
|
});
|
|
116
113
|
tasks.push(vitestTask);
|
|
117
114
|
}
|
|
@@ -255,7 +252,6 @@ async function addLint(tree, options) {
|
|
|
255
252
|
return (0, add_linting_to_project_1.addLintingToProject)(tree, {
|
|
256
253
|
linter: options.linter,
|
|
257
254
|
project: options.name,
|
|
258
|
-
addPlugin: options.addPlugin,
|
|
259
255
|
rootProject: options.rootProject,
|
|
260
256
|
unitTestRunner: options.unitTestRunner,
|
|
261
257
|
});
|
|
@@ -275,7 +271,6 @@ async function addLint(tree, options) {
|
|
|
275
271
|
unitTestRunner: options.unitTestRunner,
|
|
276
272
|
enableTypedLinting: isTypedLintingEnabled(options),
|
|
277
273
|
rootProject: options.rootProject,
|
|
278
|
-
addPlugin: options.addPlugin,
|
|
279
274
|
// Since the build target is inferred now, we need to let the generator know to add @nx/dependency-checks regardless.
|
|
280
275
|
addPackageJsonDependencyChecks: options.bundler !== 'none',
|
|
281
276
|
});
|
|
@@ -552,13 +547,10 @@ function replaceJestConfig(tree, options) {
|
|
|
552
547
|
}
|
|
553
548
|
async function normalizeOptions(tree, options) {
|
|
554
549
|
await (0, internal_1.ensureRootProjectName)(options, 'library');
|
|
555
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
556
|
-
options.addPlugin ??=
|
|
557
|
-
process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
558
|
-
nxJson.useInferencePlugins !== false;
|
|
559
550
|
options.linter = await (0, generator_prompts_1.normalizeLinterOption)(tree, options.linter);
|
|
560
|
-
const hasPlugin = (0, ts_solution_setup_1.isUsingTypeScriptPlugin)(tree);
|
|
561
551
|
const isUsingTsSolutionConfig = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
|
|
552
|
+
// Outside TS solution setups the plugin may be registered for typecheck only.
|
|
553
|
+
const hasPlugin = isUsingTsSolutionConfig && (0, ts_solution_setup_1.isUsingTypeScriptPlugin)(tree);
|
|
562
554
|
if (isUsingTsSolutionConfig) {
|
|
563
555
|
options.unitTestRunner ??= (0, internal_1.isInteractive)()
|
|
564
556
|
? await (0, internal_1.selectPrompt)({
|
|
@@ -72,9 +72,6 @@ async function setupBuildGenerator(tree, options) {
|
|
|
72
72
|
}
|
|
73
73
|
options.tsConfig = tsConfigFile;
|
|
74
74
|
const isTsSolutionSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
|
|
75
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
76
|
-
const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
77
|
-
nxJson.useInferencePlugins !== false;
|
|
78
75
|
switch (options.bundler) {
|
|
79
76
|
case 'vite': {
|
|
80
77
|
const { viteConfigurationGenerator } = (0, devkit_1.ensurePackage)('@nx/vite', versions_1.nxVersion);
|
|
@@ -85,7 +82,6 @@ async function setupBuildGenerator(tree, options) {
|
|
|
85
82
|
uiFramework: 'none',
|
|
86
83
|
includeVitest: false,
|
|
87
84
|
includeLib: true,
|
|
88
|
-
addPlugin,
|
|
89
85
|
skipFormat: true,
|
|
90
86
|
});
|
|
91
87
|
tasks.push(task);
|
|
@@ -113,7 +109,6 @@ async function setupBuildGenerator(tree, options) {
|
|
|
113
109
|
project: options.project,
|
|
114
110
|
compiler: 'tsc',
|
|
115
111
|
format: isTsSolutionSetup ? ['esm'] : ['cjs', 'esm'],
|
|
116
|
-
addPlugin,
|
|
117
112
|
skipFormat: true,
|
|
118
113
|
skipValidation: true,
|
|
119
114
|
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type CreateNodes, type TargetConfiguration } from '@nx/devkit';
|
|
2
|
+
import { type Shebang } from './shebang';
|
|
3
|
+
export interface ScriptPluginOptions {
|
|
4
|
+
/** Runs claimed scripts in watch mode as continuous targets. */
|
|
5
|
+
watch?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ScriptPluginDefinition<T extends ScriptPluginOptions> {
|
|
8
|
+
/** Prefix of the plugin's cache file. */
|
|
9
|
+
cacheName: string;
|
|
10
|
+
technology: string;
|
|
11
|
+
/** Only files whose shebang the plugin claims become targets. */
|
|
12
|
+
claims(shebang: Shebang): boolean;
|
|
13
|
+
/** `file` is relative to the target's cwd. */
|
|
14
|
+
command(file: string, shebang: Shebang, watch: boolean): string;
|
|
15
|
+
/** Targets not tied to a shebang; claimed scripts win on name clashes. */
|
|
16
|
+
extraTargets?(projectRoot: string, workspaceRoot: string, options: T): Promise<ScriptTargets>;
|
|
17
|
+
}
|
|
18
|
+
export type ScriptTargets = Record<string, TargetConfiguration>;
|
|
19
|
+
export declare function createScriptNodes<T extends ScriptPluginOptions>(definition: ScriptPluginDefinition<T>): CreateNodes<T>;
|
|
20
|
+
/**
|
|
21
|
+
* Quotes a path for a shell command when the shell would split or expand it.
|
|
22
|
+
* Double quotes keep spaces intact in sh and cmd.exe; cmd.exe still expands `%VAR%`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function quoteShellArg(arg: string): string;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createScriptNodes = createScriptNodes;
|
|
4
|
+
exports.quoteShellArg = quoteShellArg;
|
|
5
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const shebang_1 = require("./shebang");
|
|
8
|
+
const target_name_1 = require("./target-name");
|
|
9
|
+
const SCRIPT_GLOB = '**/*.{js,cjs,mjs,ts,cts,mts}';
|
|
10
|
+
const PROJECT_MARKERS = ['package.json', 'project.json'];
|
|
11
|
+
function createScriptNodes(definition) {
|
|
12
|
+
return [
|
|
13
|
+
(0, internal_1.combineGlobPatterns)([
|
|
14
|
+
SCRIPT_GLOB,
|
|
15
|
+
...PROJECT_MARKERS.map((marker) => `**/${marker}`),
|
|
16
|
+
]),
|
|
17
|
+
async (files, options, context) => {
|
|
18
|
+
const scriptsByRoot = groupScriptsByProjectRoot(files, !!definition.extraTargets);
|
|
19
|
+
const projectRoots = [...scriptsByRoot.keys()];
|
|
20
|
+
if (!projectRoots.length) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const cache = new internal_1.PluginCache((0, node_path_1.join)(internal_1.workspaceDataDirectory, `${definition.cacheName}-${(0, internal_1.hashObject)(options ?? {})}.hash`));
|
|
24
|
+
try {
|
|
25
|
+
const hashes = await (0, internal_1.calculateHashesForCreateNodes)(projectRoots, options ?? {}, context);
|
|
26
|
+
const results = [];
|
|
27
|
+
for (const [i, projectRoot] of projectRoots.entries()) {
|
|
28
|
+
const { marker, scripts } = scriptsByRoot.get(projectRoot);
|
|
29
|
+
// include/exclude can change which scripts a project gets without
|
|
30
|
+
// changing its contents.
|
|
31
|
+
const key = (0, internal_1.hashObject)([hashes[i], [...scripts].sort()]);
|
|
32
|
+
if (!cache.has(key)) {
|
|
33
|
+
cache.set(key, {
|
|
34
|
+
...(await definition.extraTargets?.(projectRoot, context.workspaceRoot, options)),
|
|
35
|
+
...createTargets(definition, context.workspaceRoot, projectRoot, scripts, options?.watch === true),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const targets = cache.get(key);
|
|
39
|
+
if (Object.keys(targets).length) {
|
|
40
|
+
results.push([
|
|
41
|
+
scripts[0] ?? marker,
|
|
42
|
+
{ projects: { [projectRoot]: { root: projectRoot, targets } } },
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return results;
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
cache.writeToDisk();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Assigns each script to its nearest enclosing project root. Roots without
|
|
56
|
+
* scripts are kept only when `includeAllRoots` is set.
|
|
57
|
+
*/
|
|
58
|
+
function groupScriptsByProjectRoot(files, includeAllRoots) {
|
|
59
|
+
const markers = new Map();
|
|
60
|
+
const scripts = [];
|
|
61
|
+
for (const file of files) {
|
|
62
|
+
if (PROJECT_MARKERS.includes((0, node_path_1.basename)(file))) {
|
|
63
|
+
markers.set((0, node_path_1.dirname)(file), file);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
scripts.push(file);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const byRoot = new Map();
|
|
70
|
+
if (includeAllRoots) {
|
|
71
|
+
for (const [root, marker] of markers) {
|
|
72
|
+
byRoot.set(root, { marker, scripts: [] });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const script of scripts) {
|
|
76
|
+
let dir = (0, node_path_1.dirname)(script);
|
|
77
|
+
while (!markers.has(dir) && dir !== '.') {
|
|
78
|
+
dir = (0, node_path_1.dirname)(dir);
|
|
79
|
+
}
|
|
80
|
+
if (!markers.has(dir)) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (!byRoot.has(dir)) {
|
|
84
|
+
byRoot.set(dir, { marker: markers.get(dir), scripts: [] });
|
|
85
|
+
}
|
|
86
|
+
byRoot.get(dir).scripts.push(script);
|
|
87
|
+
}
|
|
88
|
+
return byRoot;
|
|
89
|
+
}
|
|
90
|
+
function createTargets(definition, workspaceRoot, projectRoot, scripts, watch) {
|
|
91
|
+
const claimed = [];
|
|
92
|
+
for (const script of scripts) {
|
|
93
|
+
const header = (0, shebang_1.readScriptHeader)((0, node_path_1.join)(workspaceRoot, script));
|
|
94
|
+
const shebang = header === null ? null : (0, shebang_1.parseShebang)((0, shebang_1.getShebangLine)(header));
|
|
95
|
+
if (!shebang || !definition.claims(shebang)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const { name, warnings } = (0, target_name_1.parseTargetName)(header);
|
|
99
|
+
for (const warning of warnings) {
|
|
100
|
+
(0, internal_1.emitPluginWorkerLog)('warn', `${script}: ${warning}.`);
|
|
101
|
+
}
|
|
102
|
+
claimed.push({
|
|
103
|
+
path: script,
|
|
104
|
+
relativePath: node_path_1.posix.relative(projectRoot, script),
|
|
105
|
+
shebang,
|
|
106
|
+
targetName: name,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const baseNameCounts = new Map();
|
|
110
|
+
for (const { relativePath } of claimed) {
|
|
111
|
+
const name = withoutExtension((0, node_path_1.basename)(relativePath));
|
|
112
|
+
baseNameCounts.set(name, (baseNameCounts.get(name) ?? 0) + 1);
|
|
113
|
+
}
|
|
114
|
+
const targets = {};
|
|
115
|
+
for (const script of claimed) {
|
|
116
|
+
const baseName = withoutExtension((0, node_path_1.basename)(script.relativePath));
|
|
117
|
+
const name = script.targetName ??
|
|
118
|
+
(baseNameCounts.get(baseName) > 1
|
|
119
|
+
? withoutExtension(script.relativePath)
|
|
120
|
+
: baseName);
|
|
121
|
+
targets[name] = createTarget(definition, projectRoot, script, watch);
|
|
122
|
+
}
|
|
123
|
+
return targets;
|
|
124
|
+
}
|
|
125
|
+
function createTarget(definition, projectRoot, { path, relativePath, shebang }, watch) {
|
|
126
|
+
return {
|
|
127
|
+
command: definition.command(quoteShellArg(node_path_1.posix.relative(projectRoot, path)), shebang, watch),
|
|
128
|
+
options: { cwd: projectRoot },
|
|
129
|
+
cache: false,
|
|
130
|
+
...(watch && { continuous: true }),
|
|
131
|
+
metadata: {
|
|
132
|
+
technologies: [definition.technology],
|
|
133
|
+
description: `Runs ${relativePath}`,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Quotes a path for a shell command when the shell would split or expand it.
|
|
139
|
+
* Double quotes keep spaces intact in sh and cmd.exe; cmd.exe still expands `%VAR%`.
|
|
140
|
+
*/
|
|
141
|
+
function quoteShellArg(arg) {
|
|
142
|
+
if (/^[\w@%+=:,./-]+$/.test(arg)) {
|
|
143
|
+
return arg;
|
|
144
|
+
}
|
|
145
|
+
return '"' + arg.replace(/(["\\$`])/g, '\\$1') + '"';
|
|
146
|
+
}
|
|
147
|
+
function withoutExtension(path) {
|
|
148
|
+
return path.slice(0, path.length - (0, node_path_1.extname)(path).length);
|
|
149
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ScriptPluginOptions } from './create-script-nodes';
|
|
2
|
+
export interface NodeScriptsPluginOptions extends ScriptPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* `dependsOn` for `bin` targets whose file is build output (not a tracked
|
|
5
|
+
* workspace file). Defaults to `["build"]`.
|
|
6
|
+
*/
|
|
7
|
+
binDependsOn?: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare const createNodes: import("@nx/devkit").CreateNodes<NodeScriptsPluginOptions>;
|
|
10
|
+
export declare const createNodesV2: import("@nx/devkit").CreateNodes<NodeScriptsPluginOptions>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodesV2 = exports.createNodes = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const create_script_nodes_1 = require("./create-script-nodes");
|
|
9
|
+
exports.createNodes = (0, create_script_nodes_1.createScriptNodes)({
|
|
10
|
+
cacheName: 'js-node-scripts',
|
|
11
|
+
technology: 'node',
|
|
12
|
+
claims: (shebang) => shebang.interpreter === 'node',
|
|
13
|
+
command: (file, shebang, watch) => ['node', ...(watch ? ['--watch'] : []), ...shebang.args, file].join(' '),
|
|
14
|
+
extraTargets: createBinTargets,
|
|
15
|
+
});
|
|
16
|
+
exports.createNodesV2 = exports.createNodes;
|
|
17
|
+
async function createBinTargets(projectRoot, workspaceRoot, options) {
|
|
18
|
+
const packageJsonPath = (0, node_path_1.join)(workspaceRoot, projectRoot, 'package.json');
|
|
19
|
+
if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const bins = readBinEntries((0, devkit_1.readJsonFile)(packageJsonPath));
|
|
23
|
+
if (!bins.length) {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
const binFiles = bins.map(([, path]) => node_path_1.posix.join(projectRoot, node_path_1.posix.normalize(path)));
|
|
27
|
+
const tracked = new Set(await (0, internal_1.globWithWorkspaceContext)(workspaceRoot, binFiles));
|
|
28
|
+
const targets = {};
|
|
29
|
+
bins.forEach(([name, path], i) => {
|
|
30
|
+
const target = {
|
|
31
|
+
command: `node ${(0, create_script_nodes_1.quoteShellArg)(node_path_1.posix.normalize(path))}`,
|
|
32
|
+
options: { cwd: projectRoot },
|
|
33
|
+
cache: false,
|
|
34
|
+
metadata: {
|
|
35
|
+
technologies: ['node'],
|
|
36
|
+
description: `Runs the ${name} bin`,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
if (!tracked.has(binFiles[i])) {
|
|
40
|
+
target.dependsOn = options?.binDependsOn ?? ['build'];
|
|
41
|
+
}
|
|
42
|
+
targets[name] = target;
|
|
43
|
+
});
|
|
44
|
+
return targets;
|
|
45
|
+
}
|
|
46
|
+
function readBinEntries(packageJson) {
|
|
47
|
+
const { name, bin } = packageJson;
|
|
48
|
+
if (typeof bin === 'string') {
|
|
49
|
+
return name ? [[name.replace(/^@[^/]+\//, ''), bin]] : [];
|
|
50
|
+
}
|
|
51
|
+
return Object.entries(bin ?? {}).filter((entry) => typeof entry[1] === 'string');
|
|
52
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface Shebang {
|
|
2
|
+
/** Program that runs the file, e.g. `node` or `tsx`. */
|
|
3
|
+
interpreter: string;
|
|
4
|
+
/** Arguments that follow the interpreter on the shebang line. */
|
|
5
|
+
args: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Returns the first bytes of a script that starts with `#!`, or `null` when it
|
|
9
|
+
* has no shebang or cannot be read (e.g. a tracked broken symlink).
|
|
10
|
+
*/
|
|
11
|
+
export declare function readScriptHeader(absolutePath: string): string | null;
|
|
12
|
+
/** The shebang line of a header from `readScriptHeader`, without `#!`. */
|
|
13
|
+
export declare function getShebangLine(header: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Handles `/usr/bin/env node`, `/usr/bin/env -S node --flags`,
|
|
16
|
+
* `/usr/bin/env -S npx tsx` and direct paths such as `/usr/local/bin/node`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseShebang(line: string): Shebang | null;
|
|
19
|
+
export declare function stripBom(text: string): string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readScriptHeader = readScriptHeader;
|
|
4
|
+
exports.getShebangLine = getShebangLine;
|
|
5
|
+
exports.parseShebang = parseShebang;
|
|
6
|
+
exports.stripBom = stripBom;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const SNIFF_BYTES = 512;
|
|
10
|
+
const PACKAGE_RUNNERS = new Set(['npx', 'pnpx', 'bunx']);
|
|
11
|
+
/**
|
|
12
|
+
* Returns the first bytes of a script that starts with `#!`, or `null` when it
|
|
13
|
+
* has no shebang or cannot be read (e.g. a tracked broken symlink).
|
|
14
|
+
*/
|
|
15
|
+
function readScriptHeader(absolutePath) {
|
|
16
|
+
const buffer = Buffer.alloc(SNIFF_BYTES);
|
|
17
|
+
let bytesRead;
|
|
18
|
+
try {
|
|
19
|
+
const fd = (0, node_fs_1.openSync)(absolutePath, 'r');
|
|
20
|
+
try {
|
|
21
|
+
bytesRead = (0, node_fs_1.readSync)(fd, buffer, 0, SNIFF_BYTES, 0);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
(0, node_fs_1.closeSync)(fd);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
let text = stripBom(buffer.toString('utf8', 0, bytesRead));
|
|
31
|
+
if (!text.startsWith('#!')) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
// Drop a line the sniff cut off, so a directive is never read truncated.
|
|
35
|
+
if (bytesRead === SNIFF_BYTES && text.includes('\n')) {
|
|
36
|
+
text = text.slice(0, text.lastIndexOf('\n'));
|
|
37
|
+
}
|
|
38
|
+
return text;
|
|
39
|
+
}
|
|
40
|
+
/** The shebang line of a header from `readScriptHeader`, without `#!`. */
|
|
41
|
+
function getShebangLine(header) {
|
|
42
|
+
const end = header.search(/\r?\n/);
|
|
43
|
+
return (end === -1 ? header : header.slice(0, end)).slice(2).trim();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Handles `/usr/bin/env node`, `/usr/bin/env -S node --flags`,
|
|
47
|
+
* `/usr/bin/env -S npx tsx` and direct paths such as `/usr/local/bin/node`.
|
|
48
|
+
*/
|
|
49
|
+
function parseShebang(line) {
|
|
50
|
+
let tokens = line.split(/\s+/).filter(Boolean);
|
|
51
|
+
if (tokens.length && (0, node_path_1.basename)(tokens[0]) === 'env') {
|
|
52
|
+
tokens = tokens.slice(1);
|
|
53
|
+
if (tokens[0] === '-S') {
|
|
54
|
+
tokens = tokens.slice(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (tokens.length && PACKAGE_RUNNERS.has((0, node_path_1.basename)(tokens[0]))) {
|
|
58
|
+
tokens = tokens.slice(1);
|
|
59
|
+
}
|
|
60
|
+
if (!tokens.length) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
return { interpreter: (0, node_path_1.basename)(tokens[0]), args: tokens.slice(1) };
|
|
64
|
+
}
|
|
65
|
+
function stripBom(text) {
|
|
66
|
+
return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
|
|
67
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface TargetNameDirective {
|
|
2
|
+
name?: string;
|
|
3
|
+
warnings: string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Reads `@nx-target-name: <name>` from the comment block that opens the
|
|
7
|
+
* script. Only the first directive counts; problems come back as warnings.
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseTargetName(header: string): TargetNameDirective;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTargetName = parseTargetName;
|
|
4
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
5
|
+
/**
|
|
6
|
+
* Reads `@nx-target-name: <name>` from the comment block that opens the
|
|
7
|
+
* script. Only the first directive counts; problems come back as warnings.
|
|
8
|
+
*/
|
|
9
|
+
function parseTargetName(header) {
|
|
10
|
+
const [value, ...extra] = (0, internal_1.parseNxDirectives)(header).get('target-name') ?? [];
|
|
11
|
+
const warnings = extra.map((v) => `ignoring the extra "@nx-target-name: ${v}" directive`);
|
|
12
|
+
if (value === undefined) {
|
|
13
|
+
return { warnings };
|
|
14
|
+
}
|
|
15
|
+
if (!value) {
|
|
16
|
+
return { warnings: ['"@nx-target-name" is empty', ...warnings] };
|
|
17
|
+
}
|
|
18
|
+
return { name: value, warnings };
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodesV2 = exports.createNodes = void 0;
|
|
4
|
+
const create_script_nodes_1 = require("./create-script-nodes");
|
|
5
|
+
exports.createNodes = (0, create_script_nodes_1.createScriptNodes)({
|
|
6
|
+
cacheName: 'js-tsx-scripts',
|
|
7
|
+
technology: 'tsx',
|
|
8
|
+
claims: (shebang) => shebang.interpreter === 'tsx',
|
|
9
|
+
command: (file, shebang, watch) => ['tsx', ...(watch ? ['watch'] : []), ...shebang.args, file].join(' '),
|
|
10
|
+
});
|
|
11
|
+
exports.createNodesV2 = exports.createNodes;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TargetConfiguration } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* Whether the project's build already type-checks it, judged from its
|
|
4
|
+
* `project.json` and `package.json` targets and, when no build executor is found, its bundler
|
|
5
|
+
* config files. Options set inside a bundler config can't be read, so those
|
|
6
|
+
* builds are assumed to type-check, which is their default.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildTypechecksProject(siblingFiles: string[], targets: Record<string, TargetConfiguration> | undefined): boolean;
|