This commit is contained in:
CHEVALLIER Abel
2025-11-13 16:23:22 +01:00
parent de9c515a47
commit cb235644dc
34924 changed files with 3811102 additions and 0 deletions

21
node_modules/@angular-devkit/architect/LICENSE generated vendored Executable file
View File

@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2010-2025 Google LLC. https://angular.dev/license
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

3
node_modules/@angular-devkit/architect/README.md generated vendored Executable file
View File

@@ -0,0 +1,3 @@
# Angular Build Facade
WIP

11
node_modules/@angular-devkit/architect/builders/all-of.d.ts generated vendored Executable file
View File

@@ -0,0 +1,11 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { Builder } from '../src';
import { Schema as OperatorSchema } from './operator-schema';
declare const builder: Builder<OperatorSchema>;
export default builder;

48
node_modules/@angular-devkit/architect/builders/all-of.js generated vendored Executable file
View File

@@ -0,0 +1,48 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
const rxjs_1 = require("rxjs");
const src_1 = require("../src");
const builder = (0, src_1.createBuilder)((options, context) => {
const allRuns = [];
context.reportProgress(0, (options.targets ? options.targets.length : 0) +
(options.builders ? options.builders.length : 0));
if (options.targets) {
allRuns.push(...options.targets.map(({ target: targetStr, overrides }, i) => {
const [project, target, configuration] = targetStr.split(/:/g, 3);
return context
.scheduleTarget({ project, target, configuration }, overrides || {})
.then((run) => [i, run]);
}));
}
if (options.builders) {
allRuns.push(...options.builders.map(({ builder, options }, i) => {
return context
.scheduleBuilder(builder, options || {})
.then((run) => [i, run]);
}));
}
const allResults = allRuns.map(() => null);
let n = 0;
context.reportProgress(n++, allRuns.length);
return (0, rxjs_1.from)(allRuns).pipe((0, rxjs_1.mergeMap)((runPromise) => (0, rxjs_1.from)(runPromise)), (0, rxjs_1.mergeMap)(([i, run]) => run.output.pipe((0, rxjs_1.map)((output) => [i, output]))), (0, rxjs_1.mergeMap)(([i, output]) => {
allResults[i] = output;
context.reportProgress(n++, allRuns.length);
if (allResults.some((x) => x === null)) {
// Some builders aren't done running yet.
return rxjs_1.EMPTY;
}
else {
return (0, rxjs_1.of)({
success: allResults.every((x) => (x ? x.success : false)),
});
}
}));
});
exports.default = builder;

View File

@@ -0,0 +1,25 @@
{
"$schema": "../src/builders-schema.json",
"builders": {
"true": {
"implementation": "./true",
"schema": "./noop-schema.json",
"description": "Always succeed."
},
"false": {
"implementation": "./false",
"schema": "./noop-schema.json",
"description": "Always fails."
},
"allOf": {
"implementation": "./all-of",
"schema": "./operator-schema.json",
"description": "A builder that executes many builders in parallel, and succeed if both succeeds."
},
"concat": {
"implementation": "./concat",
"schema": "./operator-schema.json",
"description": "A builder that executes many builders one after the other, and stops when one fail. It will succeed if all builders succeeds (and return the last output)"
}
}
}

11
node_modules/@angular-devkit/architect/builders/concat.d.ts generated vendored Executable file
View File

@@ -0,0 +1,11 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { Builder } from '../src';
import { Schema as OperatorSchema } from './operator-schema';
declare const builder: Builder<OperatorSchema>;
export default builder;

45
node_modules/@angular-devkit/architect/builders/concat.js generated vendored Executable file
View File

@@ -0,0 +1,45 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
const rxjs_1 = require("rxjs");
const src_1 = require("../src");
const builder = (0, src_1.createBuilder)((options, context) => {
const allRuns = [];
context.reportProgress(0, (options.targets ? options.targets.length : 0) +
(options.builders ? options.builders.length : 0));
if (options.targets) {
allRuns.push(...options.targets.map(({ target: targetStr, overrides }) => {
const [project, target, configuration] = targetStr.split(/:/g, 3);
return () => context.scheduleTarget({ project, target, configuration }, overrides || {});
}));
}
if (options.builders) {
allRuns.push(...options.builders.map(({ builder, options }) => {
return () => context.scheduleBuilder(builder, options || {});
}));
}
let stop = null;
let i = 0;
context.reportProgress(i++, allRuns.length);
return (0, rxjs_1.from)(allRuns).pipe((0, rxjs_1.concatMap)((fn) => stop
? (0, rxjs_1.of)(null)
: (0, rxjs_1.from)(fn()).pipe((0, rxjs_1.switchMap)((run) => (run === null ? (0, rxjs_1.of)(null) : run.output.pipe((0, rxjs_1.first)()))))), (0, rxjs_1.map)((output) => {
context.reportProgress(i++, allRuns.length);
if (output === null || stop !== null) {
return stop || { success: false };
}
else if (output.success === false) {
return (stop = output);
}
else {
return output;
}
}), (0, rxjs_1.last)());
});
exports.default = builder;

10
node_modules/@angular-devkit/architect/builders/false.d.ts generated vendored Executable file
View File

@@ -0,0 +1,10 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { type Builder } from '../src';
declare const builder: Builder<{}>;
export default builder;

15
node_modules/@angular-devkit/architect/builders/false.js generated vendored Executable file
View File

@@ -0,0 +1,15 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
const src_1 = require("../src");
const builder = (0, src_1.createBuilder)(() => ({
success: false,
error: 'False builder always errors.',
}));
exports.default = builder;

View File

@@ -0,0 +1,4 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object"
}

View File

@@ -0,0 +1,22 @@
/**
* All input types of builders that perform operations on one or multiple sub-builders.
*/
export type Schema = {
builders?: Builder[];
targets?: Target[];
[property: string]: any;
};
export type Builder = {
builder: string;
options?: {
[key: string]: any;
};
[property: string]: any;
};
export type Target = {
overrides?: {
[key: string]: any;
};
target: string;
[property: string]: any;
};

View File

@@ -0,0 +1,4 @@
"use strict";
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,41 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"description": "All input types of builders that perform operations on one or multiple sub-builders.",
"type": "object",
"properties": {
"builders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"builder": {
"type": "string",
"pattern": ".*:.*"
},
"options": {
"type": "object"
}
},
"required": ["builder"]
},
"minItems": 1
},
"targets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"target": {
"type": "string",
"pattern": ".*:.*"
},
"overrides": {
"type": "object"
}
},
"required": ["target"]
},
"minItems": 1
}
}
}

10
node_modules/@angular-devkit/architect/builders/true.d.ts generated vendored Executable file
View File

@@ -0,0 +1,10 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { type Builder } from '../src';
declare const builder: Builder<{}>;
export default builder;

12
node_modules/@angular-devkit/architect/builders/true.js generated vendored Executable file
View File

@@ -0,0 +1,12 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
const src_1 = require("../src");
const builder = (0, src_1.createBuilder)(() => ({ success: true }));
exports.default = builder;

8
node_modules/@angular-devkit/architect/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,8 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export * from './src/index';

24
node_modules/@angular-devkit/architect/index.js generated vendored Executable file
View File

@@ -0,0 +1,24 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./src/index"), exports);

10
node_modules/@angular-devkit/architect/node/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,10 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as jobs from './jobs/job-registry';
export * from './node-modules-architect-host';
export { jobs };

49
node_modules/@angular-devkit/architect/node/index.js generated vendored Executable file
View File

@@ -0,0 +1,49 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.jobs = void 0;
const jobs = __importStar(require("./jobs/job-registry"));
exports.jobs = jobs;
__exportStar(require("./node-modules-architect-host"), exports);

View File

@@ -0,0 +1,20 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { JsonValue } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { jobs } from '../../src';
export declare class NodeModuleJobRegistry<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> implements jobs.Registry<MinimumArgumentValueT, MinimumInputValueT, MinimumOutputValueT> {
protected _resolve(name: string): string | null;
/**
* Get a job description for a named job.
*
* @param name The name of the job.
* @returns A description, or null if the job is not registered.
*/
get<A extends MinimumArgumentValueT, I extends MinimumInputValueT, O extends MinimumOutputValueT>(name: jobs.JobName): Observable<jobs.JobHandler<A, I, O> | null>;
}

View File

@@ -0,0 +1,59 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeModuleJobRegistry = void 0;
const core_1 = require("@angular-devkit/core");
const rxjs_1 = require("rxjs");
class NodeModuleJobRegistry {
_resolve(name) {
try {
return require.resolve(name);
}
catch (e) {
if (e.code === 'MODULE_NOT_FOUND') {
return null;
}
throw e;
}
}
/**
* Get a job description for a named job.
*
* @param name The name of the job.
* @returns A description, or null if the job is not registered.
*/
get(name) {
const [moduleName, exportName] = name.split(/#/, 2);
const resolvedPath = this._resolve(moduleName);
if (!resolvedPath) {
return (0, rxjs_1.of)(null);
}
const pkg = require(resolvedPath);
const handler = pkg[exportName || 'default'];
if (!handler) {
return (0, rxjs_1.of)(null);
}
function _getValue(...fields) {
return fields.find((x) => core_1.schema.isJsonSchema(x)) || true;
}
const argument = _getValue(pkg.argument, handler.argument);
const input = _getValue(pkg.input, handler.input);
const output = _getValue(pkg.output, handler.output);
const channels = _getValue(pkg.channels, handler.channels);
return (0, rxjs_1.of)(Object.assign(handler.bind(undefined), {
jobDescription: {
argument,
input,
output,
channels,
},
}));
}
}
exports.NodeModuleJobRegistry = NodeModuleJobRegistry;

View File

@@ -0,0 +1,54 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json, workspaces } from '@angular-devkit/core';
import { BuilderInfo } from '../src';
import { Target } from '../src/input-schema';
import { ArchitectHost, Builder } from '../src/internal';
export type NodeModulesBuilderInfo = BuilderInfo & {
import: string;
};
export interface WorkspaceHost {
getBuilderName(project: string, target: string): Promise<string>;
getMetadata(project: string): Promise<json.JsonObject>;
getOptions(project: string, target: string, configuration?: string): Promise<json.JsonObject>;
hasTarget(project: string, target: string): Promise<boolean>;
getDefaultConfigurationName(project: string, target: string): Promise<string | undefined>;
}
export declare class WorkspaceNodeModulesArchitectHost implements ArchitectHost<NodeModulesBuilderInfo> {
protected _root: string;
private workspaceHost;
constructor(workspaceHost: WorkspaceHost, _root: string);
constructor(workspace: workspaces.WorkspaceDefinition, _root: string);
getBuilderNameForTarget(target: Target): Promise<string>;
/**
* Resolve a builder. This needs to be a string which will be used in a dynamic `import()`
* clause. This should throw if no builder can be found. The dynamic import will throw if
* it is unsupported.
* @param builderStr The name of the builder to be used.
* @returns All the info needed for the builder itself.
*/
resolveBuilder(builderStr: string, basePath?: string, seenBuilders?: Set<string>): Promise<NodeModulesBuilderInfo>;
getCurrentDirectory(): Promise<string>;
getWorkspaceRoot(): Promise<string>;
getOptionsForTarget(target: Target): Promise<json.JsonObject | null>;
getProjectMetadata(target: Target | string): Promise<json.JsonObject | null>;
loadBuilder(info: NodeModulesBuilderInfo): Promise<Builder>;
}
/**
* This uses a dynamic import to load a module which may be ESM.
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
* will currently, unconditionally downlevel dynamic import into a require call.
* require calls cannot load ESM code and will result in a runtime error. To workaround
* this, a Function constructor is used to prevent TypeScript from changing the dynamic import.
* Once TypeScript provides support for keeping the dynamic import this workaround can
* be dropped.
*
* @param modulePath The path of the module to load.
* @returns A Promise that resolves to the dynamically imported module.
*/
export declare function loadEsmModule<T>(modulePath: string | URL): Promise<T>;

View File

