@nx/angular 0.0.0-pr-27940-4ec79a3 → 0.0.0-pr-27804-bc6b179

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/angular",
3
- "version": "0.0.0-pr-27940-4ec79a3",
3
+ "version": "0.0.0-pr-27804-bc6b179",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Angular contains executors, generators, and utilities for managing Angular applications and libraries within an Nx workspace. It provides: \n\n- Integration with libraries such as Storybook, Jest, ESLint, Tailwind CSS, Playwright and Cypress. \n\n- Generators to help scaffold code quickly (like: Micro Frontends, Libraries, both internal to your codebase and publishable to npm) \n\n- Single Component Application Modules (SCAMs) \n\n- NgRx helpers. \n\n- Utilities for automatic workspace refactoring.",
6
6
  "repository": {
@@ -22,6 +22,7 @@
22
22
  "./executors.json": "./executors.json",
23
23
  "./generators": "./generators.js",
24
24
  "./executors": "./executors.js",
25
+ "./plugin": "./plugin.js",
25
26
  "./tailwind": "./tailwind.js",
26
27
  "./module-federation": "./module-federation/index.js",
27
28
  "./src/utils": "./src/utils/index.js",
@@ -79,14 +80,14 @@
79
80
  "webpack-merge": "^5.8.0",
80
81
  "webpack": "^5.88.0",
81
82
  "@module-federation/enhanced": "~0.6.0",
82
- "@nx/devkit": "0.0.0-pr-27940-4ec79a3",
83
- "@nx/js": "0.0.0-pr-27940-4ec79a3",
84
- "@nx/eslint": "0.0.0-pr-27940-4ec79a3",
85
- "@nx/webpack": "0.0.0-pr-27940-4ec79a3",
86
- "@nx/web": "0.0.0-pr-27940-4ec79a3",
87
- "@nx/workspace": "0.0.0-pr-27940-4ec79a3",
83
+ "@nx/devkit": "0.0.0-pr-27804-bc6b179",
84
+ "@nx/js": "0.0.0-pr-27804-bc6b179",
85
+ "@nx/eslint": "0.0.0-pr-27804-bc6b179",
86
+ "@nx/webpack": "0.0.0-pr-27804-bc6b179",
87
+ "@nx/web": "0.0.0-pr-27804-bc6b179",
88
+ "@nx/workspace": "0.0.0-pr-27804-bc6b179",
88
89
  "piscina": "^4.4.0",
89
- "@nrwl/angular": "0.0.0-pr-27940-4ec79a3"
90
+ "@nrwl/angular": "0.0.0-pr-27804-bc6b179"
90
91
  },
91
92
  "peerDependencies": {
92
93
  "@angular-devkit/build-angular": ">= 16.0.0 < 19.0.0",
package/plugin.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createNodesV2 } from './src/plugins/plugin';
package/plugin.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = void 0;
4
+ var plugin_1 = require("./src/plugins/plugin");
5
+ Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return plugin_1.createNodesV2; } });
@@ -2,10 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.angularInitGenerator = angularInitGenerator;
4
4
  const devkit_1 = require("@nx/devkit");
5
+ const add_plugin_1 = require("@nx/devkit/src/utils/add-plugin");
5
6
  const version_utils_1 = require("../utils/version-utils");
