@angular-devkit/architect 0.1800.0-next.2 → 0.1800.0-next.4

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.
@@ -7,7 +7,6 @@
7
7
  */
8
8
  /// <reference types="node" />
9
9
  import { json, workspaces } from '@angular-devkit/core';
10
- import { URL } from 'url';
11
10
  import { BuilderInfo } from '../src';
12
11
  import { Target } from '../src/input-schema';
13
12
  import { ArchitectHost, Builder } from '../src/internal';
@@ -34,7 +33,7 @@ export declare class WorkspaceNodeModulesArchitectHost implements ArchitectHost<
34
33
  * @param builderStr The name of the builder to be used.
35
34
  * @returns All the info needed for the builder itself.
36
35
  */
37
- resolveBuilder(builderStr: string): Promise<NodeModulesBuilderInfo>;
36
+ resolveBuilder(builderStr: string, seenBuilders?: Set<string>): Promise<NodeModulesBuilderInfo>;
38
37
  getCurrentDirectory(): Promise<string>;
39
38
  getWorkspaceRoot(): Promise<string>;
40
39
  getOptionsForTarget(target: Target): Promise<json.JsonObject | null>;
@@ -31,13 +31,17 @@ var __importStar = (this && this.__importStar) || function (mod) {
31
31
  };
32
32
  Object.defineProperty(exports, "__esModule", { value: true });
33
33
  exports.loadEsmModule = exports.WorkspaceNodeModulesArchitectHost = void 0;
34
- const path = __importStar(require("path"));
35
- const url_1 = require("url");
36
- const v8_1 = require("v8");
34
+ const node_fs_1 = require("node:fs");
35
+ const node_module_1 = require("node:module");
36
+ const path = __importStar(require("node:path"));
37
+ const node_url_1 = require("node:url");
38
+ const node_v8_1 = require("node:v8");
37
39
  const internal_1 = require("../src/internal");