@@ -0,0 +1,291 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkspaceNodeModulesArchitectHost = void 0;
exports.loadEsmModule = loadEsmModule;
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, node_v8_1.deserialize)((0, node_v8_1.serialize)(obj));
}
catch {
return JSON.parse(JSON.stringify(obj));
}
}
function findProjectTarget(workspace, project, target) {
const projectDefinition = workspace.projects.get(project);
if (!projectDefinition) {
throw new Error(`Project "${project}" does not exist.`);
}
const targetDefinition = projectDefinition.targets.get(target);
if (!targetDefinition) {
throw new Error('Project target does not exist.');
}
if (!targetDefinition.builder) {
throw new Error(`A builder is not set for target '${target}' in project '${project}'.`);
}
return targetDefinition;
}
class WorkspaceNodeModulesArchitectHost {
_root;
workspaceHost;
constructor(workspaceOrHost, _root) {
this._root = _root;
if ('getBuilderName' in workspaceOrHost) {
this.workspaceHost = workspaceOrHost;
}
else {
this.workspaceHost = {
async getBuilderName(project, target) {
const { builder } = findProjectTarget(workspaceOrHost, project, target);
return builder;
},
async getOptions(project, target, configuration) {
const targetDefinition = findProjectTarget(workspaceOrHost, project, target);
if (configuration === undefined) {
return (targetDefinition.options ?? {});
}
if (!targetDefinition.configurations?.[configuration]) {
throw new Error(`Configuration '${configuration}' for target '${target}' in project '${project}' is not set in the workspace.`);
}
return (targetDefinition.configurations?.[configuration] ?? {});
},
async getMetadata(project) {
const projectDefinition = workspaceOrHost.projects.get(project);
if (!projectDefinition) {
throw new Error(`Project "${project}" does not exist.`);
}
return {
root: projectDefinition.root,
sourceRoot: projectDefinition.sourceRoot,
prefix: projectDefinition.prefix,
...clone(workspaceOrHost.extensions),
...clone(projectDefinition.extensions),
};
},
async hasTarget(project, target) {
return !!workspaceOrHost.projects.get(project)?.targets.has(target);
},
async getDefaultConfigurationName(project, target) {
return workspaceOrHost.projects.get(project)?.targets.get(target)?.defaultConfiguration;
},
};
}
}
async getBuilderNameForTarget(target) {
return this.workspaceHost.getBuilderName(target.project, target.target);
}
/**
* Resolve a builder. This needs to be a string which will be used in a dynamic `import()`
* clause. This should throw if no builder can be found. The dynamic import will throw if
* it is unsupported.
* @param builderStr The name of the builder to be used.
* @returns All the info needed for the builder itself.
*/
resolveBuilder(builderStr, basePath = this._root, seenBuilders) {
if (seenBuilders?.has(builderStr)) {
throw new Error('Circular builder alias references detected: ' + [...seenBuilders, builderStr]);
}
const [packageName, builderName] = builderStr.split(':', 2);
if (!builderName) {
throw new Error('No builder name specified.');
}
// Resolve and load the builders manifest from the package's `builders` field, if present
const packageJsonPath = localRequire.resolve(packageName + '/package.json', {
paths: [basePath],
});
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.`);
}
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)}.`);
}
// Resolve alias reference if entry is a string
if (typeof builder === 'string') {
return this.resolveBuilder(builder, path.dirname(packageJsonPath), (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)
let schemaPath = builder.schema;
if (!schemaPath) {
throw new Error('Could not find the schema for builder ' + builderStr);
}
if (path.isAbsolute(schemaPath) || path.normalize(schemaPath).startsWith('..')) {
throw new Error(`Package "${packageName}" has an invalid builder schema path: "${builderName}" --> "${builder.schema}"`);
}
// The file could be either a package reference or in the local manifest directory.
if (schemaPath.startsWith('.')) {
schemaPath = path.join(buildersManifestDirectory, schemaPath);
}
else {
const manifestRequire = (0, node_module_1.createRequire)(buildersManifestDirectory + '/');
schemaPath = manifestRequire.resolve(schemaPath);
}
const schemaText = (0, node_fs_1.readFileSync)(schemaPath, 'utf-8');
return Promise.resolve({
name: builderStr,
builderName,
description: builder['description'],
optionSchema: JSON.parse(schemaText),
import: path.join(buildersManifestDirectory, implementationPath),
});
}
async getCurrentDirectory() {
return process.cwd();
}
async getWorkspaceRoot() {
return this._root;
}
async getOptionsForTarget(target) {
if (!(await this.workspaceHost.hasTarget(target.project, target.target))) {
return null;
}
let options = await this.workspaceHost.getOptions(target.project, target.target);
const targetConfiguration = target.configuration ||
(await this.workspaceHost.getDefaultConfigurationName(target.project, target.target));
if (targetConfiguration) {
const configurations = targetConfiguration.split(',').map((c) => c.trim());
for (const configuration of configurations) {
options = {
...options,
...(await this.workspaceHost.getOptions(target.project, target.target, configuration)),
};
}
}
return clone(options);
}
async getProjectMetadata(target) {
const projectName = typeof target === 'string' ? target : target.project;
const metadata = this.workspaceHost.getMetadata(projectName);
return metadata;
}
async loadBuilder(info) {
const builder = await getBuilder(info.import);
if (builder[internal_1.BuilderSymbol]) {
return builder;
}
// Default handling code is for old builders that incorrectly export `default` with non-ESM module
if (builder?.default[internal_1.BuilderSymbol]) {
return builder.default;
}
throw new Error('Builder is not a builder');
}
}
exports.WorkspaceNodeModulesArchitectHost = WorkspaceNodeModulesArchitectHost;
/**
* Lazily compiled dynamic import loader function.
*/
let load;
/**
* This uses a dynamic import to load a module which may be ESM.
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
* will currently, unconditionally downlevel dynamic import into a require call.
* require calls cannot load ESM code and will result in a runtime error. To workaround
* this, a Function constructor is used to prevent TypeScript from changing the dynamic import.
* Once TypeScript provides support for keeping the dynamic import this workaround can
* be dropped.
*
* @param modulePath The path of the module to load.
* @returns A Promise that resolves to the dynamically imported module.
*/
function loadEsmModule(modulePath) {
load ??= new Function('modulePath', `return import(modulePath);`);
return load(modulePath);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function getBuilder(builderPath) {
let builder;
switch (path.extname(builderPath)) {
case '.mjs':
// Load the ESM configuration file using the TypeScript dynamic import workaround.
// Once TypeScript provides support for keeping the dynamic import this workaround can be
// changed to a direct dynamic import.
builder = (await loadEsmModule((0, node_url_1.pathToFileURL)(builderPath))).default;
break;
case '.cjs':
builder = localRequire(builderPath);
break;
default:
// The file could be either CommonJS or ESM.
// CommonJS is tried first then ESM if loading fails.
try {
builder = localRequire(builderPath);
}
catch (e) {
if (e.code === 'ERR_REQUIRE_ESM' ||
e.code === 'ERR_REQUIRE_ASYNC_MODULE') {
// Load the ESM configuration file using the TypeScript dynamic import workaround.
// Once TypeScript provides support for keeping the dynamic import this workaround can be
// changed to a direct dynamic import.
builder = await loadEsmModule((0, node_url_1.pathToFileURL)(builderPath));
}
throw e;
}
break;
}
return 'default' in builder ? builder.default : builder;
}

36
node_modules/@angular-devkit/architect/package.json generated vendored Executable file
View File

@@ -0,0 +1,36 @@
{
"name": "@angular-devkit/architect",
"version": "0.2003.10",
"description": "Angular Build Facade",
"experimental": true,
"main": "src/index.js",
"typings": "src/index.d.ts",
"dependencies": {
"@angular-devkit/core": "20.3.10",
"rxjs": "7.8.2"
},
"builders": "./builders/builders.json",
"keywords": [
"Angular CLI",
"Angular DevKit",
"angular",
"devkit",
"sdk"
],
"repository": {
"type": "git",
"url": "https://github.com/angular/angular-cli.git"
},
"packageManager": "pnpm@10.19.0",
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
"yarn": ">= 1.13.0"
},
"author": "Angular Authors",
"license": "MIT",
"bugs": {
"url": "https://github.com/angular/angular-cli/issues"
},
"homepage": "https://github.com/angular/angular-cli"
}

269
node_modules/@angular-devkit/architect/src/api.d.ts generated vendored Executable file
View File

@@ -0,0 +1,269 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json, logging } from '@angular-devkit/core';
import { Observable, ObservableInput } from 'rxjs';
import { Schema as RealBuilderInput, Target as RealTarget } from './input-schema';
import { Registry } from './jobs';
import { Schema as RealBuilderOutput } from './output-schema';
import { State as BuilderProgressState, Schema as RealBuilderProgress } from './progress-schema';
export type Target = json.JsonObject & RealTarget;
export { BuilderProgressState };
export type BuilderRegistry = Registry<json.JsonObject, BuilderInput, BuilderOutput>;
/**
* An API typed BuilderProgress. The interface generated from the schema is too permissive,
* so this API is the one we show in our API. Please note that not all fields are in there; this
* is in addition to fields in the schema.
*/
export type TypedBuilderProgress = {
state: BuilderProgressState.Stopped;
} | {
state: BuilderProgressState.Error;
error: json.JsonValue;
} | {
state: BuilderProgressState.Waiting;
status?: string;
} | {
state: BuilderProgressState.Running;
status?: string;
current: number;
total?: number;
};
/**
* Declaration of those types as JsonObject compatible. JsonObject is not compatible with
* optional members, so those wouldn't be directly assignable to our internal Json typings.
* Forcing the type to be both a JsonObject and the type from the Schema tells Typescript they
* are compatible (which they are).
* These types should be used everywhere.
*/
export type BuilderInput = json.JsonObject & RealBuilderInput;
export type BuilderOutput = json.JsonObject & RealBuilderOutput;
export type BuilderProgress = json.JsonObject & RealBuilderProgress & TypedBuilderProgress;
/**
* A progress report is what the tooling will receive. It contains the builder info and the target.
* Although these are serializable, they are only exposed through the tooling interface, not the
* builder interface. The watch dog sends BuilderProgress and the Builder has a set of functions
* to manage the state.
*/
export type BuilderProgressReport = BuilderProgress & {
target?: Target;
builder: BuilderInfo;
};
/**
* A Run, which is what is returned by scheduleBuilder or scheduleTarget functions. This should
* be reconstructed across memory boundaries (it's not serializable but all internal information
* are).
*/
export interface BuilderRun {
/**
* Unique amongst runs. This is the same ID as the context generated for the run. It can be
* used to identify multiple unique runs. There is no guarantee that a run is a single output;
* a builder can rebuild on its own and will generate multiple outputs.
*/
id: number;
/**
* The builder information.
*/
info: BuilderInfo;
/**
* The next output from a builder. This is recommended when scheduling a builder and only being
* interested in the result of that single run, not of a watch-mode builder.
*/
result: Promise<BuilderOutput>;
/**
* The last output from a builder. This is recommended when scheduling a builder and only being
* interested in the result of that last run.
*/
lastOutput: Promise<BuilderOutput>;
/**
* The output(s) from the builder. A builder can have multiple outputs.
* This always replay the last output when subscribed.
*/
output: Observable<BuilderOutput>;
/**
* The progress report. A progress also contains an ID, which can be different than this run's
* ID (if the builder calls scheduleBuilder or scheduleTarget).
* This will always replay the last progress on new subscriptions.
*/
progress: Observable<BuilderProgressReport>;
/**
* Stop the builder from running. Returns a promise that resolves when the builder is stopped.
* Some builders might not handle stopping properly and should have a timeout here.
*/
stop(): Promise<void>;
}
/**
* Additional optional scheduling options.
*/
export interface ScheduleOptions {
/**
* Logger to pass to the builder. Note that messages will stop being forwarded, and if you want
* to log a builder scheduled from your builder you should forward log events yourself.
*/
logger?: logging.Logger;
/**
* Target to pass to the builder.
*/
target?: Target;
}
/**
* The context received as a second argument in your builder.
*/
export interface BuilderContext {
/**
* Unique amongst contexts. Contexts instances are not guaranteed to be the same (but it could
* be the same context), and all the fields in a context could be the same, yet the builder's
* context could be different. This is the same ID as the corresponding run.
*/
id: number;
/**
* The builder info that called your function. Since the builder info is from the builder.json
* (or the host), it could contain information that is different than expected.
*/
builder: BuilderInfo;
/**
* A logger that appends messages to a log. This could be a separate interface or completely
* ignored. `console.log` could also be completely ignored.
*/
logger: logging.LoggerApi;
/**
* The absolute workspace root of this run. This is a system path and will not be normalized;
* ie. on Windows it will starts with `C:\\` (or whatever drive).
*/
workspaceRoot: string;
/**
* The current directory the user is in. This could be outside the workspace root. This is a
* system path and will not be normalized; ie. on Windows it will starts with `C:\\` (or
* whatever drive).
*/
currentDirectory: string;
/**
* The target that was used to run this builder.
* Target is optional if a builder was ran using `scheduleBuilder()`.
*/
target?: Target;
/**
* Schedule a target in the same workspace. This can be the same target that is being executed
* right now, but targets of the same name are serialized.
* Running the same target and waiting for it to end will result in a deadlocking scenario.
* Targets are considered the same if the project, the target AND the configuration are the same.
* @param target The target to schedule.
* @param overrides A set of options to override the workspace set of options.
* @param scheduleOptions Additional optional scheduling options.
* @return A promise of a run. It will resolve when all the members of the run are available.
*/
scheduleTarget(target: Target, overrides?: json.JsonObject, scheduleOptions?: ScheduleOptions): Promise<BuilderRun>;
/**
* Schedule a builder by its name. This can be the same builder that is being executed.
* @param builderName The name of the builder, ie. its `packageName:builderName` tuple.
* @param options All options to use for the builder (by default empty object). There is no
* additional options added, e.g. from the workspace.
* @param scheduleOptions Additional optional scheduling options.
* @return A promise of a run. It will resolve when all the members of the run are available.
*/
scheduleBuilder(builderName: string, options?: json.JsonObject, scheduleOptions?: ScheduleOptions): Promise<BuilderRun>;
/**
* Resolve and return options for a specified target. If the target isn't defined in the
* workspace this will reject the promise. This object will be read directly from the workspace
* but not validated against the builder of the target.
* @param target The target to resolve the options of.
* @return A non-validated object resolved from the workspace.
*/
getTargetOptions(target: Target): Promise<json.JsonObject>;
getProjectMetadata(projectName: string): Promise<json.JsonObject>;
getProjectMetadata(target: Target): Promise<json.JsonObject>;
/**
* Resolves and return a builder name. The exact format of the name is up to the host,
* so it should not be parsed to gather information (it's free form). This string can be
* used to validate options or schedule a builder directly.
* @param target The target to resolve the builder name.
*/
getBuilderNameForTarget(target: Target): Promise<string>;
/**
* Validates the options against a builder schema. This uses the same methods as the
* scheduleTarget and scheduleBrowser methods to validate and apply defaults to the options.
* It can be generically typed, if you know which interface it is supposed to validate against.
* @param options A generic option object to validate.
* @param builderName The name of a builder to use. This can be gotten for a target by using the
* getBuilderForTarget() method on the context.
*/
validateOptions<T extends json.JsonObject = json.JsonObject>(options: json.JsonObject, builderName: string): Promise<T>;
/**
* Set the builder to running. This should be used if an external event triggered a re-run,
* e.g. a file watched was changed.
*/
reportRunning(): void;
/**
* Update the status string shown on the interface.
* @param status The status to set it to. An empty string can be used to remove the status.
*/
reportStatus(status: string): void;
/**
* Update the progress for this builder run.
* @param current The current progress. This will be between 0 and total.
* @param total A new total to set. By default at the start of a run this is 1. If omitted it
* will use the same value as the last total.
* @param status Update the status string. If omitted the status string is not modified.
*/
reportProgress(current: number, total?: number, status?: string): void;
/**
* Add teardown logic to this Context, so that when it's being stopped it will execute teardown.
*/
addTeardown(teardown: () => Promise<void> | void): void;
}
/**
* An accepted return value from a builder. Can be either an Observable, a Promise or a vector.
*/
export type BuilderOutputLike = ObservableInput<BuilderOutput> | BuilderOutput;
export declare function isBuilderOutput(obj: any): obj is BuilderOutput;
export declare function fromAsyncIterable<T>(iterable: AsyncIterable<T>): Observable<T>;
/**
* A builder handler function. The function signature passed to `createBuilder()`.
*/
export interface BuilderHandlerFn<A> {
/**
* Builders are defined by users to perform any kind of task, like building, testing or linting,
* and should use this interface.
* @param input The options (a JsonObject), validated by the schema and received by the
* builder. This can include resolved options from the CLI or the workspace.
* @param context A context that can be used to interact with the Architect framework.
* @return One or many builder output.
*/
(input: A, context: BuilderContext): BuilderOutputLike;
}
/**
* A Builder general information. This is generated by the host and is expanded by the host, but
* the public API contains those fields.
*/
export type BuilderInfo = json.JsonObject & {
builderName: string;
description: string;
optionSchema: json.schema.JsonSchema;
};
/**
* Returns a string of "project:target[:configuration]" for the target object.
*/
export declare function targetStringFromTarget({ project, target, configuration }: Target): string;
/**
* Return a Target tuple from a specifier string.
* Supports abbreviated target specifiers (examples: `::`, `::development`, or `:build:production`).
*/
export declare function targetFromTargetString(specifier: string, abbreviatedProjectName?: string, abbreviatedTargetName?: string): Target;
/**
* Schedule a target, and forget about its run. This will return an observable of outputs, that
* as a teardown will stop the target from running. This means that the Run object this returns
* should not be shared.
*
* The reason this is not part of the Context interface is to keep the Context as normal form as
* possible. This is really an utility that people would implement in their project.
*
* @param context The context of your current execution.
* @param target The target to schedule.
* @param overrides Overrides that are used in the target.
* @param scheduleOptions Additional scheduling options.
*/
export declare function scheduleTargetAndForget(context: BuilderContext, target: Target, overrides?: json.JsonObject, scheduleOptions?: ScheduleOptions): Observable<BuilderOutput>;

97
node_modules/@angular-devkit/architect/src/api.js generated vendored Executable file
View File