7
+ const plugin_1 = require("../../plugins/plugin");
6
8
  async function angularInitGenerator(tree, options) {
7
9
  ignoreAngularCacheDirectory(tree);
8
10
  const installTask = installAngularDevkitCoreIfMissing(tree, options);
11
+ // For Angular inference plugin, we only want it during import since our
12
+ // generators do not use `angular.json`, and `nx init` should split
13
+ // `angular.json` into multiple `project.json` files -- as this is preferred
14
+ // by most folks we've talked to.
15
+ options.addPlugin ??= process.env.NX_RUNNING_NX_IMPORT === 'true';
16
+ if (options.addPlugin) {
17
+ await (0, add_plugin_1.addPlugin)(tree, await (0, devkit_1.createProjectGraphAsync)(), '@nx/angular/plugin', plugin_1.createNodesV2, {
18
+ targetNamePrefix: ['', 'angular:', 'angular-'],
19
+ }, options.updatePackageScripts);
20
+ }
9
21
  if (!options.skipFormat) {
10
22
  await (0, devkit_1.formatFiles)(tree);
11
23
  }
@@ -3,4 +3,7 @@ export interface Schema {
3
3
  skipInstall?: boolean;
4
4
  skipPackageJson?: boolean;
5
5
  keepExistingVersions?: boolean;
6
+ /* internal */
7
+ addPlugin?: boolean;
8
+ updatePackageScripts?: boolean;
6
9
  }
@@ -0,0 +1,19 @@
1
+ import { type CreateNodesV2 } from '@nx/devkit';
2
+ export interface AngularPluginOptions {
3
+ targetNamePrefix?: string;
4
+ }
5
+ type AngularTargetConfiguration = {
6
+ builder: string;
7
+ options?: Record<string, any>;
8
+ configurations?: Record<string, any>;
9
+ defaultConfiguration?: string;
10
+ };
11
+ export type AngularProjectConfiguration = {
12
+ projectType: 'application' | 'library';
13
+ root: string;
14
+ sourceRoot?: string;
15
+ architect?: Record<string, AngularTargetConfiguration>;
16
+ targets?: Record<string, AngularTargetConfiguration>;
17
+ };
18
+ export declare const createNodesV2: CreateNodesV2<AngularPluginOptions>;
19
+ export {};
@@ -0,0 +1,416 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
7
+ const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
8
+ const js_1 = require("@nx/js");
9
+ const node_fs_1 = require("node:fs");
10
+ const node_path_1 = require("node:path");
11
+ const posix = tslib_1.__importStar(require("node:path/posix"));
12
+ const devkit_internals_1 = require("nx/src/devkit-internals");
13
+ const cache_directory_1 = require("nx/src/utils/cache-directory");
14
+ const knownExecutors = {
15
+ appShell: new Set(['@angular-devkit/build-angular:app-shell']),
16
+ build: new Set([
17
+ '@angular-devkit/build-angular:application',
18
+ '@angular/build:application',
19
+ '@angular-devkit/build-angular:browser-esbuild',
20
+ '@angular-devkit/build-angular:browser',
21
+ '@angular-devkit/build-angular:ng-packagr',
22
+ ]),
23
+ devServer: new Set(['@angular-devkit/build-angular:dev-server']),
24
+ extractI18n: new Set(['@angular-devkit/build-angular:extract-i18n']),
25
+ prerender: new Set([
26
+ '@angular-devkit/build-angular:prerender',
27
+ '@nguniversal/builders:prerender',
28
+ ]),
29
+ server: new Set(['@angular-devkit/build-angular:server']),
30
+ serveSsr: new Set([
31
+ '@angular-devkit/build-angular:ssr-dev-server',
32
+ '@nguniversal/builders:ssr-dev-server',
33
+ ]),
34
+ test: new Set(['@angular-devkit/build-angular:karma']),
35
+ };
36
+ const pmc = (0, devkit_1.getPackageManagerCommand)();
37
+ function readProjectsCache(cachePath) {
38
+ return (0, node_fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
39
+ }
40
+ function writeProjectsToCache(cachePath, results) {
41
+ (0, devkit_1.writeJsonFile)(cachePath, results);
42
+ }
43
+ exports.createNodesV2 = [
44
+ '**/angular.json',
45
+ async (configFiles, options, context) => {
46
+ const optionsHash = (0, devkit_internals_1.hashObject)(options);
47
+ const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `angular-${optionsHash}.hash`);
48
+ const projectsCache = readProjectsCache(cachePath);
49
+ try {
50
+ return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, projectsCache), configFiles, options, context);
51
+ }
52
+ finally {
53
+ writeProjectsToCache(cachePath, projectsCache);
54
+ }
55
+ },
56
+ ];
57
+ async function createNodesInternal(configFilePath, options, context, projectsCache) {
58
+ const angularWorkspaceRoot = (0, node_path_1.dirname)(configFilePath);
59
+ // Do not create a project if package.json isn't there
60
+ const siblingFiles = (0, node_fs_1.readdirSync)((0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot));
61
+ if (!siblingFiles.includes('package.json')) {
62
+ return {};
63
+ }
64
+ const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(angularWorkspaceRoot, options, context, [(0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot))]);
65
+ projectsCache[hash] ??= await buildAngularProjects(configFilePath, options, angularWorkspaceRoot, context);
66
+ return { projects: projectsCache[hash] };
67
+ }
68
+ async function buildAngularProjects(configFilePath, options, angularWorkspaceRoot, context) {
69
+ const projects = {};
70
+ const absoluteConfigFilePath = (0, node_path_1.join)(context.workspaceRoot, configFilePath);
71
+ const angularJson = (0, devkit_1.readJsonFile)(absoluteConfigFilePath);
72
+ const appShellTargets = [];
73
+ const prerenderTargets = [];
74
+ for (const [projectName, project] of Object.entries(angularJson.projects ?? {})) {
75
+ const targets = {};
76
+ const projectTargets = getAngularJsonProjectTargets(project);
77
+ if (!projectTargets) {
78
+ continue;
79
+ }
80
+ const namedInputs = (0, get_named_inputs_1.getNamedInputs)(project.root, context);
81
+ for (const [_targetName, angularTarget] of Object.entries(projectTargets)) {
82
+ const targetName = options?.targetNamePrefix
83
+ ? `${options.targetNamePrefix}${_targetName}`
84
+ : _targetName;
85
+ const externalDependencies = ['@angular/cli'];
86
+ targets[targetName] = {
87
+ command:
88
+ // For targets that are also Angular CLI commands, infer the simplified form.
89
+ // Otherwise, use `ng run` to support non-command targets so that they will run.
90
+ targetName === 'build' ||
91
+ targetName === 'deploy' ||
92
+ targetName === 'extract-i18n' ||
93
+ targetName === 'e2e' ||
94
+ targetName === 'lint' ||
95
+ targetName === 'serve' ||
96
+ targetName === 'test'
97
+ ? `ng ${targetName}`
98
+ : `ng run ${projectName}:${targetName}`,
99
+ options: { cwd: angularWorkspaceRoot },
100
+ metadata: {
101
+ technologies: ['angular'],
102
+ description: `Run the "${targetName}" target for "${projectName}".`,
103
+ help: {
104
+ command: `${pmc.exec} ng run ${projectName}:${targetName} --help`,
105
+ example: {},
106
+ },
107
+ },
108
+ };
109
+ if (knownExecutors.appShell.has(angularTarget.builder)) {
110
+ appShellTargets.push({ target: targetName, project: projectName });
111
+ }
112
+ else if (knownExecutors.build.has(angularTarget.builder)) {
113
+ await updateBuildTarget(targetName, targets[targetName], angularTarget, context, angularWorkspaceRoot, project.root, namedInputs);
114
+ }
115
+ else if (knownExecutors.devServer.has(angularTarget.builder)) {
116
+ targets[targetName].metadata.help.example.options = { port: 4201 };
117
+ }
118
+ else if (knownExecutors.extractI18n.has(angularTarget.builder)) {
119
+ targets[targetName].metadata.help.example.options = { format: 'json' };
120
+ }
121
+ else if (knownExecutors.test.has(angularTarget.builder)) {
122
+ updateTestTarget(targets[targetName], angularTarget, context, angularWorkspaceRoot, project.root, namedInputs, externalDependencies);
123
+ }
124
+ else if (knownExecutors.server.has(angularTarget.builder)) {
125
+ updateServerTarget(targets[targetName], angularTarget, context, angularWorkspaceRoot, project.root, namedInputs);
126
+ }
127
+ else if (knownExecutors.serveSsr.has(angularTarget.builder)) {
128
+ targets[targetName].metadata.help.example.options = { port: 4201 };
129
+ }
130
+ else if (knownExecutors.prerender.has(angularTarget.builder)) {
131
+ prerenderTargets.push({ target: targetName, project: projectName });
132
+ }
133
+ if (targets[targetName].inputs?.length) {
134
+ targets[targetName].inputs.push({ externalDependencies });
135
+ }
136
+ if (angularTarget.configurations) {
137
+ for (const configurationName of Object.keys(angularTarget.configurations)) {
138
+ targets[targetName].configurations = {
139
+ ...targets[targetName].configurations,
140
+ [configurationName]: {
141
+ command: `ng run ${projectName}:${targetName}:${configurationName}`,
142
+ },
143
+ };
144
+ }
145
+ }
146
+ if (angularTarget.defaultConfiguration) {
147
+ targets[targetName].defaultConfiguration =
148
+ angularTarget.defaultConfiguration;
149
+ }
150
+ }
151
+ projects[projectName] = {
152
+ projectType: project.projectType,
153
+ root: posix.join(angularWorkspaceRoot, project.root),
154
+ sourceRoot: project.sourceRoot
155
+ ? posix.join(angularWorkspaceRoot, project.sourceRoot)
156
+ : undefined,
157
+ targets,
158
+ };
159
+ }
160
+ for (const { project, target } of appShellTargets) {
161
+ updateAppShellTarget(project, target, projects, angularJson, angularWorkspaceRoot, context);
162
+ }
163
+ for (const { project, target } of prerenderTargets) {
164
+ updatePrerenderTarget(project, target, projects, angularJson);
165
+ }
166
+ return Object.entries(projects).reduce((acc, [projectName, project]) => {
167
+ acc[project.root] = {
168
+ projectType: project.projectType,
169
+ sourceRoot: project.sourceRoot,
170
+ targets: project.targets,
171
+ };
172
+ return acc;
173
+ }, {});
174
+ }
175
+ function updateAppShellTarget(projectName, targetName, projects, angularJson, angularWorkspaceRoot, context) {
176
+ // it must exist since we collected it when processing it
177
+ const target = projects[projectName].targets[targetName];
178
+ target.metadata.help.example.options = { route: '/some/route' };
179
+ const { inputs, outputs } = getBrowserAndServerTargetInputsAndOutputs(projectName, targetName, projects, angularJson);
180
+ const outputIndexPath = getAngularJsonProjectTargets(angularJson.projects[projectName])[targetName].options?.outputIndexPath;
181
+ if (outputIndexPath) {
182
+ const fullOutputIndexPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, outputIndexPath);
183
+ outputs.push(getOutput(fullOutputIndexPath, context.workspaceRoot, angularWorkspaceRoot, angularJson.projects[projectName].root));
184
+ }
185
+ if (!outputs.length) {
186
+ // no outputs were identified for the build or server target, so we don't
187
+ // set any Nx cache options
188
+ return;
189
+ }
190
+ target.cache = true;
191
+ target.inputs = inputs;
192
+ target.outputs = outputs;
193
+ }
194
+ async function updateBuildTarget(targetName, target, angularTarget, context, angularWorkspaceRoot, projectRoot, namedInputs) {
195
+ target.dependsOn = [`^${targetName}`];
196
+ if (angularTarget.options?.outputPath) {
197
+ const fullOutputPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, angularTarget.options.outputPath);
198
+ target.outputs = [
199
+ getOutput(fullOutputPath, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
200
+ ];
201
+ }
202
+ else if (angularTarget.builder === '@angular-devkit/build-angular:ng-packagr') {
203
+ const outputs = await getNgPackagrOutputs(angularTarget, angularWorkspaceRoot, projectRoot, context);
204
+ if (outputs.length) {
205
+ target.outputs = outputs;
206
+ }
207
+ }
208
+ if (target.outputs?.length) {
209
+ // make it cacheable if we were able to identify outputs
210
+ target.cache = true;
211
+ target.inputs =
212
+ 'production' in namedInputs
213
+ ? ['production', '^production']
214
+ : ['default', '^default'];
215
+ }
216
+ if (angularTarget.builder === '@angular-devkit/build-angular:ng-packagr') {
217
+ target.metadata.help.example.options = { watch: true };
218
+ }
219
+ else {
220
+ target.metadata.help.example.options = { localize: true };
221
+ }
222
+ }
223
+ function updateTestTarget(target, angularTarget, context, angularWorkspaceRoot, projectRoot, namedInputs, externalDependencies) {
224
+ target.cache = true;
225
+ target.inputs =
226
+ 'production' in namedInputs
227
+ ? ['default', '^production']
228
+ : ['default', '^default'];
229
+ target.outputs = getKarmaTargetOutputs(angularTarget, angularWorkspaceRoot, projectRoot, context);
230
+ externalDependencies.push('karma');
231
+ target.metadata.help.example.options = { codeCoverage: true };
232
+ }
233
+ function updateServerTarget(target, angularTarget, context, angularWorkspaceRoot, projectRoot, namedInputs) {
234
+ target.metadata.help.example.options = { localize: true };
235
+ if (!angularTarget.options?.outputPath) {
236
+ // only make it cacheable if we were able to identify outputs
237
+ return;
238
+ }
239
+ target.cache = true;
240
+ target.inputs =
241
+ 'production' in namedInputs
242
+ ? ['production', '^production']
243
+ : ['default', '^default'];
244
+ const fullOutputPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, angularTarget.options.outputPath);
245
+ target.outputs = [
246
+ getOutput(fullOutputPath, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
247
+ ];
248
+ }
249
+ function updatePrerenderTarget(projectName, targetName, projects, angularJson) {
250
+ // it must exist since we collected it when processing it
251
+ const target = projects[projectName].targets[targetName];
252
+ target.metadata.help.example.options =
253
+ getAngularJsonProjectTargets(angularJson.projects[projectName])[targetName]
254
+ .builder === '@angular-devkit/build-angular:prerender'
255
+ ? { discoverRoutes: false }
256
+ : { guessRoutes: false };
257
+ const { inputs, outputs } = getBrowserAndServerTargetInputsAndOutputs(projectName, targetName, projects, angularJson);
258
+ if (!outputs.length) {
259
+ // no outputs were identified for the build or server target, so we don't
260
+ // set any Nx cache options
261
+ return;
262
+ }
263
+ target.cache = true;
264
+ target.inputs = inputs;
265
+ target.outputs = outputs;
266
+ }
267
+ async function getNgPackagrOutputs(target, angularWorkspaceRoot, projectRoot, context) {
268
+ let ngPackageJsonPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, target.options.project);
269
+ const readConfig = async (configPath) => {
270
+ if (!(0, node_fs_1.existsSync)(configPath)) {
271
+ return undefined;
272
+ }
273
+ try {
274
+ if (configPath.endsWith('.js')) {
275
+ const result = await import(configPath);
276
+ return result['default'] ?? result;
277
+ }
278
+ return (0, devkit_1.readJsonFile)(configPath);
279
+ }
280
+ catch { }
281
+ return undefined;
282
+ };
283
+ let ngPackageJson;
284
+ let basePath;
285
+ if ((0, node_fs_1.statSync)(ngPackageJsonPath).isDirectory()) {
286
+ basePath = ngPackageJsonPath;
287
+ ngPackageJson = await readConfig((0, node_path_1.join)(ngPackageJsonPath, 'ng-package.json'));
288
+ if (!ngPackageJson) {
289
+ ngPackageJson = await readConfig((0, node_path_1.join)(ngPackageJsonPath, 'ng-package.js'));
290
+ }
291
+ }
292
+ else {
293
+ basePath = (0, node_path_1.dirname)(ngPackageJsonPath);
294
+ ngPackageJson = await readConfig(ngPackageJsonPath);
295
+ }
296
+ if (!ngPackageJson) {
297
+ return [];
298
+ }
299
+ const destination = ngPackageJson.dest
300
+ ? (0, node_path_1.join)(basePath, ngPackageJson.dest)
301
+ : (0, node_path_1.join)(basePath, 'dist');
302
+ return [
303
+ getOutput(destination, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
304
+ ];
305
+ }
306
+ function getKarmaTargetOutputs(target, angularWorkspaceRoot, projectRoot, context) {
307
+ const defaultOutput = posix.join('{workspaceRoot}', angularWorkspaceRoot, 'coverage/{projectName}');
308
+ if (!target.options?.karmaConfig) {
309
+ return [defaultOutput];
310
+ }
311
+ try {
312
+ const { parseConfig } = require('karma/lib/config');
313
+ const karmaConfigPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, projectRoot, target.options.karmaConfig);
314
+ const config = parseConfig(karmaConfigPath);
315
+ if (config.coverageReporter.dir) {
316
+ return [
317
+ getOutput(config.coverageReporter.dir, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
318
+ ];
319
+ }
320
+ }
321
+ catch {
322
+ // we silently ignore any error here and fall back to the default output
323
+ }
324
+ return [defaultOutput];
325
+ }
326
+ function getBrowserAndServerTargetInputsAndOutputs(projectName, targetName, projects, angularJson) {
327
+ const { browserTarget, serverTarget } = extractBrowserAndServerTargets(angularJson, projectName, targetName);
328
+ if (!browserTarget || !serverTarget) {
329
+ // if any of these are missing, the target is invalid so we return empty values
330
+ return { inputs: [], outputs: [] };
331
+ }
332
+ const browserTargetInputs = projects[browserTarget.project]?.targets?.[browserTarget.target]?.inputs ??
333
+ [];
334
+ const serverTargetInputs = projects[serverTarget.project]?.targets?.[serverTarget.target]?.inputs ??
335
+ [];
336
+ const browserTargetOutputs = projects[browserTarget.project]?.targets?.[browserTarget.target]?.outputs ??
337
+ [];
338
+ const serverTargetOutputs = projects[serverTarget.project]?.targets?.[serverTarget.target]?.outputs ??
339
+ [];
340
+ return {
341
+ inputs: mergeInputs(...browserTargetInputs, ...serverTargetInputs),
342
+ outputs: Array.from(new Set([...browserTargetOutputs, ...serverTargetOutputs])),
343
+ };
344
+ }
345
+ function extractBrowserAndServerTargets(angularJson, projectName, targetName) {
346
+ let browserTarget;
347
+ let serverTarget;
348
+ try {
349
+ const targets = getAngularJsonProjectTargets(angularJson.projects[projectName]);
350
+ const target = targets[targetName];
351
+ let browserTargetSpecifier = target.options?.browserTarget;
352
+ if (!browserTargetSpecifier) {
353
+ const configuration = Object.values(target.configurations ?? {}).find((config) => !!config.browserTarget);
354
+ browserTargetSpecifier = configuration?.browserTarget;
355
+ }
356
+ if (browserTargetSpecifier) {
357
+ browserTarget = targetFromTargetString(browserTargetSpecifier, projectName, targetName);
358
+ }
359
+ let serverTargetSpecifier = target.options?.serverTarget;
360
+ if (!serverTargetSpecifier) {
361
+ serverTargetSpecifier = Object.values(target.configurations ?? {}).find((config) => !!config.serverTarget)?.serverTarget;
362
+ }
363
+ if (serverTargetSpecifier) {
364
+ serverTarget = targetFromTargetString(serverTargetSpecifier, projectName, targetName);
365
+ }
366
+ }
367
+ catch { }
368
+ return { browserTarget: browserTarget, serverTarget };
369
+ }
370
+ function mergeInputs(...inputs) {
371
+ const stringInputs = new Set();
372
+ const externalDependencies = new Set();
373
+ for (const input of inputs) {
374
+ if (typeof input === 'string') {
375
+ stringInputs.add(input);
376
+ }
377
+ else if ('externalDependencies' in input) {
378
+ // we only infer external dependencies, so we don't need to handle the other input definitions
379
+ for (const externalDependency of input.externalDependencies) {
380
+ externalDependencies.add(externalDependency);
381
+ }
382
+ }
383
+ }
384
+ return [
385
+ ...stringInputs,
386
+ ...(externalDependencies.size
387
+ ? [{ externalDependencies: Array.from(externalDependencies) }]
388
+ : []),
389
+ ];
390
+ }
391
+ // angular support abbreviated target specifiers, this is adapter from:
392
+ // https://github.com/angular/angular-cli/blob/7d9ce246a33c60ec96eb4bf99520f5475716a910/packages/angular_devkit/architect/src/api.ts#L336
393
+ function targetFromTargetString(specifier, abbreviatedProjectName, abbreviatedTargetName) {
394
+ const tuple = specifier.split(':', 3);
395
+ if (tuple.length < 2) {
396
+ // invalid target, ignore
397
+ return undefined;
398
+ }
399
+ // we only care about project and target
400
+ return {
401
+ project: tuple[0] || abbreviatedProjectName || '',
402
+ target: tuple[1] || abbreviatedTargetName || '',
403
+ };
404
+ }
405
+ function getOutput(path, workspaceRoot, angularWorkspaceRoot, projectRoot) {
406
+ const relativePath = (0, node_path_1.relative)((0, node_path_1.join)(workspaceRoot, angularWorkspaceRoot, projectRoot), path);
407
+ if (relativePath.startsWith('..')) {
408
+ return posix.join('{workspaceRoot}', (0, node_path_1.join)(angularWorkspaceRoot, projectRoot, relativePath));
409
+ }
410
+ else {
411
+ return posix.join('{projectRoot}', relativePath);
412
+ }
413
+ }
414
+ function getAngularJsonProjectTargets(project) {
415
+ return project.architect ?? project.targets;
416
+ }