@nx/devkit 23.1.0-beta.4 → 23.1.0-beta.5
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 +1 -1
- package/dist/internal.js +6 -1
- package/dist/src/generators/e2e-web-server-info-utils.js +8 -12
- package/dist/src/generators/plugin-migrations/executor-to-plugin-migrator.d.ts +2 -1
- package/dist/src/generators/plugin-migrations/executor-to-plugin-migrator.js +19 -1
- package/dist/src/generators/target-defaults-utils.d.ts +118 -1
- package/dist/src/generators/target-defaults-utils.js +360 -17
- package/package.json +2 -2
package/dist/internal.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { migrateProjectExecutorsToPlugin, migrateProjectExecutorsToPluginV1, NoT
|
|
|
7
7
|
export { processTargetOutputs, deleteMatchingProperties, toProjectRelativePath, } from './src/generators/plugin-migrations/plugin-migration-utils';
|
|
8
8
|
export { determineProjectNameAndRootOptions, ensureRootProjectName, resolveImportPath, } from './src/generators/project-name-and-root-utils';
|
|
9
9
|
export { promptWhenInteractive } from './src/generators/prompt';
|
|
10
|
-
export { addBuildTargetDefaults, addE2eCiTargetDefaults, } from './src/generators/target-defaults-utils';
|
|
10
|
+
export { addBuildTargetDefaults, addE2eCiTargetDefaults, findTargetDefault, readTargetDefaultsForTarget, updateTargetDefault, upsertTargetDefault, } from './src/generators/target-defaults-utils';
|
|
11
11
|
export { addPlugin } from './src/utils/add-plugin';
|
|
12
12
|
export { getDeclaredPackageVersion, getInstalledPackageVersion, } from './src/utils/installed-version';
|
|
13
13
|
export { assertSupportedInstalledPackageVersion, assertSupportedPackageVersion, } from './src/utils/version-floor';
|
package/dist/internal.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.checkAndCleanWithSemver = exports.eachValueFrom = exports.logShowProjectCommand = exports.getNamedInputs = exports.findPluginForConfigFile = exports.clearRequireCache = exports.loadConfigFile = exports.getCatalogManager = exports.calculateHashesForCreateNodes = exports.calculateHashForCreateNodes = exports.mapAsyncIterable = exports.combineAsyncIterables = exports.createAsyncIterable = exports.assertSupportedPackageVersion = exports.assertSupportedInstalledPackageVersion = exports.getInstalledPackageVersion = exports.getDeclaredPackageVersion = exports.addPlugin = exports.upsertTargetDefault = exports.updateTargetDefault = exports.readTargetDefaultsForTarget = exports.findTargetDefault = exports.addE2eCiTargetDefaults = exports.addBuildTargetDefaults = exports.promptWhenInteractive = exports.resolveImportPath = exports.ensureRootProjectName = exports.determineProjectNameAndRootOptions = exports.toProjectRelativePath = exports.deleteMatchingProperties = exports.processTargetOutputs = exports.NoTargetsToMigrateError = exports.migrateProjectExecutorsToPluginV1 = exports.migrateProjectExecutorsToPlugin = exports.AggregatedLog = exports.forEachExecutorOptions = exports.getE2EWebServerInfo = exports.getRelativeCwd = exports.determineArtifactNameAndDirectoryOptions = exports.PromptResolutionError = exports.resolvePrompt = exports.SchemaResolutionError = exports.ImplementationResolutionError = exports.resolveSchema = exports.resolveImplementation = exports.emitPluginWorkerLog = exports.safeWriteFileCache = exports.PluginCache = exports.createProjectRootMappingsFromProjectConfigurations = exports.signalToCode = void 0;
|
|
4
|
+
exports.dasherize = exports.classify = exports.capitalize = exports.camelize = void 0;
|
|
4
5
|
var devkit_internals_1 = require("nx/src/devkit-internals");
|
|
5
6
|
Object.defineProperty(exports, "signalToCode", { enumerable: true, get: function () { return devkit_internals_1.signalToCode; } });
|
|
6
7
|
Object.defineProperty(exports, "createProjectRootMappingsFromProjectConfigurations", { enumerable: true, get: function () { return devkit_internals_1.createProjectRootMappingsFromProjectConfigurations; } });
|
|
@@ -40,6 +41,10 @@ Object.defineProperty(exports, "promptWhenInteractive", { enumerable: true, get:
|
|
|
40
41
|
var target_defaults_utils_1 = require("./src/generators/target-defaults-utils");
|
|
41
42
|
Object.defineProperty(exports, "addBuildTargetDefaults", { enumerable: true, get: function () { return target_defaults_utils_1.addBuildTargetDefaults; } });
|
|
42
43
|
Object.defineProperty(exports, "addE2eCiTargetDefaults", { enumerable: true, get: function () { return target_defaults_utils_1.addE2eCiTargetDefaults; } });
|
|
44
|
+
Object.defineProperty(exports, "findTargetDefault", { enumerable: true, get: function () { return target_defaults_utils_1.findTargetDefault; } });
|
|
45
|
+
Object.defineProperty(exports, "readTargetDefaultsForTarget", { enumerable: true, get: function () { return target_defaults_utils_1.readTargetDefaultsForTarget; } });
|
|
46
|
+
Object.defineProperty(exports, "updateTargetDefault", { enumerable: true, get: function () { return target_defaults_utils_1.updateTargetDefault; } });
|
|
47
|
+
Object.defineProperty(exports, "upsertTargetDefault", { enumerable: true, get: function () { return target_defaults_utils_1.upsertTargetDefault; } });
|
|
43
48
|
// Utils
|
|
44
49
|
var add_plugin_1 = require("./src/utils/add-plugin");
|
|
45
50
|
Object.defineProperty(exports, "addPlugin", { enumerable: true, get: function () { return add_plugin_1.addPlugin; } });
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getE2EWebServerInfo = getE2EWebServerInfo;
|
|
4
4
|
const devkit_exports_1 = require("nx/src/devkit-exports");
|
|
5
|
+
const target_defaults_utils_1 = require("./target-defaults-utils");
|
|
5
6
|
const find_plugin_for_config_file_1 = require("../utils/find-plugin-for-config-file");
|
|
6
7
|
async function getE2EWebServerInfo(tree, projectName, pluginOptions, defaultValues, isPluginBeingAdded) {
|
|
7
8
|
const pm = (0, devkit_exports_1.getPackageManagerCommand)((0, devkit_exports_1.detectPackageManager)(tree.root));
|
|
@@ -33,23 +34,18 @@ async function getE2EWebServerInfoForPlugin(tree, projectName, pluginOptions, de
|
|
|
33
34
|
}
|
|
34
35
|
const nxJson = (0, devkit_exports_1.readNxJson)(tree);
|
|
35
36
|
let e2ePort = defaultValues.defaultE2EPort ?? 4200;
|
|
36
|
-
|
|
37
|
-
defaultValues.defaultServeTargetName
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
nxJson.targetDefaults?.[foundPlugin.options[pluginOptions.serveTargetName] ??
|
|
42
|
-
defaultValues.defaultServeTargetName].options?.port;
|
|
43
|
-
}
|
|
37
|
+
const serveTargetName = foundPlugin.options[pluginOptions.serveTargetName] ??
|
|
38
|
+
defaultValues.defaultServeTargetName;
|
|
39
|
+
e2ePort =
|
|
40
|
+
(0, target_defaults_utils_1.readTargetDefaultsForTarget)(serveTargetName, nxJson.targetDefaults)?.options
|
|
41
|
+
?.port ?? e2ePort;
|
|
44
42
|
const e2eWebServerAddress = defaultValues.defaultE2EWebServerAddress.replace(/:\d+/, `:${e2ePort}`);
|
|
45
43
|
return {
|
|
46
44
|
e2eWebServerAddress,
|
|
47
|
-
e2eWebServerCommand: `${pm.exec} nx run ${projectName}:${
|
|
48
|
-
defaultValues.defaultServeTargetName}`,
|
|
45
|
+
e2eWebServerCommand: `${pm.exec} nx run ${projectName}:${serveTargetName}`,
|
|
49
46
|
e2eCiWebServerCommand: `${pm.exec} nx run ${projectName}:${foundPlugin.options[pluginOptions.serveStaticTargetName] ??
|
|
50
47
|
defaultValues.defaultServeStaticTargetName}`,
|
|
51
48
|
e2eCiBaseUrl: defaultValues.defaultE2ECiBaseUrl,
|
|
52
|
-
e2eDevServerTarget: `${projectName}:${
|
|
53
|
-
defaultValues.defaultServeTargetName}`,
|
|
49
|
+
e2eDevServerTarget: `${projectName}:${serveTargetName}`,
|
|
54
50
|
};
|
|
55
51
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json';
|
|
2
|
-
import { type CreateNodes, type ProjectGraph, type TargetConfiguration, type Tree } from 'nx/src/devkit-exports';
|
|
2
|
+
import { type CreateNodes, type NxJsonConfiguration, type ProjectGraph, type TargetConfiguration, type Tree } from 'nx/src/devkit-exports';
|
|
3
3
|
import { logger as devkitLogger } from 'nx/src/devkit-exports';
|
|
4
4
|
export type InferredTargetConfiguration = TargetConfiguration & {
|
|
5
5
|
name: string;
|
|
@@ -13,6 +13,7 @@ type SkipProjectFilter = (projectConfiguration: ProjectConfiguration) => false |
|
|
|
13
13
|
export declare class NoTargetsToMigrateError extends Error {
|
|
14
14
|
constructor();
|
|
15
15
|
}
|
|
16
|
+
export declare function readTargetDefaultsForExecutor(executor: string, targetDefaults: NxJsonConfiguration['targetDefaults'] | undefined): Partial<TargetConfiguration> | undefined;
|
|
16
17
|
export declare function migrateProjectExecutorsToPlugin<T>(tree: Tree, projectGraph: ProjectGraph, pluginPath: string, createNodesV2: CreateNodes<T>, defaultPluginOptions: T, migrations: Array<{
|
|
17
18
|
executors: string[];
|
|
18
19
|
targetPluginOptionMapper: (targetName: string) => Partial<T>;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var _ExecutorToPluginMigrator_instances, _ExecutorToPluginMigrator_projectGraph, _ExecutorToPluginMigrator_executor, _ExecutorToPluginMigrator_pluginPath, _ExecutorToPluginMigrator_pluginOptionsBuilder, _ExecutorToPluginMigrator_postTargetTransformer, _ExecutorToPluginMigrator_skipTargetFilter, _ExecutorToPluginMigrator_skipProjectFilter, _ExecutorToPluginMigrator_specificProjectToMigrate, _ExecutorToPluginMigrator_logger, _ExecutorToPluginMigrator_nxJson, _ExecutorToPluginMigrator_targetDefaultsForExecutor, _ExecutorToPluginMigrator_targetAndProjectsToMigrate, _ExecutorToPluginMigrator_createNodes, _ExecutorToPluginMigrator_createNodesV2, _ExecutorToPluginMigrator_createNodesResultsForTargets, _ExecutorToPluginMigrator_skippedProjects, _ExecutorToPluginMigrator_init, _ExecutorToPluginMigrator_migrateTarget, _ExecutorToPluginMigrator_migrateProject, _ExecutorToPluginMigrator_mergeInputs, _ExecutorToPluginMigrator_getTargetAndProjectsToMigrate, _ExecutorToPluginMigrator_getTargetDefaultsForExecutor, _ExecutorToPluginMigrator_getCreatedTargetForProjectRoot, _ExecutorToPluginMigrator_getCreateNodesResults;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.NoTargetsToMigrateError = void 0;
|
|
5
|
+
exports.readTargetDefaultsForExecutor = readTargetDefaultsForExecutor;
|
|
5
6
|
exports.migrateProjectExecutorsToPlugin = migrateProjectExecutorsToPlugin;
|
|
6
7
|
exports.migrateProjectExecutorsToPluginV1 = migrateProjectExecutorsToPluginV1;
|
|
7
8
|
const tslib_1 = require("tslib");
|
|
@@ -11,6 +12,7 @@ const posix_1 = require("node:path/posix");
|
|
|
11
12
|
const devkit_exports_1 = require("nx/src/devkit-exports");
|
|
12
13
|
const devkit_internals_1 = require("nx/src/devkit-internals");
|
|
13
14
|
const executor_options_utils_1 = require("../executor-options-utils");
|
|
15
|
+
const target_defaults_utils_1 = require("../target-defaults-utils");
|
|
14
16
|
const plugin_migration_utils_1 = require("./plugin-migration-utils");
|
|
15
17
|
const devkit_exports_2 = require("nx/src/devkit-exports");
|
|
16
18
|
class ExecutorToPluginMigrator {
|
|
@@ -169,7 +171,7 @@ _ExecutorToPluginMigrator_projectGraph = new WeakMap(), _ExecutorToPluginMigrato
|
|
|
169
171
|
}
|
|
170
172
|
});
|
|
171
173
|
}, _ExecutorToPluginMigrator_getTargetDefaultsForExecutor = function _ExecutorToPluginMigrator_getTargetDefaultsForExecutor() {
|
|
172
|
-
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_targetDefaultsForExecutor, structuredClone(tslib_1.__classPrivateFieldGet(this,
|
|
174
|
+
tslib_1.__classPrivateFieldSet(this, _ExecutorToPluginMigrator_targetDefaultsForExecutor, structuredClone(readTargetDefaultsForExecutor(tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_executor, "f"), tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_nxJson, "f").targetDefaults) ?? {}), "f");
|
|
173
175
|
}, _ExecutorToPluginMigrator_getCreatedTargetForProjectRoot = function _ExecutorToPluginMigrator_getCreatedTargetForProjectRoot(targetName, projectRoot) {
|
|
174
176
|
const entry = Object.entries(tslib_1.__classPrivateFieldGet(this, _ExecutorToPluginMigrator_createNodesResultsForTargets, "f").get(targetName)?.projects ?? {}).find(([root]) => root === projectRoot);
|
|
175
177
|
if (!entry) {
|
|
@@ -204,6 +206,22 @@ class NoTargetsToMigrateError extends Error {
|
|
|
204
206
|
}
|
|
205
207
|
}
|
|
206
208
|
exports.NoTargetsToMigrateError = NoTargetsToMigrateError;
|
|
209
|
+
function readTargetDefaultsForExecutor(executor, targetDefaults) {
|
|
210
|
+
// Preserve the legacy record-shape semantics this migrator used before
|
|
211
|
+
// array support: only an unfiltered default keyed directly by executor
|
|
212
|
+
// applies here. Target-scoped or filtered array entries remain opt-in
|
|
213
|
+
// behaviors for callers that can evaluate them in project context.
|
|
214
|
+
const entry = (0, target_defaults_utils_1.findTargetDefault)(targetDefaults, { executor });
|
|
215
|
+
if (!entry) {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
const config = { ...entry };
|
|
219
|
+
delete config.target;
|
|
220
|
+
delete config.executor;
|
|
221
|
+
delete config.projects;
|
|
222
|
+
delete config.plugin;
|
|
223
|
+
return config;
|
|
224
|
+
}
|
|
207
225
|
async function migrateProjectExecutorsToPlugin(tree, projectGraph, pluginPath, createNodesV2, defaultPluginOptions, migrations, specificProjectToMigrate, logger) {
|
|
208
226
|
const projects = await migrateProjects(tree, projectGraph, pluginPath, undefined, createNodesV2, defaultPluginOptions, migrations, specificProjectToMigrate, logger);
|
|
209
227
|
return projects;
|
|
@@ -1,3 +1,120 @@
|
|
|
1
|
-
import { type TargetConfiguration, type Tree } from 'nx/src/devkit-exports';
|
|
1
|
+
import { type NxJsonConfiguration, type TargetConfiguration, type TargetDefaultEntry, type TargetDefaultFilter, type TargetDefaults, type Tree } from 'nx/src/devkit-exports';
|
|
2
|
+
import { readTargetDefaultsForTarget as readTargetDefaultsForTargetFromNx } from 'nx/src/devkit-internals';
|
|
3
|
+
/**
|
|
4
|
+
* Upsert a `targetDefaults` entry on the provided `nxJson`. Mutates
|
|
5
|
+
* `nxJson` in place and returns it so the caller can chain or batch
|
|
6
|
+
* other edits before persisting via `updateNxJson` exactly once.
|
|
7
|
+
*
|
|
8
|
+
* The input is the logical {@link TargetDefaultEntry} shape
|
|
9
|
+
* (`{ target?, executor?, projects?, plugin?, ...config }`). The `projects` /
|
|
10
|
+
* `plugin` filter is *context* describing what the caller is configuring, used
|
|
11
|
+
* to pick which existing entry to merge into — it is never authored as a new
|
|
12
|
+
* filtered entry. For the key (`target` ?? `executor`):
|
|
13
|
+
*
|
|
14
|
+
* - No value yet → create the generic (plain object) value.
|
|
15
|
+
* - Only a generic value → merge into it.
|
|
16
|
+
* - A filtered entry matching the context filter exists → merge into that one
|
|
17
|
+
* (so a caller updating a project the user already scoped a default for edits
|
|
18
|
+
* that scoped entry rather than clobbering the workspace baseline).
|
|
19
|
+
* - Otherwise → merge into the generic, creating one if needed.
|
|
20
|
+
*
|
|
21
|
+
* A lone unfiltered entry is always stored as a plain object, never a
|
|
22
|
+
* single-element array. The entry must set at least one of `target` /
|
|
23
|
+
* `executor`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function upsertTargetDefault(tree: Tree, nxJson: NxJsonConfiguration, options: TargetDefaultEntry): NxJsonConfiguration;
|
|
26
|
+
/**
|
|
27
|
+
* Find a `targetDefaults` entry by its logical locator tuple
|
|
28
|
+
* `(target, executor, projects, plugin)`. Locator keys default to
|
|
29
|
+
* `undefined`, matching only entries that also leave them unset — same
|
|
30
|
+
* semantics as `upsertTargetDefault`.
|
|
31
|
+
*
|
|
32
|
+
* Throws when called with an empty locator (no `target`, `executor`,
|
|
33
|
+
* `projects`, or `plugin`). An empty locator is almost always a bug — the
|
|
34
|
+
* caller intended to find a specific entry but forgot to populate the lookup.
|
|
35
|
+
*/
|
|
36
|
+
export declare function findTargetDefault(targetDefaults: TargetDefaults | undefined, locator: Pick<TargetDefaultEntry, 'target' | 'executor' | 'projects' | 'plugin'>): TargetDefaultEntry | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* The subset of a project graph node that the `projects` narrowing reads —
|
|
39
|
+
* names come from the map keys, `root`/`tags` drive `findMatchingProjects`.
|
|
40
|
+
* Mirrors `MatcherProjectNode` without importing it, so the signature stays
|
|
41
|
+
* stable across the supported nx version range.
|
|
42
|
+
*/
|
|
43
|
+
type ContextProjectNode = {
|
|
44
|
+
data: {
|
|
45
|
+
root: string;
|
|
46
|
+
tags?: string[];
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* What the caller is updating, used to pick which `targetDefaults` entries the
|
|
51
|
+
* callback runs against. At least one of `executor` / `projects` is required.
|
|
52
|
+
*/
|
|
53
|
+
export interface UpdateTargetDefaultContext {
|
|
54
|
+
/**
|
|
55
|
+
* Visit only entries that resolve to this executor — matched against the map
|
|
56
|
+
* key (executor-keyed form), an entry's `executor` field, or its
|
|
57
|
+
* `filter.executor`. When omitted, entries are not filtered by executor.
|
|
58
|
+
*/
|
|
59
|
+
executor?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Project nodes the update is scoped to, keyed by project name. When set, a
|
|
62
|
+
* project-filtered entry is visited only if its `filter.projects` covers
|
|
63
|
+
* *every* one of these projects; unfiltered entries always match. When
|
|
64
|
+
* omitted, project filters are not a constraint and every (executor-matching)
|
|
65
|
+
* entry is visited — the workspace-wide case.
|
|
66
|
+
*/
|
|
67
|
+
projects?: Record<string, ContextProjectNode>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Describes the entry a callback invocation is operating on, so the callback
|
|
71
|
+
* can tell the executor-keyed form from the target-keyed form and read the
|
|
72
|
+
* entry's filter.
|
|
73
|
+
*/
|
|
74
|
+
export interface UpdateTargetDefaultEntryInfo {
|
|
75
|
+
/** The `targetDefaults` map key the entry lives under. */
|
|
76
|
+
key: string;
|
|
77
|
+
/** Logical target name — `undefined` for executor-keyed entries. */
|
|
78
|
+
target?: string;
|
|
79
|
+
/** Executor the entry resolves to (from the key, `executor` field, or filter). */
|
|
80
|
+
executor?: string;
|
|
81
|
+
/** The entry's filter, present only for filtered array entries. */
|
|
82
|
+
filter?: TargetDefaultFilter;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Called once per matching entry. Receives the entry's flat config (everything
|
|
86
|
+
* but `filter`) and may mutate it in place. Return a new config to replace the
|
|
87
|
+
* entry's payload, return `null` to drop the entry, or return nothing to keep
|
|
88
|
+
* the (possibly mutated) config.
|
|
89
|
+
*/
|
|
90
|
+
export type UpdateTargetDefaultCallback = (config: Partial<TargetConfiguration>, info: UpdateTargetDefaultEntryInfo) => Partial<TargetConfiguration> | null | void;
|
|
91
|
+
/**
|
|
92
|
+
* Walk the `targetDefaults` entries matching `context` and run `callback`
|
|
93
|
+
* against each, mutating `nxJson` in place and returning it. This is the
|
|
94
|
+
* read-modify-write counterpart to {@link upsertTargetDefault}, meant for
|
|
95
|
+
* generators and migrations that need to edit *existing* defaults across both
|
|
96
|
+
* value forms (plain object and filtered array) without re-implementing the
|
|
97
|
+
* normalize → edit → collapse dance by hand.
|
|
98
|
+
*
|
|
99
|
+
* Matching, per the `context`:
|
|
100
|
+
* - `executor` selects entries that reference it as the map key, an `executor`
|
|
101
|
+
* config field, or `filter.executor`.
|
|
102
|
+
* - `projects` narrows to entries whose `filter.projects` covers the scoped
|
|
103
|
+
* projects (unfiltered entries always match). With no `projects` context,
|
|
104
|
+
* project filters are ignored and every executor-matching entry is visited.
|
|
105
|
+
*
|
|
106
|
+
* Removal and collapsing follow the storage-form rules:
|
|
107
|
+
* - Array entry whose callback returns `null` → dropped from the array.
|
|
108
|
+
* - An array that collapses to a single unfiltered entry → stored as the plain
|
|
109
|
+
* object form; an emptied array → the whole key is deleted.
|
|
110
|
+
* - Object-form value whose callback returns `null` → the whole key is deleted.
|
|
111
|
+
* - An emptied `targetDefaults` map → removed from `nxJson` entirely.
|
|
112
|
+
*
|
|
113
|
+
* Throws when neither `executor` nor `projects` is provided — an empty context
|
|
114
|
+
* would match everything and is almost always a bug.
|
|
115
|
+
*/
|
|
116
|
+
export declare function updateTargetDefault(nxJson: NxJsonConfiguration, context: UpdateTargetDefaultContext, callback: UpdateTargetDefaultCallback): NxJsonConfiguration;
|
|
117
|
+
export declare function readTargetDefaultsForTarget(targetName: string, targetDefaults: TargetDefaults | undefined, executor?: string, opts?: Parameters<typeof readTargetDefaultsForTargetFromNx>[3]): Partial<TargetConfiguration> | null;
|
|
2
118
|
export declare function addBuildTargetDefaults(tree: Tree, executorName: string, buildTargetName?: string, extraInputs?: TargetConfiguration['inputs']): void;
|
|
3
119
|
export declare function addE2eCiTargetDefaults(tree: Tree, e2ePlugin: string, buildTarget: string, pathToE2EConfigFile: string): Promise<void>;
|
|
120
|
+
export {};
|
|
@@ -1,14 +1,362 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.upsertTargetDefault = upsertTargetDefault;
|
|
4
|
+
exports.findTargetDefault = findTargetDefault;
|
|
5
|
+
exports.updateTargetDefault = updateTargetDefault;
|
|
6
|
+
exports.readTargetDefaultsForTarget = readTargetDefaultsForTarget;
|
|
3
7
|
exports.addBuildTargetDefaults = addBuildTargetDefaults;
|
|
4
8
|
exports.addE2eCiTargetDefaults = addE2eCiTargetDefaults;
|
|
5
9
|
const devkit_exports_1 = require("nx/src/devkit-exports");
|
|
6
10
|
const devkit_internals_1 = require("nx/src/devkit-internals");
|
|
7
11
|
const minimatch_1 = require("minimatch");
|
|
12
|
+
/**
|
|
13
|
+
* Upsert a `targetDefaults` entry on the provided `nxJson`. Mutates
|
|
14
|
+
* `nxJson` in place and returns it so the caller can chain or batch
|
|
15
|
+
* other edits before persisting via `updateNxJson` exactly once.
|
|
16
|
+
*
|
|
17
|
+
* The input is the logical {@link TargetDefaultEntry} shape
|
|
18
|
+
* (`{ target?, executor?, projects?, plugin?, ...config }`). The `projects` /
|
|
19
|
+
* `plugin` filter is *context* describing what the caller is configuring, used
|
|
20
|
+
* to pick which existing entry to merge into — it is never authored as a new
|
|
21
|
+
* filtered entry. For the key (`target` ?? `executor`):
|
|
22
|
+
*
|
|
23
|
+
* - No value yet → create the generic (plain object) value.
|
|
24
|
+
* - Only a generic value → merge into it.
|
|
25
|
+
* - A filtered entry matching the context filter exists → merge into that one
|
|
26
|
+
* (so a caller updating a project the user already scoped a default for edits
|
|
27
|
+
* that scoped entry rather than clobbering the workspace baseline).
|
|
28
|
+
* - Otherwise → merge into the generic, creating one if needed.
|
|
29
|
+
*
|
|
30
|
+
* A lone unfiltered entry is always stored as a plain object, never a
|
|
31
|
+
* single-element array. The entry must set at least one of `target` /
|
|
32
|
+
* `executor`.
|
|
33
|
+
*/
|
|
34
|
+
function upsertTargetDefault(tree, nxJson, options) {
|
|
35
|
+
const { target, executor, projects, plugin, ...config } = options;
|
|
36
|
+
const key = target ?? executor;
|
|
37
|
+
if (key === undefined) {
|
|
38
|
+
throw new Error('upsertTargetDefault requires at least one of `target` or `executor` to be set.');
|
|
39
|
+
}
|
|
40
|
+
// `executor` is the map key itself when no `target` is given; when a `target`
|
|
41
|
+
// is present it is a configuration field (a default executor) written onto
|
|
42
|
+
// the value.
|
|
43
|
+
const valueConfig = target !== undefined && executor !== undefined
|
|
44
|
+
? { executor, ...config }
|
|
45
|
+
: config;
|
|
46
|
+
const targetDefaults = (nxJson.targetDefaults ??= {});
|
|
47
|
+
targetDefaults[key] = collapse(upsertValue(targetDefaults[key], valueConfig, {
|
|
48
|
+
tree,
|
|
49
|
+
projects,
|
|
50
|
+
plugin,
|
|
51
|
+
executor,
|
|
52
|
+
}));
|
|
53
|
+
return nxJson;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Merge `config` into the right entry of a key's value, per the algorithm
|
|
57
|
+
* documented on {@link upsertTargetDefault}. Returns the new value (always an
|
|
58
|
+
* array here; {@link collapse} downgrades a lone unfiltered one to an object).
|
|
59
|
+
*/
|
|
60
|
+
function upsertValue(existing, config, context) {
|
|
61
|
+
// No value yet → create the generic.
|
|
62
|
+
if (existing === undefined) {
|
|
63
|
+
return { ...config };
|
|
64
|
+
}
|
|
65
|
+
const entries = Array.isArray(existing)
|
|
66
|
+
? [...existing]
|
|
67
|
+
: [existing];
|
|
68
|
+
// A filtered entry that covers what's being configured → merge into it,
|
|
69
|
+
// preserving its filter.
|
|
70
|
+
const matchIdx = entries.findIndex((e) => e.filter !== undefined && filterCoversContext(e.filter, context));
|
|
71
|
+
if (matchIdx >= 0) {
|
|
72
|
+
entries[matchIdx] = { ...entries[matchIdx], ...config };
|
|
73
|
+
return entries;
|
|
74
|
+
}
|
|
75
|
+
// Otherwise merge into the generic (catch-all) entry, creating one if absent.
|
|
76
|
+
const genericIdx = entries.findIndex((e) => e.filter === undefined);
|
|
77
|
+
if (genericIdx >= 0) {
|
|
78
|
+
const { filter: _filter, ...rest } = entries[genericIdx];
|
|
79
|
+
entries[genericIdx] = { ...rest, ...config };
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
entries.push({ ...config });
|
|
83
|
+
}
|
|
84
|
+
return entries;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Whether an entry's `filter` applies to what the caller is configuring:
|
|
88
|
+
* `plugin` / `executor` must match exactly, and `projects` is evaluated as
|
|
89
|
+
* *coverage* — every configured project must match the filter's patterns
|
|
90
|
+
* (names, globs, `tag:`, directories, negation) via `findMatchingProjects`,
|
|
91
|
+
* resolved against each project's tags/root in the tree. A `projects` filter
|
|
92
|
+
* can't be confirmed when no project context is supplied (or the project
|
|
93
|
+
* isn't in the tree), so it falls through to the generic.
|
|
94
|
+
*/
|
|
95
|
+
function filterCoversContext(filter, context) {
|
|
96
|
+
if (filter.plugin !== undefined && filter.plugin !== context.plugin) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
if (filter.executor !== undefined && filter.executor !== context.executor) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
if (filter.projects !== undefined) {
|
|
103
|
+
const configured = context.projects ?? [];
|
|
104
|
+
const nodes = contextProjectNodes(context.tree, configured);
|
|
105
|
+
if (!projectsFilterCovers(filter.projects, nodes, configured)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Whether a `filter.projects` pattern set covers *every* required project name:
|
|
113
|
+
* each must be returned by `findMatchingProjects` against `nodes`. An empty
|
|
114
|
+
* `requiredNames` can never be "covered", so the entry falls through to the
|
|
115
|
+
* generic baseline. Shared by the upsert and update paths so the coverage
|
|
116
|
+
* semantics live in one place.
|
|
117
|
+
*/
|
|
118
|
+
function projectsFilterCovers(patterns, nodes, requiredNames) {
|
|
119
|
+
if (requiredNames.length === 0) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
const matched = (0, devkit_internals_1.findMatchingProjects)([...patterns], nodes);
|
|
123
|
+
return requiredNames.every((name) => matched.includes(name));
|
|
124
|
+
}
|
|
125
|
+
function contextProjectNodes(tree, projectNames) {
|
|
126
|
+
const projects = (0, devkit_exports_1.getProjects)(tree);
|
|
127
|
+
const nodes = {};
|
|
128
|
+
for (const name of projectNames) {
|
|
129
|
+
const config = projects.get(name);
|
|
130
|
+
if (config) {
|
|
131
|
+
nodes[name] = { data: { root: config.root, tags: config.tags } };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return nodes;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Collapse a key's value back to the plain object form when it has degenerated
|
|
138
|
+
* to a single entry with no filter — at that point the array wrapper carries no
|
|
139
|
+
* information the object form doesn't, and the object form is the tidier,
|
|
140
|
+
* record-shape-compatible representation.
|
|
141
|
+
*/
|
|
142
|
+
function collapse(value) {
|
|
143
|
+
if (Array.isArray(value) &&
|
|
144
|
+
value.length === 1 &&
|
|
145
|
+
value[0].filter === undefined) {
|
|
146
|
+
// Drop the (already-undefined) `filter` key so the result matches the
|
|
147
|
+
// object value form, which forbids `filter`.
|
|
148
|
+
const { filter: _filter, ...config } = value[0];
|
|
149
|
+
return config;
|
|
150
|
+
}
|
|
151
|
+
return value;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Find a `targetDefaults` entry by its logical locator tuple
|
|
155
|
+
* `(target, executor, projects, plugin)`. Locator keys default to
|
|
156
|
+
* `undefined`, matching only entries that also leave them unset — same
|
|
157
|
+
* semantics as `upsertTargetDefault`.
|
|
158
|
+
*
|
|
159
|
+
* Throws when called with an empty locator (no `target`, `executor`,
|
|
160
|
+
* `projects`, or `plugin`). An empty locator is almost always a bug — the
|
|
161
|
+
* caller intended to find a specific entry but forgot to populate the lookup.
|
|
162
|
+
*/
|
|
163
|
+
function findTargetDefault(targetDefaults, locator) {
|
|
164
|
+
if (locator.target === undefined &&
|
|
165
|
+
locator.executor === undefined &&
|
|
166
|
+
locator.projects === undefined &&
|
|
167
|
+
locator.plugin === undefined) {
|
|
168
|
+
throw new Error('findTargetDefault requires at least one of `target`, `executor`, `projects`, or `plugin` on the locator.');
|
|
169
|
+
}
|
|
170
|
+
for (const entry of logicalTargetDefaultEntries(targetDefaults)) {
|
|
171
|
+
if (entry.target === locator.target &&
|
|
172
|
+
entry.executor === locator.executor &&
|
|
173
|
+
projectsEqual(entry.projects, locator.projects) &&
|
|
174
|
+
entry.plugin === locator.plugin) {
|
|
175
|
+
return entry;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Expand the nested `targetDefaults` map into its logical {@link
|
|
182
|
+
* TargetDefaultEntry} view, one entry at a time. The key becomes `target` (or
|
|
183
|
+
* `executor` for executor-shaped keys) and any `filter` is un-nested into the
|
|
184
|
+
* flat `projects`/`plugin`/`executor` siblings. Lazy so callers that find a
|
|
185
|
+
* match early stop iterating. Internal to this module — the flat shape is a
|
|
186
|
+
* lookup convenience, never a `targetDefaults` value form.
|
|
187
|
+
*/
|
|
188
|
+
function* logicalTargetDefaultEntries(targetDefaults) {
|
|
189
|
+
for (const key of Object.keys(targetDefaults ?? {})) {
|
|
190
|
+
const locator = isExecutorLikeKey(key)
|
|
191
|
+
? { executor: key }
|
|
192
|
+
: { target: key };
|
|
193
|
+
const value = targetDefaults[key];
|
|
194
|
+
const entries = Array.isArray(value)
|
|
195
|
+
? value
|
|
196
|
+
: [value ?? {}];
|
|
197
|
+
for (const entry of entries) {
|
|
198
|
+
const { filter, ...config } = entry;
|
|
199
|
+
yield {
|
|
200
|
+
...locator,
|
|
201
|
+
...(filter?.projects !== undefined
|
|
202
|
+
? { projects: filter.projects }
|
|
203
|
+
: {}),
|
|
204
|
+
...(filter?.plugin !== undefined ? { plugin: filter.plugin } : {}),
|
|
205
|
+
...(filter?.executor !== undefined
|
|
206
|
+
? { executor: filter.executor }
|
|
207
|
+
: {}),
|
|
208
|
+
...config,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Mirrors `isGlobPattern` from `nx/src/utils/globs.ts`, which isn't on the
|
|
214
|
+
// devkit-exports surface guaranteed across the supported nx version range.
|
|
215
|
+
//
|
|
216
|
+
// Known limitation: a `:` is also legal in a target name, so a target literally
|
|
217
|
+
// named e.g. `e2e:ci` is classified as an executor key here. This matches how
|
|
218
|
+
// the rest of the target-defaults stack disambiguates keys (executor-shaped
|
|
219
|
+
// keys win), and such target names are vanishingly rare — accepted rather than
|
|
220
|
+
// worked around.
|
|
221
|
+
const GLOB_CHARACTERS = new Set(['*', '|', '{', '}', '(', ')', '[']);
|
|
222
|
+
function isExecutorLikeKey(key) {
|
|
223
|
+
if (!key.includes(':'))
|
|
224
|
+
return false;
|
|
225
|
+
for (const c of key)
|
|
226
|
+
if (GLOB_CHARACTERS.has(c))
|
|
227
|
+
return false;
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Walk the `targetDefaults` entries matching `context` and run `callback`
|
|
232
|
+
* against each, mutating `nxJson` in place and returning it. This is the
|
|
233
|
+
* read-modify-write counterpart to {@link upsertTargetDefault}, meant for
|
|
234
|
+
* generators and migrations that need to edit *existing* defaults across both
|
|
235
|
+
* value forms (plain object and filtered array) without re-implementing the
|
|
236
|
+
* normalize → edit → collapse dance by hand.
|
|
237
|
+
*
|
|
238
|
+
* Matching, per the `context`:
|
|
239
|
+
* - `executor` selects entries that reference it as the map key, an `executor`
|
|
240
|
+
* config field, or `filter.executor`.
|
|
241
|
+
* - `projects` narrows to entries whose `filter.projects` covers the scoped
|
|
242
|
+
* projects (unfiltered entries always match). With no `projects` context,
|
|
243
|
+
* project filters are ignored and every executor-matching entry is visited.
|
|
244
|
+
*
|
|
245
|
+
* Removal and collapsing follow the storage-form rules:
|
|
246
|
+
* - Array entry whose callback returns `null` → dropped from the array.
|
|
247
|
+
* - An array that collapses to a single unfiltered entry → stored as the plain
|
|
248
|
+
* object form; an emptied array → the whole key is deleted.
|
|
249
|
+
* - Object-form value whose callback returns `null` → the whole key is deleted.
|
|
250
|
+
* - An emptied `targetDefaults` map → removed from `nxJson` entirely.
|
|
251
|
+
*
|
|
252
|
+
* Throws when neither `executor` nor `projects` is provided — an empty context
|
|
253
|
+
* would match everything and is almost always a bug.
|
|
254
|
+
*/
|
|
255
|
+
function updateTargetDefault(nxJson, context, callback) {
|
|
256
|
+
const { executor, projects } = context;
|
|
257
|
+
if (executor === undefined && projects === undefined) {
|
|
258
|
+
throw new Error('updateTargetDefault requires at least one of `executor` or `projects` on the context to locate entries to update.');
|
|
259
|
+
}
|
|
260
|
+
const targetDefaults = nxJson.targetDefaults;
|
|
261
|
+
if (!targetDefaults) {
|
|
262
|
+
return nxJson;
|
|
263
|
+
}
|
|
264
|
+
const projectNames = projects ? Object.keys(projects) : [];
|
|
265
|
+
for (const key of Object.keys(targetDefaults)) {
|
|
266
|
+
const value = targetDefaults[key];
|
|
267
|
+
const entries = Array.isArray(value)
|
|
268
|
+
? value
|
|
269
|
+
: [value];
|
|
270
|
+
const kept = [];
|
|
271
|
+
for (const entry of entries) {
|
|
272
|
+
if (!entryMatchesContext(key, entry, executor, projects, projectNames)) {
|
|
273
|
+
kept.push(entry);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const { filter, ...config } = entry;
|
|
277
|
+
const result = callback(config, {
|
|
278
|
+
key,
|
|
279
|
+
target: isExecutorLikeKey(key) ? undefined : key,
|
|
280
|
+
executor: isExecutorLikeKey(key)
|
|
281
|
+
? key
|
|
282
|
+
: (config.executor ?? filter?.executor),
|
|
283
|
+
filter,
|
|
284
|
+
});
|
|
285
|
+
// `null` drops the entry; anything else keeps the (mutated or replaced)
|
|
286
|
+
// config, re-attaching the filter so a filtered entry stays filtered.
|
|
287
|
+
if (result === null) {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const nextConfig = result ?? config;
|
|
291
|
+
kept.push(filter !== undefined ? { filter, ...nextConfig } : nextConfig);
|
|
292
|
+
}
|
|
293
|
+
if (kept.length === 0) {
|
|
294
|
+
delete targetDefaults[key];
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
targetDefaults[key] = collapse(kept);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (Object.keys(targetDefaults).length === 0) {
|
|
301
|
+
delete nxJson.targetDefaults;
|
|
302
|
+
}
|
|
303
|
+
return nxJson;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Whether `callback` should run against this entry: it must reference the
|
|
307
|
+
* context's `executor` (when given), and — when the context is scoped to
|
|
308
|
+
* `projects` — any `filter.projects` it carries must cover every scoped
|
|
309
|
+
* project. Unfiltered entries always pass the project check.
|
|
310
|
+
*/
|
|
311
|
+
function entryMatchesContext(key, entry, executor, projects, projectNames) {
|
|
312
|
+
if (executor !== undefined) {
|
|
313
|
+
const referencesExecutor = key === executor ||
|
|
314
|
+
entry.executor === executor ||
|
|
315
|
+
entry.filter?.executor === executor;
|
|
316
|
+
if (!referencesExecutor) {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (projects !== undefined && entry.filter?.projects !== undefined) {
|
|
321
|
+
const patterns = Array.isArray(entry.filter.projects)
|
|
322
|
+
? entry.filter.projects
|
|
323
|
+
: [entry.filter.projects];
|
|
324
|
+
if (!projectsFilterCovers(patterns, projects, projectNames)) {
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
function readTargetDefaultsForTarget(targetName, targetDefaults, executor, opts) {
|
|
331
|
+
// `targetDefaults` is the nested map; the nx reader resolves either the
|
|
332
|
+
// object or array value form for `targetName` natively.
|
|
333
|
+
return (0, devkit_internals_1.readTargetDefaultsForTarget)(targetName, targetDefaults, executor, opts);
|
|
334
|
+
}
|
|
335
|
+
// Order-insensitive equality so re-upserts with reordered patterns merge into
|
|
336
|
+
// the same entry rather than appending a duplicate. Comparing sorted copies
|
|
337
|
+
// keeps duplicates significant (`['a','a']` ≠ `['a']`) without special-casing.
|
|
338
|
+
function projectsEqual(a, b) {
|
|
339
|
+
if (a === b)
|
|
340
|
+
return true;
|
|
341
|
+
if (!a || !b)
|
|
342
|
+
return false;
|
|
343
|
+
if (a.length !== b.length)
|
|
344
|
+
return false;
|
|
345
|
+
const sortedA = [...a].sort();
|
|
346
|
+
const sortedB = [...b].sort();
|
|
347
|
+
return sortedA.every((value, i) => value === sortedB[i]);
|
|
348
|
+
}
|
|
8
349
|
function addBuildTargetDefaults(tree, executorName, buildTargetName = 'build', extraInputs = []) {
|
|
9
|
-
const nxJson = (0, devkit_exports_1.readNxJson)(tree);
|
|
10
|
-
|
|
11
|
-
|
|
350
|
+
const nxJson = (0, devkit_exports_1.readNxJson)(tree) ?? {};
|
|
351
|
+
// Only skip when an *unfiltered* entry already covers this executor.
|
|
352
|
+
// A filtered entry (`projects:` or `plugin:`) only applies to a subset
|
|
353
|
+
// of targets, so it doesn't satisfy the workspace-wide default this
|
|
354
|
+
// helper writes — we still need to add the unfiltered baseline.
|
|
355
|
+
if (findTargetDefault(nxJson.targetDefaults, { executor: executorName })) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
upsertTargetDefault(tree, nxJson, {
|
|
359
|
+
executor: executorName,
|
|
12
360
|
cache: true,
|
|
13
361
|
dependsOn: [`^${buildTargetName}`],
|
|
14
362
|
inputs: [
|
|
@@ -17,12 +365,12 @@ function addBuildTargetDefaults(tree, executorName, buildTargetName = 'build', e
|
|
|
17
365
|
: ['default', '^default']),
|
|
18
366
|
...extraInputs,
|
|
19
367
|
],
|
|
20
|
-
};
|
|
368
|
+
});
|
|
21
369
|
(0, devkit_exports_1.updateNxJson)(tree, nxJson);
|
|
22
370
|
}
|
|
23
371
|
async function addE2eCiTargetDefaults(tree, e2ePlugin, buildTarget, pathToE2EConfigFile) {
|
|
24
372
|
const nxJson = (0, devkit_exports_1.readNxJson)(tree);
|
|
25
|
-
if (!nxJson
|
|
373
|
+
if (!nxJson?.plugins) {
|
|
26
374
|
return;
|
|
27
375
|
}
|
|
28
376
|
const e2ePluginRegistrations = nxJson.plugins.filter((p) => typeof p === 'string' ? p === e2ePlugin : p.plugin === e2ePlugin);
|
|
@@ -58,18 +406,13 @@ async function addE2eCiTargetDefaults(tree, e2ePlugin, buildTarget, pathToE2ECon
|
|
|
58
406
|
? 'e2e-ci'
|
|
59
407
|
: (foundPluginForApplication.options?.ciTargetName ?? 'e2e-ci');
|
|
60
408
|
const ciTargetNameGlob = `${ciTargetName}--**/**`;
|
|
61
|
-
nxJson.targetDefaults
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
e2eCiTargetDefaults.dependsOn ??= [];
|
|
70
|
-
if (!e2eCiTargetDefaults.dependsOn.includes(buildTarget)) {
|
|
71
|
-
e2eCiTargetDefaults.dependsOn.push(buildTarget);
|
|
72
|
-
}
|
|
409
|
+
const existing = findTargetDefault(nxJson.targetDefaults, {
|
|
410
|
+
target: ciTargetNameGlob,
|
|
411
|
+
});
|
|
412
|
+
const dependsOn = [...(existing?.dependsOn ?? [])];
|
|
413
|
+
if (!dependsOn.includes(buildTarget)) {
|
|
414
|
+
dependsOn.push(buildTarget);
|
|
73
415
|
}
|
|
416
|
+
upsertTargetDefault(tree, nxJson, { target: ciTargetNameGlob, dependsOn });
|
|
74
417
|
(0, devkit_exports_1.updateNxJson)(tree, nxJson);
|
|
75
418
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/devkit",
|
|
3
|
-
"version": "23.1.0-beta.
|
|
3
|
+
"version": "23.1.0-beta.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"files": [
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"jest": "30.3.0",
|
|
63
|
-
"nx": "23.1.0-beta.
|
|
63
|
+
"nx": "23.1.0-beta.5"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"nx": ">= 22 <= 24 || ^23.0.0-0"
|