@@ -0,0 +1,97 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.BuilderProgressState = void 0;
exports.isBuilderOutput = isBuilderOutput;
exports.fromAsyncIterable = fromAsyncIterable;
exports.targetStringFromTarget = targetStringFromTarget;
exports.targetFromTargetString = targetFromTargetString;
exports.scheduleTargetAndForget = scheduleTargetAndForget;
const rxjs_1 = require("rxjs");
const progress_schema_1 = require("./progress-schema");
Object.defineProperty(exports, "BuilderProgressState", { enumerable: true, get: function () { return progress_schema_1.State; } });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isBuilderOutput(obj) {
if (!obj || typeof obj.then === 'function' || typeof obj.subscribe === 'function') {
return false;
}
if (typeof obj[Symbol.asyncIterator] === 'function') {
return false;
}
return typeof obj.success === 'boolean';
}
function fromAsyncIterable(iterable) {
return new rxjs_1.Observable((subscriber) => {
handleAsyncIterator(subscriber, iterable[Symbol.asyncIterator]()).then(() => subscriber.complete(), (error) => subscriber.error(error));
});
}
async function handleAsyncIterator(subscriber, iterator) {
const teardown = new Promise((resolve) => subscriber.add(() => resolve()));
try {
while (!subscriber.closed) {
const result = await Promise.race([teardown, iterator.next()]);
if (!result || result.done) {
break;
}
subscriber.next(result.value);
}
}
finally {
await iterator.return?.();
}
}
/**
* Returns a string of "project:target[:configuration]" for the target object.
*/
function targetStringFromTarget({ project, target, configuration }) {
return `${project}:${target}${configuration !== undefined ? ':' + configuration : ''}`;
}
/**
* Return a Target tuple from a specifier string.
* Supports abbreviated target specifiers (examples: `::`, `::development`, or `:build:production`).
*/
function targetFromTargetString(specifier, abbreviatedProjectName, abbreviatedTargetName) {
const tuple = specifier.split(':', 3);
if (tuple.length < 2) {
throw new Error('Invalid target string: ' + JSON.stringify(specifier));
}
return {
project: tuple[0] || abbreviatedProjectName || '',
target: tuple[1] || abbreviatedTargetName || '',
...(tuple[2] !== undefined && { configuration: tuple[2] }),
};
}
/**
* Schedule a target, and forget about its run. This will return an observable of outputs, that
* as a teardown will stop the target from running. This means that the Run object this returns
* should not be shared.
*
* The reason this is not part of the Context interface is to keep the Context as normal form as
* possible. This is really an utility that people would implement in their project.
*
* @param context The context of your current execution.
* @param target The target to schedule.
* @param overrides Overrides that are used in the target.
* @param scheduleOptions Additional scheduling options.
*/
function scheduleTargetAndForget(context, target, overrides, scheduleOptions) {
let resolve = null;
const promise = new Promise((r) => (resolve = r));
context.addTeardown(() => promise);
return (0, rxjs_1.from)(context.scheduleTarget(target, overrides, scheduleOptions)).pipe((0, rxjs_1.switchMap)((run) => new rxjs_1.Observable((observer) => {
const subscription = run.output.subscribe(observer);
return () => {
subscription.unsubscribe();
// We can properly ignore the floating promise as it's a "reverse" promise; the teardown
// is waiting for the resolve.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
run.stop().then(resolve);
};
})));
}

25
node_modules/@angular-devkit/architect/src/architect.d.ts generated vendored Executable file
View File

@@ -0,0 +1,25 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json, logging } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { BuilderRun, Target } from './api';
import { ArchitectHost } from './internal';
import { JobName, Registry } from './jobs';
export interface ScheduleOptions {
logger?: logging.Logger;
}
export declare class Architect {
private _host;
private readonly _scheduler;
private readonly _jobCache;
private readonly _infoCache;
constructor(_host: ArchitectHost, registry?: json.schema.SchemaRegistry, additionalJobRegistry?: Registry);
has(name: JobName): Observable<boolean>;
scheduleBuilder(name: string, options: json.JsonObject, scheduleOptions?: ScheduleOptions): Promise<BuilderRun>;
scheduleTarget(target: Target, overrides?: json.JsonObject, scheduleOptions?: ScheduleOptions): Promise<BuilderRun>;
}

267
node_modules/@angular-devkit/architect/src/architect.js generated vendored Executable file
View File

@@ -0,0 +1,267 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Architect = void 0;
const core_1 = require("@angular-devkit/core");
const rxjs_1 = require("rxjs");
const api_1 = require("./api");
const jobs_1 = require("./jobs");
const options_1 = require("./options");
const schedule_by_name_1 = require("./schedule-by-name");
function _createJobHandlerFromBuilderInfo(info, target, host, registry, baseOptions) {
const jobDescription = {
name: target ? `{${(0, api_1.targetStringFromTarget)(target)}}` : info.builderName,
argument: true,
input: true,
output: true,
info,
};
function handler(argument, context) {
// Add input validation to the inbound bus.
const inboundBusWithInputValidation = context.inboundBus.pipe((0, rxjs_1.concatMap)(async (message) => {
if (message.kind === jobs_1.JobInboundMessageKind.Input) {
const v = message.value;
const options = (0, options_1.mergeOptions)(baseOptions, v.options);
// Validate v against the options schema.
const validation = await registry.compile(info.optionSchema);
const validationResult = await validation(options);
const { data, success, errors } = validationResult;
if (!success) {
throw new core_1.json.schema.SchemaValidationException(errors);
}
return { ...message, value: { ...v, options: data } };
}
else {
return message;
}
}),
// Using a share replay because the job might be synchronously sending input, but
// asynchronously listening to it.
(0, rxjs_1.shareReplay)(1));
// Make an inboundBus that completes instead of erroring out.
// We'll merge the errors into the output instead.
const inboundBus = (0, rxjs_1.onErrorResumeNext)(inboundBusWithInputValidation);
const output = (0, rxjs_1.from)(host.loadBuilder(info)).pipe((0, rxjs_1.concatMap)((builder) => {
if (builder === null) {
throw new Error(`Cannot load builder for builderInfo ${JSON.stringify(info, null, 2)}`);
}
return builder.handler(argument, { ...context, inboundBus }).pipe((0, rxjs_1.map)((output) => {
if (output.kind === jobs_1.JobOutboundMessageKind.Output) {
// Add target to it.
return {
...output,
value: {
...output.value,
...(target ? { target } : 0),
},
};
}
else {
return output;
}
}));
}),
// Share subscriptions to the output, otherwise the handler will be re-run.
(0, rxjs_1.shareReplay)());
// Separate the errors from the inbound bus into their own observable that completes when the
// builder output does.
const inboundBusErrors = inboundBusWithInputValidation.pipe((0, rxjs_1.ignoreElements)(), (0, rxjs_1.takeUntil)((0, rxjs_1.onErrorResumeNext)(output.pipe((0, rxjs_1.last)()))));
// Return the builder output plus any input errors.
return (0, rxjs_1.merge)(inboundBusErrors, output);
}
return (0, rxjs_1.of)(Object.assign(handler, { jobDescription }));
}
/**
* A JobRegistry that resolves builder targets from the host.
*/
class ArchitectBuilderJobRegistry {
_host;
_registry;
_jobCache;
_infoCache;
constructor(_host, _registry, _jobCache, _infoCache) {
this._host = _host;
this._registry = _registry;
this._jobCache = _jobCache;
this._infoCache = _infoCache;
}
_resolveBuilder(name) {
const cache = this._infoCache;
if (cache) {
const maybeCache = cache.get(name);
if (maybeCache !== undefined) {
return maybeCache;
}
const info = (0, rxjs_1.from)(this._host.resolveBuilder(name)).pipe((0, rxjs_1.shareReplay)(1));
cache.set(name, info);
return info;
}
return (0, rxjs_1.from)(this._host.resolveBuilder(name));
}
_createBuilder(info, target, options) {
const cache = this._jobCache;
if (target) {
const maybeHit = cache && cache.get((0, api_1.targetStringFromTarget)(target));
if (maybeHit) {
return maybeHit;
}
}
else {
const maybeHit = cache && cache.get(info.builderName);
if (maybeHit) {
return maybeHit;
}
}
const result = _createJobHandlerFromBuilderInfo(info, target, this._host, this._registry, options || {});
if (cache) {
if (target) {
cache.set((0, api_1.targetStringFromTarget)(target), result.pipe((0, rxjs_1.shareReplay)(1)));
}
else {
cache.set(info.builderName, result.pipe((0, rxjs_1.shareReplay)(1)));
}
}
return result;
}
get(name) {
const m = name.match(/^([^:]+):([^:]+)$/i);
if (!m) {
return (0, rxjs_1.of)(null);
}
return (0, rxjs_1.from)(this._resolveBuilder(name)).pipe((0, rxjs_1.concatMap)((builderInfo) => (builderInfo ? this._createBuilder(builderInfo) : (0, rxjs_1.of)(null))), (0, rxjs_1.first)(null, null));
}
}
/**
* A JobRegistry that resolves targets from the host.
*/
class ArchitectTargetJobRegistry extends ArchitectBuilderJobRegistry {
get(name) {
const m = name.match(/^{([^:]+):([^:]+)(?::([^:]*))?}$/i);
if (!m) {
return (0, rxjs_1.of)(null);
}
const target = {
project: m[1],
target: m[2],
configuration: m[3],
};
return (0, rxjs_1.from)(Promise.all([
this._host.getBuilderNameForTarget(target),
this._host.getOptionsForTarget(target),
])).pipe((0, rxjs_1.concatMap)(([builderStr, options]) => {
if (builderStr === null || options === null) {
return (0, rxjs_1.of)(null);
}
return this._resolveBuilder(builderStr).pipe((0, rxjs_1.concatMap)((builderInfo) => {
if (builderInfo === null) {
return (0, rxjs_1.of)(null);
}
return this._createBuilder(builderInfo, target, options);
}));
}), (0, rxjs_1.first)(null, null));
}
}
function _getTargetOptionsFactory(host) {
return (0, jobs_1.createJobHandler)((target) => {
return host.getOptionsForTarget(target).then((options) => {
if (options === null) {
throw new Error(`Invalid target: ${JSON.stringify(target)}.`);
}
return options;
});
}, {
name: '..getTargetOptions',
});
}
function _getProjectMetadataFactory(host) {
return (0, jobs_1.createJobHandler)((target) => {
return host.getProjectMetadata(target).then((options) => {
if (options === null) {
throw new Error(`Invalid target: ${JSON.stringify(target)}.`);
}
return options;
});
}, {
name: '..getProjectMetadata',
});
}
function _getBuilderNameForTargetFactory(host) {
return (0, jobs_1.createJobHandler)(async (target) => {
const builderName = await host.getBuilderNameForTarget(target);
if (!builderName) {
throw new Error(`No builder were found for target ${(0, api_1.targetStringFromTarget)(target)}.`);
}
return builderName;
}, {
name: '..getBuilderNameForTarget',
});
}
function _validateOptionsFactory(host, registry) {
return (0, jobs_1.createJobHandler)(async ([builderName, options]) => {
// Get option schema from the host.
const builderInfo = await host.resolveBuilder(builderName);
if (!builderInfo) {
throw new Error(`No builder info were found for builder ${JSON.stringify(builderName)}.`);
}
const validation = await registry.compile(builderInfo.optionSchema);
const { data, success, errors } = await validation(options);
if (!success) {
throw new core_1.json.schema.SchemaValidationException(errors);
}
return data;
}, {
name: '..validateOptions',
});
}
class Architect {
_host;
_scheduler;
_jobCache = new Map();
_infoCache = new Map();
constructor(_host, registry = new core_1.json.schema.CoreSchemaRegistry(), additionalJobRegistry) {
this._host = _host;
const privateArchitectJobRegistry = new jobs_1.SimpleJobRegistry();
// Create private jobs.
privateArchitectJobRegistry.register(_getTargetOptionsFactory(_host));
privateArchitectJobRegistry.register(_getBuilderNameForTargetFactory(_host));
privateArchitectJobRegistry.register(_validateOptionsFactory(_host, registry));
privateArchitectJobRegistry.register(_getProjectMetadataFactory(_host));
const jobRegistry = new jobs_1.FallbackRegistry([
new ArchitectTargetJobRegistry(_host, registry, this._jobCache, this._infoCache),
new ArchitectBuilderJobRegistry(_host, registry, this._jobCache, this._infoCache),
privateArchitectJobRegistry,
...(additionalJobRegistry ? [additionalJobRegistry] : []),
]);
this._scheduler = new jobs_1.SimpleScheduler(jobRegistry, registry);
}
has(name) {
return this._scheduler.has(name);
}
scheduleBuilder(name, options, scheduleOptions = {}) {
// The below will match 'project:target:configuration'
if (!/^[^:]+:[^:]+(:[^:]+)?$/.test(name)) {
throw new Error('Invalid builder name: ' + JSON.stringify(name));
}
return (0, schedule_by_name_1.scheduleByName)(name, options, {
scheduler: this._scheduler,
logger: scheduleOptions.logger || new core_1.logging.NullLogger(),
currentDirectory: this._host.getCurrentDirectory(),
workspaceRoot: this._host.getWorkspaceRoot(),
});
}
scheduleTarget(target, overrides = {}, scheduleOptions = {}) {
return (0, schedule_by_name_1.scheduleByTarget)(target, overrides, {
scheduler: this._scheduler,
logger: scheduleOptions.logger || new core_1.logging.NullLogger(),
currentDirectory: this._host.getCurrentDirectory(),
workspaceRoot: this._host.getWorkspaceRoot(),
});
}
}
exports.Architect = Architect;

View File

@@ -0,0 +1,33 @@
export type Schema = {
/**
* Link to schema.
*/
$schema?: string;
builders: {
[key: string]: BuilderValue;
};
[property: string]: any;
};
export type BuilderValue = Builder | string;
/**
* Target options for Builders.
*/
export type Builder = {
/**
* The builder class module.
*/
class?: string;
/**
* Builder description.
*/
description: string;
/**
* The next generation builder module.
*/
implementation?: string;
/**
* Schema for builder option validation.
*/
schema: string;
[property: string]: any;
};

View File

@@ -0,0 +1,4 @@
"use strict";
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,70 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "BuildersSchema",
"title": "Builders schema for validating a list of builders.",
"type": "object",
"properties": {
"$schema": {
"type": "string",
"description": "Link to schema."
},
"builders": {
"type": "object",
"additionalProperties": {
"oneOf": [
{
"$ref": "#/definitions/builder"
},
{
"type": "string",
"minLength": 1
}
]
}
}
},
"required": ["builders"],
"definitions": {
"builder": {
"type": "object",
"description": "Target options for Builders.",
"allOf": [
{
"properties": {
"schema": {
"type": "string",
"description": "Schema for builder option validation."
},
"description": {
"type": "string",
"description": "Builder description."
}
},
"required": ["schema", "description"]
},
{
"anyOf": [
{
"properties": {
"implementation": {
"type": "string",
"description": "The next generation builder module."
}
},
"required": ["implementation"]
},
{
"properties": {
"class": {
"type": "string",
"description": "The builder class module."
}
},
"required": ["class"]
}
]
}
]
}
}
}

View File

@@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json } from '@angular-devkit/core';
import { BuilderHandlerFn, BuilderOutput } from './api';
import { Builder } from './internal';
export type { Builder };
export declare function createBuilder<OptT = json.JsonObject, OutT extends BuilderOutput = BuilderOutput>(fn: BuilderHandlerFn<OptT>): Builder<OptT & json.JsonObject>;

183
node_modules/@angular-devkit/architect/src/create-builder.js generated vendored Executable file
View File

