123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- "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.FileSystemEngineHostBase = exports.SchematicNameCollisionException = exports.SchematicMissingDescriptionException = exports.SchematicMissingFieldsException = exports.CollectionMissingFieldsException = exports.CollectionMissingSchematicsMapException = exports.FactoryCannotBeResolvedException = exports.SchematicMissingFactoryException = exports.InvalidCollectionJsonException = exports.CollectionCannotBeResolvedException = void 0;
- const core_1 = require("@angular-devkit/core");
- const node_1 = require("@angular-devkit/core/node");
- const fs_1 = require("fs");
- const path_1 = require("path");
- const rxjs_1 = require("rxjs");
- const src_1 = require("../src");
- const file_system_utility_1 = require("./file-system-utility");
- class CollectionCannotBeResolvedException extends core_1.BaseException {
- constructor(name) {
- super(`Collection ${JSON.stringify(name)} cannot be resolved.`);
- }
- }
- exports.CollectionCannotBeResolvedException = CollectionCannotBeResolvedException;
- class InvalidCollectionJsonException extends core_1.BaseException {
- constructor(_name, path, jsonException) {
- let msg = `Collection JSON at path ${JSON.stringify(path)} is invalid.`;
- if (jsonException) {
- msg = `${msg} ${jsonException.message}`;
- }
- super(msg);
- }
- }
- exports.InvalidCollectionJsonException = InvalidCollectionJsonException;
- class SchematicMissingFactoryException extends core_1.BaseException {
- constructor(name) {
- super(`Schematic ${JSON.stringify(name)} is missing a factory.`);
- }
- }
- exports.SchematicMissingFactoryException = SchematicMissingFactoryException;
- class FactoryCannotBeResolvedException extends core_1.BaseException {
- constructor(name) {
- super(`Schematic ${JSON.stringify(name)} cannot resolve the factory.`);
- }
- }
- exports.FactoryCannotBeResolvedException = FactoryCannotBeResolvedException;
- class CollectionMissingSchematicsMapException extends core_1.BaseException {
- constructor(name) {
- super(`Collection "${name}" does not have a schematics map.`);
- }
- }
- exports.CollectionMissingSchematicsMapException = CollectionMissingSchematicsMapException;
- class CollectionMissingFieldsException extends core_1.BaseException {
- constructor(name) {
- super(`Collection "${name}" is missing fields.`);
- }
- }
- exports.CollectionMissingFieldsException = CollectionMissingFieldsException;
- class SchematicMissingFieldsException extends core_1.BaseException {
- constructor(name) {
- super(`Schematic "${name}" is missing fields.`);
- }
- }
- exports.SchematicMissingFieldsException = SchematicMissingFieldsException;
- class SchematicMissingDescriptionException extends core_1.BaseException {
- constructor(name) {
- super(`Schematics "${name}" does not have a description.`);
- }
- }
- exports.SchematicMissingDescriptionException = SchematicMissingDescriptionException;
- class SchematicNameCollisionException extends core_1.BaseException {
- constructor(name) {
- super(`Schematics/alias ${JSON.stringify(name)} collides with another alias or schematic` +
- ' name.');
- }
- }
- exports.SchematicNameCollisionException = SchematicNameCollisionException;
- /**
- * A EngineHost base class that uses the file system to resolve collections. This is the base of
- * all other EngineHost provided by the tooling part of the Schematics library.
- */
- class FileSystemEngineHostBase {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- _transforms = [];
- _contextTransforms = [];
- _taskFactories = new Map();
- listSchematicNames(collection, includeHidden) {
- const schematics = [];
- for (const key of Object.keys(collection.schematics)) {
- const schematic = collection.schematics[key];
- if ((schematic.hidden && !includeHidden) || schematic.private) {
- continue;
- }
- // If extends is present without a factory it is an alias, do not return it
- // unless it is from another collection.
- if (!schematic.extends || schematic.factory) {
- schematics.push(key);
- }
- else if (schematic.extends && schematic.extends.indexOf(':') !== -1) {
- schematics.push(key);
- }
- }
- return schematics;
- }
- registerOptionsTransform(t) {
- this._transforms.push(t);
- }
- registerContextTransform(t) {
- this._contextTransforms.push(t);
- }
- /**
- *
- * @param name
- * @return {{path: string}}
- */
- createCollectionDescription(name, requester) {
- const path = this._resolveCollectionPath(name, requester?.path);
- const jsonValue = (0, file_system_utility_1.readJsonFile)(path);
- if (!jsonValue || typeof jsonValue != 'object' || Array.isArray(jsonValue)) {
- throw new InvalidCollectionJsonException(name, path);
- }
- // normalize extends property to an array
- if (typeof jsonValue['extends'] === 'string') {
- jsonValue['extends'] = [jsonValue['extends']];
- }
- const description = this._transformCollectionDescription(name, {
- ...jsonValue,
- path,
- });
- if (!description || !description.name) {
- throw new InvalidCollectionJsonException(name, path);
- }
- // Validate aliases.
- const allNames = Object.keys(description.schematics);
- for (const schematicName of Object.keys(description.schematics)) {
- const aliases = description.schematics[schematicName].aliases || [];
- for (const alias of aliases) {
- if (allNames.indexOf(alias) != -1) {
- throw new SchematicNameCollisionException(alias);
- }
- }
- allNames.push(...aliases);
- }
- return description;
- }
- createSchematicDescription(name, collection) {
- // Resolve aliases first.
- for (const schematicName of Object.keys(collection.schematics)) {
- const schematicDescription = collection.schematics[schematicName];
- if (schematicDescription.aliases && schematicDescription.aliases.indexOf(name) != -1) {
- name = schematicName;
- break;
- }
- }
- if (!(name in collection.schematics)) {
- return null;
- }
- const collectionPath = (0, path_1.dirname)(collection.path);
- const partialDesc = collection.schematics[name];
- if (!partialDesc) {
- return null;
- }
- if (partialDesc.extends) {
- const index = partialDesc.extends.indexOf(':');
- const collectionName = index !== -1 ? partialDesc.extends.slice(0, index) : null;
- const schematicName = index === -1 ? partialDesc.extends : partialDesc.extends.slice(index + 1);
- if (collectionName !== null) {
- const extendCollection = this.createCollectionDescription(collectionName);
- return this.createSchematicDescription(schematicName, extendCollection);
- }
- else {
- return this.createSchematicDescription(schematicName, collection);
- }
- }
- // Use any on this ref as we don't have the OptionT here, but we don't need it (we only need
- // the path).
- if (!partialDesc.factory) {
- throw new SchematicMissingFactoryException(name);
- }
- const resolvedRef = this._resolveReferenceString(partialDesc.factory, collectionPath, collection);
- if (!resolvedRef) {
- throw new FactoryCannotBeResolvedException(name);
- }
- let schema = partialDesc.schema;
- let schemaJson = undefined;
- if (schema) {
- if (!(0, path_1.isAbsolute)(schema)) {
- schema = (0, path_1.join)(collectionPath, schema);
- }
- schemaJson = (0, file_system_utility_1.readJsonFile)(schema);
- }
- // The schematic path is used to resolve URLs.
- // We should be able to just do `dirname(resolvedRef.path)` but for compatibility with
- // Bazel under Windows this directory needs to be resolved from the collection instead.
- // This is needed because on Bazel under Windows the data files (such as the collection or
- // url files) are not in the same place as the compiled JS.
- const maybePath = (0, path_1.join)(collectionPath, partialDesc.factory);
- const path = (0, fs_1.existsSync)(maybePath) && (0, fs_1.statSync)(maybePath).isDirectory() ? maybePath : (0, path_1.dirname)(maybePath);
- return this._transformSchematicDescription(name, collection, {
- ...partialDesc,
- schema,
- schemaJson,
- name,
- path,
- factoryFn: resolvedRef.ref,
- collection,
- });
- }
- createSourceFromUrl(url) {
- switch (url.protocol) {
- case null:
- case 'file:':
- return (context) => {
- // Check if context has necessary FileSystemSchematicContext path property
- const fileDescription = context.schematic.description;
- if (fileDescription.path === undefined) {
- throw new Error('Unsupported schematic context. Expected a FileSystemSchematicContext.');
- }
- // Resolve all file:///a/b/c/d from the schematic's own path, and not the current
- // path.
- const root = (0, core_1.normalize)((0, path_1.resolve)(fileDescription.path, url.path || ''));
- return new src_1.HostCreateTree(new core_1.virtualFs.ScopedHost(new node_1.NodeJsSyncHost(), root));
- };
- }
- return null;
- }
- transformOptions(schematic, options, context) {
- const transform = async () => {
- let transformedOptions = options;
- for (const transformer of this._transforms) {
- const transformerResult = transformer(schematic, transformedOptions, context);
- transformedOptions = await ((0, rxjs_1.isObservable)(transformerResult)
- ? (0, rxjs_1.lastValueFrom)(transformerResult)
- : transformerResult);
- }
- return transformedOptions;
- };
- return (0, rxjs_1.from)(transform());
- }
- transformContext(context) {
- return this._contextTransforms.reduce((acc, curr) => curr(acc), context);
- }
- getSchematicRuleFactory(schematic, _collection) {
- return schematic.factoryFn;
- }
- registerTaskExecutor(factory, options) {
- this._taskFactories.set(factory.name, () => (0, rxjs_1.from)(factory.create(options)));
- }
- createTaskExecutor(name) {
- const factory = this._taskFactories.get(name);
- if (factory) {
- return factory();
- }
- return (0, rxjs_1.throwError)(new src_1.UnregisteredTaskException(name));
- }
- hasTaskExecutor(name) {
- return this._taskFactories.has(name);
- }
- }
- exports.FileSystemEngineHostBase = FileSystemEngineHostBase;
|