40
+ // TODO_ESM: Update to use import.meta.url
41
+ const localRequire = (0, node_module_1.createRequire)(__filename);
38
42
  function clone(obj) {
39
43
  try {
40
- return (0, v8_1.deserialize)((0, v8_1.serialize)(obj));
44
+ return (0, node_v8_1.deserialize)((0, node_v8_1.serialize)(obj));
41
45
  }
42
46
  catch {
43
47
  return JSON.parse(JSON.stringify(obj));
@@ -110,34 +114,62 @@ class WorkspaceNodeModulesArchitectHost {
110
114
  * @param builderStr The name of the builder to be used.
111
115
  * @returns All the info needed for the builder itself.
112
116
  */
113
- resolveBuilder(builderStr) {
117
+ resolveBuilder(builderStr, seenBuilders) {
118
+ if (seenBuilders?.has(builderStr)) {
119
+ throw new Error('Circular builder alias references detected: ' + [...seenBuilders, builderStr]);
120
+ }
114
121
  const [packageName, builderName] = builderStr.split(':', 2);
115
122
  if (!builderName) {
116
123
  throw new Error('No builder name specified.');
117
124
  }
118
- const packageJsonPath = require.resolve(packageName + '/package.json', {
125
+ // Resolve and load the builders manifest from the package's `builders` field, if present
126
+ const packageJsonPath = localRequire.resolve(packageName + '/package.json', {
119
127
  paths: [this._root],
120
128
  });
121
- const packageJson = require(packageJsonPath);
122
- if (!packageJson['builders']) {
129
+ const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8'));
130
+ const buildersManifestRawPath = packageJson['builders'];
131
+ if (!buildersManifestRawPath) {
123
132
  throw new Error(`Package ${JSON.stringify(packageName)} has no builders defined.`);
124
133
  }
125
- const builderJsonPath = path.resolve(path.dirname(packageJsonPath), packageJson['builders']);
126
- const builderJson = require(builderJsonPath);
127
- const builder = builderJson.builders && builderJson.builders[builderName];
134
+ let buildersManifestPath = path.normalize(buildersManifestRawPath);
135
+ if (path.isAbsolute(buildersManifestRawPath) || buildersManifestRawPath.startsWith('..')) {
136
+ throw new Error(`Package "${packageName}" has an invalid builders manifest path: "${buildersManifestRawPath}"`);
137
+ }
138
+ buildersManifestPath = path.join(path.dirname(packageJsonPath), buildersManifestPath);
139
+ const buildersManifest = JSON.parse((0, node_fs_1.readFileSync)(buildersManifestPath, 'utf-8'));
140
+ const buildersManifestDirectory = path.dirname(buildersManifestPath);
141
+ // Attempt to locate an entry for the specified builder by name
142
+ const builder = buildersManifest.builders?.[builderName];
128
143
  if (!builder) {
129
144
  throw new Error(`Cannot find builder ${JSON.stringify(builderStr)}.`);
130
145
  }
131
- const importPath = builder.implementation;
132
- if (!importPath) {
146
+ // Resolve alias reference if entry is a string
147
+ if (typeof builder === 'string') {
148
+ return this.resolveBuilder(builder, (seenBuilders ?? new Set()).add(builderStr));
149
+ }
150
+ // Determine builder implementation path (relative within package only)
151
+ const implementationPath = builder.implementation && path.normalize(builder.implementation);
152
+ if (!implementationPath) {
133
153
  throw new Error('Could not find the implementation for builder ' + builderStr);
134
154
  }
155
+ if (path.isAbsolute(implementationPath) || implementationPath.startsWith('..')) {
156
+ throw new Error(`Package "${packageName}" has an invalid builder implementation path: "${builderName}" --> "${builder.implementation}"`);
157
+ }
158
+ // Determine builder option schema path (relative within package only)
159
+ const schemaPath = builder.schema && path.normalize(builder.schema);
160
+ if (!schemaPath) {
161
+ throw new Error('Could not find the schema for builder ' + builderStr);
162
+ }
163
+ if (path.isAbsolute(schemaPath) || schemaPath.startsWith('..')) {
164
+ throw new Error(`Package "${packageName}" has an invalid builder implementation path: "${builderName}" --> "${builder.schema}"`);
165
+ }
166
+ const schemaText = (0, node_fs_1.readFileSync)(path.join(buildersManifestDirectory, schemaPath), 'utf-8');
135
167
  return Promise.resolve({
136
168
  name: builderStr,
137
169
  builderName,
138
170
  description: builder['description'],
139
- optionSchema: require(path.resolve(path.dirname(builderJsonPath), builder.schema)),
140
- import: path.resolve(path.dirname(builderJsonPath), importPath),
171
+ optionSchema: JSON.parse(schemaText),
172
+ import: path.join(buildersManifestDirectory, implementationPath),
141
173
  });
142
174
  }
143
175
  async getCurrentDirectory() {
@@ -210,21 +242,21 @@ async function getBuilder(builderPath) {
210
242
  // Load the ESM configuration file using the TypeScript dynamic import workaround.
211
243
  // Once TypeScript provides support for keeping the dynamic import this workaround can be
212
244
  // changed to a direct dynamic import.
213
- return (await loadEsmModule((0, url_1.pathToFileURL)(builderPath))).default;
245
+ return (await loadEsmModule((0, node_url_1.pathToFileURL)(builderPath))).default;
214
246
  case '.cjs':
215
- return require(builderPath);
247
+ return localRequire(builderPath);
216
248
  default:
217
249
  // The file could be either CommonJS or ESM.
218
250
  // CommonJS is tried first then ESM if loading fails.
219
251
  try {
220
- return require(builderPath);
252
+ return localRequire(builderPath);
221
253
  }
222
254
  catch (e) {
223
255
  if (e.code === 'ERR_REQUIRE_ESM') {
224
256
  // Load the ESM configuration file using the TypeScript dynamic import workaround.
225
257
  // Once TypeScript provides support for keeping the dynamic import this workaround can be
226
258
  // changed to a direct dynamic import.
227
- return (await loadEsmModule((0, url_1.pathToFileURL)(builderPath))).default;
259
+ return (await loadEsmModule((0, node_url_1.pathToFileURL)(builderPath))).default;
228
260
  }
229
261
  throw e;
230
262
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@angular-devkit/architect",
3
- "version": "0.1800.0-next.2",
3
+ "version": "0.1800.0-next.4",
4
4
  "description": "Angular Build Facade",
5
5
  "experimental": true,
6
6
  "main": "src/index.js",
7
7
  "typings": "src/index.d.ts",
8
8
  "dependencies": {
9
- "@angular-devkit/core": "18.0.0-next.2",
9
+ "@angular-devkit/core": "18.0.0-next.4",
10
10
  "rxjs": "7.8.1"
11
11
  },
12
12
  "builders": "./builders/builders.json",
@@ -22,7 +22,7 @@
22
22
  "url": "https://github.com/angular/angular-cli.git"
23
23
  },
24
24
  "engines": {
25
- "node": "^18.19.1 || >=20.11.1",
25
+ "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
26
26
  "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
27
27
  "yarn": ">= 1.13.0"
28
28
  },
@@ -4,10 +4,11 @@ export interface Schema {
4
4
  */
5
5
  $schema?: string;
6
6
  builders: {
7
- [key: string]: Builder;
7
+ [key: string]: BuilderValue;
8
8
  };
9
9
  [property: string]: any;
10
10
  }
11
+ export type BuilderValue = Builder | string;
11
12
  /**
12
13
  * Target options for Builders.
13
14
  */
@@ -11,7 +11,15 @@
11
11
  "builders": {
12
12
  "type": "object",
13
13
  "additionalProperties": {
14
- "$ref": "#/definitions/builder"
14
+ "oneOf": [
15
+ {
16
+ "$ref": "#/definitions/builder"
17
+ },
18
+ {
19
+ "type": "string",
20
+ "minLength": 1
21
+ }
22
+ ]
15
23
  }
16
24
  }
17
25
  },