@@ -0,0 +1,183 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBuilder = createBuilder;
const core_1 = require("@angular-devkit/core");
const rxjs_1 = require("rxjs");
const api_1 = require("./api");
const internal_1 = require("./internal");
const jobs_1 = require("./jobs");
const schedule_by_name_1 = require("./schedule-by-name");
// eslint-disable-next-line max-lines-per-function
function createBuilder(fn) {
const cjh = jobs_1.createJobHandler;
// eslint-disable-next-line max-lines-per-function
const handler = cjh((options, context) => {
const scheduler = context.scheduler;
const progressChannel = context.createChannel('progress');
const logChannel = context.createChannel('log');
const addTeardown = context.addTeardown.bind(context);
let currentState = api_1.BuilderProgressState.Stopped;
let current = 0;
let status = '';
let total = 1;
function log(entry) {
logChannel.next(entry);
}
function progress(progress, context) {
currentState = progress.state;
if (progress.state === api_1.BuilderProgressState.Running) {
current = progress.current;
total = progress.total !== undefined ? progress.total : total;
if (progress.status === undefined) {
progress.status = status;
}
else {
status = progress.status;
}
}
progressChannel.next({
...progress,
...(context.target && { target: context.target }),
...(context.builder && { builder: context.builder }),
id: context.id,
});
}
return new rxjs_1.Observable((observer) => {
const subscriptions = [];
const inputSubscription = context.inboundBus.subscribe((i) => {
switch (i.kind) {
case jobs_1.JobInboundMessageKind.Input:
onInput(i.value);
break;
}
});
function onInput(i) {
const builder = i.info;
const loggerName = i.target
? (0, api_1.targetStringFromTarget)(i.target)
: builder.builderName;
const logger = new core_1.logging.Logger(loggerName);
subscriptions.push(logger.subscribe((entry) => log(entry)));
const context = {
builder,
workspaceRoot: i.workspaceRoot,
currentDirectory: i.currentDirectory,
target: i.target,
logger: logger,
id: i.id,
async scheduleTarget(target, overrides = {}, scheduleOptions = {}) {
const run = await (0, schedule_by_name_1.scheduleByTarget)(target, overrides, {
scheduler,
logger: scheduleOptions.logger || logger.createChild(''),
workspaceRoot: i.workspaceRoot,
currentDirectory: i.currentDirectory,
});
// We don't want to subscribe errors and complete.
subscriptions.push(run.progress.subscribe((event) => progressChannel.next(event)));
return run;
},
async scheduleBuilder(builderName, options = {}, scheduleOptions = {}) {
const run = await (0, schedule_by_name_1.scheduleByName)(builderName, options, {
scheduler,
target: scheduleOptions.target,
logger: scheduleOptions.logger || logger.createChild(''),
workspaceRoot: i.workspaceRoot,
currentDirectory: i.currentDirectory,
});
// We don't want to subscribe errors and complete.
subscriptions.push(run.progress.subscribe((event) => progressChannel.next(event)));
return run;
},
async getTargetOptions(target) {
return (0, rxjs_1.firstValueFrom)(scheduler.schedule('..getTargetOptions', target).output);
},
async getProjectMetadata(target) {
return (0, rxjs_1.firstValueFrom)(scheduler.schedule('..getProjectMetadata', target).output);
},
async getBuilderNameForTarget(target) {
return (0, rxjs_1.firstValueFrom)(scheduler.schedule('..getBuilderNameForTarget', target).output);
},
async validateOptions(options, builderName) {
return (0, rxjs_1.firstValueFrom)(scheduler.schedule('..validateOptions', [builderName, options]).output);
},
reportRunning() {
switch (currentState) {
case api_1.BuilderProgressState.Waiting:
case api_1.BuilderProgressState.Stopped:
progress({ state: api_1.BuilderProgressState.Running, current: 0, total }, context);
break;
}
},
reportStatus(status) {
switch (currentState) {
case api_1.BuilderProgressState.Running:
progress({ state: currentState, status, current, total }, context);
break;
case api_1.BuilderProgressState.Waiting:
progress({ state: currentState, status }, context);
break;
}
},
reportProgress(current, total, status) {
switch (currentState) {
case api_1.BuilderProgressState.Running:
progress({ state: currentState, current, total, status }, context);
}
},
addTeardown,
};
context.reportRunning();
let result;
try {
result = fn(i.options, context);
if ((0, api_1.isBuilderOutput)(result)) {
result = (0, rxjs_1.of)(result);
}
else if (!(0, rxjs_1.isObservable)(result) && isAsyncIterable(result)) {
result = (0, api_1.fromAsyncIterable)(result);
}
else {
result = (0, rxjs_1.from)(result);
}
}
catch (e) {
result = (0, rxjs_1.throwError)(e);
}
// Manage some state automatically.
progress({ state: api_1.BuilderProgressState.Running, current: 0, total: 1 }, context);
subscriptions.push(result
.pipe((0, rxjs_1.defaultIfEmpty)({ success: false }), (0, rxjs_1.tap)(() => {
progress({ state: api_1.BuilderProgressState.Running, current: total }, context);
progress({ state: api_1.BuilderProgressState.Stopped }, context);
}), (0, rxjs_1.mergeMap)(async (value) => {
// Allow the log queue to flush
await new Promise(setImmediate);
return value;
}))
.subscribe((message) => observer.next(message), (error) => observer.error(error), () => observer.complete()));
}
return () => {
subscriptions.forEach((x) => x.unsubscribe());
inputSubscription.unsubscribe();
};
});
});
return {
handler,
[internal_1.BuilderSymbol]: true,
[internal_1.BuilderVersionSymbol]: require('../package.json').version,
// Only needed for type safety around `Builder` types.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
__OptionT: null,
};
}
function isAsyncIterable(obj) {
return !!obj && typeof obj[Symbol.asyncIterator] === 'function';
}

12
node_modules/@angular-devkit/architect/src/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as jobs from './jobs';
export * from './api';
export { Architect, type ScheduleOptions } from './architect';
export { createBuilder, type Builder } from './create-builder';
export { jobs };

53
node_modules/@angular-devkit/architect/src/index.js generated vendored Executable file
View File

@@ -0,0 +1,53 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.jobs = exports.createBuilder = exports.Architect = void 0;
const jobs = __importStar(require("./jobs"));
exports.jobs = jobs;
__exportStar(require("./api"), exports);
var architect_1 = require("./architect");
Object.defineProperty(exports, "Architect", { enumerable: true, get: function () { return architect_1.Architect; } });
var create_builder_1 = require("./create-builder");
Object.defineProperty(exports, "createBuilder", { enumerable: true, get: function () { return create_builder_1.createBuilder; } });

19
node_modules/@angular-devkit/architect/src/input-schema.d.ts generated vendored Executable file
View File

@@ -0,0 +1,19 @@
export type Schema = {
currentDirectory: string;
id: number;
info: {
[key: string]: any;
};
options?: {
[key: string]: any;
};
target?: Target;
workspaceRoot: string;
[property: string]: any;
};
export type Target = {
configuration?: string;
project: string;
target: string;
[property: string]: any;
};

4
node_modules/@angular-devkit/architect/src/input-schema.js generated vendored Executable file
View File

@@ -0,0 +1,4 @@
"use strict";
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
Object.defineProperty(exports, "__esModule", { value: true });

39
node_modules/@angular-devkit/architect/src/input-schema.json generated vendored Executable file
View File

@@ -0,0 +1,39 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "BuilderInputSchema",
"title": "Input schema for builders.",
"type": "object",
"properties": {
"workspaceRoot": {
"type": "string"
},
"currentDirectory": {
"type": "string"
},
"id": {
"type": "number"
},
"target": {
"type": "object",
"properties": {
"project": {
"type": "string"
},
"target": {
"type": "string"
},
"configuration": {
"type": "string"
}
},
"required": ["project", "target"]
},
"info": {
"type": "object"
},
"options": {
"type": "object"
}
},
"required": ["currentDirectory", "id", "info", "workspaceRoot"]
}

68
node_modules/@angular-devkit/architect/src/internal.d.ts generated vendored Executable file
View File

@@ -0,0 +1,68 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json } from '@angular-devkit/core';
import { BuilderInfo, BuilderInput, BuilderOutput, Target } from './api';
import { JobDescription, JobHandler } from './jobs';
/**
* BuilderSymbol used for knowing if a function was created using createBuilder(). This is a
* property set on the function that should be `true`.
* Using Symbol.for() as it's a global registry that's the same for all installations of
* Architect (if some libraries depends directly on architect instead of sharing the files).
*/
export declare const BuilderSymbol: unique symbol;
/**
* BuilderVersionSymbol used for knowing which version of the library createBuilder() came from.
* This is to make sure we don't try to use an incompatible builder.
* Using Symbol.for() as it's a global registry that's the same for all installations of
* Architect (if some libraries depends directly on architect instead of sharing the files).
*/
export declare const BuilderVersionSymbol: unique symbol;
/**
* A Specialization of the JobHandler type. This exposes BuilderDescription as the job description
* type.
*/
export type BuilderJobHandler<A extends json.JsonObject = json.JsonObject, I extends BuilderInput = BuilderInput, O extends BuilderOutput = BuilderOutput> = JobHandler<A, I, O> & {
jobDescription: BuilderDescription;
};
/**
* A Builder description, which is used internally. Adds the builder info which is the
* metadata attached to a builder in Architect.
*/
export interface BuilderDescription extends JobDescription {
info: BuilderInfo;
}
/**
* A Builder instance. Use createBuilder() to create one of these.
*/
export interface Builder<OptionT extends json.JsonObject = json.JsonObject> {
handler: JobHandler<json.JsonObject, BuilderInput, BuilderOutput>;
[BuilderSymbol]: true;
[BuilderVersionSymbol]: string;
__OptionT: OptionT;
}
export interface ArchitectHost<BuilderInfoT extends BuilderInfo = BuilderInfo> {
/**
* Get the builder name for a target.
* @param target The target to inspect.
*/
getBuilderNameForTarget(target: Target): Promise<string | null>;
/**
* Resolve a builder. This needs to return a string which will be used in a dynamic `import()`
* clause. This should throw if no builder can be found. The dynamic import will throw if
* it is unsupported.
* @param builderName The name of the builder to be used.
* @returns All the info needed for the builder itself.
*/
resolveBuilder(builderName: string): Promise<BuilderInfoT | null>;
loadBuilder(info: BuilderInfoT): Promise<Builder | null>;
getCurrentDirectory(): Promise<string>;
getWorkspaceRoot(): Promise<string>;
getOptionsForTarget(target: Target): Promise<json.JsonObject | null>;
getProjectMetadata(projectName: string): Promise<json.JsonObject | null>;
getProjectMetadata(target: Target): Promise<json.JsonObject | null>;
}

26
node_modules/@angular-devkit/architect/src/internal.js generated vendored Executable file
View File

@@ -0,0 +1,26 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.BuilderVersionSymbol = exports.BuilderSymbol = void 0;
// Internal types that should not be exported directly. These are used by the host and architect
// itself. Host implementations should import the host.ts file.
/**
* BuilderSymbol used for knowing if a function was created using createBuilder(). This is a
* property set on the function that should be `true`.
* Using Symbol.for() as it's a global registry that's the same for all installations of
* Architect (if some libraries depends directly on architect instead of sharing the files).
*/
exports.BuilderSymbol = Symbol.for('@angular-devkit/architect:builder');
/**
* BuilderVersionSymbol used for knowing which version of the library createBuilder() came from.
* This is to make sure we don't try to use an incompatible builder.
* Using Symbol.for() as it's a global registry that's the same for all installations of
* Architect (if some libraries depends directly on architect instead of sharing the files).
*/
exports.BuilderVersionSymbol = Symbol.for('@angular-devkit/architect:version');

332
node_modules/@angular-devkit/architect/src/jobs/api.d.ts generated vendored Executable file
View File

@@ -0,0 +1,332 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { JsonObject, JsonValue, schema } from '@angular-devkit/core';
import { Observable, Observer } from 'rxjs';
import { DeepReadonly } from './types';
/**
* A job name is just a string (needs to be serializable).
*/
export type JobName = string;
/**
* The job handler function, which is a method that's executed for the job.
*/
export interface JobHandler<ArgT extends JsonValue, InputT extends JsonValue, OutputT extends JsonValue> {
(argument: ArgT, context: JobHandlerContext<ArgT, InputT, OutputT>): Observable<JobOutboundMessage<OutputT>>;
jobDescription: Partial<JobDescription>;
}
/**
* The context in which the job is run.
*/
export interface JobHandlerContext<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> {
readonly description: JobDescription;
readonly scheduler: Scheduler<JsonValue, JsonValue, JsonValue>;
readonly dependencies: Job<JsonValue, JsonValue, JsonValue>[];
readonly inboundBus: Observable<JobInboundMessage<MinimumInputValueT>>;
}
/**
* Metadata associated with a job.
*/
export interface JobDescription extends JsonObject {
readonly name: JobName;
readonly argument: DeepReadonly<schema.JsonSchema>;
readonly input: DeepReadonly<schema.JsonSchema>;
readonly output: DeepReadonly<schema.JsonSchema>;
}
/**
* Messages that can be sent TO a job. The job needs to listen to those.
*/
export declare enum JobInboundMessageKind {
Ping = "ip",
Stop = "is",
Input = "in"
}
/** Base interface for the all job inbound messages. */
export interface JobInboundMessageBase extends JsonObject {
/**
* The kind of message this is.
*/
readonly kind: JobInboundMessageKind;
}
/**
* A ping to the job. The job should reply with a pong as soon as possible.
*/
export interface JobInboundMessagePing extends JobInboundMessageBase {
readonly kind: JobInboundMessageKind.Ping;
/**
* An ID that should be returned in the corresponding Pong.
*/
readonly id: number;
}
/**
* Stop the job. This is handled by the job itself and jobs might not handle it. It will also
* unsubscribe from the Observable<>.
* This is equivalent to SIGTERM.
*/
export interface JobInboundMessageStop extends JobInboundMessageBase {
readonly kind: JobInboundMessageKind.Stop;
}
/**
* A Job wants to send a message to a channel. This can be marshaled, and the Job object
* has helpers to transform this into an observable. The context also can create RxJS subjects that
* marshall messages through a channel.
*/
export interface JobInboundMessageInput<InputT extends JsonValue> extends JobInboundMessageBase {
readonly kind: JobInboundMessageKind.Input;
/**
* The input being sent to the job.
*/
readonly value: InputT;
}
export type JobInboundMessage<InputT extends JsonValue> = JobInboundMessagePing | JobInboundMessageStop | JobInboundMessageInput<InputT>;
/**
* Kind of messages that can be outputted from a job.
*/
export declare enum JobOutboundMessageKind {
OnReady = "c",
Start = "s",
End = "e",
Pong = "p",
Output = "o",
ChannelCreate = "cn",
ChannelMessage = "cm",
ChannelError = "ce",
ChannelComplete = "cc"
}
/** Base interface for the all job messages. */
export interface JobOutboundMessageBase {
/**
* The job description.
*/
readonly description: JobDescription;
/**
* The kind of message this is.
*/
readonly kind: JobOutboundMessageKind;
}
/**
* The job has been created and will validate its input.
*/
export interface JobOutboundMessageOnReady extends JobOutboundMessageBase {
readonly kind: JobOutboundMessageKind.OnReady;
}
/**
* The job started. This is done by the job itself.
*/
export interface JobOutboundMessageStart extends JobOutboundMessageBase {
readonly kind: JobOutboundMessageKind.Start;
}
/**
* An output value is available.
*/
export interface JobOutboundMessageOutput<OutputT extends JsonValue> extends JobOutboundMessageBase {
readonly kind: JobOutboundMessageKind.Output;
/**
* The message being outputted from the job.
*/
readonly value: OutputT;
}
/**
* Base interface for all job message related to channels.
*/
export interface JobOutboundMessageChannelBase extends JobOutboundMessageBase {
/**
* The name of the channel.
*/
readonly name: string;
}
/**
* A job wants to send a message to a channel. This can be marshaled, and the Job object
* has helpers to transform this into an observable. The context also can create RxJS subjects that
* marshall messages through a channel.
*/
export interface JobOutboundMessageChannelMessage extends JobOutboundMessageChannelBase {
readonly kind: JobOutboundMessageKind.ChannelMessage;
/**
* The message being sent to the channel.
*/
readonly message: JsonValue;
}
/**
* A job wants to send an error to one of its channel. This is the equivalent of throwing through
* an Observable. The side channel will not receive any more messages after this, and will not
* complete.
*/
export interface JobOutboundMessageChannelError extends JobOutboundMessageChannelBase {
readonly kind: JobOutboundMessageKind.ChannelError;
/**
* The error message being sent to the channel.
*/
readonly error: JsonValue;
}
/**
* A job wants to create a new channel.
*/
export interface JobOutboundMessageChannelCreate extends JobOutboundMessageChannelBase {
readonly kind: JobOutboundMessageKind.ChannelCreate;
}
/**
* A job wants to close the channel, as completed. This is done automatically when the job ends,
* or can be done from the job to close it. A closed channel might be reopened, but the user
* need to recall getChannel().
*/
export interface JobOutboundMessageChannelComplete extends JobOutboundMessageChannelBase {
readonly kind: JobOutboundMessageKind.ChannelComplete;
}
/**
* OnEnd of the job run.
*/
export interface JobOutboundMessageEnd extends JobOutboundMessageBase {
readonly kind: JobOutboundMessageKind.End;
}
/**
* A pong response from a ping input. The id is the same as the one passed in.
*/
export interface JobOutboundMessagePong extends JobOutboundMessageBase {
readonly kind: JobOutboundMessageKind.Pong;
/**
* The ID that was passed in the `Ping` messages.
*/
readonly id: number;
}
/**
* Generic message type.
*/
export type JobOutboundMessage<OutputT extends JsonValue> = JobOutboundMessageOnReady | JobOutboundMessageStart | JobOutboundMessageOutput<OutputT> | JobOutboundMessageChannelCreate | JobOutboundMessageChannelMessage | JobOutboundMessageChannelError | JobOutboundMessageChannelComplete | JobOutboundMessageEnd | JobOutboundMessagePong;
/**
* The state of a job. These are changed as the job reports a new state through its messages.
*/
export declare enum JobState {
/**
* The job was queued and is waiting to start.
*/
Queued = "queued",
/**
* The job description was found, its dependencies (see "Synchronizing and Dependencies")
* are done running, and the job's argument is validated and the job's code will be executed.
*/
Ready = "ready",
/**
* The job has been started. The job implementation is expected to send this as soon as its
* work is starting.
*/
Started = "started",
/**
* The job has ended and is done running.
*/
Ended = "ended",
/**
* An error occured and the job stopped because of internal state.
*/
Errored = "errored"
}
/**
* A Job instance, returned from scheduling a job. A Job instance is _not_ serializable.
*/
export interface Job<ArgumentT extends JsonValue = JsonValue, InputT extends JsonValue = JsonValue, OutputT extends JsonValue = JsonValue> {
/**
* Description of the job. Resolving the job's description can be done asynchronously, so this
* is an observable that will resolve when it's ready.
*/
readonly description: Observable<JobDescription>;
/**
* Argument sent when scheduling the job. This is a copy of the argument.
*/
readonly argument: ArgumentT;
/**
* The input to the job. This goes through the input channel as messages.
*/
readonly input: Observer<InputT>;
/**
* Outputs of this job.
*/
readonly output: Observable<OutputT>;
/**
* The current state of the job.
*/
readonly state: JobState;
/**
* Get a channel that validates against the schema. Messages will be filtered by the schema.
* @param name The name of the channel.
* @param schema A schema to use to validate messages.
*/
getChannel<T extends JsonValue>(name: string, schema?: schema.JsonSchema): Observable<T>;
/**
* Pings the job and wait for the resulting Pong before completing.
*/
ping(): Observable<never>;
/**
* Stops the job from running. This is different than unsubscribing from the output as in it
* sends the JobInboundMessageKind.Stop raw input to the job.
*/
stop(): void;
/**
* The JobInboundMessage messages TO the job.
*/
readonly inboundBus: Observer<JobInboundMessage<InputT>>;
/**
* The JobOutboundMessage FROM the job.
*/
readonly outboundBus: Observable<JobOutboundMessage<OutputT>>;
}
/**
* Options for scheduling jobs.
*/
export interface ScheduleJobOptions {
/**
* Jobs that need to finish before scheduling this job. These dependencies will be passed
* to the job itself in its context.
*/
dependencies?: Job | Job[];
}
export interface Registry<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> {
/**
* Get a job handler.
* @param name The name of the job to get a handler from.
*/
get<A extends MinimumArgumentValueT, I extends MinimumInputValueT, O extends MinimumOutputValueT>(name: JobName): Observable<JobHandler<A, I, O> | null>;
}
/**
* An interface that can schedule jobs.
*/
export interface Scheduler<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> {
/**
* Get a job description for a named job.
*
* @param name The name of the job.
* @returns A description, or null if no description is available for this job.
*/
getDescription(name: JobName): Observable<JobDescription | null>;
/**
* Returns true if the job name has been registered.
* @param name The name of the job.
* @returns True if the job exists, false otherwise.
*/
has(name: JobName): Observable<boolean>;
/**
* Pause the scheduler, temporary queueing _new_ jobs. Returns a resume function that should be
* used to resume execution. If multiple `pause()` were called, all their resume functions must
* be called before the Scheduler actually starts new jobs. Additional calls to the same resume
* function will have no effect.
*
* Jobs already running are NOT paused. This is pausing the scheduler only.
*
* @returns A function that can be run to resume the scheduler. If multiple `pause()` calls
* were made, all their return function must be called (in any order) before the
* scheduler can resume.
*/
pause(): () => void;
/**
* Schedule a job to be run, using its name.
* @param name The name of job to be run.
* @param argument The argument to send to the job when starting it.
* @param options Scheduling options.
* @returns The job being run.
*/
schedule<A extends MinimumArgumentValueT, I extends MinimumInputValueT, O extends MinimumOutputValueT>(name: JobName, argument: A, options?: ScheduleJobOptions): Job<A, I, O>;
}
export declare function isJobHandler<A extends JsonValue, I extends JsonValue, O extends JsonValue>(value: unknown): value is JobHandler<A, I, O>;

