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

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."
}
}
}