Primeiro commit do projeto Angular
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2026 Google LLC. https://angular.dev/license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Angular Build Facade
|
||||
|
||||
WIP
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @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 {};
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
#!/usr/bin/env node
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const node_1 = require("@angular-devkit/core/node");
|
||||
const node_fs_1 = require("node:fs");
|
||||
const path = __importStar(require("node:path"));
|
||||
const node_util_1 = require("node:util");
|
||||
const index_1 = require("../index");
|
||||
const index_2 = require("../node/index");
|
||||
function findUp(names, from) {
|
||||
const filenames = Array.isArray(names) ? names : [names];
|
||||
let currentDir = path.resolve(from);
|
||||
while (true) {
|
||||
for (const name of filenames) {
|
||||
const p = path.join(currentDir, name);
|
||||
if ((0, node_fs_1.existsSync)(p)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
const parentDir = path.dirname(currentDir);
|
||||
if (parentDir === currentDir) {
|
||||
break;
|
||||
}
|
||||
currentDir = parentDir;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Show usage of the CLI tool, and exit the process.
|
||||
*/
|
||||
function usage(logger, exitCode = 0) {
|
||||
logger.info(core_1.tags.stripIndent `
|
||||
architect [project][:target][:configuration] [options, ...]
|
||||
|
||||
Run a project target.
|
||||
If project/target/configuration are not specified, the workspace defaults will be used.
|
||||
|
||||
Options:
|
||||
--help Show available options for project target.
|
||||
Shows this message instead when ran without the run argument.
|
||||
|
||||
|
||||
Any additional option is passed the target, overriding existing options.
|
||||
`);
|
||||
return process.exit(exitCode);
|
||||
}
|
||||
async function _executeTarget(parentLogger, workspace, root, targetStr, options, registry) {
|
||||
const architectHost = new index_2.WorkspaceNodeModulesArchitectHost(workspace, root);
|
||||
const architect = new index_1.Architect(architectHost, registry);
|
||||
// Split a target into its parts.
|
||||
const [project, target, configuration] = targetStr.split(':');
|
||||
const targetSpec = { project, target, configuration };
|
||||
const logger = new core_1.logging.Logger('jobs');
|
||||
const logs = [];
|
||||
logger.subscribe((entry) => logs.push({ ...entry, message: `${entry.name}: ` + entry.message }));
|
||||
const run = await architect.scheduleTarget(targetSpec, options, { logger });
|
||||
// Wait for full completion of the builder.
|
||||
try {
|
||||
const result = await run.lastOutput;
|
||||
if (result.success) {
|
||||
parentLogger.info((0, node_util_1.styleText)(['green'], 'SUCCESS'));
|
||||
}
|
||||
else {
|
||||
parentLogger.info((0, node_util_1.styleText)(['red'], 'FAILURE'));
|
||||
}
|
||||
parentLogger.info('Result: ' + JSON.stringify({ ...result, info: undefined }, null, 4));
|
||||
parentLogger.info('\nLogs:');
|
||||
logs.forEach((l) => parentLogger.next(l));
|
||||
logs.splice(0);
|
||||
await run.stop();
|
||||
return result.success ? 0 : 1;
|
||||
}
|
||||
catch (err) {
|
||||
parentLogger.info((0, node_util_1.styleText)(['red'], 'ERROR'));
|
||||
parentLogger.info('\nLogs:');
|
||||
logs.forEach((l) => parentLogger.next(l));
|
||||
parentLogger.fatal('Exception:');
|
||||
parentLogger.fatal((err instanceof Error && err.stack) || `${err}`);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
const CLI_OPTION_DEFINITIONS = {
|
||||
'help': { type: 'boolean' },
|
||||
'verbose': { type: 'boolean' },
|
||||
};
|
||||
/** Parse the command line. */
|
||||
function parseOptions(args) {
|
||||
const { values, tokens } = (0, node_util_1.parseArgs)({
|
||||
args,
|
||||
strict: false,
|
||||
tokens: true,
|
||||
allowPositionals: true,
|
||||
allowNegative: true,
|
||||
options: CLI_OPTION_DEFINITIONS,
|
||||
});
|
||||
const builderOptions = {};
|
||||
const positionals = [];
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
if (token.kind === 'positional') {
|
||||
positionals.push(token.value);
|
||||
continue;
|
||||
}
|
||||
if (token.kind !== 'option') {
|
||||
continue;
|
||||
}
|
||||
const name = token.name;
|
||||
let value = token.value ?? true;
|
||||
// `parseArgs` already handled known boolean args and their --no- forms.
|
||||
// Only process options not in CLI_OPTION_DEFINITIONS here.
|
||||
if (name in CLI_OPTION_DEFINITIONS) {
|
||||
continue;
|
||||
}
|
||||
if (/[A-Z]/.test(name)) {
|
||||
throw new Error(`Unknown argument ${name}. Did you mean ${core_1.strings.decamelize(name).replaceAll('_', '-')}?`);
|
||||
}
|
||||
// Handle --no-flag for unknown options, treating it as false
|
||||
if (name.startsWith('no-')) {
|
||||
const realName = name.slice(3);
|
||||
builderOptions[core_1.strings.camelize(realName)] = false;
|
||||
continue;
|
||||
}
|
||||
// Handle value for unknown options
|
||||
if (token.inlineValue === undefined) {
|
||||
// Look ahead
|
||||
const nextToken = tokens[i + 1];
|
||||
if (nextToken?.kind === 'positional') {
|
||||
value = nextToken.value;
|
||||
i++; // Consume next token
|
||||
}
|
||||
else {
|
||||
value = true; // Treat as boolean if no value follows
|
||||
}
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
if (!isNaN(Number(value))) {
|
||||
// Type inference for numbers
|
||||
value = Number(value);
|
||||
}
|
||||
else if (value === 'true') {
|
||||
// Type inference for booleans
|
||||
value = true;
|
||||
}
|
||||
else if (value === 'false') {
|
||||
value = false;
|
||||
}
|
||||
}
|
||||
const camelName = core_1.strings.camelize(name);
|
||||
if (Object.prototype.hasOwnProperty.call(builderOptions, camelName)) {
|
||||
const existing = builderOptions[camelName];
|
||||
if (Array.isArray(existing)) {
|
||||
existing.push(value);
|
||||
}
|
||||
else {
|
||||
builderOptions[camelName] = [existing, value];
|
||||
}
|
||||
}
|
||||
else {
|
||||
builderOptions[camelName] = value;
|
||||
}
|
||||
}
|
||||
return {
|
||||
positionals,
|
||||
builderOptions,
|
||||
cliOptions: values,
|
||||
};
|
||||
}
|
||||
async function main(args) {
|
||||
/** Parse the command line. */
|
||||
const { positionals, cliOptions, builderOptions } = parseOptions(args);
|
||||
/** Create the DevKit Logger used through the CLI. */
|
||||
const logger = (0, node_1.createConsoleLogger)(!!cliOptions['verbose'], process.stdout, process.stderr, {
|
||||
info: (s) => s,
|
||||
debug: (s) => s,
|
||||
warn: (s) => (0, node_util_1.styleText)(['yellow', 'bold'], s),
|
||||
error: (s) => (0, node_util_1.styleText)(['red', 'bold'], s),
|
||||
fatal: (s) => (0, node_util_1.styleText)(['red', 'bold'], s),
|
||||
});
|
||||
// Check the target.
|
||||
const targetStr = positionals[0];
|
||||
if (!targetStr || cliOptions.help) {
|
||||
// Show architect usage if there's no target.
|
||||
usage(logger);
|
||||
}
|
||||
// Load workspace configuration file.
|
||||
const currentPath = process.cwd();
|
||||
const configFileNames = ['angular.json', '.angular.json', 'workspace.json', '.workspace.json'];
|
||||
const configFilePath = findUp(configFileNames, currentPath);
|
||||
if (!configFilePath) {
|
||||
logger.fatal(`Workspace configuration file (${configFileNames.join(', ')}) cannot be found in ` +
|
||||
`'${currentPath}' or in parent directories.`);
|
||||
return 3;
|
||||
}
|
||||
const root = path.dirname(configFilePath);
|
||||
const registry = new core_1.schema.CoreSchemaRegistry();
|
||||
registry.addPostTransform(core_1.schema.transforms.addUndefinedDefaults);
|
||||
// Show usage of deprecated options
|
||||
registry.useXDeprecatedProvider((msg) => logger.warn(msg));
|
||||
const { workspace } = await core_1.workspaces.readWorkspace(configFilePath, core_1.workspaces.createWorkspaceHost(new node_1.NodeJsSyncHost()));
|
||||
// Clear the console.
|
||||
process.stdout.write('\u001Bc');
|
||||
return await _executeTarget(logger, workspace, root, targetStr, builderOptions, registry);
|
||||
}
|
||||
main(process.argv.slice(2)).then((code) => {
|
||||
process.exit(code);
|
||||
}, (err) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Error: ' + err.stack || err.message || err);
|
||||
process.exit(-1);
|
||||
});
|
||||
//# sourceMappingURL=architect.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
require('./architect');
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Builder } from '../src';
|
||||
import { Schema as OperatorSchema } from './operator-schema';
|
||||
declare const builder: Builder<OperatorSchema>;
|
||||
export default builder;
|
||||
+49
@@ -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 });
|
||||
const rxjs_1 = require("rxjs");
|
||||
const src_1 = require("../src");
|
||||
const builder = (0, src_1.createBuilder)((options, context) => {
|
||||
const allRuns = [];
|
||||
context.reportProgress(0, (options.targets ? options.targets.length : 0) +
|
||||
(options.builders ? options.builders.length : 0));
|
||||
if (options.targets) {
|
||||
allRuns.push(...options.targets.map(({ target: targetStr, overrides }, i) => {
|
||||
const [project, target, configuration] = targetStr.split(/:/g, 3);
|
||||
return context
|
||||
.scheduleTarget({ project, target, configuration }, overrides || {})
|
||||
.then((run) => [i, run]);
|
||||
}));
|
||||
}
|
||||
if (options.builders) {
|
||||
allRuns.push(...options.builders.map(({ builder, options }, i) => {
|
||||
return context
|
||||
.scheduleBuilder(builder, options || {})
|
||||
.then((run) => [i, run]);
|
||||
}));
|
||||
}
|
||||
const allResults = allRuns.map(() => null);
|
||||
let n = 0;
|
||||
context.reportProgress(n++, allRuns.length);
|
||||
return (0, rxjs_1.from)(allRuns).pipe((0, rxjs_1.mergeMap)((runPromise) => (0, rxjs_1.from)(runPromise)), (0, rxjs_1.mergeMap)(([i, run]) => run.output.pipe((0, rxjs_1.map)((output) => [i, output]))), (0, rxjs_1.mergeMap)(([i, output]) => {
|
||||
allResults[i] = output;
|
||||
context.reportProgress(n++, allRuns.length);
|
||||
if (allResults.some((x) => x === null)) {
|
||||
// Some builders aren't done running yet.
|
||||
return rxjs_1.EMPTY;
|
||||
}
|
||||
else {
|
||||
return (0, rxjs_1.of)({
|
||||
success: allResults.every((x) => (x ? x.success : false)),
|
||||
});
|
||||
}
|
||||
}));
|
||||
});
|
||||
exports.default = builder;
|
||||
//# sourceMappingURL=all-of.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"all-of.js","sourceRoot":"","sources":["all-of.ts"],"names":[],"mappings":"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"}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "../src/builders-schema.json",
|
||||
"builders": {
|
||||
"true": {
|
||||
"implementation": "./true",
|
||||
"schema": "./noop-schema.json",
|
||||
"description": "Always succeed."
|
||||
},
|
||||
"false": {
|
||||
"implementation": "./false",
|
||||
"schema": "./noop-schema.json",
|
||||
"description": "Always fails."
|
||||
},
|
||||
"allOf": {
|
||||
"implementation": "./all-of",
|
||||
"schema": "./operator-schema.json",
|
||||
"description": "A builder that executes many builders in parallel, and succeed if both succeeds."
|
||||
},
|
||||
"concat": {
|
||||
"implementation": "./concat",
|
||||
"schema": "./operator-schema.json",
|
||||
"description": "A builder that executes many builders one after the other, and stops when one fail. It will succeed if all builders succeeds (and return the last output)"
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Builder } from '../src';
|
||||
import { Schema as OperatorSchema } from './operator-schema';
|
||||
declare const builder: Builder<OperatorSchema>;
|
||||
export default builder;
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const rxjs_1 = require("rxjs");
|
||||
const src_1 = require("../src");
|
||||
const builder = (0, src_1.createBuilder)((options, context) => {
|
||||
const allRuns = [];
|
||||
context.reportProgress(0, (options.targets ? options.targets.length : 0) +
|
||||
(options.builders ? options.builders.length : 0));
|
||||
if (options.targets) {
|
||||
allRuns.push(...options.targets.map(({ target: targetStr, overrides }) => {
|
||||
const [project, target, configuration] = targetStr.split(/:/g, 3);
|
||||
return () => context.scheduleTarget({ project, target, configuration }, overrides || {});
|
||||
}));
|
||||
}
|
||||
if (options.builders) {
|
||||
allRuns.push(...options.builders.map(({ builder, options }) => {
|
||||
return () => context.scheduleBuilder(builder, options || {});
|
||||
}));
|
||||
}
|
||||
let stop = null;
|
||||
let i = 0;
|
||||
context.reportProgress(i++, allRuns.length);
|
||||
return (0, rxjs_1.from)(allRuns).pipe((0, rxjs_1.concatMap)((fn) => stop
|
||||
? (0, rxjs_1.of)(null)
|
||||
: (0, rxjs_1.from)(fn()).pipe((0, rxjs_1.switchMap)((run) => (run === null ? (0, rxjs_1.of)(null) : run.output.pipe((0, rxjs_1.first)()))))), (0, rxjs_1.map)((output) => {
|
||||
context.reportProgress(i++, allRuns.length);
|
||||
if (output === null || stop !== null) {
|
||||
return stop || { success: false };
|
||||
}
|
||||
else if (output.success === false) {
|
||||
return (stop = output);
|
||||
}
|
||||
else {
|
||||
return output;
|
||||
}
|
||||
}), (0, rxjs_1.last)());
|
||||
});
|
||||
exports.default = builder;
|
||||
//# sourceMappingURL=concat.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"concat.js","sourceRoot":"","sources":["concat.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,+BAAwE;AACxE,gCAA2E;AAG3E,MAAM,OAAO,GAA4B,IAAA,mBAAa,EAAC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;IAC1E,MAAM,OAAO,GAAkC,EAAE,CAAC;IAElD,OAAO,CAAC,cAAc,CACpB,CAAC,EACD,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CACnD,CAAC;IAEF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CACV,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE;YAC1D,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAElE,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;QAC3F,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CACV,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;YAC/C,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,GAAyB,IAAI,CAAC;IACtC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5C,OAAO,IAAA,WAAI,EAAC,OAAO,CAAC,CAAC,IAAI,CACvB,IAAA,gBAAS,EAAC,CAAC,EAAE,EAAE,EAAE,CACf,IAAI;QACF,CAAC,CAAC,IAAA,SAAE,EAAC,IAAI,CAAC;QACV,CAAC,CAAC,IAAA,WAAI,EAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAA,gBAAS,EAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAA,SAAE,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,YAAK,GAAE,CAAC,CAAC,CAAC,CAAC,CAC9F,EACD,IAAA,UAAG,EAAC,CAAC,MAAM,EAAE,EAAE;QACb,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACrC,OAAO,IAAI,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACpC,CAAC;aAAM,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YACpC,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,EACF,IAAA,WAAI,GAAE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,kBAAe,OAAO,CAAC"}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { type Builder } from '../src';
|
||||
declare const builder: Builder<{}>;
|
||||
export default builder;
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const src_1 = require("../src");
|
||||
const builder = (0, src_1.createBuilder)(() => ({
|
||||
success: false,
|
||||
error: 'False builder always errors.',
|
||||
}));
|
||||
exports.default = builder;
|
||||
//# sourceMappingURL=false.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"false.js","sourceRoot":"","sources":["false.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,gCAAqD;AAErD,MAAM,OAAO,GAAgB,IAAA,mBAAa,EAAC,GAAG,EAAE,CAAC,CAAC;IAChD,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,8BAA8B;CACtC,CAAC,CAAC,CAAC;AAEJ,kBAAe,OAAO,CAAC"}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"type": "object"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* All input types of builders that perform operations on one or multiple sub-builders.
|
||||
*/
|
||||
export type Schema = {
|
||||
builders?: Builder[];
|
||||
targets?: Target[];
|
||||
[property: string]: any;
|
||||
};
|
||||
export type Builder = {
|
||||
builder: string;
|
||||
options?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
[property: string]: any;
|
||||
};
|
||||
export type Target = {
|
||||
overrides?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
target: string;
|
||||
[property: string]: any;
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"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 });
|
||||
//# sourceMappingURL=operator-schema.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"operator-schema.js","sourceRoot":"","sources":["operator-schema.ts"],"names":[],"mappings":";AACA,mFAAmF;AACnF,oFAAoF"}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"description": "All input types of builders that perform operations on one or multiple sub-builders.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"builders": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"builder": {
|
||||
"type": "string",
|
||||
"pattern": ".*:.*"
|
||||
},
|
||||
"options": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": ["builder"]
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
"targets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"target": {
|
||||
"type": "string",
|
||||
"pattern": ".*:.*"
|
||||
},
|
||||
"overrides": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": ["target"]
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { type Builder } from '../src';
|
||||
declare const builder: Builder<{}>;
|
||||
export default builder;
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const src_1 = require("../src");
|
||||
const builder = (0, src_1.createBuilder)(() => ({ success: true }));
|
||||
exports.default = builder;
|
||||
//# sourceMappingURL=true.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"true.js","sourceRoot":"","sources":["true.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,gCAAqD;AAErD,MAAM,OAAO,GAAgB,IAAA,mBAAa,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAEtE,kBAAe,OAAO,CAAC"}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
export * from './src/index';
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./src/index"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;AAEH,8CAA4B"}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import * as jobs from './jobs/job-registry';
|
||||
export * from './node-modules-architect-host';
|
||||
export { jobs };
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.jobs = void 0;
|
||||
const jobs = __importStar(require("./jobs/job-registry"));
|
||||
exports.jobs = jobs;
|
||||
__exportStar(require("./node-modules-architect-host"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,0DAA4C;AAInC,oBAAI;AAFb,gEAA8C"}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { JsonValue } from '@angular-devkit/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { jobs } from '../../src';
|
||||
export declare class NodeModuleJobRegistry<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> implements jobs.Registry<MinimumArgumentValueT, MinimumInputValueT, MinimumOutputValueT> {
|
||||
protected _resolve(name: string): string | null;
|
||||
/**
|
||||
* Get a job description for a named job.
|
||||
*
|
||||
* @param name The name of the job.
|
||||
* @returns A description, or null if the job is not registered.
|
||||
*/
|
||||
get<A extends MinimumArgumentValueT, I extends MinimumInputValueT, O extends MinimumOutputValueT>(name: jobs.JobName): Observable<jobs.JobHandler<A, I, O> | null>;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.NodeModuleJobRegistry = void 0;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const rxjs_1 = require("rxjs");
|
||||
class NodeModuleJobRegistry {
|
||||
_resolve(name) {
|
||||
try {
|
||||
return require.resolve(name);
|
||||
}
|
||||
catch (e) {
|
||||
if (e.code === 'MODULE_NOT_FOUND') {
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get a job description for a named job.
|
||||
*
|
||||
* @param name The name of the job.
|
||||
* @returns A description, or null if the job is not registered.
|
||||
*/
|
||||
get(name) {
|
||||
const [moduleName, exportName] = name.split(/#/, 2);
|
||||
const resolvedPath = this._resolve(moduleName);
|
||||
if (!resolvedPath) {
|
||||
return (0, rxjs_1.of)(null);
|
||||
}
|
||||
const pkg = require(resolvedPath);
|
||||
const handler = pkg[exportName || 'default'];
|
||||
if (!handler) {
|
||||
return (0, rxjs_1.of)(null);
|
||||
}
|
||||
function _getValue(...fields) {
|
||||
return fields.find((x) => core_1.schema.isJsonSchema(x)) || true;
|
||||
}
|
||||
const argument = _getValue(pkg.argument, handler.argument);
|
||||
const input = _getValue(pkg.input, handler.input);
|
||||
const output = _getValue(pkg.output, handler.output);
|
||||
const channels = _getValue(pkg.channels, handler.channels);
|
||||
return (0, rxjs_1.of)(Object.assign(handler.bind(undefined), {
|
||||
jobDescription: {
|
||||
argument,
|
||||
input,
|
||||
output,
|
||||
channels,
|
||||
},
|
||||
}));
|
||||
}
|
||||
}
|
||||
exports.NodeModuleJobRegistry = NodeModuleJobRegistry;
|
||||
//# sourceMappingURL=job-registry.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"job-registry.js","sourceRoot":"","sources":["job-registry.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,+CAAyD;AACzD,+BAAsC;AAGtC,MAAa,qBAAqB;IAMtB,QAAQ,CAAC,IAAY;QAC7B,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAA2B,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CACD,IAAkB;QAElB,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAEpD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,IAAA,SAAE,EAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAA,SAAE,EAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,SAAS,SAAS,CAAC,GAAG,MAAiB;YACrC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAC5D,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAE3D,OAAO,IAAA,SAAE,EACP,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;YACrC,cAAc,EAAE;gBACd,QAAQ;gBACR,KAAK;gBACL,MAAM;gBACN,QAAQ;aACT;SACF,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AA3DD,sDA2DC"}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { json, workspaces } from '@angular-devkit/core';
|
||||
import { BuilderInfo } from '../src';
|
||||
import { Target } from '../src/input-schema';
|
||||
import { ArchitectHost, Builder } from '../src/internal';
|
||||
export type NodeModulesBuilderInfo = BuilderInfo & {
|
||||
import: string;
|
||||
};
|
||||
export interface WorkspaceHost {
|
||||
getBuilderName(project: string, target: string): Promise<string>;
|
||||
getMetadata(project: string): Promise<json.JsonObject>;
|
||||
getOptions(project: string, target: string, configuration?: string): Promise<json.JsonObject>;
|
||||
hasTarget(project: string, target: string): Promise<boolean>;
|
||||
getDefaultConfigurationName(project: string, target: string): Promise<string | undefined>;
|
||||
}
|
||||
export declare class WorkspaceNodeModulesArchitectHost implements ArchitectHost<NodeModulesBuilderInfo> {
|
||||
protected _root: string;
|
||||
private workspaceHost;
|
||||
constructor(workspaceHost: WorkspaceHost, _root: string);
|
||||
constructor(workspace: workspaces.WorkspaceDefinition, _root: string);
|
||||
getBuilderNameForTarget(target: Target): Promise<string>;
|
||||
/**
|
||||
* Resolve a builder. This needs to be a string which will be used in a dynamic `import()`
|
||||
* clause. This should throw if no builder can be found. The dynamic import will throw if
|
||||
* it is unsupported.
|
||||
* @param builderStr The name of the builder to be used.
|
||||
* @returns All the info needed for the builder itself.
|
||||
*/
|
||||
resolveBuilder(builderStr: string, basePath?: string, seenBuilders?: Set<string>): Promise<NodeModulesBuilderInfo>;
|
||||
getCurrentDirectory(): Promise<string>;
|
||||
getWorkspaceRoot(): Promise<string>;
|
||||
getOptionsForTarget(target: Target): Promise<json.JsonObject | null>;
|
||||
getProjectMetadata(target: Target | string): Promise<json.JsonObject | null>;
|
||||
loadBuilder(info: NodeModulesBuilderInfo): Promise<Builder>;
|
||||
}
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.WorkspaceNodeModulesArchitectHost = void 0;
|
||||
const node_fs_1 = require("node:fs");
|
||||
const node_module_1 = require("node:module");
|
||||
const path = __importStar(require("node:path"));
|
||||
const node_v8_1 = require("node:v8");
|
||||
const internal_1 = require("../src/internal");
|
||||
// TODO_ESM: Update to use import.meta.url
|
||||
const localRequire = (0, node_module_1.createRequire)(__filename);
|
||||
function clone(obj) {
|
||||
try {
|
||||
return (0, node_v8_1.deserialize)((0, node_v8_1.serialize)(obj));
|
||||
}
|
||||
catch {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
}
|
||||
function findProjectTarget(workspace, project, target) {
|
||||
const projectDefinition = workspace.projects.get(project);
|
||||
if (!projectDefinition) {
|
||||
throw new Error(`Project "${project}" does not exist.`);
|
||||
}
|
||||
const targetDefinition = projectDefinition.targets.get(target);
|
||||
if (!targetDefinition) {
|
||||
throw new Error('Project target does not exist.');
|
||||
}
|
||||
if (!targetDefinition.builder) {
|
||||
throw new Error(`A builder is not set for target '${target}' in project '${project}'.`);
|
||||
}
|
||||
return targetDefinition;
|
||||
}
|
||||
class WorkspaceNodeModulesArchitectHost {
|
||||
_root;
|
||||
workspaceHost;
|
||||
constructor(workspaceOrHost, _root) {
|
||||
this._root = _root;
|
||||
if ('getBuilderName' in workspaceOrHost) {
|
||||
this.workspaceHost = workspaceOrHost;
|
||||
}
|
||||
else {
|
||||
this.workspaceHost = {
|
||||
async getBuilderName(project, target) {
|
||||
const { builder } = findProjectTarget(workspaceOrHost, project, target);
|
||||
return builder;
|
||||
},
|
||||
async getOptions(project, target, configuration) {
|
||||
const targetDefinition = findProjectTarget(workspaceOrHost, project, target);
|
||||
if (configuration === undefined) {
|
||||
return (targetDefinition.options ?? {});
|
||||
}
|
||||
if (!targetDefinition.configurations?.[configuration]) {
|
||||
throw new Error(`Configuration '${configuration}' for target '${target}' in project '${project}' is not set in the workspace.`);
|
||||
}
|
||||
return (targetDefinition.configurations?.[configuration] ?? {});
|
||||
},
|
||||
async getMetadata(project) {
|
||||
const projectDefinition = workspaceOrHost.projects.get(project);
|
||||
if (!projectDefinition) {
|
||||
throw new Error(`Project "${project}" does not exist.`);
|
||||
}
|
||||
return {
|
||||
root: projectDefinition.root,
|
||||
sourceRoot: projectDefinition.sourceRoot,
|
||||
prefix: projectDefinition.prefix,
|
||||
...clone(workspaceOrHost.extensions),
|
||||
...clone(projectDefinition.extensions),
|
||||
};
|
||||
},
|
||||
async hasTarget(project, target) {
|
||||
return !!workspaceOrHost.projects.get(project)?.targets.has(target);
|
||||
},
|
||||
async getDefaultConfigurationName(project, target) {
|
||||
return workspaceOrHost.projects.get(project)?.targets.get(target)?.defaultConfiguration;
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
async getBuilderNameForTarget(target) {
|
||||
return this.workspaceHost.getBuilderName(target.project, target.target);
|
||||
}
|
||||
/**
|
||||
* Resolve a builder. This needs to be a string which will be used in a dynamic `import()`
|
||||
* clause. This should throw if no builder can be found. The dynamic import will throw if
|
||||
* it is unsupported.
|
||||
* @param builderStr The name of the builder to be used.
|
||||
* @returns All the info needed for the builder itself.
|
||||
*/
|
||||
resolveBuilder(builderStr, basePath = this._root, seenBuilders) {
|
||||
if (seenBuilders?.has(builderStr)) {
|
||||
throw new Error('Circular builder alias references detected: ' + [...seenBuilders, builderStr]);
|
||||
}
|
||||
const [packageName, builderName] = builderStr.split(':', 2);
|
||||
if (!builderName) {
|
||||
throw new Error('No builder name specified.');
|
||||
}
|
||||
// Resolve and load the builders manifest from the package's `builders` field, if present
|
||||
const packageJsonPath = localRequire.resolve(packageName + '/package.json', {
|
||||
paths: [basePath],
|
||||
});
|
||||
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
||||
const buildersManifestRawPath = packageJson['builders'];
|
||||
if (!buildersManifestRawPath) {
|
||||
throw new Error(`Package ${JSON.stringify(packageName)} has no builders defined.`);
|
||||
}
|
||||
let buildersManifestPath = path.normalize(buildersManifestRawPath);
|
||||
if (path.isAbsolute(buildersManifestRawPath) || buildersManifestRawPath.startsWith('..')) {
|
||||
throw new Error(`Package "${packageName}" has an invalid builders manifest path: "${buildersManifestRawPath}"`);
|
||||
}
|
||||
buildersManifestPath = path.join(path.dirname(packageJsonPath), buildersManifestPath);
|
||||
const buildersManifest = JSON.parse((0, node_fs_1.readFileSync)(buildersManifestPath, 'utf-8'));
|
||||
const buildersManifestDirectory = path.dirname(buildersManifestPath);
|
||||
// Attempt to locate an entry for the specified builder by name
|
||||
const builder = buildersManifest.builders?.[builderName];
|
||||
if (!builder) {
|
||||
throw new Error(`Cannot find builder ${JSON.stringify(builderStr)}.`);
|
||||
}
|
||||
// Resolve alias reference if entry is a string
|
||||
if (typeof builder === 'string') {
|
||||
return this.resolveBuilder(builder, path.dirname(packageJsonPath), (seenBuilders ?? new Set()).add(builderStr));
|
||||
}
|
||||
// Determine builder implementation path (relative within package only)
|
||||
const implementationPath = builder.implementation && path.normalize(builder.implementation);
|
||||
if (!implementationPath) {
|
||||
throw new Error('Could not find the implementation for builder ' + builderStr);
|
||||
}
|
||||
if (path.isAbsolute(implementationPath) || implementationPath.startsWith('..')) {
|
||||
throw new Error(`Package "${packageName}" has an invalid builder implementation path: "${builderName}" --> "${builder.implementation}"`);
|
||||
}
|
||||
// Determine builder option schema path (relative within package only)
|
||||
let schemaPath = builder.schema;
|
||||
if (!schemaPath) {
|
||||
throw new Error('Could not find the schema for builder ' + builderStr);
|
||||
}
|
||||
if (path.isAbsolute(schemaPath) || path.normalize(schemaPath).startsWith('..')) {
|
||||
throw new Error(`Package "${packageName}" has an invalid builder schema path: "${builderName}" --> "${builder.schema}"`);
|
||||
}
|
||||
// The file could be either a package reference or in the local manifest directory.
|
||||
if (schemaPath.startsWith('.')) {
|
||||
schemaPath = path.join(buildersManifestDirectory, schemaPath);
|
||||
}
|
||||
else {
|
||||
const manifestRequire = (0, node_module_1.createRequire)(buildersManifestDirectory + '/');
|
||||
schemaPath = manifestRequire.resolve(schemaPath);
|
||||
}
|
||||
const schemaText = (0, node_fs_1.readFileSync)(schemaPath, 'utf-8');
|
||||
return Promise.resolve({
|
||||
name: builderStr,
|
||||
builderName,
|
||||
description: builder['description'],
|
||||
optionSchema: JSON.parse(schemaText),
|
||||
import: path.join(buildersManifestDirectory, implementationPath),
|
||||
});
|
||||
}
|
||||
async getCurrentDirectory() {
|
||||
return process.cwd();
|
||||
}
|
||||
async getWorkspaceRoot() {
|
||||
return this._root;
|
||||
}
|
||||
async getOptionsForTarget(target) {
|
||||
if (!(await this.workspaceHost.hasTarget(target.project, target.target))) {
|
||||
return null;
|
||||
}
|
||||
let options = await this.workspaceHost.getOptions(target.project, target.target);
|
||||
const targetConfiguration = target.configuration ||
|
||||
(await this.workspaceHost.getDefaultConfigurationName(target.project, target.target));
|
||||
if (targetConfiguration) {
|
||||
const configurations = targetConfiguration.split(',').map((c) => c.trim());
|
||||
for (const configuration of configurations) {
|
||||
options = {
|
||||
...options,
|
||||
...(await this.workspaceHost.getOptions(target.project, target.target, configuration)),
|
||||
};
|
||||
}
|
||||
}
|
||||
return clone(options);
|
||||
}
|
||||
async getProjectMetadata(target) {
|
||||
const projectName = typeof target === 'string' ? target : target.project;
|
||||
const metadata = this.workspaceHost.getMetadata(projectName);
|
||||
return metadata;
|
||||
}
|
||||
async loadBuilder(info) {
|
||||
const builder = await getBuilder(info.import);
|
||||
if (builder[internal_1.BuilderSymbol]) {
|
||||
return builder;
|
||||
}
|
||||
// Default handling code is for old builders that incorrectly export `default` with non-ESM module
|
||||
if (builder?.default[internal_1.BuilderSymbol]) {
|
||||
return builder.default;
|
||||
}
|
||||
throw new Error('Builder is not a builder');
|
||||
}
|
||||
}
|
||||
exports.WorkspaceNodeModulesArchitectHost = WorkspaceNodeModulesArchitectHost;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async function getBuilder(builderPath) {
|
||||
const builder = await Promise.resolve(`${builderPath}`).then(s => __importStar(require(s)));
|
||||
return 'default' in builder ? builder.default : builder;
|
||||
}
|
||||
//# sourceMappingURL=node-modules-architect-host.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+39
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@angular-devkit/architect",
|
||||
"version": "0.2102.1",
|
||||
"description": "Angular Build Facade",
|
||||
"experimental": true,
|
||||
"bin": {
|
||||
"architect": "./bin/cli.js"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"typings": "src/index.d.ts",
|
||||
"dependencies": {
|
||||
"@angular-devkit/core": "21.2.1",
|
||||
"rxjs": "7.8.2"
|
||||
},
|
||||
"builders": "./builders/builders.json",
|
||||
"keywords": [
|
||||
"Angular CLI",
|
||||
"Angular DevKit",
|
||||
"angular",
|
||||
"devkit",
|
||||
"sdk"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular-cli.git"
|
||||
},
|
||||
"packageManager": "pnpm@10.30.3",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
||||
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
||||
"yarn": ">= 1.13.0"
|
||||
},
|
||||
"author": "Angular Authors",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/angular/angular-cli/issues"
|
||||
},
|
||||
"homepage": "https://github.com/angular/angular-cli"
|
||||
}
|
||||
+269
@@ -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>;
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
"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);
|
||||
};
|
||||
})));
|
||||
}
|
||||
//# sourceMappingURL=api.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"api.js","sourceRoot":"","sources":["api.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AA4PH,0CAUC;AAED,8CAOC;AAkDD,wDAEC;AAMD,wDAeC;AAeD,0DA0BC;AA9XD,+BAAgF;AAIhF,uDAAiG;AAGxF,qGAHS,uBAAoB,OAGT;AAiP7B,8DAA8D;AAC9D,SAAgB,eAAe,CAAC,GAAQ;IACtC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QAClF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,UAAU,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC;AAC1C,CAAC;AAED,SAAgB,iBAAiB,CAAI,QAA0B;IAC7D,OAAO,IAAI,iBAAU,CAAC,CAAC,UAAU,EAAE,EAAE;QACnC,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,IAAI,CACpE,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAC3B,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CACnC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,UAAyB,EACzB,QAA0B;IAE1B,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAEjF,IAAI,CAAC;QACH,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC3B,MAAM;YACR,CAAC;YAED,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AA2BD;;GAEG;AACH,SAAgB,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAU;IAC/E,OAAO,GAAG,OAAO,IAAI,MAAM,GAAG,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACzF,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CACpC,SAAiB,EACjB,sBAA+B,EAC/B,qBAA8B;IAE9B,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,sBAAsB,IAAI,EAAE;QACjD,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,qBAAqB,IAAI,EAAE;QAC/C,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,uBAAuB,CACrC,OAAuB,EACvB,MAAc,EACd,SAA2B,EAC3B,eAAiC;IAEjC,IAAI,OAAO,GAAwB,IAAI,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;IAEnC,OAAO,IAAA,WAAI,EAAC,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAC1E,IAAA,gBAAS,EACP,CAAC,GAAG,EAAE,EAAE,CACN,IAAI,iBAAU,CAAgB,CAAC,QAAQ,EAAE,EAAE;QACzC,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEpD,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,WAAW,EAAE,CAAC;YAC3B,wFAAwF;YACxF,8BAA8B;YAC9B,mEAAmE;YACnE,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC,CAAC,CACL,CACF,CAAC;AACJ,CAAC"}
|
||||
+25
@@ -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>;
|
||||
}
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
"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;
|
||||
//# sourceMappingURL=architect.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+33
@@ -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;
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"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 });
|
||||
//# sourceMappingURL=builders-schema.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"builders-schema.js","sourceRoot":"","sources":["builders-schema.ts"],"names":[],"mappings":";AACA,mFAAmF;AACnF,oFAAoF"}
|
||||
+70
@@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -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>;
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
"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';
|
||||
}
|
||||
//# sourceMappingURL=create-builder.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+12
@@ -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 };
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
"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; } });
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,6CAA+B;AAMtB,oBAAI;AAJb,wCAAsB;AACtB,yCAA8D;AAArD,sGAAA,SAAS,OAAA;AAClB,mDAA+D;AAAtD,+GAAA,aAAa,OAAA"}
|
||||
+19
@@ -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;
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"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 });
|
||||
//# sourceMappingURL=input-schema.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"input-schema.js","sourceRoot":"","sources":["input-schema.ts"],"names":[],"mappings":";AACA,mFAAmF;AACnF,oFAAoF"}
|
||||
+39
@@ -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
@@ -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>;
|
||||
}
|
||||
+27
@@ -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.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');
|
||||
//# sourceMappingURL=internal.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"internal.js","sourceRoot":"","sources":["internal.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAMH,gGAAgG;AAChG,+DAA+D;AAE/D;;;;;GAKG;AACU,QAAA,aAAa,GAAkB,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AAE5F;;;;;GAKG;AACU,QAAA,oBAAoB,GAAkB,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC"}
|
||||
+332
@@ -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>;
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
"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);
|
||||
}
|
||||
//# sourceMappingURL=api.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"api.js","sourceRoot":"","sources":["api.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAsbH,oCAQC;AAvYD;;GAEG;AACH,IAAY,qBAQX;AARD,WAAY,qBAAqB;IAC/B,oCAAW,CAAA;IACX,oCAAW,CAAA;IAEX,6BAA6B;IAC7B,qCAAY,CAAA;IACZ,6FAA6F;IAC7F,0BAA0B;AAC5B,CAAC,EARW,qBAAqB,qCAArB,qBAAqB,QAQhC;AAkDD;;GAEG;AACH,IAAY,sBAeX;AAfD,WAAY,sBAAsB;IAChC,+BAA+B;IAC/B,uCAAa,CAAA;IACb,qCAAW,CAAA;IACX,mCAAS,CAAA;IACT,oCAAU,CAAA;IAEV,qBAAqB;IACrB,sCAAY,CAAA;IAEZ,6BAA6B;IAC7B,8CAAoB,CAAA;IACpB,+CAAqB,CAAA;IACrB,6CAAmB,CAAA;IACnB,gDAAsB,CAAA;AACxB,CAAC,EAfW,sBAAsB,sCAAtB,sBAAsB,QAejC;AAiID;;GAEG;AACH,IAAY,QA2BX;AA3BD,WAAY,QAAQ;IAClB;;OAEG;IACH,6BAAiB,CAAA;IAEjB;;;OAGG;IACH,2BAAe,CAAA;IAEf;;;OAGG;IACH,+BAAmB,CAAA;IAEnB;;OAEG;IACH,2BAAe,CAAA;IAEf;;OAEG;IACH,+BAAmB,CAAA;AACrB,CAAC,EA3BW,QAAQ,wBAAR,QAAQ,QA2BnB;AAiJD,SAAgB,YAAY,CAC1B,KAAc;IAEd,MAAM,GAAG,GAAG,KAA4B,CAAC;IAEzC,OAAO,CACL,OAAO,GAAG,IAAI,UAAU,IAAI,OAAO,GAAG,CAAC,cAAc,IAAI,QAAQ,IAAI,GAAG,CAAC,cAAc,KAAK,IAAI,CACjG,CAAC;AACJ,CAAC"}
|
||||
+47
@@ -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>;
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
"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);
|
||||
}
|
||||
//# sourceMappingURL=create-job-handler.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create-job-handler.js","sourceRoot":"","sources":["create-job-handler.ts"],"names":[],"mappings":"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"}
|
||||
+31
@@ -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>;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
"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.
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=dispatcher.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["dispatcher.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AA8BH,4CAyCC;AApED,+BAAkG;AAClG,2CAAuD;AAsBvD;;;GAGG;AACH,SAAgB,gBAAgB,CAC9B,UAA8C,EAAE;IAEhD,IAAI,eAAe,GAAmB,IAAI,CAAC;IAC3C,MAAM,uBAAuB,GAA8C,EAAE,CAAC;IAE9E,MAAM,GAAG,GAAgD,MAAM,CAAC,MAAM,CACpE,CAAC,QAAmB,EAAE,OAA0B,EAAE,EAAE;QAClD,MAAM,aAAa,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzF,IAAI,QAAQ,GAAgD,IAAI,CAAC;QAEjE,IAAI,aAAa,EAAE,CAAC;YAClB,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACpE,CAAC;aAAM,IAAI,eAAe,EAAE,CAAC;YAC3B,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,oCAAwB,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAElD,OAAO,QAAQ,CAAC,WAAW,CAAC;IAC9B,CAAC,EACD;QACE,cAAc,EAAE,OAAO;KACxB,CACF,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;QACxB,aAAa,CAAC,IAAkE;YAC9E,IAAI,IAAA,kBAAY,EAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YAClF,CAAC;YAED,eAAe,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,iBAAiB,CAAC,SAAuC,EAAE,IAAa;YACtE,uBAAuB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,gEAAgE;KACjE,CAAsC,CAAC;AAC1C,CAAC"}
|
||||
+15
@@ -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);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
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;
|
||||
//# sourceMappingURL=exception.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"exception.js","sourceRoot":"","sources":["exception.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,+CAAqD;AAGrD,MAAa,iCAAkC,SAAQ,oBAAa;IAClE,YAAY,IAAa;QACvB,KAAK,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7D,CAAC;CACF;AAJD,8EAIC;AAED,MAAa,wBAAyB,SAAQ,oBAAa;IACzD,YAAY,IAAa;QACvB,KAAK,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC5D,CAAC;CACF;AAJD,4DAIC"}
|
||||
+19
@@ -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>;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
"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;
|
||||
//# sourceMappingURL=fallback-registry.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"fallback-registry.js","sourceRoot":"","sources":["fallback-registry.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAGH,+BAA0D;AAG1D;;GAEG;AACH,MAAa,gBAAgB;IAOf;IADZ,YACY,aAIJ,EAAE;QAJE,eAAU,GAAV,UAAU,CAIZ;IACP,CAAC;IAEJ,WAAW,CAAC,QAAkB;QAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CAID,IAAa;QACb,OAAO,IAAA,WAAI,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAC/B,IAAA,gBAAS,EAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAU,IAAI,CAAC,CAAC,EACxC,IAAA,YAAK,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,CAAC,CAC/B,CAAC;IACJ,CAAC;CACF;AA5BD,4CA4BC"}
|
||||
+16
@@ -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 };
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
"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);
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,qDAAuC;AAS9B,4BAAQ;AAPjB,wCAAsB;AACtB,uDAAqC;AACrC,8CAA4B;AAC5B,+CAA6B;AAC7B,sDAAoC;AACpC,oDAAkC;AAClC,qDAAmC"}
|
||||
+44
@@ -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[];
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
"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;
|
||||
//# sourceMappingURL=simple-registry.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"simple-registry.js","sourceRoot":"","sources":["simple-registry.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,+CAAyD;AACzD,+BAAsC;AACtC,+BAAoF;AACpF,2CAAgE;AAQhE;;GAEG;AACH,MAAa,iBAAiB;IAMpB,SAAS,GAAG,IAAI,GAAG,EAGxB,CAAC;IAEJ,GAAG,CAID,IAAa;QACb,OAAO,IAAA,SAAE,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAA2C,IAAI,IAAI,CAAC,CAAC;IACzF,CAAC;IA2BD,QAAQ,CACN,aAA+D,EAC/D,mBAAgF,EAAE,EAClF,UAA8B,EAAE;QAEhC,2BAA2B;QAC3B,IAAI,OAAO,aAAa,IAAI,QAAQ,EAAE,CAAC;YACrC,IAAI,CAAC,IAAA,kBAAY,EAAC,gBAAgB,CAAC,EAAE,CAAC;gBACpC,oBAAoB;gBACpB,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;YACnE,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,IAAA,kBAAY,EAAC,aAAa,CAAC,EAAE,CAAC;YACvC,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE,CAAC;gBACzC,oBAAoB;gBACpB,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;YACxE,CAAC;YAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,aAAa,CAAC,cAAc,CAAC,IAAI,IAAI,gBAAgB,CAAC,IAAI,CAAC;YACxF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;YACvD,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAES,SAAS,CAKjB,IAAa,EACb,OAA+C,EAC/C,OAA2B;QAE3B,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,gCAAgC;YAChC,MAAM,IAAI,6CAAiC,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QAED,uFAAuF;QACvF,MAAM,QAAQ,GAAG,aAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxF,MAAM,KAAK,GAAG,aAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,aAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAElF,8BAA8B;QAC9B,MAAM,cAAc,GAAmB;YACrC,IAAI;YACJ,QAAQ;YACR,MAAM;YACN,KAAK;SACN,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;YACxD,cAAc;SACf,CAA0F,CAAC;QAC5F,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;CACF;AAjHD,8CAiHC"}
|
||||
+77
@@ -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>;
|
||||
}
|
||||
+395
@@ -0,0 +1,395 @@
|
||||
"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,
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=simple-scheduler.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+26
@@ -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>;
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
"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 || {});
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=strategy.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["strategy.ts"],"names":[],"mappings":"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"}
|
||||
+15
@@ -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];
|
||||
};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
"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 });
|
||||
//# sourceMappingURL=types.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
|
||||
+12
@@ -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 {};
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
"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;
|
||||
}
|
||||
//# sourceMappingURL=options.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"options.js","sourceRoot":"","sources":["options.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAQH,oCAwBC;AA9BD,+CAA4C;AAM5C,SAAgB,YAAY,CAC1B,WAA4B,EAC5B,eAAgC;IAEhC,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,OAAO,GAAG;QACd,GAAG,WAAW;QACd,GAAG,eAAe;KACnB,CAAC;IAEF,wDAAwD;IACxD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAE9B,IAAI,WAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,WAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
||||
+15
@@ -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;
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"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 });
|
||||
//# sourceMappingURL=output-schema.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"output-schema.js","sourceRoot":"","sources":["output-schema.ts"],"names":[],"mappings":";AACA,mFAAmF;AACnF,oFAAoF"}
|
||||
+33
@@ -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"]
|
||||
}
|
||||
+21
@@ -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"
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
"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 = {}));
|
||||
//# sourceMappingURL=progress-schema.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"progress-schema.js","sourceRoot":"","sources":["progress-schema.ts"],"names":[],"mappings":";AACA,mFAAmF;AACnF,oFAAoF;;;AAcpF,IAAY,KAKX;AALD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,4BAAmB,CAAA;IACnB,4BAAmB,CAAA;IACnB,4BAAmB,CAAA;AACvB,CAAC,EALW,KAAK,qBAAL,KAAK,QAKhB"}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user