73
node_modules/@angular-devkit/architect/src/jobs/api.js generated vendored Executable file
View File

@@ -0,0 +1,73 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.JobState = exports.JobOutboundMessageKind = exports.JobInboundMessageKind = void 0;
exports.isJobHandler = isJobHandler;
/**
* Messages that can be sent TO a job. The job needs to listen to those.
*/
var JobInboundMessageKind;
(function (JobInboundMessageKind) {
JobInboundMessageKind["Ping"] = "ip";
JobInboundMessageKind["Stop"] = "is";
// Channel specific messages.
JobInboundMessageKind["Input"] = "in";
// Input channel does not allow completion / error. Erroring this will just close the Subject
// but not notify the job.
})(JobInboundMessageKind || (exports.JobInboundMessageKind = JobInboundMessageKind = {}));
/**
* Kind of messages that can be outputted from a job.
*/
var JobOutboundMessageKind;
(function (JobOutboundMessageKind) {
// Lifecycle specific messages.
JobOutboundMessageKind["OnReady"] = "c";
JobOutboundMessageKind["Start"] = "s";
JobOutboundMessageKind["End"] = "e";
JobOutboundMessageKind["Pong"] = "p";
// Feedback messages.
JobOutboundMessageKind["Output"] = "o";
// Channel specific messages.
JobOutboundMessageKind["ChannelCreate"] = "cn";
JobOutboundMessageKind["ChannelMessage"] = "cm";
JobOutboundMessageKind["ChannelError"] = "ce";
JobOutboundMessageKind["ChannelComplete"] = "cc";
})(JobOutboundMessageKind || (exports.JobOutboundMessageKind = JobOutboundMessageKind = {}));
/**
* The state of a job. These are changed as the job reports a new state through its messages.
*/
var JobState;
(function (JobState) {
/**
* The job was queued and is waiting to start.
*/
JobState["Queued"] = "queued";
/**
* The job description was found, its dependencies (see "Synchronizing and Dependencies")
* are done running, and the job's argument is validated and the job's code will be executed.
*/
JobState["Ready"] = "ready";
/**
* The job has been started. The job implementation is expected to send this as soon as its
* work is starting.
*/
JobState["Started"] = "started";
/**
* The job has ended and is done running.
*/
JobState["Ended"] = "ended";
/**
* An error occured and the job stopped because of internal state.
*/
JobState["Errored"] = "errored";
})(JobState || (exports.JobState = JobState = {}));
function isJobHandler(value) {
const job = value;
return (typeof job == 'function' && typeof job.jobDescription == 'object' && job.jobDescription !== null);
}

View File

@@ -0,0 +1,47 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { BaseException, JsonValue, logging } from '@angular-devkit/core';
import { Observable, Observer } from 'rxjs';
import { JobDescription, JobHandler, JobHandlerContext } from './api';
export declare class ChannelAlreadyExistException extends BaseException {
constructor(name: string);
}
/**
* Interface for the JobHandler context that is used when using `createJobHandler()`. It extends
* the basic `JobHandlerContext` with additional functionality.
*/
export interface SimpleJobHandlerContext<A extends JsonValue, I extends JsonValue, O extends JsonValue> extends JobHandlerContext<A, I, O> {
createChannel: (name: string) => Observer<JsonValue>;
input: Observable<I>;
addTeardown(teardown: () => Promise<void> | void): void;
}
/**
* A simple version of the JobHandler. This simplifies a lot of the interaction with the job
* scheduler and registry. For example, instead of returning a JobOutboundMessage observable, you
* can directly return an output.
*/
export type SimpleJobHandlerFn<A extends JsonValue, I extends JsonValue, O extends JsonValue> = (input: A, context: SimpleJobHandlerContext<A, I, O>) => O | Promise<O> | Observable<O>;
/**
* Make a simple job handler that sets start and end from a function that's synchronous.
*
* @param fn The function to create a handler for.
* @param options An optional set of properties to set on the handler. Some fields might be
* required by registry or schedulers.
*/
export declare function createJobHandler<A extends JsonValue, I extends JsonValue, O extends JsonValue>(fn: SimpleJobHandlerFn<A, I, O>, options?: Partial<JobDescription>): JobHandler<A, I, O>;
/**
* Lazily create a job using a function.
* @param loader A factory function that returns a promise/observable of a JobHandler.
* @param options Same options as createJob.
*/
export declare function createJobFactory<A extends JsonValue, I extends JsonValue, O extends JsonValue>(loader: () => Promise<JobHandler<A, I, O>>, options?: Partial<JobDescription>): JobHandler<A, I, O>;
/**
* Creates a job that logs out input/output messages of another Job. The messages are still
* propagated to the other job.
*/
export declare function createLoggerJob<A extends JsonValue, I extends JsonValue, O extends JsonValue>(job: JobHandler<A, I, O>, logger: logging.LoggerApi): JobHandler<A, I, O>;

View File

@@ -0,0 +1,145 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChannelAlreadyExistException = void 0;
exports.createJobHandler = createJobHandler;
exports.createJobFactory = createJobFactory;
exports.createLoggerJob = createLoggerJob;
const core_1 = require("@angular-devkit/core");
const rxjs_1 = require("rxjs");
const api_1 = require("./api");
class ChannelAlreadyExistException extends core_1.BaseException {
constructor(name) {
super(`Channel ${JSON.stringify(name)} already exist.`);
}
}
exports.ChannelAlreadyExistException = ChannelAlreadyExistException;
/**
* Make a simple job handler that sets start and end from a function that's synchronous.
*
* @param fn The function to create a handler for.
* @param options An optional set of properties to set on the handler. Some fields might be
* required by registry or schedulers.
*/
function createJobHandler(fn, options = {}) {
const handler = (argument, context) => {
const description = context.description;
const inboundBus = context.inboundBus;
const inputChannel = new rxjs_1.Subject();
let subscription;
const teardownLogics = [];
let tearingDown = false;
return new rxjs_1.Observable((subject) => {
function complete() {
if (subscription) {
subscription.unsubscribe();
}
subject.next({ kind: api_1.JobOutboundMessageKind.End, description });
subject.complete();
inputChannel.complete();
}
// Handle input.
const inboundSub = inboundBus.subscribe((message) => {
switch (message.kind) {
case api_1.JobInboundMessageKind.Ping:
subject.next({ kind: api_1.JobOutboundMessageKind.Pong, description, id: message.id });
break;
case api_1.JobInboundMessageKind.Stop:
// Run teardown logic then complete.
tearingDown = true;
if (teardownLogics.length) {
Promise.all(teardownLogics.map((fn) => fn())).then(() => complete(), () => complete());
}
else {
complete();
}
break;
case api_1.JobInboundMessageKind.Input:
if (!tearingDown) {
inputChannel.next(message.value);
}
break;
}
});
// Execute the function with the additional context.
const channels = new Map();
const newContext = {
...context,
input: inputChannel.asObservable(),
addTeardown(teardown) {
teardownLogics.push(teardown);
},
createChannel(name) {
if (channels.has(name)) {
throw new ChannelAlreadyExistException(name);
}
const channelSubject = new rxjs_1.Subject();
const channelSub = channelSubject.subscribe((message) => {
subject.next({
kind: api_1.JobOutboundMessageKind.ChannelMessage,
description,
name,
message,
});
}, (error) => {
subject.next({ kind: api_1.JobOutboundMessageKind.ChannelError, description, name, error });
// This can be reopened.
channels.delete(name);
}, () => {
subject.next({ kind: api_1.JobOutboundMessageKind.ChannelComplete, description, name });
// This can be reopened.
channels.delete(name);
});
channels.set(name, channelSubject);
if (subscription) {
subscription.add(channelSub);
}
return channelSubject;
},
};
subject.next({ kind: api_1.JobOutboundMessageKind.Start, description });
let result = fn(argument, newContext);
// If the result is a promise, simply wait for it to complete before reporting the result.
if ((0, core_1.isPromise)(result)) {
result = (0, rxjs_1.from)(result);
}
else if (!(0, rxjs_1.isObservable)(result)) {
result = (0, rxjs_1.of)(result);
}
subscription = result.subscribe((value) => subject.next({ kind: api_1.JobOutboundMessageKind.Output, description, value }), (error) => subject.error(error), () => complete());
subscription.add(inboundSub);
return subscription;
});
};
return Object.assign(handler, { jobDescription: options });
}
/**
* Lazily create a job using a function.
* @param loader A factory function that returns a promise/observable of a JobHandler.
* @param options Same options as createJob.
*/
function createJobFactory(loader, options = {}) {
const handler = (argument, context) => {
return (0, rxjs_1.from)(loader()).pipe((0, rxjs_1.switchMap)((fn) => fn(argument, context)));
};
return Object.assign(handler, { jobDescription: options });
}
/**
* Creates a job that logs out input/output messages of another Job. The messages are still
* propagated to the other job.
*/
function createLoggerJob(job, logger) {
const handler = (argument, context) => {
context.inboundBus
.pipe((0, rxjs_1.tap)((message) => logger.info(`Input: ${JSON.stringify(message)}`)))
.subscribe();
return job(argument, context).pipe((0, rxjs_1.tap)((message) => logger.info(`Message: ${JSON.stringify(message)}`), (error) => logger.warn(`Error: ${JSON.stringify(error)}`), () => logger.info(`Completed`)));
};
return Object.assign(handler, job);
}

View File

@@ -0,0 +1,31 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { JsonValue } from '@angular-devkit/core';
import { JobDescription, JobHandler, JobName } from './api';
import { Readwrite } from './types';
/**
* A JobDispatcher can be used to dispatch between multiple jobs.
*/
export interface JobDispatcher<A extends JsonValue, I extends JsonValue, O extends JsonValue> extends JobHandler<A, I, O> {
/**
* Set the default job if all conditionals failed.
* @param name The default name if all conditions are false.
*/
setDefaultJob(name: JobName | null | JobHandler<JsonValue, JsonValue, JsonValue>): void;
/**
* Add a conditional job that will be selected if the input fits a predicate.
* @param predicate
* @param name
*/
addConditionalJob(predicate: (args: A) => boolean, name: string): void;
}
/**
* OnReady a dispatcher that can dispatch to a sub job, depending on conditions.
* @param options
*/
export declare function createDispatcher<A extends JsonValue, I extends JsonValue, O extends JsonValue>(options?: Partial<Readwrite<JobDescription>>): JobDispatcher<A, I, O>;

View File

@@ -0,0 +1,49 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createDispatcher = createDispatcher;
const api_1 = require("./api");
const exception_1 = require("./exception");
/**
* OnReady a dispatcher that can dispatch to a sub job, depending on conditions.
* @param options
*/
function createDispatcher(options = {}) {
let defaultDelegate = null;
const conditionalDelegateList = [];
const job = Object.assign((argument, context) => {
const maybeDelegate = conditionalDelegateList.find(([predicate]) => predicate(argument));
let delegate = null;
if (maybeDelegate) {
delegate = context.scheduler.schedule(maybeDelegate[1], argument);
}
else if (defaultDelegate) {
delegate = context.scheduler.schedule(defaultDelegate, argument);
}
else {
throw new exception_1.JobDoesNotExistException('<null>');
}
context.inboundBus.subscribe(delegate.inboundBus);
return delegate.outboundBus;
}, {
jobDescription: options,
});
return Object.assign(job, {
setDefaultJob(name) {
if ((0, api_1.isJobHandler)(name)) {
name = name.jobDescription.name === undefined ? null : name.jobDescription.name;
}
defaultDelegate = name;
},
addConditionalJob(predicate, name) {
conditionalDelegateList.push([predicate, name]);
},
// TODO: Remove return-only generic from createDispatcher() API.
});
}

