@angular-devkit/architect
Advanced tools
Comparing version 0.1800.0-next.2 to 0.1800.0-next.3
@@ -10,3 +10,2 @@ /** | ||
import { json, workspaces } from '@angular-devkit/core'; | ||
import { URL } from 'url'; | ||
import { BuilderInfo } from '../src'; | ||
@@ -38,3 +37,3 @@ import { Target } from '../src/input-schema'; | ||
*/ | ||
resolveBuilder(builderStr: string): Promise<NodeModulesBuilderInfo>; | ||
resolveBuilder(builderStr: string, seenBuilders?: Set<string>): Promise<NodeModulesBuilderInfo>; | ||
getCurrentDirectory(): Promise<string>; | ||
@@ -41,0 +40,0 @@ getWorkspaceRoot(): Promise<string>; |
@@ -34,9 +34,13 @@ "use strict"; | ||
exports.loadEsmModule = exports.WorkspaceNodeModulesArchitectHost = void 0; | ||
const path = __importStar(require("path")); | ||
const url_1 = require("url"); | ||
const v8_1 = require("v8"); | ||
const node_fs_1 = require("node:fs"); | ||
const node_module_1 = require("node:module"); | ||
const path = __importStar(require("node:path")); | ||
const node_url_1 = require("node:url"); | ||
const node_v8_1 = require("node:v8"); | ||
const internal_1 = require("../src/internal"); | ||
// TODO_ESM: Update to use import.meta.url | ||
const localRequire = (0, node_module_1.createRequire)(__filename); | ||
function clone(obj) { | ||
try { | ||
return (0, v8_1.deserialize)((0, v8_1.serialize)(obj)); | ||
return (0, node_v8_1.deserialize)((0, node_v8_1.serialize)(obj)); | ||
} | ||
@@ -114,3 +118,6 @@ catch { | ||
*/ | ||
resolveBuilder(builderStr) { | ||
resolveBuilder(builderStr, seenBuilders) { | ||
if (seenBuilders?.has(builderStr)) { | ||
throw new Error('Circular builder alias references detected: ' + [...seenBuilders, builderStr]); | ||
} | ||
const [packageName, builderName] = builderStr.split(':', 2); | ||
@@ -120,19 +127,44 @@ if (!builderName) { | ||
} | ||
const packageJsonPath = require.resolve(packageName + '/package.json', { | ||
// Resolve and load the builders manifest from the package's `builders` field, if present | ||
const packageJsonPath = localRequire.resolve(packageName + '/package.json', { | ||
paths: [this._root], | ||
}); | ||
const packageJson = require(packageJsonPath); | ||
if (!packageJson['builders']) { | ||
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8')); | ||
const buildersManifestRawPath = packageJson['builders']; | ||
if (!buildersManifestRawPath) { | ||
throw new Error(`Package ${JSON.stringify(packageName)} has no builders defined.`); | ||
} | ||
const builderJsonPath = path.resolve(path.dirname(packageJsonPath), packageJson['builders']); | ||
const builderJson = require(builderJsonPath); | ||
const builder = builderJson.builders && builderJson.builders[builderName]; | ||
let buildersManifestPath = path.normalize(buildersManifestRawPath); | ||
if (path.isAbsolute(buildersManifestRawPath) || buildersManifestRawPath.startsWith('..')) { | ||
throw new Error(`Package "${packageName}" has an invalid builders manifest path: "${buildersManifestRawPath}"`); | ||
} | ||
buildersManifestPath = path.join(path.dirname(packageJsonPath), buildersManifestPath); | ||
const buildersManifest = JSON.parse((0, node_fs_1.readFileSync)(buildersManifestPath, 'utf-8')); | ||
const buildersManifestDirectory = path.dirname(buildersManifestPath); | ||
// Attempt to locate an entry for the specified builder by name | ||
const builder = buildersManifest.builders?.[builderName]; | ||
if (!builder) { | ||
throw new Error(`Cannot find builder ${JSON.stringify(builderStr)}.`); | ||
} | ||
const importPath = builder.implementation; | ||
if (!importPath) { | ||
// Resolve alias reference if entry is a string | ||
if (typeof builder === 'string') { | ||
return this.resolveBuilder(builder, (seenBuilders ?? new Set()).add(builderStr)); | ||
} | ||
// Determine builder implementation path (relative within package only) | ||
const implementationPath = builder.implementation && path.normalize(builder.implementation); | ||
if (!implementationPath) { | ||
throw new Error('Could not find the implementation for builder ' + builderStr); | ||
} | ||
if (path.isAbsolute(implementationPath) || implementationPath.startsWith('..')) { | ||
throw new Error(`Package "${packageName}" has an invalid builder implementation path: "${builderName}" --> "${builder.implementation}"`); | ||
} | ||
// Determine builder option schema path (relative within package only) | ||
const schemaPath = builder.schema && path.normalize(builder.schema); | ||
if (!schemaPath) { | ||
throw new Error('Could not find the schema for builder ' + builderStr); | ||
} | ||
if (path.isAbsolute(schemaPath) || schemaPath.startsWith('..')) { | ||
throw new Error(`Package "${packageName}" has an invalid builder implementation path: "${builderName}" --> "${builder.schema}"`); | ||
} | ||
const schemaText = (0, node_fs_1.readFileSync)(path.join(buildersManifestDirectory, schemaPath), 'utf-8'); | ||
return Promise.resolve({ | ||
@@ -142,4 +174,4 @@ name: builderStr, | ||
description: builder['description'], | ||
optionSchema: require(path.resolve(path.dirname(builderJsonPath), builder.schema)), | ||
import: path.resolve(path.dirname(builderJsonPath), importPath), | ||
optionSchema: JSON.parse(schemaText), | ||
import: path.join(buildersManifestDirectory, implementationPath), | ||
}); | ||
@@ -217,5 +249,5 @@ } | ||
// changed to a direct dynamic import. | ||
return (await loadEsmModule((0, url_1.pathToFileURL)(builderPath))).default; | ||
return (await loadEsmModule((0, node_url_1.pathToFileURL)(builderPath))).default; | ||
case '.cjs': | ||
return require(builderPath); | ||
return localRequire(builderPath); | ||
default: | ||
@@ -225,3 +257,3 @@ // The file could be either CommonJS or ESM. | ||
try { | ||
return require(builderPath); | ||
return localRequire(builderPath); | ||
} | ||
@@ -233,3 +265,3 @@ catch (e) { | ||
// changed to a direct dynamic import. | ||
return (await loadEsmModule((0, url_1.pathToFileURL)(builderPath))).default; | ||
return (await loadEsmModule((0, node_url_1.pathToFileURL)(builderPath))).default; | ||
} | ||
@@ -236,0 +268,0 @@ throw e; |
{ | ||
"name": "@angular-devkit/architect", | ||
"version": "0.1800.0-next.2", | ||
"version": "0.1800.0-next.3", | ||
"description": "Angular Build Facade", | ||
@@ -9,3 +9,3 @@ "experimental": true, | ||
"dependencies": { | ||
"@angular-devkit/core": "18.0.0-next.2", | ||
"@angular-devkit/core": "18.0.0-next.3", | ||
"rxjs": "7.8.1" | ||
@@ -12,0 +12,0 @@ }, |
@@ -7,6 +7,7 @@ export interface Schema { | ||
builders: { | ||
[key: string]: Builder; | ||
[key: string]: BuilderValue; | ||
}; | ||
[property: string]: any; | ||
} | ||
export type BuilderValue = Builder | string; | ||
/** | ||
@@ -13,0 +14,0 @@ * Target options for Builders. |
@@ -14,3 +14,11 @@ { | ||
"additionalProperties": { | ||
"$ref": "#/definitions/builder" | ||
"oneOf": [ | ||
{ | ||
"$ref": "#/definitions/builder" | ||
}, | ||
{ | ||
"type": "string", | ||
"minLength": 1 | ||
} | ||
] | ||
} | ||
@@ -17,0 +25,0 @@ } |
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
168916
4105
6
+ Added@angular-devkit/core@18.0.0-next.3(transitive)
- Removed@angular-devkit/core@18.0.0-next.2(transitive)