View File

@@ -0,0 +1,15 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { BaseException } from '@angular-devkit/core';
import { JobName } from './api';
export declare class JobNameAlreadyRegisteredException extends BaseException {
constructor(name: JobName);
}
export declare class JobDoesNotExistException extends BaseException {
constructor(name: JobName);
}

23
node_modules/@angular-devkit/architect/src/jobs/exception.js generated vendored Executable file
View File

@@ -0,0 +1,23 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.JobDoesNotExistException = exports.JobNameAlreadyRegisteredException = void 0;
const core_1 = require("@angular-devkit/core");
class JobNameAlreadyRegisteredException extends core_1.BaseException {
constructor(name) {
super(`Job named ${JSON.stringify(name)} already exists.`);
}
}
exports.JobNameAlreadyRegisteredException = JobNameAlreadyRegisteredException;
class JobDoesNotExistException extends core_1.BaseException {
constructor(name) {
super(`Job name ${JSON.stringify(name)} does not exist.`);
}
}
exports.JobDoesNotExistException = JobDoesNotExistException;

View File

@@ -0,0 +1,19 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { JsonValue } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { JobHandler, JobName, Registry } from './api';
/**
* A simple job registry that keep a map of JobName => JobHandler internally.
*/
export declare class FallbackRegistry<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> implements Registry<MinimumArgumentValueT, MinimumInputValueT, MinimumOutputValueT> {
protected _fallbacks: Registry<MinimumArgumentValueT, MinimumInputValueT, MinimumOutputValueT>[];
constructor(_fallbacks?: Registry<MinimumArgumentValueT, MinimumInputValueT, MinimumOutputValueT>[]);
addFallback(registry: Registry): void;
get<A extends MinimumArgumentValueT = MinimumArgumentValueT, I extends MinimumInputValueT = MinimumInputValueT, O extends MinimumOutputValueT = MinimumOutputValueT>(name: JobName): Observable<JobHandler<A, I, O> | null>;
}

View File

@@ -0,0 +1,27 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FallbackRegistry = void 0;
const rxjs_1 = require("rxjs");
/**
* A simple job registry that keep a map of JobName => JobHandler internally.
*/
class FallbackRegistry {
_fallbacks;
constructor(_fallbacks = []) {
this._fallbacks = _fallbacks;
}
addFallback(registry) {
this._fallbacks.push(registry);
}
get(name) {
return (0, rxjs_1.from)(this._fallbacks).pipe((0, rxjs_1.concatMap)((fb) => fb.get(name)), (0, rxjs_1.first)((x) => x !== null, null));
}
}
exports.FallbackRegistry = FallbackRegistry;

16
node_modules/@angular-devkit/architect/src/jobs/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,16 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import * as strategy from './strategy';
export * from './api';
export * from './create-job-handler';
export * from './exception';
export * from './dispatcher';
export * from './fallback-registry';
export * from './simple-registry';
export * from './simple-scheduler';
export { strategy };

55
node_modules/@angular-devkit/architect/src/jobs/index.js generated vendored Executable file
View File

@@ -0,0 +1,55 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.strategy = void 0;
const strategy = __importStar(require("./strategy"));
exports.strategy = strategy;
__exportStar(require("./api"), exports);
__exportStar(require("./create-job-handler"), exports);
__exportStar(require("./exception"), exports);
__exportStar(require("./dispatcher"), exports);
__exportStar(require("./fallback-registry"), exports);
__exportStar(require("./simple-registry"), exports);
__exportStar(require("./simple-scheduler"), exports);

View File

@@ -0,0 +1,44 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { JsonValue } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { JobDescription, JobHandler, JobName, Registry } from './api';
/**
* SimpleJobRegistry job registration options.
*/
export interface RegisterJobOptions extends Partial<JobDescription> {
}
/**
* A simple job registry that keep a map of JobName => JobHandler internally.
*/
export declare class SimpleJobRegistry<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> implements Registry<MinimumArgumentValueT, MinimumInputValueT, MinimumOutputValueT> {
private _jobNames;
get<A extends MinimumArgumentValueT = MinimumArgumentValueT, I extends MinimumInputValueT = MinimumInputValueT, O extends MinimumOutputValueT = MinimumOutputValueT>(name: JobName): Observable<JobHandler<A, I, O> | null>;
/**
* Register a job handler. The name must be unique.
*
* @param name The name of the job.
* @param handler The function that will be called for the job.
* @param options An optional list of options to override the handler. {@see RegisterJobOptions}
*/
register<A extends MinimumArgumentValueT, I extends MinimumInputValueT, O extends MinimumOutputValueT>(name: JobName, handler: JobHandler<A, I, O>, options?: RegisterJobOptions): void;
/**
* Register a job handler. The name must be unique.
*
* @param handler The function that will be called for the job.
* @param options An optional list of options to override the handler. {@see RegisterJobOptions}
*/
register<ArgumentT extends JsonValue, InputT extends JsonValue, OutputT extends JsonValue>(handler: JobHandler<ArgumentT, InputT, OutputT>, options?: RegisterJobOptions & {
name: string;
}): void;
protected _register<ArgumentT extends JsonValue, InputT extends JsonValue, OutputT extends JsonValue>(name: JobName, handler: JobHandler<ArgumentT, InputT, OutputT>, options: RegisterJobOptions): void;
/**
* Returns the job names of all jobs.
*/
getJobNames(): JobName[];
}

View File

@@ -0,0 +1,75 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleJobRegistry = void 0;
const core_1 = require("@angular-devkit/core");
const rxjs_1 = require("rxjs");
const api_1 = require("./api");
const exception_1 = require("./exception");
/**
* A simple job registry that keep a map of JobName => JobHandler internally.
*/
class SimpleJobRegistry {
_jobNames = new Map();
get(name) {
return (0, rxjs_1.of)(this._jobNames.get(name) || null);
}
register(nameOrHandler, handlerOrOptions = {}, options = {}) {
// Switch on the arguments.
if (typeof nameOrHandler == 'string') {
if (!(0, api_1.isJobHandler)(handlerOrOptions)) {
// This is an error.
throw new TypeError('Expected a JobHandler as second argument.');
}
this._register(nameOrHandler, handlerOrOptions, options);
}
else if ((0, api_1.isJobHandler)(nameOrHandler)) {
if (typeof handlerOrOptions !== 'object') {
// This is an error.
throw new TypeError('Expected an object options as second argument.');
}
const name = options.name || nameOrHandler.jobDescription.name || handlerOrOptions.name;
if (name === undefined) {
throw new TypeError('Expected name to be a string.');
}
this._register(name, nameOrHandler, options);
}
else {
throw new TypeError('Unrecognized arguments.');
}
}
_register(name, handler, options) {
if (this._jobNames.has(name)) {
// We shouldn't allow conflicts.
throw new exception_1.JobNameAlreadyRegisteredException(name);
}
// Merge all fields with the ones in the handler (to make sure we respect the handler).
const argument = core_1.schema.mergeSchemas(handler.jobDescription.argument, options.argument);
const input = core_1.schema.mergeSchemas(handler.jobDescription.input, options.input);
const output = core_1.schema.mergeSchemas(handler.jobDescription.output, options.output);
// Create the job description.
const jobDescription = {
name,
argument,
output,
input,
};
const jobHandler = Object.assign(handler.bind(undefined), {
jobDescription,
});
this._jobNames.set(name, jobHandler);
}
/**
* Returns the job names of all jobs.
*/
getJobNames() {
return [...this._jobNames.keys()];
}
}
exports.SimpleJobRegistry = SimpleJobRegistry;

View File

@@ -0,0 +1,77 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { JsonValue, schema } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { Job, JobDescription, JobName, Registry, ScheduleJobOptions, Scheduler } from './api';
export declare class JobArgumentSchemaValidationError extends schema.SchemaValidationException {
constructor(errors?: schema.SchemaValidatorError[]);
}
export declare class JobInboundMessageSchemaValidationError extends schema.SchemaValidationException {
constructor(errors?: schema.SchemaValidatorError[]);
}
export declare class JobOutputSchemaValidationError extends schema.SchemaValidationException {
constructor(errors?: schema.SchemaValidatorError[]);
}
/**
* Simple scheduler. Should be the base of all registries and schedulers.
*/
export declare class SimpleScheduler<MinimumArgumentT extends JsonValue = JsonValue, MinimumInputT extends JsonValue = JsonValue, MinimumOutputT extends JsonValue = JsonValue> implements Scheduler<MinimumArgumentT, MinimumInputT, MinimumOutputT> {
protected _jobRegistry: Registry<MinimumArgumentT, MinimumInputT, MinimumOutputT>;
protected _schemaRegistry: schema.SchemaRegistry;
private _internalJobDescriptionMap;
private _queue;
private _pauseCounter;
constructor(_jobRegistry: Registry<MinimumArgumentT, MinimumInputT, MinimumOutputT>, _schemaRegistry?: schema.SchemaRegistry);
private _getInternalDescription;
/**
* Get a job description for a named job.
*
* @param name The name of the job.
* @returns A description, or null if the job is not registered.
*/
getDescription(name: JobName): Observable<JobDescription | null>;
/**
* Returns true if the job name has been registered.
* @param name The name of the job.
* @returns True if the job exists, false otherwise.
*/
has(name: JobName): Observable<boolean>;
/**
* Pause the scheduler, temporary queueing _new_ jobs. Returns a resume function that should be
* used to resume execution. If multiple `pause()` were called, all their resume functions must
* be called before the Scheduler actually starts new jobs. Additional calls to the same resume
* function will have no effect.
*
* Jobs already running are NOT paused. This is pausing the scheduler only.
*/
pause(): () => void;
/**
* Schedule a job to be run, using its name.
* @param name The name of job to be run.
* @param argument The argument to send to the job when starting it.
* @param options Scheduling options.
* @returns The Job being run.
*/
schedule<A extends MinimumArgumentT, I extends MinimumInputT, O extends MinimumOutputT>(name: JobName, argument: A, options?: ScheduleJobOptions): Job<A, I, O>;
/**
* Filter messages.
* @private
*/
private _filterJobOutboundMessages;
/**
* Return a new state. This is just to simplify the reading of the _createJob method.
* @private
*/
private _updateState;
/**
* Create the job.
* @private
*/
private _createJob;
protected _scheduleJob<A extends MinimumArgumentT, I extends MinimumInputT, O extends MinimumOutputT>(name: JobName, argument: A, options: ScheduleJobOptions, waitable: Observable<never>): Job<A, I, O>;
}

View File

@@ -0,0 +1,394 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleScheduler = exports.JobOutputSchemaValidationError = exports.JobInboundMessageSchemaValidationError = exports.JobArgumentSchemaValidationError = void 0;
const core_1 = require("@angular-devkit/core");
const rxjs_1 = require("rxjs");
const api_1 = require("./api");
const exception_1 = require("./exception");
class JobArgumentSchemaValidationError extends core_1.schema.SchemaValidationException {
constructor(errors) {
super(errors, 'Job Argument failed to validate. Errors: ');
}
}
exports.JobArgumentSchemaValidationError = JobArgumentSchemaValidationError;
class JobInboundMessageSchemaValidationError extends core_1.schema.SchemaValidationException {
constructor(errors) {
super(errors, 'Job Inbound Message failed to validate. Errors: ');
}
}
exports.JobInboundMessageSchemaValidationError = JobInboundMessageSchemaValidationError;
class JobOutputSchemaValidationError extends core_1.schema.SchemaValidationException {
constructor(errors) {
super(errors, 'Job Output failed to validate. Errors: ');
}
}
exports.JobOutputSchemaValidationError = JobOutputSchemaValidationError;
function _jobShare() {
// This is the same code as a `shareReplay()` operator, but uses a dumber Subject rather than a
// ReplaySubject.
return (source) => {
let refCount = 0;
let subject;
let hasError = false;
let isComplete = false;
let subscription;
return new rxjs_1.Observable((subscriber) => {
let innerSub;
refCount++;
if (!subject) {
subject = new rxjs_1.Subject();
innerSub = subject.subscribe(subscriber);
subscription = source.subscribe({
next(value) {
subject.next(value);
},
error(err) {
hasError = true;
subject.error(err);
},
complete() {
isComplete = true;
subject.complete();
},
});
}
else {
innerSub = subject.subscribe(subscriber);
}
return () => {
refCount--;
innerSub.unsubscribe();
if (subscription && refCount === 0 && (isComplete || hasError)) {
subscription.unsubscribe();
}
};
});
};
}
/**
* Simple scheduler. Should be the base of all registries and schedulers.
*/
class SimpleScheduler {
_jobRegistry;
_schemaRegistry;
_internalJobDescriptionMap = new Map();
_queue = [];
_pauseCounter = 0;
constructor(_jobRegistry, _schemaRegistry = new core_1.schema.CoreSchemaRegistry()) {
this._jobRegistry = _jobRegistry;
this._schemaRegistry = _schemaRegistry;
}
_getInternalDescription(name) {
const maybeHandler = this._internalJobDescriptionMap.get(name);
if (maybeHandler !== undefined) {
return (0, rxjs_1.of)(maybeHandler);
}
const handler = this._jobRegistry.get(name);
return handler.pipe((0, rxjs_1.switchMap)((handler) => {
if (handler === null) {
return (0, rxjs_1.of)(null);
}
const description = {
// Make a copy of it to be sure it's proper JSON.
...JSON.parse(JSON.stringify(handler.jobDescription)),
name: handler.jobDescription.name || name,
argument: handler.jobDescription.argument || true,
input: handler.jobDescription.input || true,
output: handler.jobDescription.output || true,
channels: handler.jobDescription.channels || {},
};
const noopValidator = noopSchemaValidator();
const handlerWithExtra = Object.assign(handler.bind(undefined), {
jobDescription: description,
argumentV: description.argument === true
? noopValidator
: this._schemaRegistry.compile(description.argument),
inputV: description.input === true
? noopValidator
: this._schemaRegistry.compile(description.input),
outputV: description.output === true
? noopValidator
: this._schemaRegistry.compile(description.output),
});
this._internalJobDescriptionMap.set(name, handlerWithExtra);
return (0, rxjs_1.of)(handlerWithExtra);
}));
}
/**
* Get a job description for a named job.
*
* @param name The name of the job.
* @returns A description, or null if the job is not registered.
*/
getDescription(name) {
return (0, rxjs_1.concat)(this._getInternalDescription(name).pipe((0, rxjs_1.map)((x) => x && x.jobDescription)), (0, rxjs_1.of)(null)).pipe((0, rxjs_1.first)());
}
/**
* Returns true if the job name has been registered.
* @param name The name of the job.
* @returns True if the job exists, false otherwise.
*/
has(name) {
return this.getDescription(name).pipe((0, rxjs_1.map)((x) => x !== null));
}
/**
* Pause the scheduler, temporary queueing _new_ jobs. Returns a resume function that should be
* used to resume execution. If multiple `pause()` were called, all their resume functions must
* be called before the Scheduler actually starts new jobs. Additional calls to the same resume
* function will have no effect.
*
* Jobs already running are NOT paused. This is pausing the scheduler only.
*/
pause() {
let called = false;
this._pauseCounter++;
return () => {
if (!called) {
called = true;
if (--this._pauseCounter == 0) {
// Resume the queue.
const q = this._queue;
this._queue = [];
q.forEach((fn) => fn());
}
}
};
}
/**
* Schedule a job to be run, using its name.
* @param name The name of job to be run.
* @param argument The argument to send to the job when starting it.
* @param options Scheduling options.
* @returns The Job being run.
*/
schedule(name, argument, options) {
if (this._pauseCounter > 0) {
const waitable = new rxjs_1.Subject();
this._queue.push(() => waitable.complete());
return this._scheduleJob(name, argument, options || {}, waitable);
}
return this._scheduleJob(name, argument, options || {}, rxjs_1.EMPTY);
}
/**
* Filter messages.
* @private
*/
_filterJobOutboundMessages(message, state) {
switch (message.kind) {
case api_1.JobOutboundMessageKind.OnReady:
return state == api_1.JobState.Queued;
case api_1.JobOutboundMessageKind.Start:
return state == api_1.JobState.Ready;
case api_1.JobOutboundMessageKind.End:
return state == api_1.JobState.Started || state == api_1.JobState.Ready;
}
return true;
}
/**
* Return a new state. This is just to simplify the reading of the _createJob method.
* @private
*/
_updateState(message, state) {
switch (message.kind) {
case api_1.JobOutboundMessageKind.OnReady:
return api_1.JobState.Ready;
case api_1.JobOutboundMessageKind.Start:
return api_1.JobState.Started;
case api_1.JobOutboundMessageKind.End:
return api_1.JobState.Ended;
}
return state;
}
/**
* Create the job.
* @private
*/
// eslint-disable-next-line max-lines-per-function
_createJob(name, argument, handler, inboundBus, outboundBus) {
const schemaRegistry = this._schemaRegistry;
const channelsSubject = new Map();
const channels = new Map();
let state = api_1.JobState.Queued;
let pingId = 0;
// Create the input channel by having a filter.
const input = new rxjs_1.Subject();
input
.pipe((0, rxjs_1.concatMap)((message) => handler.pipe((0, rxjs_1.switchMap)(async (handler) => {
if (handler === null) {
throw new exception_1.JobDoesNotExistException(name);
}
const validator = await handler.inputV;
return validator(message);
}))), (0, rxjs_1.filter)((result) => result.success), (0, rxjs_1.map)((result) => result.data))
.subscribe((value) => inboundBus.next({ kind: api_1.JobInboundMessageKind.Input, value }));
outboundBus = (0, rxjs_1.concat)(outboundBus,
// Add an End message at completion. This will be filtered out if the job actually send an
// End.
handler.pipe((0, rxjs_1.switchMap)((handler) => {
if (handler) {
return (0, rxjs_1.of)({
kind: api_1.JobOutboundMessageKind.End,
description: handler.jobDescription,
});
}
else {
return rxjs_1.EMPTY;
}
}))).pipe((0, rxjs_1.filter)((message) => this._filterJobOutboundMessages(message, state)),
// Update internal logic and Job<> members.
(0, rxjs_1.tap)((message) => {
// Update the state.
state = this._updateState(message, state);
switch (message.kind) {
case api_1.JobOutboundMessageKind.ChannelCreate: {
const maybeSubject = channelsSubject.get(message.name);
// If it doesn't exist or it's closed on the other end.
if (!maybeSubject) {
const s = new rxjs_1.Subject();
channelsSubject.set(message.name, s);
channels.set(message.name, s.asObservable());
}
break;
}
case api_1.JobOutboundMessageKind.ChannelMessage: {
const maybeSubject = channelsSubject.get(message.name);
if (maybeSubject) {
maybeSubject.next(message.message);
}
break;
}
case api_1.JobOutboundMessageKind.ChannelComplete: {
const maybeSubject = channelsSubject.get(message.name);
if (maybeSubject) {
maybeSubject.complete();
channelsSubject.delete(message.name);
}
break;
}
case api_1.JobOutboundMessageKind.ChannelError: {
const maybeSubject = channelsSubject.get(message.name);
if (maybeSubject) {
maybeSubject.error(message.error);
channelsSubject.delete(message.name);
}
break;
}
}
}, () => {
state = api_1.JobState.Errored;
}),
// Do output validation (might include default values so this might have side
// effects). We keep all messages in order.
(0, rxjs_1.concatMap)((message) => {
if (message.kind !== api_1.JobOutboundMessageKind.Output) {
return (0, rxjs_1.of)(message);
}
return handler.pipe((0, rxjs_1.switchMap)(async (handler) => {
if (handler === null) {
throw new exception_1.JobDoesNotExistException(name);
}
const validate = await handler.outputV;
const output = await validate(message.value);
if (!output.success) {
throw new JobOutputSchemaValidationError(output.errors);
}
return {
...message,
output: output.data,
};
}));
}), _jobShare());
const output = outboundBus.pipe((0, rxjs_1.filter)((x) => x.kind == api_1.JobOutboundMessageKind.Output), (0, rxjs_1.map)((x) => x.value), (0, rxjs_1.shareReplay)(1));
// Return the Job.
return {
get state() {
return state;
},
argument,
description: handler.pipe((0, rxjs_1.switchMap)((handler) => {
if (handler === null) {
throw new exception_1.JobDoesNotExistException(name);
}
else {
return (0, rxjs_1.of)(handler.jobDescription);
}
})),
output,
getChannel(name, schema = true) {
let maybeObservable = channels.get(name);
if (!maybeObservable) {
const s = new rxjs_1.Subject();
channelsSubject.set(name, s);
channels.set(name, s.asObservable());
maybeObservable = s.asObservable();
}
return maybeObservable.pipe(
// Keep the order of messages.
(0, rxjs_1.concatMap)((message) => {
return (0, rxjs_1.from)(schemaRegistry.compile(schema)).pipe((0, rxjs_1.switchMap)((validate) => validate(message)), (0, rxjs_1.filter)((x) => x.success), (0, rxjs_1.map)((x) => x.data));
}));
},
ping() {
const id = pingId++;
inboundBus.next({ kind: api_1.JobInboundMessageKind.Ping, id });
return outboundBus.pipe((0, rxjs_1.filter)((x) => x.kind === api_1.JobOutboundMessageKind.Pong && x.id == id), (0, rxjs_1.first)(), (0, rxjs_1.ignoreElements)());
},
stop() {
inboundBus.next({ kind: api_1.JobInboundMessageKind.Stop });
},
input,
inboundBus,
outboundBus,
};
}
_scheduleJob(name, argument, options, waitable) {
// Get handler first, since this can error out if there's no handler for the job name.
const handler = this._getInternalDescription(name);
const optionsDeps = (options && options.dependencies) || [];
const dependencies = Array.isArray(optionsDeps) ? optionsDeps : [optionsDeps];
const inboundBus = new rxjs_1.Subject();
const outboundBus = (0, rxjs_1.concat)(
// Wait for dependencies, make sure to not report messages from dependencies. Subscribe to
// all dependencies at the same time so they run concurrently.
(0, rxjs_1.merge)(...dependencies.map((x) => x.outboundBus)).pipe((0, rxjs_1.ignoreElements)()),
// Wait for pause() to clear (if necessary).
waitable, (0, rxjs_1.from)(handler).pipe((0, rxjs_1.switchMap)((handler) => new rxjs_1.Observable((subscriber) => {
if (!handler) {
throw new exception_1.JobDoesNotExistException(name);
}
// Validate the argument.
return (0, rxjs_1.from)(handler.argumentV)
.pipe((0, rxjs_1.switchMap)((validate) => validate(argument)), (0, rxjs_1.switchMap)((output) => {
if (!output.success) {
throw new JobArgumentSchemaValidationError(output.errors);
}
const argument = output.data;
const description = handler.jobDescription;
subscriber.next({ kind: api_1.JobOutboundMessageKind.OnReady, description });
const context = {
description,
dependencies: [...dependencies],
inboundBus: inboundBus.asObservable(),
scheduler: this,
};
return handler(argument, context);
}))
.subscribe(subscriber);
}))));
return this._createJob(name, argument, handler, inboundBus, outboundBus);
}
}
exports.SimpleScheduler = SimpleScheduler;
async function noopSchemaValidator() {
return async (data) => ({
data,
success: true,
});
}

View File

@@ -0,0 +1,26 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { JsonValue } from '@angular-devkit/core';
import { JobDescription, JobHandler } from './api';
export type JobStrategy<A extends JsonValue = JsonValue, I extends JsonValue = JsonValue, O extends JsonValue = JsonValue> = (handler: JobHandler<A, I, O>, options?: Partial<Readonly<JobDescription>>) => JobHandler<A, I, O>;
/**
* Creates a JobStrategy that serializes every call. This strategy can be mixed between jobs.
*/
export declare function serialize<A extends JsonValue = JsonValue, I extends JsonValue = JsonValue, O extends JsonValue = JsonValue>(): JobStrategy<A, I, O>;
/**
* Creates a JobStrategy that will always reuse a running job, and restart it if the job ended.
* @param replayMessages Replay ALL messages if a job is reused, otherwise just hook up where it
* is.
*/
export declare function reuse<A extends JsonValue = JsonValue, I extends JsonValue = JsonValue, O extends JsonValue = JsonValue>(replayMessages?: boolean): JobStrategy<A, I, O>;
/**
* Creates a JobStrategy that will reuse a running job if the argument matches.
* @param replayMessages Replay ALL messages if a job is reused, otherwise just hook up where it
* is.
*/
export declare function memoize<A extends JsonValue = JsonValue, I extends JsonValue = JsonValue, O extends JsonValue = JsonValue>(replayMessages?: boolean): JobStrategy<A, I, O>;

93
node_modules/@angular-devkit/architect/src/jobs/strategy.js generated vendored Executable file
View File

@@ -0,0 +1,93 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.serialize = serialize;
exports.reuse = reuse;
exports.memoize = memoize;
const core_1 = require("@angular-devkit/core");
const rxjs_1 = require("rxjs");
const api_1 = require("./api");
/**
* Creates a JobStrategy that serializes every call. This strategy can be mixed between jobs.
*/
function serialize() {
let latest = (0, rxjs_1.of)();
return (handler, options) => {
const newHandler = (argument, context) => {
const previous = latest;
latest = (0, rxjs_1.concat)(previous.pipe((0, rxjs_1.ignoreElements)()), new rxjs_1.Observable((o) => handler(argument, context).subscribe(o))).pipe((0, rxjs_1.shareReplay)(0));
return latest;
};
return Object.assign(newHandler, {
jobDescription: Object.assign({}, handler.jobDescription, options),
});
};
}
/**
* Creates a JobStrategy that will always reuse a running job, and restart it if the job ended.
* @param replayMessages Replay ALL messages if a job is reused, otherwise just hook up where it
* is.
*/
function reuse(replayMessages = false) {
let inboundBus = new rxjs_1.Subject();
let run = null;
let state = null;
return (handler, options) => {
const newHandler = (argument, context) => {
// Forward inputs.
const subscription = context.inboundBus.subscribe(inboundBus);
if (run) {
return (0, rxjs_1.concat)(
// Update state.
(0, rxjs_1.of)(state), run).pipe((0, rxjs_1.finalize)(() => subscription.unsubscribe()));
}
run = handler(argument, { ...context, inboundBus: inboundBus.asObservable() }).pipe((0, rxjs_1.tap)((message) => {
if (message.kind == api_1.JobOutboundMessageKind.Start ||
message.kind == api_1.JobOutboundMessageKind.OnReady ||
message.kind == api_1.JobOutboundMessageKind.End) {
state = message;
}
}, undefined, () => {
subscription.unsubscribe();
inboundBus = new rxjs_1.Subject();
run = null;
}), replayMessages ? (0, rxjs_1.shareReplay)() : (0, rxjs_1.share)());
return run;
};
return Object.assign(newHandler, handler, options || {});
};
}
/**
* Creates a JobStrategy that will reuse a running job if the argument matches.
* @param replayMessages Replay ALL messages if a job is reused, otherwise just hook up where it
* is.
*/
function memoize(replayMessages = false) {
const runs = new Map();
return (handler, options) => {
const newHandler = (argument, context) => {
const argumentJson = JSON.stringify((0, core_1.isJsonObject)(argument)
? Object.keys(argument)
.sort()
.reduce((result, key) => {
result[key] = argument[key];
return result;
}, {})
: argument);
const maybeJob = runs.get(argumentJson);
if (maybeJob) {
return maybeJob;
}
const run = handler(argument, context).pipe(replayMessages ? (0, rxjs_1.shareReplay)() : (0, rxjs_1.share)());
runs.set(argumentJson, run);
return run;
};
return Object.assign(newHandler, handler, options || {});
};
}

15
node_modules/@angular-devkit/architect/src/jobs/types.d.ts generated vendored Executable file
View File

@@ -0,0 +1,15 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export type DeepReadonly<T> = T extends (infer R)[] ? DeepReadonlyArray<R> : T extends Function ? T : T extends object ? DeepReadonlyObject<T> : T;
export type DeepReadonlyArray<T> = Array<DeepReadonly<T>>;
export type DeepReadonlyObject<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;
};
export type Readwrite<T> = {
-readonly [P in keyof T]: T[P];
};

9
node_modules/@angular-devkit/architect/src/jobs/types.js generated vendored Executable file
View File

@@ -0,0 +1,9 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });

12
node_modules/@angular-devkit/architect/src/options.d.ts generated vendored Executable file
View File

@@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json } from '@angular-devkit/core';
import { BuilderInput } from './api';
type OverrideOptions = BuilderInput['options'];
export declare function mergeOptions(baseOptions: json.JsonObject, overrideOptions: OverrideOptions): json.JsonObject;
export {};

29
node_modules/@angular-devkit/architect/src/options.js generated vendored Executable file
View File

@@ -0,0 +1,29 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeOptions = mergeOptions;
const core_1 = require("@angular-devkit/core");
function mergeOptions(baseOptions, overrideOptions) {
if (!overrideOptions) {
return { ...baseOptions };
}
const options = {
...baseOptions,
...overrideOptions,
};
// For object-object overrides, we merge one layer deep.
for (const key of Object.keys(overrideOptions)) {
const override = overrideOptions[key];
const base = baseOptions[key];
if (core_1.json.isJsonObject(base) && core_1.json.isJsonObject(override)) {
options[key] = { ...base, ...override };
}
}
return options;
}

View File

@@ -0,0 +1,15 @@
export type Schema = {
error?: string;
info?: {
[key: string]: any;
};
success: boolean;
target?: Target;
[property: string]: any;
};
export type Target = {
configuration?: string;
project?: string;
target?: string;
[property: string]: any;
};

View File

@@ -0,0 +1,4 @@
"use strict";
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,33 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "BuilderOutputSchema",
"title": "Output schema for builders.",
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"error": {
"type": "string"
},
"target": {
"type": "object",
"properties": {
"project": {
"type": "string"
},
"target": {
"type": "string"
},
"configuration": {
"type": "string"
}
}
},
"info": {
"type": "object"
}
},
"additionalProperties": true,
"required": ["success"]
}

View File

@@ -0,0 +1,21 @@
export type Schema = {
builder: {
[key: string]: any;
};
current?: number;
error?: any;
id: number;
state: State;
status?: string;
target?: {
[key: string]: any;
};
total?: number;
[property: string]: any;
};
export declare enum State {
Error = "error",
Running = "running",
Stopped = "stopped",
Waiting = "waiting"
}

View File

@@ -0,0 +1,12 @@
"use strict";
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
Object.defineProperty(exports, "__esModule", { value: true });
exports.State = void 0;
var State;
(function (State) {
State["Error"] = "error";
State["Running"] = "running";
State["Stopped"] = "stopped";
State["Waiting"] = "waiting";
})(State || (exports.State = State = {}));

View File

@@ -0,0 +1,83 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "BuilderProgressSchema",
"title": "Progress schema for builders.",
"type": "object",
"allOf": [
{
"type": "object",
"oneOf": [
{
"type": "object",
"properties": {
"state": {
"type": "string",
"enum": ["stopped"]
}
},
"required": ["state"]
},
{
"type": "object",
"properties": {
"state": {
"type": "string",
"enum": ["waiting"]
},
"status": {
"type": "string"
}
},
"required": ["state"]
},
{
"type": "object",
"properties": {
"state": {
"type": "string",
"enum": ["running"]
},
"current": {
"type": "number",
"minimum": 0
},
"total": {
"type": "number",
"minimum": 0
},
"status": {
"type": "string"
}
},
"required": ["state"]
},
{
"type": "object",
"properties": {
"state": {
"type": "string",
"enum": ["error"]
},
"error": true
},
"required": ["state"]
}
]
},
{
"type": "object",
"properties": {
"builder": {
"type": "object"
},
"target": {
"type": "object"
},
"id": {
"type": "number"
}
},
"required": ["builder", "id"]
}
]
}

View File

@@ -0,0 +1,23 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json, logging } from '@angular-devkit/core';
import { BuilderRun, Target } from './api';
import { Scheduler } from './jobs';
export declare function scheduleByName(name: string, buildOptions: json.JsonObject, options: {
target?: Target;
scheduler: Scheduler;
logger: logging.LoggerApi;
workspaceRoot: string | Promise<string>;
currentDirectory: string | Promise<string>;
}): Promise<BuilderRun>;
export declare function scheduleByTarget(target: Target, overrides: json.JsonObject, options: {
scheduler: Scheduler;
logger: logging.LoggerApi;
workspaceRoot: string | Promise<string>;
currentDirectory: string | Promise<string>;
}): Promise<BuilderRun>;

View File

@@ -0,0 +1,100 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.scheduleByName = scheduleByName;
exports.scheduleByTarget = scheduleByTarget;
const rxjs_1 = require("rxjs");
const api_1 = require("./api");
const jobs_1 = require("./jobs");
const progressSchema = require('./progress-schema.json');
let _uniqueId = 0;
async function scheduleByName(name, buildOptions, options) {
const childLoggerName = options.target ? `{${(0, api_1.targetStringFromTarget)(options.target)}}` : name;
const logger = options.logger.createChild(childLoggerName);
const job = options.scheduler.schedule(name, {});
let stateSubscription;
const workspaceRoot = await options.workspaceRoot;
const currentDirectory = await options.currentDirectory;
const description = await (0, rxjs_1.firstValueFrom)(job.description);
const info = description.info;
const id = ++_uniqueId;
const message = {
id,
currentDirectory,
workspaceRoot,
info: info,
options: buildOptions,
...(options.target ? { target: options.target } : {}),
};
// Wait for the job to be ready.
if (job.state !== jobs_1.JobState.Started) {
stateSubscription = job.outboundBus.subscribe({
next: (event) => {
if (event.kind === jobs_1.JobOutboundMessageKind.Start) {
job.input.next(message);
}
},
error: () => { },
});
}
else {
job.input.next(message);
}
const logChannelSub = job.getChannel('log').subscribe({
next: (entry) => {
logger.next(entry);
},
error: () => { },
});
const outboundBusSub = job.outboundBus.subscribe({
error() { },
complete() {
outboundBusSub.unsubscribe();
logChannelSub.unsubscribe();
stateSubscription.unsubscribe();
},
});
const output = job.output.pipe((0, rxjs_1.map)((output) => ({
...output,
...(options.target ? { target: options.target } : 0),
info,
})), (0, rxjs_1.shareReplay)());
// Start the builder.
output.pipe((0, rxjs_1.first)()).subscribe({
error: () => { },
});
return {
id,
info,
// This is a getter so that it always returns the next output, and not the same one.
get result() {
return (0, rxjs_1.firstValueFrom)(output);
},
get lastOutput() {
return (0, rxjs_1.lastValueFrom)(output);
},
output,
progress: job
.getChannel('progress', progressSchema)
.pipe((0, rxjs_1.shareReplay)(1)),
stop() {
job.stop();
return job.outboundBus
.pipe((0, rxjs_1.ignoreElements)(), (0, rxjs_1.catchError)(() => rxjs_1.EMPTY))
.toPromise();
},
};
}
async function scheduleByTarget(target, overrides, options) {
return scheduleByName(`{${(0, api_1.targetStringFromTarget)(target)}}`, overrides, {
...options,
target,
logger: options.logger,
});
}

View File

@@ -0,0 +1,39 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "ArchitectTargets",
"title": "Targets schema for validating Architect targets configuration.",
"type": "object",
"description": "A map of available project targets.",
"additionalProperties": {
"$ref": "#/definitions/target"
},
"required": [],
"definitions": {
"target": {
"type": "object",
"description": "Target options.",
"properties": {
"builder": {
"type": "string",
"description": "The builder used for this package."
},
"options": {
"$ref": "#/definitions/options"
},
"configurations": {
"type": "object",
"description": "A map of alternative target options.",
"additionalProperties": {
"$ref": "#/definitions/options"
}
}
},
"additionalProperties": false,
"required": ["builder", "options"]
},
"options": {
"type": "object",
"description": "Target options."
}
}
}

9
node_modules/@angular-devkit/architect/testing/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,9 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export * from './testing-architect-host';
export * from './test-project-host';

25
node_modules/@angular-devkit/architect/testing/index.js generated vendored Executable file
View File

@@ -0,0 +1,25 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./testing-architect-host"), exports);
__exportStar(require("./test-project-host"), exports);

View File

@@ -0,0 +1,32 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { Path, PathFragment, virtualFs } from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import { Stats } from 'node:fs';
import { Observable } from 'rxjs';
/**
* @deprecated
*/
export declare class TestProjectHost extends NodeJsSyncHost {
protected _templateRoot: Path;
private _currentRoot;
private _scopedSyncHost;
constructor(_templateRoot: Path);
root(): Path;
scopedSync(): virtualFs.SyncDelegateHost<Stats>;
initialize(): Observable<void>;
restore(): Observable<void>;
writeMultipleFiles(files: {
[path: string]: string | ArrayBufferLike | Buffer;
}): void;
replaceInFile(path: string, match: RegExp | string, replacement: string): void;
appendToFile(path: string, str: string): void;
fileMatchExists(dir: string, regex: RegExp): PathFragment | undefined;
copyFile(from: string, to: string): void;
private findUniqueFolderPath;
}

View File

@@ -0,0 +1,109 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestProjectHost = void 0;
const core_1 = require("@angular-devkit/core");
const node_1 = require("@angular-devkit/core/node");
const rxjs_1 = require("rxjs");
/**
* @deprecated
*/
class TestProjectHost extends node_1.NodeJsSyncHost {
_templateRoot;
_currentRoot = null;
_scopedSyncHost = null;
constructor(_templateRoot) {
super();
this._templateRoot = _templateRoot;
}
root() {
if (this._currentRoot === null) {
throw new Error('TestProjectHost must be initialized before being used.');
}
return this._currentRoot;
}
scopedSync() {
if (this._currentRoot === null || this._scopedSyncHost === null) {
throw new Error('TestProjectHost must be initialized before being used.');
}
return this._scopedSyncHost;
}
initialize() {
const recursiveList = (path) => this.list(path).pipe(
// Emit each fragment individually.
(0, rxjs_1.concatMap)((fragments) => (0, rxjs_1.from)(fragments)),
// Join the path with fragment.
(0, rxjs_1.map)((fragment) => (0, core_1.join)(path, fragment)),
// Emit directory content paths instead of the directory path.
(0, rxjs_1.mergeMap)((path) => this.isDirectory(path).pipe((0, rxjs_1.concatMap)((isDir) => (isDir ? recursiveList(path) : (0, rxjs_1.of)(path))))));
// Find a unique folder that we can write to use as current root.
return this.findUniqueFolderPath().pipe(
// Save the path and create a scoped host for it.
(0, rxjs_1.tap)((newFolderPath) => {
this._currentRoot = newFolderPath;
this._scopedSyncHost = new core_1.virtualFs.SyncDelegateHost(new core_1.virtualFs.ScopedHost(this, this.root()));
}),
// List all files in root.
(0, rxjs_1.concatMap)(() => recursiveList(this._templateRoot)),
// Copy them over to the current root.
(0, rxjs_1.concatMap)((from) => {
const to = (0, core_1.join)(this.root(), (0, core_1.relative)(this._templateRoot, from));
return this.read(from).pipe((0, rxjs_1.concatMap)((buffer) => this.write(to, buffer)));
}), (0, rxjs_1.map)(() => { }));
}
restore() {
if (this._currentRoot === null) {
return rxjs_1.EMPTY;
}
// Delete the current root and clear the variables.
// Wait 50ms and retry up to 10 times, to give time for file locks to clear.
return this.exists(this.root()).pipe((0, rxjs_1.delay)(50), (0, rxjs_1.concatMap)((exists) => (exists ? this.delete(this.root()) : rxjs_1.EMPTY)), (0, rxjs_1.retry)(10), (0, rxjs_1.finalize)(() => {
this._currentRoot = null;
this._scopedSyncHost = null;
}));
}
writeMultipleFiles(files) {
Object.keys(files).forEach((fileName) => {
let content = files[fileName];
if (typeof content == 'string') {
content = core_1.virtualFs.stringToFileBuffer(content);
}
else if (content instanceof Buffer) {
content = content.buffer.slice(content.byteOffset, content.byteOffset + content.byteLength);
}
this.scopedSync().write((0, core_1.normalize)(fileName), content);
});
}
replaceInFile(path, match, replacement) {
const content = core_1.virtualFs.fileBufferToString(this.scopedSync().read((0, core_1.normalize)(path)));
this.scopedSync().write((0, core_1.normalize)(path), core_1.virtualFs.stringToFileBuffer(content.replace(match, replacement)));
}
appendToFile(path, str) {
const content = core_1.virtualFs.fileBufferToString(this.scopedSync().read((0, core_1.normalize)(path)));
this.scopedSync().write((0, core_1.normalize)(path), core_1.virtualFs.stringToFileBuffer(content.concat(str)));
}
fileMatchExists(dir, regex) {
const [fileName] = this.scopedSync()
.list((0, core_1.normalize)(dir))
.filter((name) => name.match(regex));
return fileName || undefined;
}
copyFile(from, to) {
const content = this.scopedSync().read((0, core_1.normalize)(from));
this.scopedSync().write((0, core_1.normalize)(to), content);
}
findUniqueFolderPath() {
// 11 character alphanumeric string.
const randomString = Math.random().toString(36).slice(2);
const newFolderName = `test-project-host-${(0, core_1.basename)(this._templateRoot)}-${randomString}`;
const newFolderPath = (0, core_1.join)((0, core_1.dirname)(this._templateRoot), newFolderName);
return this.exists(newFolderPath).pipe((0, rxjs_1.concatMap)((exists) => (exists ? this.findUniqueFolderPath() : (0, rxjs_1.of)(newFolderPath))));
}
}
exports.TestProjectHost = TestProjectHost;

View File

@@ -0,0 +1,42 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { json } from '@angular-devkit/core';
import { BuilderInfo, Target } from '../src';
import { ArchitectHost, Builder } from '../src/internal';
export declare class TestingArchitectHost implements ArchitectHost {
workspaceRoot: string;
currentDirectory: string;
private _backendHost;
private _builderImportMap;
private _builderMap;
private _targetMap;
/**
* Can provide a backend host, in case of integration tests.
* @param workspaceRoot The workspace root to use.
* @param currentDirectory The current directory to use.
* @param _backendHost A host to defer calls that aren't resolved here.
*/
constructor(workspaceRoot?: string, currentDirectory?: string, _backendHost?: ArchitectHost | null);
addBuilder(builderName: string, builder: Builder, description?: string, optionSchema?: json.schema.JsonSchema): void;
addBuilderFromPackage(packageName: string): Promise<void>;
addTarget(target: Target, builderName: string, options?: json.JsonObject): void;
getBuilderNameForTarget(target: Target): Promise<string | null>;
/**
* Resolve a builder. This needs to return a string which will be used in a dynamic `import()`
* clause. This should throw if no builder can be found. The dynamic import will throw if
* it is unsupported.
* @param builderName The name of the builder to be used.
* @returns All the info needed for the builder itself.
*/
resolveBuilder(builderName: string): Promise<BuilderInfo | null>;
getCurrentDirectory(): Promise<string>;
getWorkspaceRoot(): Promise<string>;
getOptionsForTarget(target: Target): Promise<json.JsonObject | null>;
getProjectMetadata(target: Target | string): Promise<json.JsonObject | null>;
loadBuilder(info: BuilderInfo): Promise<Builder | null>;
}

View File

@@ -0,0 +1,136 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestingArchitectHost = void 0;
const src_1 = require("../src");
class TestingArchitectHost {
workspaceRoot;
currentDirectory;
_backendHost;
_builderImportMap = new Map();
_builderMap = new Map();
_targetMap = new Map();
/**
* Can provide a backend host, in case of integration tests.
* @param workspaceRoot The workspace root to use.
* @param currentDirectory The current directory to use.
* @param _backendHost A host to defer calls that aren't resolved here.
*/
constructor(workspaceRoot = '', currentDirectory = workspaceRoot, _backendHost = null) {
this.workspaceRoot = workspaceRoot;
this.currentDirectory = currentDirectory;
this._backendHost = _backendHost;
}
addBuilder(builderName, builder, description = 'Testing only builder.', optionSchema = { type: 'object' }) {
this._builderImportMap.set(builderName, builder);
this._builderMap.set(builderName, { builderName, description, optionSchema });
}
async addBuilderFromPackage(packageName) {
const packageJson = await Promise.resolve(`${packageName + '/package.json'}`).then(s => __importStar(require(s)));
if (!('builders' in packageJson)) {
throw new Error('Invalid package.json, builders key not found.');
}
if (!packageJson.name) {
throw new Error('Invalid package name');
}
const builderJsonPath = packageName + '/' + packageJson['builders'];
const builderJson = await Promise.resolve(`${builderJsonPath}`).then(s => __importStar(require(s)));
const builders = builderJson['builders'];
if (!builders) {
throw new Error('Invalid builders.json, builders key not found.');
}
for (const builderName of Object.keys(builders)) {
const b = builders[builderName];
// TODO: remove this check as v1 is not supported anymore.
if (!b.implementation) {
continue;
}
const handler = (await Promise.resolve(`${builderJsonPath + '/../' + b.implementation}`).then(s => __importStar(require(s)))).default;
const optionsSchema = await Promise.resolve(`${builderJsonPath + '/../' + b.schema}`).then(s => __importStar(require(s)));
this.addBuilder(`${packageJson.name}:${builderName}`, handler, b.description, optionsSchema);
}
}
addTarget(target, builderName, options = {}) {
this._targetMap.set((0, src_1.targetStringFromTarget)(target), { builderName, options });
}
async getBuilderNameForTarget(target) {
const name = (0, src_1.targetStringFromTarget)(target);
const maybeTarget = this._targetMap.get(name);
if (!maybeTarget) {
return this._backendHost && this._backendHost.getBuilderNameForTarget(target);
}
return maybeTarget.builderName;
}
/**
* Resolve a builder. This needs to return a string which will be used in a dynamic `import()`
* clause. This should throw if no builder can be found. The dynamic import will throw if
* it is unsupported.
* @param builderName The name of the builder to be used.
* @returns All the info needed for the builder itself.
*/
async resolveBuilder(builderName) {
return (this._builderMap.get(builderName) ||
(this._backendHost && this._backendHost.resolveBuilder(builderName)));
}
async getCurrentDirectory() {
return this.currentDirectory;
}
async getWorkspaceRoot() {
return this.workspaceRoot;
}
async getOptionsForTarget(target) {
const name = (0, src_1.targetStringFromTarget)(target);
const maybeTarget = this._targetMap.get(name);
if (!maybeTarget) {
return this._backendHost && this._backendHost.getOptionsForTarget(target);
}
return maybeTarget.options;
}
async getProjectMetadata(target) {
return this._backendHost && this._backendHost.getProjectMetadata(target);
}
async loadBuilder(info) {
return (this._builderImportMap.get(info.builderName) ||
(this._backendHost && this._backendHost.loadBuilder(info)));
}
}
exports.TestingArchitectHost = TestingArchitectHost;