Updated the files.

This commit is contained in:
Batuhan Berk Başoğlu 2024-02-08 19:38:41 -05:00
parent 1553e6b971
commit 753967d4f5
23418 changed files with 3784666 additions and 0 deletions

View file

@ -0,0 +1,19 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { Rule } from '@angular-devkit/schematics';
export interface DeclarationToNgModuleOptions {
module?: string;
path?: string;
name: string;
flat?: boolean;
export?: boolean;
type: string;
skipImport?: boolean;
standalone?: boolean;
}
export declare function addDeclarationToNgModule(options: DeclarationToNgModuleOptions): Rule;

View file

@ -0,0 +1,68 @@
"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.io/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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addDeclarationToNgModule = void 0;
const schematics_1 = require("@angular-devkit/schematics");
const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
const ast_utils_1 = require("./ast-utils");
const change_1 = require("./change");
const find_module_1 = require("./find-module");
function addDeclarationToNgModule(options) {
return (host) => {
const modulePath = options.module;
if (options.skipImport || options.standalone || !modulePath) {
return host;
}
const sourceText = host.readText(modulePath);
const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
const filePath = `/${options.path}/` +
(options.flat ? '' : schematics_1.strings.dasherize(options.name) + '/') +
schematics_1.strings.dasherize(options.name) +
(options.type ? '.' : '') +
schematics_1.strings.dasherize(options.type);
const importPath = (0, find_module_1.buildRelativePath)(modulePath, filePath);
const classifiedName = schematics_1.strings.classify(options.name) + schematics_1.strings.classify(options.type);
const changes = (0, ast_utils_1.addDeclarationToModule)(source, modulePath, classifiedName, importPath);
if (options.export) {
changes.push(...(0, ast_utils_1.addSymbolToNgModuleMetadata)(source, modulePath, 'exports', classifiedName));
}
const recorder = host.beginUpdate(modulePath);
for (const change of changes) {
if (change instanceof change_1.InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
}
host.commitUpdate(recorder);
return host;
};
}
exports.addDeclarationToNgModule = addDeclarationToNgModule;

View file

@ -0,0 +1,106 @@
/**
* @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.io/license
*/
import * as ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript';
import { Change } from './change';
/**
* Add Import `import { symbolName } from fileName` if the import doesn't exit
* already. Assumes fileToEdit can be resolved and accessed.
* @param fileToEdit File we want to add import to.
* @param symbolName Item to import.
* @param fileName Path to the file.
* @param isDefault If true, import follows style for importing default exports.
* @param alias Alias that the symbol should be inserted under.
* @return Change
*/
export declare function insertImport(source: ts.SourceFile, fileToEdit: string, symbolName: string, fileName: string, isDefault?: boolean, alias?: string): Change;
/**
* Find all nodes from the AST in the subtree of node of SyntaxKind kind.
* @param node
* @param kind
* @param max The maximum number of items to return.
* @param recursive Continue looking for nodes of kind recursive until end
* the last child even when node of kind has been found.
* @return all nodes of kind, or [] if none is found
*/
export declare function findNodes(node: ts.Node, kind: ts.SyntaxKind, max?: number, recursive?: boolean): ts.Node[];
/**
* Find all nodes from the AST in the subtree that satisfy a type guard.
* @param node
* @param guard
* @param max The maximum number of items to return.
* @param recursive Continue looking for nodes of kind recursive until end
* the last child even when node of kind has been found.
* @return all nodes that satisfy the type guard, or [] if none is found
*/
export declare function findNodes<T extends ts.Node>(node: ts.Node, guard: (node: ts.Node) => node is T, max?: number, recursive?: boolean): T[];
/**
* Get all the nodes from a source.
* @param sourceFile The source file object.
* @returns {Array<ts.Node>} An array of all the nodes in the source.
*/
export declare function getSourceNodes(sourceFile: ts.SourceFile): ts.Node[];
export declare function findNode(node: ts.Node, kind: ts.SyntaxKind, text: string): ts.Node | null;
/**
* Insert `toInsert` after the last occurence of `ts.SyntaxKind[nodes[i].kind]`
* or after the last of occurence of `syntaxKind` if the last occurence is a sub child
* of ts.SyntaxKind[nodes[i].kind] and save the changes in file.
*
* @param nodes insert after the last occurence of nodes
* @param toInsert string to insert
* @param file file to insert changes into
* @param fallbackPos position to insert if toInsert happens to be the first occurence
* @param syntaxKind the ts.SyntaxKind of the subchildren to insert after
* @return Change instance
* @throw Error if toInsert is first occurence but fall back is not set
*/
export declare function insertAfterLastOccurrence(nodes: ts.Node[] | ts.NodeArray<ts.Node>, toInsert: string, file: string, fallbackPos: number, syntaxKind?: ts.SyntaxKind): Change;
export declare function getDecoratorMetadata(source: ts.SourceFile, identifier: string, module: string): ts.Node[];
export declare function getMetadataField(node: ts.ObjectLiteralExpression, metadataField: string): ts.ObjectLiteralElement[];
export declare function addSymbolToNgModuleMetadata(source: ts.SourceFile, ngModulePath: string, metadataField: string, symbolName: string, importPath?: string | null): Change[];
/**
* Custom function to insert a declaration (component, pipe, directive)
* into NgModule declarations. It also imports the component.
*/
export declare function addDeclarationToModule(source: ts.SourceFile, modulePath: string, classifiedName: string, importPath: string): Change[];
/**
* Custom function to insert an NgModule into NgModule imports. It also imports the module.
*/
export declare function addImportToModule(source: ts.SourceFile, modulePath: string, classifiedName: string, importPath: string): Change[];
/**
* Custom function to insert a provider into NgModule. It also imports it.
*/
export declare function addProviderToModule(source: ts.SourceFile, modulePath: string, classifiedName: string, importPath: string): Change[];
/**
* Custom function to insert an export into NgModule. It also imports it.
*/
export declare function addExportToModule(source: ts.SourceFile, modulePath: string, classifiedName: string, importPath: string): Change[];
/**
* Custom function to insert an export into NgModule. It also imports it.
*/
export declare function addBootstrapToModule(source: ts.SourceFile, modulePath: string, classifiedName: string, importPath: string): Change[];
/**
* Determine if an import already exists.
*/
export declare function isImported(source: ts.SourceFile, classifiedName: string, importPath: string): boolean;
/**
* Returns the RouterModule declaration from NgModule metadata, if any.
*/
export declare function getRouterModuleDeclaration(source: ts.SourceFile): ts.Expression | undefined;
/**
* Adds a new route declaration to a router module (i.e. has a RouterModule declaration)
*/
export declare function addRouteDeclarationToModule(source: ts.SourceFile, fileToAdd: string, routeLiteral: string): Change;
/**
* Determines if a SourceFile has a top-level declaration whose name matches a specific symbol.
* Can be used to avoid conflicts when inserting new imports into a file.
* @param sourceFile File in which to search.
* @param symbolName Name of the symbol to search for.
* @param skipModule Path of the module that the symbol may have been imported from. Used to
* avoid false positives where the same symbol we're looking for may have been imported.
*/
export declare function hasTopLevelIdentifier(sourceFile: ts.SourceFile, symbolName: string, skipModule?: string | null): boolean;

544
my-app/node_modules/@schematics/angular/utility/ast-utils.js generated vendored Executable file
View file

@ -0,0 +1,544 @@
"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.io/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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasTopLevelIdentifier = exports.addRouteDeclarationToModule = exports.getRouterModuleDeclaration = exports.isImported = exports.addBootstrapToModule = exports.addExportToModule = exports.addProviderToModule = exports.addImportToModule = exports.addDeclarationToModule = exports.addSymbolToNgModuleMetadata = exports.getMetadataField = exports.getDecoratorMetadata = exports.insertAfterLastOccurrence = exports.findNode = exports.getSourceNodes = exports.findNodes = exports.insertImport = void 0;
const core_1 = require("@angular-devkit/core");
const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
const change_1 = require("./change");
const eol_1 = require("./eol");
/**
* Add Import `import { symbolName } from fileName` if the import doesn't exit
* already. Assumes fileToEdit can be resolved and accessed.
* @param fileToEdit File we want to add import to.
* @param symbolName Item to import.
* @param fileName Path to the file.
* @param isDefault If true, import follows style for importing default exports.
* @param alias Alias that the symbol should be inserted under.
* @return Change
*/
function insertImport(source, fileToEdit, symbolName, fileName, isDefault = false, alias) {
const rootNode = source;
const allImports = findNodes(rootNode, ts.isImportDeclaration);
const importExpression = alias ? `${symbolName} as ${alias}` : symbolName;
// get nodes that map to import statements from the file fileName
const relevantImports = allImports.filter((node) => {
return ts.isStringLiteralLike(node.moduleSpecifier) && node.moduleSpecifier.text === fileName;
});
if (relevantImports.length > 0) {
const hasNamespaceImport = relevantImports.some((node) => {
return node.importClause?.namedBindings?.kind === ts.SyntaxKind.NamespaceImport;
});
// if imports * from fileName, don't add symbolName
if (hasNamespaceImport) {
return new change_1.NoopChange();
}
const imports = relevantImports.flatMap((node) => {
return node.importClause?.namedBindings && ts.isNamedImports(node.importClause.namedBindings)
? node.importClause.namedBindings.elements
: [];
});
// insert import if it's not there
if (!imports.some((node) => (node.propertyName || node.name).text === symbolName)) {
const fallbackPos = findNodes(relevantImports[0], ts.SyntaxKind.CloseBraceToken)[0].getStart() ||
findNodes(relevantImports[0], ts.SyntaxKind.FromKeyword)[0].getStart();
return insertAfterLastOccurrence(imports, `, ${importExpression}`, fileToEdit, fallbackPos);
}
return new change_1.NoopChange();
}
// no such import declaration exists
const useStrict = findNodes(rootNode, ts.isStringLiteral).filter((n) => n.text === 'use strict');
let fallbackPos = 0;
if (useStrict.length > 0) {
fallbackPos = useStrict[0].end;
}
const open = isDefault ? '' : '{ ';
const close = isDefault ? '' : ' }';
const eol = (0, eol_1.getEOL)(rootNode.getText());
// if there are no imports or 'use strict' statement, insert import at beginning of file
const insertAtBeginning = allImports.length === 0 && useStrict.length === 0;
const separator = insertAtBeginning ? '' : `;${eol}`;
const toInsert = `${separator}import ${open}${importExpression}${close}` +
` from '${fileName}'${insertAtBeginning ? `;${eol}` : ''}`;
return insertAfterLastOccurrence(allImports, toInsert, fileToEdit, fallbackPos, ts.SyntaxKind.StringLiteral);
}
exports.insertImport = insertImport;
function findNodes(node, kindOrGuard, max = Infinity, recursive = false) {
if (!node || max == 0) {
return [];
}
const test = typeof kindOrGuard === 'function'
? kindOrGuard
: (node) => node.kind === kindOrGuard;
const arr = [];
if (test(node)) {
arr.push(node);
max--;
}
if (max > 0 && (recursive || !test(node))) {
for (const child of node.getChildren()) {
findNodes(child, test, max, recursive).forEach((node) => {
if (max > 0) {
arr.push(node);
}
max--;
});
if (max <= 0) {
break;
}
}
}
return arr;
}
exports.findNodes = findNodes;
/**
* Get all the nodes from a source.
* @param sourceFile The source file object.
* @returns {Array<ts.Node>} An array of all the nodes in the source.
*/
function getSourceNodes(sourceFile) {
const nodes = [sourceFile];
const result = [];
while (nodes.length > 0) {
const node = nodes.shift();
if (node) {
result.push(node);
if (node.getChildCount(sourceFile) >= 0) {
nodes.unshift(...node.getChildren());
}
}
}
return result;
}
exports.getSourceNodes = getSourceNodes;
function findNode(node, kind, text) {
if (node.kind === kind && node.getText() === text) {
return node;
}
let foundNode = null;
ts.forEachChild(node, (childNode) => {
foundNode = foundNode || findNode(childNode, kind, text);
});
return foundNode;
}
exports.findNode = findNode;
/**
* Helper for sorting nodes.
* @return function to sort nodes in increasing order of position in sourceFile
*/
function nodesByPosition(first, second) {
return first.getStart() - second.getStart();
}
/**
* Insert `toInsert` after the last occurence of `ts.SyntaxKind[nodes[i].kind]`
* or after the last of occurence of `syntaxKind` if the last occurence is a sub child
* of ts.SyntaxKind[nodes[i].kind] and save the changes in file.
*
* @param nodes insert after the last occurence of nodes
* @param toInsert string to insert
* @param file file to insert changes into
* @param fallbackPos position to insert if toInsert happens to be the first occurence
* @param syntaxKind the ts.SyntaxKind of the subchildren to insert after
* @return Change instance
* @throw Error if toInsert is first occurence but fall back is not set
*/
function insertAfterLastOccurrence(nodes, toInsert, file, fallbackPos, syntaxKind) {
let lastItem;
for (const node of nodes) {
if (!lastItem || lastItem.getStart() < node.getStart()) {
lastItem = node;
}
}
if (syntaxKind && lastItem) {
lastItem = findNodes(lastItem, syntaxKind).sort(nodesByPosition).pop();
}
if (!lastItem && fallbackPos == undefined) {
throw new Error(`tried to insert ${toInsert} as first occurence with no fallback position`);
}
const lastItemPosition = lastItem ? lastItem.getEnd() : fallbackPos;
return new change_1.InsertChange(file, lastItemPosition, toInsert);
}
exports.insertAfterLastOccurrence = insertAfterLastOccurrence;
function _angularImportsFromNode(node) {
const ms = node.moduleSpecifier;
let modulePath;
switch (ms.kind) {
case ts.SyntaxKind.StringLiteral:
modulePath = ms.text;
break;
default:
return {};
}
if (!modulePath.startsWith('@angular/')) {
return {};
}
if (node.importClause) {
if (node.importClause.name) {
// This is of the form `import Name from 'path'`. Ignore.
return {};
}
else if (node.importClause.namedBindings) {
const nb = node.importClause.namedBindings;
if (nb.kind == ts.SyntaxKind.NamespaceImport) {
// This is of the form `import * as name from 'path'`. Return `name.`.
return {
[nb.name.text + '.']: modulePath,
};
}
else {
// This is of the form `import {a,b,c} from 'path'`
const namedImports = nb;
return namedImports.elements
.map((is) => (is.propertyName ? is.propertyName.text : is.name.text))
.reduce((acc, curr) => {
acc[curr] = modulePath;
return acc;
}, {});
}
}
return {};
}
else {
// This is of the form `import 'path';`. Nothing to do.
return {};
}
}
function getDecoratorMetadata(source, identifier, module) {
const angularImports = findNodes(source, ts.isImportDeclaration)
.map((node) => _angularImportsFromNode(node))
.reduce((acc, current) => {
for (const key of Object.keys(current)) {
acc[key] = current[key];
}
return acc;
}, {});
return getSourceNodes(source)
.filter((node) => {
return (node.kind == ts.SyntaxKind.Decorator &&
node.expression.kind == ts.SyntaxKind.CallExpression);
})
.map((node) => node.expression)
.filter((expr) => {
if (expr.expression.kind == ts.SyntaxKind.Identifier) {
const id = expr.expression;
return id.text == identifier && angularImports[id.text] === module;
}
else if (expr.expression.kind == ts.SyntaxKind.PropertyAccessExpression) {
// This covers foo.NgModule when importing * as foo.
const paExpr = expr.expression;
// If the left expression is not an identifier, just give up at that point.
if (paExpr.expression.kind !== ts.SyntaxKind.Identifier) {
return false;
}
const id = paExpr.name.text;
const moduleId = paExpr.expression.text;
return id === identifier && angularImports[moduleId + '.'] === module;
}
return false;
})
.filter((expr) => expr.arguments[0] && expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression)
.map((expr) => expr.arguments[0]);
}
exports.getDecoratorMetadata = getDecoratorMetadata;
function getMetadataField(node, metadataField) {
return (node.properties
.filter(ts.isPropertyAssignment)
// Filter out every fields that's not "metadataField". Also handles string literals
// (but not expressions).
.filter(({ name }) => {
return (ts.isIdentifier(name) || ts.isStringLiteral(name)) && name.text === metadataField;
}));
}
exports.getMetadataField = getMetadataField;
function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbolName, importPath = null) {
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
const node = nodes[0];
// Find the decorator declaration.
if (!node || !ts.isObjectLiteralExpression(node)) {
return [];
}
// Get all the children property assignment of object literals.
const matchingProperties = getMetadataField(node, metadataField);
if (matchingProperties.length == 0) {
// We haven't found the field in the metadata declaration. Insert a new field.
let position;
let toInsert;
if (node.properties.length == 0) {
position = node.getEnd() - 1;
toInsert = `\n ${metadataField}: [\n${core_1.tags.indentBy(4) `${symbolName}`}\n ]\n`;
}
else {
const childNode = node.properties[node.properties.length - 1];
position = childNode.getEnd();
// Get the indentation of the last element, if any.
const text = childNode.getFullText(source);
const matches = text.match(/^(\r?\n)(\s*)/);
if (matches) {
toInsert =
`,${matches[0]}${metadataField}: [${matches[1]}` +
`${core_1.tags.indentBy(matches[2].length + 2) `${symbolName}`}${matches[0]}]`;
}
else {
toInsert = `, ${metadataField}: [${symbolName}]`;
}
}
if (importPath !== null) {
return [
new change_1.InsertChange(ngModulePath, position, toInsert),
insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath),
];
}
else {
return [new change_1.InsertChange(ngModulePath, position, toInsert)];
}
}
const assignment = matchingProperties[0];
// If it's not an array, nothing we can do really.
if (!ts.isPropertyAssignment(assignment) ||
!ts.isArrayLiteralExpression(assignment.initializer)) {
return [];
}
let expression;
const assignmentInit = assignment.initializer;
const elements = assignmentInit.elements;
if (elements.length) {
const symbolsArray = elements.map((node) => core_1.tags.oneLine `${node.getText()}`);
if (symbolsArray.includes(core_1.tags.oneLine `${symbolName}`)) {
return [];
}
expression = elements[elements.length - 1];
}
else {
expression = assignmentInit;
}
let toInsert;
let position = expression.getEnd();
if (ts.isArrayLiteralExpression(expression)) {
// We found the field but it's empty. Insert it just before the `]`.
position--;
toInsert = `\n${core_1.tags.indentBy(4) `${symbolName}`}\n `;
}
else {
// Get the indentation of the last element, if any.
const text = expression.getFullText(source);
const matches = text.match(/^(\r?\n)(\s*)/);
if (matches) {
toInsert = `,${matches[1]}${core_1.tags.indentBy(matches[2].length) `${symbolName}`}`;
}
else {
toInsert = `, ${symbolName}`;
}
}
if (importPath !== null) {
return [
new change_1.InsertChange(ngModulePath, position, toInsert),
insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath),
];
}
return [new change_1.InsertChange(ngModulePath, position, toInsert)];
}
exports.addSymbolToNgModuleMetadata = addSymbolToNgModuleMetadata;
/**
* Custom function to insert a declaration (component, pipe, directive)
* into NgModule declarations. It also imports the component.
*/
function addDeclarationToModule(source, modulePath, classifiedName, importPath) {
return addSymbolToNgModuleMetadata(source, modulePath, 'declarations', classifiedName, importPath);
}
exports.addDeclarationToModule = addDeclarationToModule;
/**
* Custom function to insert an NgModule into NgModule imports. It also imports the module.
*/
function addImportToModule(source, modulePath, classifiedName, importPath) {
return addSymbolToNgModuleMetadata(source, modulePath, 'imports', classifiedName, importPath);
}
exports.addImportToModule = addImportToModule;
/**
* Custom function to insert a provider into NgModule. It also imports it.
*/
function addProviderToModule(source, modulePath, classifiedName, importPath) {
return addSymbolToNgModuleMetadata(source, modulePath, 'providers', classifiedName, importPath);
}
exports.addProviderToModule = addProviderToModule;
/**
* Custom function to insert an export into NgModule. It also imports it.
*/
function addExportToModule(source, modulePath, classifiedName, importPath) {
return addSymbolToNgModuleMetadata(source, modulePath, 'exports', classifiedName, importPath);
}
exports.addExportToModule = addExportToModule;
/**
* Custom function to insert an export into NgModule. It also imports it.
*/
function addBootstrapToModule(source, modulePath, classifiedName, importPath) {
return addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath);
}
exports.addBootstrapToModule = addBootstrapToModule;
/**
* Determine if an import already exists.
*/
function isImported(source, classifiedName, importPath) {
const allNodes = getSourceNodes(source);
const matchingNodes = allNodes
.filter(ts.isImportDeclaration)
.filter((imp) => ts.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text === importPath)
.filter((imp) => {
if (!imp.importClause) {
return false;
}
const nodes = findNodes(imp.importClause, ts.isImportSpecifier).filter((n) => n.getText() === classifiedName);
return nodes.length > 0;
});
return matchingNodes.length > 0;
}
exports.isImported = isImported;
/**
* Returns the RouterModule declaration from NgModule metadata, if any.
*/
function getRouterModuleDeclaration(source) {
const result = getDecoratorMetadata(source, 'NgModule', '@angular/core');
const node = result[0];
if (!node || !ts.isObjectLiteralExpression(node)) {
return undefined;
}
const matchingProperties = getMetadataField(node, 'imports');
if (!matchingProperties) {
return;
}
const assignment = matchingProperties[0];
if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
return;
}
const arrLiteral = assignment.initializer;
return arrLiteral.elements
.filter((el) => el.kind === ts.SyntaxKind.CallExpression)
.find((el) => el.getText().startsWith('RouterModule'));
}
exports.getRouterModuleDeclaration = getRouterModuleDeclaration;
/**
* Adds a new route declaration to a router module (i.e. has a RouterModule declaration)
*/
function addRouteDeclarationToModule(source, fileToAdd, routeLiteral) {
const routerModuleExpr = getRouterModuleDeclaration(source);
if (!routerModuleExpr) {
throw new Error(`Couldn't find a route declaration in ${fileToAdd}.\n` +
`Use the '--module' option to specify a different routing module.`);
}
const scopeConfigMethodArgs = routerModuleExpr.arguments;
if (!scopeConfigMethodArgs.length) {
const { line } = source.getLineAndCharacterOfPosition(routerModuleExpr.getStart());
throw new Error(`The router module method doesn't have arguments ` + `at line ${line} in ${fileToAdd}`);
}
let routesArr;
const routesArg = scopeConfigMethodArgs[0];
// Check if the route declarations array is
// an inlined argument of RouterModule or a standalone variable
if (ts.isArrayLiteralExpression(routesArg)) {
routesArr = routesArg;
}
else {
const routesVarName = routesArg.getText();
let routesVar;
if (routesArg.kind === ts.SyntaxKind.Identifier) {
routesVar = source.statements.filter(ts.isVariableStatement).find((v) => {
return v.declarationList.declarations[0].name.getText() === routesVarName;
});
}
if (!routesVar) {
const { line } = source.getLineAndCharacterOfPosition(routesArg.getStart());
throw new Error(`No route declaration array was found that corresponds ` +
`to router module at line ${line} in ${fileToAdd}`);
}
routesArr = findNodes(routesVar, ts.SyntaxKind.ArrayLiteralExpression, 1)[0];
}
const occurrencesCount = routesArr.elements.length;
const text = routesArr.getFullText(source);
let route = routeLiteral;
let insertPos = routesArr.elements.pos;
if (occurrencesCount > 0) {
const lastRouteLiteral = [...routesArr.elements].pop();
const lastRouteIsWildcard = ts.isObjectLiteralExpression(lastRouteLiteral) &&
lastRouteLiteral.properties.some((n) => ts.isPropertyAssignment(n) &&
ts.isIdentifier(n.name) &&
n.name.text === 'path' &&
ts.isStringLiteral(n.initializer) &&
n.initializer.text === '**');
const indentation = text.match(/\r?\n(\r?)\s*/) || [];
const routeText = `${indentation[0] || ' '}${routeLiteral}`;
// Add the new route before the wildcard route
// otherwise we'll always redirect to the wildcard route
if (lastRouteIsWildcard) {
insertPos = lastRouteLiteral.pos;
route = `${routeText},`;
}
else {
insertPos = lastRouteLiteral.end;
route = `,${routeText}`;
}
}
return new change_1.InsertChange(fileToAdd, insertPos, route);
}
exports.addRouteDeclarationToModule = addRouteDeclarationToModule;
/** Asserts if the specified node is a named declaration (e.g. class, interface). */
function isNamedNode(node) {
return !!node.name && ts.isIdentifier(node.name);
}
/**
* Determines if a SourceFile has a top-level declaration whose name matches a specific symbol.
* Can be used to avoid conflicts when inserting new imports into a file.
* @param sourceFile File in which to search.
* @param symbolName Name of the symbol to search for.
* @param skipModule Path of the module that the symbol may have been imported from. Used to
* avoid false positives where the same symbol we're looking for may have been imported.
*/
function hasTopLevelIdentifier(sourceFile, symbolName, skipModule = null) {
for (const node of sourceFile.statements) {
if (isNamedNode(node) && node.name.text === symbolName) {
return true;
}
if (ts.isVariableStatement(node) &&
node.declarationList.declarations.some((decl) => {
return isNamedNode(decl) && decl.name.text === symbolName;
})) {
return true;
}
if (ts.isImportDeclaration(node) &&
ts.isStringLiteralLike(node.moduleSpecifier) &&
node.moduleSpecifier.text !== skipModule &&
node.importClause?.namedBindings &&
ts.isNamedImports(node.importClause.namedBindings) &&
node.importClause.namedBindings.elements.some((el) => el.name.text === symbolName)) {
return true;
}
}
return false;
}
exports.hasTopLevelIdentifier = hasTopLevelIdentifier;

68
my-app/node_modules/@schematics/angular/utility/change.d.ts generated vendored Executable file
View file

@ -0,0 +1,68 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { UpdateRecorder } from '@angular-devkit/schematics';
export interface Host {
write(path: string, content: string): Promise<void>;
read(path: string): Promise<string>;
}
export interface Change {
apply(host: Host): Promise<void>;
readonly path: string | null;
readonly order: number;
readonly description: string;
}
/**
* An operation that does nothing.
*/
export declare class NoopChange implements Change {
description: string;
order: number;
path: null;
apply(): Promise<void>;
}
/**
* Will add text to the source code.
*/
export declare class InsertChange implements Change {
path: string;
pos: number;
toAdd: string;
order: number;
description: string;
constructor(path: string, pos: number, toAdd: string);
/**
* This method does not insert spaces if there is none in the original string.
*/
apply(host: Host): Promise<void>;
}
/**
* Will remove text from the source code.
*/
export declare class RemoveChange implements Change {
path: string;
private pos;
toRemove: string;
order: number;
description: string;
constructor(path: string, pos: number, toRemove: string);
apply(host: Host): Promise<void>;
}
/**
* Will replace text from the source code.
*/
export declare class ReplaceChange implements Change {
path: string;
private pos;
oldText: string;
newText: string;
order: number;
description: string;
constructor(path: string, pos: number, oldText: string, newText: string);
apply(host: Host): Promise<void>;
}
export declare function applyToUpdateRecorder(recorder: UpdateRecorder, changes: Change[]): void;

135
my-app/node_modules/@schematics/angular/utility/change.js generated vendored Executable file
View file

@ -0,0 +1,135 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyToUpdateRecorder = exports.ReplaceChange = exports.RemoveChange = exports.InsertChange = exports.NoopChange = void 0;
/**
* An operation that does nothing.
*/
class NoopChange {
description = 'No operation.';
order = Infinity;
path = null;
apply() {
return Promise.resolve();
}
}
exports.NoopChange = NoopChange;
/**
* Will add text to the source code.
*/
class InsertChange {
path;
pos;
toAdd;
order;
description;
constructor(path, pos, toAdd) {
this.path = path;
this.pos = pos;
this.toAdd = toAdd;
if (pos < 0) {
throw new Error('Negative positions are invalid');
}
this.description = `Inserted ${toAdd} into position ${pos} of ${path}`;
this.order = pos;
}
/**
* This method does not insert spaces if there is none in the original string.
*/
apply(host) {
return host.read(this.path).then((content) => {
const prefix = content.substring(0, this.pos);
const suffix = content.substring(this.pos);
return host.write(this.path, `${prefix}${this.toAdd}${suffix}`);
});
}
}
exports.InsertChange = InsertChange;
/**
* Will remove text from the source code.
*/
class RemoveChange {
path;
pos;
toRemove;
order;
description;
constructor(path, pos, toRemove) {
this.path = path;
this.pos = pos;
this.toRemove = toRemove;
if (pos < 0) {
throw new Error('Negative positions are invalid');
}
this.description = `Removed ${toRemove} into position ${pos} of ${path}`;
this.order = pos;
}
apply(host) {
return host.read(this.path).then((content) => {
const prefix = content.substring(0, this.pos);
const suffix = content.substring(this.pos + this.toRemove.length);
// TODO: throw error if toRemove doesn't match removed string.
return host.write(this.path, `${prefix}${suffix}`);
});
}
}
exports.RemoveChange = RemoveChange;
/**
* Will replace text from the source code.
*/
class ReplaceChange {
path;
pos;
oldText;
newText;
order;
description;
constructor(path, pos, oldText, newText) {
this.path = path;
this.pos = pos;
this.oldText = oldText;
this.newText = newText;
if (pos < 0) {
throw new Error('Negative positions are invalid');
}
this.description = `Replaced ${oldText} into position ${pos} of ${path} with ${newText}`;
this.order = pos;
}
apply(host) {
return host.read(this.path).then((content) => {
const prefix = content.substring(0, this.pos);
const suffix = content.substring(this.pos + this.oldText.length);
const text = content.substring(this.pos, this.pos + this.oldText.length);
if (text !== this.oldText) {
return Promise.reject(new Error(`Invalid replace: "${text}" != "${this.oldText}".`));
}
// TODO: throw error if oldText doesn't match removed string.
return host.write(this.path, `${prefix}${this.newText}${suffix}`);
});
}
}
exports.ReplaceChange = ReplaceChange;
function applyToUpdateRecorder(recorder, changes) {
for (const change of changes) {
if (change instanceof InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
else if (change instanceof RemoveChange) {
recorder.remove(change.order, change.toRemove.length);
}
else if (change instanceof ReplaceChange) {
recorder.remove(change.order, change.oldText.length);
recorder.insertLeft(change.order, change.newText);
}
else if (!(change instanceof NoopChange)) {
throw new Error('Unknown Change type encountered when updating a recorder.');
}
}
}
exports.applyToUpdateRecorder = applyToUpdateRecorder;

View file

@ -0,0 +1,23 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { Tree } from '@angular-devkit/schematics';
export declare enum NodeDependencyType {
Default = "dependencies",
Dev = "devDependencies",
Peer = "peerDependencies",
Optional = "optionalDependencies"
}
export interface NodeDependency {
type: NodeDependencyType;
name: string;
version: string;
overwrite?: boolean;
}
export declare function addPackageJsonDependency(tree: Tree, dependency: NodeDependency, pkgJsonPath?: string): void;
export declare function removePackageJsonDependency(tree: Tree, name: string, pkgJsonPath?: string): void;
export declare function getPackageJsonDependency(tree: Tree, name: string, pkgJsonPath?: string): NodeDependency | null;

View file

@ -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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPackageJsonDependency = exports.removePackageJsonDependency = exports.addPackageJsonDependency = exports.NodeDependencyType = void 0;
const json_file_1 = require("./json-file");
const PKG_JSON_PATH = '/package.json';
var NodeDependencyType;
(function (NodeDependencyType) {
NodeDependencyType["Default"] = "dependencies";
NodeDependencyType["Dev"] = "devDependencies";
NodeDependencyType["Peer"] = "peerDependencies";
NodeDependencyType["Optional"] = "optionalDependencies";
})(NodeDependencyType || (exports.NodeDependencyType = NodeDependencyType = {}));
const ALL_DEPENDENCY_TYPE = [
NodeDependencyType.Default,
NodeDependencyType.Dev,
NodeDependencyType.Optional,
NodeDependencyType.Peer,
];
function addPackageJsonDependency(tree, dependency, pkgJsonPath = PKG_JSON_PATH) {
const json = new json_file_1.JSONFile(tree, pkgJsonPath);
const { overwrite, type, name, version } = dependency;
const path = [type, name];
if (overwrite || !json.get(path)) {
json.modify(path, version);
}
}
exports.addPackageJsonDependency = addPackageJsonDependency;
function removePackageJsonDependency(tree, name, pkgJsonPath = PKG_JSON_PATH) {
const json = new json_file_1.JSONFile(tree, pkgJsonPath);
for (const depType of ALL_DEPENDENCY_TYPE) {
json.remove([depType, name]);
}
}
exports.removePackageJsonDependency = removePackageJsonDependency;
function getPackageJsonDependency(tree, name, pkgJsonPath = PKG_JSON_PATH) {
const json = new json_file_1.JSONFile(tree, pkgJsonPath);
for (const depType of ALL_DEPENDENCY_TYPE) {
const version = json.get([depType, name]);
if (typeof version === 'string') {
return {
type: depType,
name: name,
version,
};
}
}
return null;
}
exports.getPackageJsonDependency = getPackageJsonDependency;

View file

@ -0,0 +1,96 @@
/**
* @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.io/license
*/
import { Rule } from '@angular-devkit/schematics';
/**
* An enum used to specify the type of a dependency found within a package manifest
* file (`package.json`).
*/
export declare enum DependencyType {
Default = "dependencies",
Dev = "devDependencies",
Peer = "peerDependencies"
}
/**
* An enum used to specify the dependency installation behavior for the {@link addDependency}
* schematics rule. The installation behavior affects if and when {@link NodePackageInstallTask}
* will be scheduled when using the rule.
*/
export declare enum InstallBehavior {
/**
* No installation will occur as a result of the rule when specified.
*
* NOTE: This does not prevent other rules from scheduling a {@link NodePackageInstallTask}
* which may install the dependency.
*/
None = 0,
/**
* Automatically determine the need to schedule a {@link NodePackageInstallTask} based on
* previous usage of the {@link addDependency} within the schematic.
*/
Auto = 1,
/**
* Always schedule a {@link NodePackageInstallTask} when the rule is executed.
*/
Always = 2
}
/**
* An enum used to specify the existing dependency behavior for the {@link addDependency}
* schematics rule. The existing behavior affects whether the named dependency will be added
* to the `package.json` when the dependency is already present with a differing specifier.
*/
export declare enum ExistingBehavior {
/**
* The dependency will not be added or otherwise changed if it already exists.
*/
Skip = 0,
/**
* The dependency's existing specifier will be replaced with the specifier provided in the
* {@link addDependency} call. A warning will also be shown during schematic execution to
* notify the user of the replacement.
*/
Replace = 1
}
/**
* Adds a package as a dependency to a `package.json`. By default the `package.json` located
* at the schematic's root will be used. The `manifestPath` option can be used to explicitly specify
* a `package.json` in different location. The type of the dependency can also be specified instead
* of the default of the `dependencies` section by using the `type` option for either `devDependencies`
* or `peerDependencies`.
*
* When using this rule, {@link NodePackageInstallTask} does not need to be included directly by
* a schematic. A package manager install task will be automatically scheduled as needed.
*
* @param name The name of the package to add.
* @param specifier The package specifier for the package to add. Typically a SemVer range.
* @param options An optional object that can contain the `type` of the dependency
* and/or a path (`packageJsonPath`) of a manifest file (`package.json`) to modify.
* @returns A Schematics {@link Rule}
*/
export declare function addDependency(name: string, specifier: string, options?: {
/**
* The type of the dependency determines the section of the `package.json` to which the
* dependency will be added. Defaults to {@link DependencyType.Default} (`dependencies`).
*/
type?: DependencyType;
/**
* The path of the package manifest file (`package.json`) that will be modified.
* Defaults to `/package.json`.
*/
packageJsonPath?: string;
/**
* The dependency installation behavior to use to determine whether a
* {@link NodePackageInstallTask} should be scheduled after adding the dependency.
* Defaults to {@link InstallBehavior.Auto}.
*/
install?: InstallBehavior;
/**
* The behavior to use when the dependency already exists within the `package.json`.
* Defaults to {@link ExistingBehavior.Replace}.
*/
existing?: ExistingBehavior;
}): Rule;

145
my-app/node_modules/@schematics/angular/utility/dependency.js generated vendored Executable file
View file

@ -0,0 +1,145 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addDependency = exports.ExistingBehavior = exports.InstallBehavior = exports.DependencyType = void 0;
const tasks_1 = require("@angular-devkit/schematics/tasks");
const path = __importStar(require("path"));
const installTasks = new WeakMap();
/**
* An enum used to specify the type of a dependency found within a package manifest
* file (`package.json`).
*/
var DependencyType;
(function (DependencyType) {
DependencyType["Default"] = "dependencies";
DependencyType["Dev"] = "devDependencies";
DependencyType["Peer"] = "peerDependencies";
})(DependencyType || (exports.DependencyType = DependencyType = {}));
/**
* An enum used to specify the dependency installation behavior for the {@link addDependency}
* schematics rule. The installation behavior affects if and when {@link NodePackageInstallTask}
* will be scheduled when using the rule.
*/
var InstallBehavior;
(function (InstallBehavior) {
/**
* No installation will occur as a result of the rule when specified.
*
* NOTE: This does not prevent other rules from scheduling a {@link NodePackageInstallTask}
* which may install the dependency.
*/
InstallBehavior[InstallBehavior["None"] = 0] = "None";
/**
* Automatically determine the need to schedule a {@link NodePackageInstallTask} based on
* previous usage of the {@link addDependency} within the schematic.
*/
InstallBehavior[InstallBehavior["Auto"] = 1] = "Auto";
/**
* Always schedule a {@link NodePackageInstallTask} when the rule is executed.
*/
InstallBehavior[InstallBehavior["Always"] = 2] = "Always";
})(InstallBehavior || (exports.InstallBehavior = InstallBehavior = {}));
/**
* An enum used to specify the existing dependency behavior for the {@link addDependency}
* schematics rule. The existing behavior affects whether the named dependency will be added
* to the `package.json` when the dependency is already present with a differing specifier.
*/
var ExistingBehavior;
(function (ExistingBehavior) {
/**
* The dependency will not be added or otherwise changed if it already exists.
*/
ExistingBehavior[ExistingBehavior["Skip"] = 0] = "Skip";
/**
* The dependency's existing specifier will be replaced with the specifier provided in the
* {@link addDependency} call. A warning will also be shown during schematic execution to
* notify the user of the replacement.
*/
ExistingBehavior[ExistingBehavior["Replace"] = 1] = "Replace";
})(ExistingBehavior || (exports.ExistingBehavior = ExistingBehavior = {}));
/**
* Adds a package as a dependency to a `package.json`. By default the `package.json` located
* at the schematic's root will be used. The `manifestPath` option can be used to explicitly specify
* a `package.json` in different location. The type of the dependency can also be specified instead
* of the default of the `dependencies` section by using the `type` option for either `devDependencies`
* or `peerDependencies`.
*
* When using this rule, {@link NodePackageInstallTask} does not need to be included directly by
* a schematic. A package manager install task will be automatically scheduled as needed.
*
* @param name The name of the package to add.
* @param specifier The package specifier for the package to add. Typically a SemVer range.
* @param options An optional object that can contain the `type` of the dependency
* and/or a path (`packageJsonPath`) of a manifest file (`package.json`) to modify.
* @returns A Schematics {@link Rule}
*/
function addDependency(name, specifier, options = {}) {
const { type = DependencyType.Default, packageJsonPath = '/package.json', install = InstallBehavior.Auto, existing = ExistingBehavior.Replace, } = options;
return (tree, context) => {
const manifest = tree.readJson(packageJsonPath);
const dependencySection = manifest[type];
if (!dependencySection) {
// Section is not present. The dependency can be added to a new object literal for the section.
manifest[type] = { [name]: specifier };
}
else {
const existingSpecifier = dependencySection[name];
if (existingSpecifier === specifier) {
// Already present with same specifier
return;
}
if (existingSpecifier) {
// Already present but different specifier
if (existing === ExistingBehavior.Skip) {
return;
}
// ExistingBehavior.Replace is the only other behavior currently
context.logger.warn(`Package dependency "${name}" already exists with a different specifier. ` +
`"${existingSpecifier}" will be replaced with "${specifier}".`);
}
// Add new dependency in alphabetical order
const entries = Object.entries(dependencySection);
entries.push([name, specifier]);
entries.sort((a, b) => a[0].localeCompare(b[0]));
manifest[type] = Object.fromEntries(entries);
}
tree.overwrite(packageJsonPath, JSON.stringify(manifest, null, 2));
const installPaths = installTasks.get(context) ?? new Set();
if (install === InstallBehavior.Always ||
(install === InstallBehavior.Auto && !installPaths.has(packageJsonPath))) {
context.addTask(new tasks_1.NodePackageInstallTask({ workingDirectory: path.dirname(packageJsonPath) }));
installPaths.add(packageJsonPath);
installTasks.set(context, installPaths);
}
};
}
exports.addDependency = addDependency;

8
my-app/node_modules/@schematics/angular/utility/eol.d.ts generated vendored Executable file
View file

@ -0,0 +1,8 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export declare function getEOL(content: string): string;

23
my-app/node_modules/@schematics/angular/utility/eol.js generated vendored Executable file
View file

@ -0,0 +1,23 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEOL = void 0;
const node_os_1 = require("node:os");
const CRLF = '\r\n';
const LF = '\n';
function getEOL(content) {
const newlines = content.match(/(?:\r?\n)/g);
if (newlines?.length) {
const crlf = newlines.filter((l) => l === CRLF).length;
const lf = newlines.length - crlf;
return crlf > lf ? CRLF : LF;
}
return node_os_1.EOL;
}
exports.getEOL = getEOL;

View file

@ -0,0 +1,33 @@
/**
* @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.io/license
*/
import { Path } from '@angular-devkit/core';
import { Tree } from '@angular-devkit/schematics';
export interface ModuleOptions {
module?: string;
name: string;
flat?: boolean;
path?: string;
skipImport?: boolean;
moduleExt?: string;
routingModuleExt?: string;
standalone?: boolean;
}
export declare const MODULE_EXT = ".module.ts";
export declare const ROUTING_MODULE_EXT = "-routing.module.ts";
/**
* Find the module referred by a set of options passed to the schematics.
*/
export declare function findModuleFromOptions(host: Tree, options: ModuleOptions): Path | undefined;
/**
* Function to find the "closest" module to a generated file's path.
*/
export declare function findModule(host: Tree, generateDir: string, moduleExt?: string, routingModuleExt?: string): Path;
/**
* Build a relative path from one file path to another file path.
*/
export declare function buildRelativePath(from: string, to: string): string;

View file

@ -0,0 +1,105 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildRelativePath = exports.findModule = exports.findModuleFromOptions = exports.ROUTING_MODULE_EXT = exports.MODULE_EXT = void 0;
const core_1 = require("@angular-devkit/core");
exports.MODULE_EXT = '.module.ts';
exports.ROUTING_MODULE_EXT = '-routing.module.ts';
/**
* Find the module referred by a set of options passed to the schematics.
*/
function findModuleFromOptions(host, options) {
if (options.standalone || options.skipImport) {
return undefined;
}
const moduleExt = options.moduleExt || exports.MODULE_EXT;
const routingModuleExt = options.routingModuleExt || exports.ROUTING_MODULE_EXT;
if (!options.module) {
const pathToCheck = (options.path || '') + '/' + options.name;
return (0, core_1.normalize)(findModule(host, pathToCheck, moduleExt, routingModuleExt));
}
else {
const modulePath = (0, core_1.normalize)(`/${options.path}/${options.module}`);
const componentPath = (0, core_1.normalize)(`/${options.path}/${options.name}`);
const moduleBaseName = (0, core_1.normalize)(modulePath).split('/').pop();
const candidateSet = new Set([(0, core_1.normalize)(options.path || '/')]);
for (let dir = modulePath; dir != core_1.NormalizedRoot; dir = (0, core_1.dirname)(dir)) {
candidateSet.add(dir);
}
for (let dir = componentPath; dir != core_1.NormalizedRoot; dir = (0, core_1.dirname)(dir)) {
candidateSet.add(dir);
}
const candidatesDirs = [...candidateSet].sort((a, b) => b.length - a.length);
for (const c of candidatesDirs) {
const candidateFiles = ['', `${moduleBaseName}.ts`, `${moduleBaseName}${moduleExt}`].map((x) => (0, core_1.join)(c, x));
for (const sc of candidateFiles) {
if (host.exists(sc)) {
return (0, core_1.normalize)(sc);
}
}
}
throw new Error(`Specified module '${options.module}' does not exist.\n` +
`Looked in the following directories:\n ${candidatesDirs.join('\n ')}`);
}
}
exports.findModuleFromOptions = findModuleFromOptions;
/**
* Function to find the "closest" module to a generated file's path.
*/
function findModule(host, generateDir, moduleExt = exports.MODULE_EXT, routingModuleExt = exports.ROUTING_MODULE_EXT) {
let dir = host.getDir('/' + generateDir);
let foundRoutingModule = false;
while (dir) {
const allMatches = dir.subfiles.filter((p) => p.endsWith(moduleExt));
const filteredMatches = allMatches.filter((p) => !p.endsWith(routingModuleExt));
foundRoutingModule = foundRoutingModule || allMatches.length !== filteredMatches.length;
if (filteredMatches.length == 1) {
return (0, core_1.join)(dir.path, filteredMatches[0]);
}
else if (filteredMatches.length > 1) {
throw new Error(`More than one module matches. Use the '--skip-import' option to skip importing ` +
'the component into the closest module or use the module option to specify a module.');
}
dir = dir.parent;
}
const errorMsg = foundRoutingModule
? 'Could not find a non Routing NgModule.' +
`\nModules with suffix '${routingModuleExt}' are strictly reserved for routing.` +
`\nUse the '--skip-import' option to skip importing in NgModule.`
: `Could not find an NgModule. Use the '--skip-import' option to skip importing in NgModule.`;
throw new Error(errorMsg);
}
exports.findModule = findModule;
/**
* Build a relative path from one file path to another file path.
*/
function buildRelativePath(from, to) {
from = (0, core_1.normalize)(from);
to = (0, core_1.normalize)(to);
// Convert to arrays.
const fromParts = from.split('/');
const toParts = to.split('/');
// Remove file names (preserving destination)
fromParts.pop();
const toFileName = toParts.pop();
const relativePath = (0, core_1.relative)((0, core_1.normalize)(fromParts.join('/') || '/'), (0, core_1.normalize)(toParts.join('/') || '/'));
let pathPrefix = '';
// Set the path prefix for same dir or child dir, parent dir starts with `..`
if (!relativePath) {
pathPrefix = '.';
}
else if (!relativePath.startsWith('.')) {
pathPrefix = `./`;
}
if (pathPrefix && !pathPrefix.endsWith('/')) {
pathPrefix += '/';
}
return pathPrefix + (relativePath ? relativePath + '/' : '') + toFileName;
}
exports.buildRelativePath = buildRelativePath;

View file

@ -0,0 +1,18 @@
/**
* @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.io/license
*/
import { Rule } from '@angular-devkit/schematics';
export interface GenerateFromFilesOptions {
flat?: boolean;
name: string;
path?: string;
prefix?: string;
project: string;
skipTests?: boolean;
templateFilesDirectory?: string;
}
export declare function generateFromFiles(options: GenerateFromFilesOptions, extraTemplateValues?: Record<string, string | ((v: string) => string)>): Rule;

View file

@ -0,0 +1,37 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateFromFiles = void 0;
const schematics_1 = require("@angular-devkit/schematics");
const parse_name_1 = require("./parse-name");
const validation_1 = require("./validation");
const workspace_1 = require("./workspace");
function generateFromFiles(options, extraTemplateValues = {}) {
return async (host) => {
options.path ??= await (0, workspace_1.createDefaultPath)(host, options.project);
options.prefix ??= '';
options.flat ??= true;
const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
(0, validation_1.validateClassName)(schematics_1.strings.classify(options.name));
const templateFilesDirectory = options.templateFilesDirectory ?? './files';
const templateSource = (0, schematics_1.apply)((0, schematics_1.url)(templateFilesDirectory), [
options.skipTests ? (0, schematics_1.filter)((path) => !path.endsWith('.spec.ts.template')) : (0, schematics_1.noop)(),
(0, schematics_1.applyTemplates)({
...schematics_1.strings,
...options,
...extraTemplateValues,
}),
(0, schematics_1.move)(parsedPath.path + (options.flat ? '' : '/' + schematics_1.strings.dasherize(options.name))),
]);
return (0, schematics_1.chain)([(0, schematics_1.mergeWith)(templateSource)]);
};
}
exports.generateFromFiles = generateFromFiles;

11
my-app/node_modules/@schematics/angular/utility/index.d.ts generated vendored Executable file
View file

@ -0,0 +1,11 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export { ProjectDefinition, TargetDefinition, WorkspaceDefinition, getWorkspace as readWorkspace, updateWorkspace, writeWorkspace, } from './workspace';
export { Builders as AngularBuilder } from './workspace-models';
export * from './standalone';
export { DependencyType, ExistingBehavior, InstallBehavior, addDependency } from './dependency';

38
my-app/node_modules/@schematics/angular/utility/index.js generated vendored Executable file
View file

@ -0,0 +1,38 @@
"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.io/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 });
exports.addDependency = exports.InstallBehavior = exports.ExistingBehavior = exports.DependencyType = exports.AngularBuilder = exports.writeWorkspace = exports.updateWorkspace = exports.readWorkspace = void 0;
// Workspace related rules and types
var workspace_1 = require("./workspace");
Object.defineProperty(exports, "readWorkspace", { enumerable: true, get: function () { return workspace_1.getWorkspace; } });
Object.defineProperty(exports, "updateWorkspace", { enumerable: true, get: function () { return workspace_1.updateWorkspace; } });
Object.defineProperty(exports, "writeWorkspace", { enumerable: true, get: function () { return workspace_1.writeWorkspace; } });
var workspace_models_1 = require("./workspace-models");
Object.defineProperty(exports, "AngularBuilder", { enumerable: true, get: function () { return workspace_models_1.Builders; } });
__exportStar(require("./standalone"), exports);
// Package dependency related rules and types
var dependency_1 = require("./dependency");
Object.defineProperty(exports, "DependencyType", { enumerable: true, get: function () { return dependency_1.DependencyType; } });
Object.defineProperty(exports, "ExistingBehavior", { enumerable: true, get: function () { return dependency_1.ExistingBehavior; } });
Object.defineProperty(exports, "InstallBehavior", { enumerable: true, get: function () { return dependency_1.InstallBehavior; } });
Object.defineProperty(exports, "addDependency", { enumerable: true, get: function () { return dependency_1.addDependency; } });

View file

@ -0,0 +1,24 @@
/**
* @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.io/license
*/
import { JsonValue } from '@angular-devkit/core';
import { Tree } from '@angular-devkit/schematics';
export type InsertionIndex = (properties: string[]) => number;
export type JSONPath = (string | number)[];
/** @private */
export declare class JSONFile {
private readonly host;
private readonly path;
content: string;
private eol;
constructor(host: Tree, path: string);
private _jsonAst;
private get JsonAst();
get(jsonPath: JSONPath): unknown;
modify(jsonPath: JSONPath, value: JsonValue | undefined, insertInOrder?: InsertionIndex | false): void;
remove(jsonPath: JSONPath): void;
}

76
my-app/node_modules/@schematics/angular/utility/json-file.js generated vendored Executable file
View file

@ -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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.JSONFile = void 0;
const jsonc_parser_1 = require("jsonc-parser");
const eol_1 = require("./eol");
/** @private */
class JSONFile {
host;
path;
content;
eol;
constructor(host, path) {
this.host = host;
this.path = path;
this.content = this.host.readText(this.path);
this.eol = (0, eol_1.getEOL)(this.content);
}
_jsonAst;
get JsonAst() {
if (this._jsonAst) {
return this._jsonAst;
}
const errors = [];
this._jsonAst = (0, jsonc_parser_1.parseTree)(this.content, errors, { allowTrailingComma: true });
if (errors.length) {
const { error, offset } = errors[0];
throw new Error(`Failed to parse "${this.path}" as JSON AST Object. ${(0, jsonc_parser_1.printParseErrorCode)(error)} at location: ${offset}.`);
}
return this._jsonAst;
}
get(jsonPath) {
const jsonAstNode = this.JsonAst;
if (!jsonAstNode) {
return undefined;
}
if (jsonPath.length === 0) {
return (0, jsonc_parser_1.getNodeValue)(jsonAstNode);
}
const node = (0, jsonc_parser_1.findNodeAtLocation)(jsonAstNode, jsonPath);
return node === undefined ? undefined : (0, jsonc_parser_1.getNodeValue)(node);
}
modify(jsonPath, value, insertInOrder) {
let getInsertionIndex;
if (insertInOrder === undefined) {
const property = jsonPath.slice(-1)[0];
getInsertionIndex = (properties) => [...properties, property].sort().findIndex((p) => p === property);
}
else if (insertInOrder !== false) {
getInsertionIndex = insertInOrder;
}
const edits = (0, jsonc_parser_1.modify)(this.content, jsonPath, value, {
getInsertionIndex,
formattingOptions: {
eol: this.eol,
insertSpaces: true,
tabSize: 2,
},
});
this.content = (0, jsonc_parser_1.applyEdits)(this.content, edits);
this.host.overwrite(this.path, this.content);
this._jsonAst = undefined;
}
remove(jsonPath) {
if (this.get(jsonPath) !== undefined) {
this.modify(jsonPath, undefined);
}
}
}
exports.JSONFile = JSONFile;

View file

@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export declare const latestVersions: Record<string, string> & {
Angular: string;
DevkitBuildAngular: string;
AngularSSR: string;
};

View file

@ -0,0 +1,19 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.latestVersions = void 0;
exports.latestVersions = {
// We could have used TypeScripts' `resolveJsonModule` to make the `latestVersion` object typesafe,
// but ts_library doesn't support JSON inputs.
...require('./latest-versions/package.json')['dependencies'],
// As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
Angular: '^17.1.0',
DevkitBuildAngular: '^17.1.3',
AngularSSR: '^17.1.3',
};

View file

@ -0,0 +1,26 @@
{
"description": "Package versions used by schematics in @schematics/angular.",
"comment": "This file is needed so that dependencies are synced by Renovate.",
"private": true,
"dependencies": {
"@types/express": "^4.17.17",
"@types/jasmine": "~5.1.0",
"@types/node": "^18.18.0",
"browser-sync": "^3.0.0",
"express": "^4.18.2",
"jasmine-core": "~5.1.0",
"jasmine-spec-reporter": "~7.0.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine-html-reporter": "~2.1.0",
"karma-jasmine": "~5.1.0",
"karma": "~6.4.0",
"ng-packagr": "^17.1.0",
"protractor": "~7.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"ts-node": "~10.9.0",
"typescript": "~5.3.2",
"zone.js": "~0.14.3"
}
}

View file

@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { Tree } from '@angular-devkit/schematics';
import * as ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript';
export declare function findBootstrapModuleCall(host: Tree, mainPath: string): ts.CallExpression | null;
export declare function getAppModulePath(host: Tree, mainPath: string): string;
export declare function isStandaloneApp(host: Tree, mainPath: string): boolean;

View file

@ -0,0 +1,96 @@
"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.io/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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isStandaloneApp = exports.getAppModulePath = exports.findBootstrapModuleCall = void 0;
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const path_1 = require("path");
const standalone_1 = require("../private/standalone");
const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
const ast_utils_1 = require("../utility/ast-utils");
function findBootstrapModuleCall(host, mainPath) {
const mainText = host.readText(mainPath);
const source = ts.createSourceFile(mainPath, mainText, ts.ScriptTarget.Latest, true);
const allNodes = (0, ast_utils_1.getSourceNodes)(source);
let bootstrapCall = null;
for (const node of allNodes) {
let bootstrapCallNode = null;
bootstrapCallNode = (0, ast_utils_1.findNode)(node, ts.SyntaxKind.Identifier, 'bootstrapModule');
// Walk up the parent until CallExpression is found.
while (bootstrapCallNode &&
bootstrapCallNode.parent &&
bootstrapCallNode.parent.kind !== ts.SyntaxKind.CallExpression) {
bootstrapCallNode = bootstrapCallNode.parent;
}
if (bootstrapCallNode !== null &&
bootstrapCallNode.parent !== undefined &&
bootstrapCallNode.parent.kind === ts.SyntaxKind.CallExpression) {
bootstrapCall = bootstrapCallNode.parent;
break;
}
}
return bootstrapCall;
}
exports.findBootstrapModuleCall = findBootstrapModuleCall;
function findBootstrapModulePath(host, mainPath) {
const bootstrapCall = findBootstrapModuleCall(host, mainPath);
if (!bootstrapCall) {
throw new schematics_1.SchematicsException('Bootstrap call not found');
}
const bootstrapModule = bootstrapCall.arguments[0];
const mainText = host.readText(mainPath);
const source = ts.createSourceFile(mainPath, mainText, ts.ScriptTarget.Latest, true);
const allNodes = (0, ast_utils_1.getSourceNodes)(source);
const bootstrapModuleRelativePath = allNodes
.filter(ts.isImportDeclaration)
.filter((imp) => {
return (0, ast_utils_1.findNode)(imp, ts.SyntaxKind.Identifier, bootstrapModule.getText());
})
.map((imp) => {
const modulePathStringLiteral = imp.moduleSpecifier;
return modulePathStringLiteral.text;
})[0];
return bootstrapModuleRelativePath;
}
function getAppModulePath(host, mainPath) {
const moduleRelativePath = findBootstrapModulePath(host, mainPath);
const mainDir = (0, path_1.dirname)(mainPath);
const modulePath = (0, core_1.normalize)(`/${mainDir}/${moduleRelativePath}.ts`);
return modulePath;
}
exports.getAppModulePath = getAppModulePath;
function isStandaloneApp(host, mainPath) {
const source = ts.createSourceFile(mainPath, host.readText(mainPath), ts.ScriptTarget.Latest, true);
const bootstrapCall = (0, standalone_1.findBootstrapApplicationCall)(source);
return bootstrapCall !== null;
}
exports.isStandaloneApp = isStandaloneApp;

View file

@ -0,0 +1,13 @@
/**
* @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.io/license
*/
import { Path } from '@angular-devkit/core';
export interface Location {
name: string;
path: Path;
}
export declare function parseName(path: string, name: string): Location;

View file

@ -0,0 +1,20 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseName = void 0;
const core_1 = require("@angular-devkit/core");
function parseName(path, name) {
const nameWithoutPath = (0, core_1.basename)((0, core_1.normalize)(name));
const namePath = (0, core_1.dirname)((0, core_1.join)((0, core_1.normalize)(path), name));
return {
name: nameWithoutPath,
path: (0, core_1.normalize)('/' + namePath),
};
}
exports.parseName = parseName;

8
my-app/node_modules/@schematics/angular/utility/paths.d.ts generated vendored Executable file
View file

@ -0,0 +1,8 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export declare function relativePathToWorkspaceRoot(projectRoot: string | undefined): string;

21
my-app/node_modules/@schematics/angular/utility/paths.js generated vendored Executable file
View file

@ -0,0 +1,21 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.relativePathToWorkspaceRoot = void 0;
const core_1 = require("@angular-devkit/core");
function relativePathToWorkspaceRoot(projectRoot) {
const normalizedPath = (0, core_1.split)((0, core_1.normalize)(projectRoot || ''));
if (normalizedPath.length === 0 || !normalizedPath[0]) {
return '.';
}
else {
return normalizedPath.map(() => '..').join('/');
}
}
exports.relativePathToWorkspaceRoot = relativePathToWorkspaceRoot;

View file

@ -0,0 +1,9 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { SchematicsException } from '@angular-devkit/schematics';
export declare function targetBuildNotFoundError(): SchematicsException;

View file

@ -0,0 +1,15 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.targetBuildNotFoundError = void 0;
const schematics_1 = require("@angular-devkit/schematics");
function targetBuildNotFoundError() {
return new schematics_1.SchematicsException(`Project target "build" not found.`);
}
exports.targetBuildNotFoundError = targetBuildNotFoundError;

View file

@ -0,0 +1,23 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { Tree } from '@angular-devkit/schematics';
import ts from '../../third_party/github.com/Microsoft/TypeScript/lib/typescript';
/** App config that was resolved to its source node. */
export interface ResolvedAppConfig {
/** Tree-relative path of the file containing the app config. */
filePath: string;
/** Node defining the app config. */
node: ts.ObjectLiteralExpression;
}
/**
* Resolves the node that defines the app config from a bootstrap call.
* @param bootstrapCall Call for which to resolve the config.
* @param tree File tree of the project.
* @param filePath File path of the bootstrap call.
*/
export declare function findAppConfig(bootstrapCall: ts.CallExpression, tree: Tree, filePath: string): ResolvedAppConfig | null;

View file

@ -0,0 +1,92 @@
"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.io/license
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findAppConfig = void 0;
const path_1 = require("path");
const typescript_1 = __importDefault(require("../../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
const util_1 = require("./util");
/**
* Resolves the node that defines the app config from a bootstrap call.
* @param bootstrapCall Call for which to resolve the config.
* @param tree File tree of the project.
* @param filePath File path of the bootstrap call.
*/
function findAppConfig(bootstrapCall, tree, filePath) {
if (bootstrapCall.arguments.length > 1) {
const config = bootstrapCall.arguments[1];
if (typescript_1.default.isObjectLiteralExpression(config)) {
return { filePath, node: config };
}
if (typescript_1.default.isIdentifier(config)) {
return resolveAppConfigFromIdentifier(config, tree, filePath);
}
}
return null;
}
exports.findAppConfig = findAppConfig;
/**
* Resolves the app config from an identifier referring to it.
* @param identifier Identifier referring to the app config.
* @param tree File tree of the project.
* @param bootstapFilePath Path of the bootstrap call.
*/
function resolveAppConfigFromIdentifier(identifier, tree, bootstapFilePath) {
const sourceFile = identifier.getSourceFile();
for (const node of sourceFile.statements) {
// Only look at relative imports. This will break if the app uses a path
// mapping to refer to the import, but in order to resolve those, we would
// need knowledge about the entire program.
if (!typescript_1.default.isImportDeclaration(node) ||
!node.importClause?.namedBindings ||
!typescript_1.default.isNamedImports(node.importClause.namedBindings) ||
!typescript_1.default.isStringLiteralLike(node.moduleSpecifier) ||
!node.moduleSpecifier.text.startsWith('.')) {
continue;
}
for (const specifier of node.importClause.namedBindings.elements) {
if (specifier.name.text !== identifier.text) {
continue;
}
// Look for a variable with the imported name in the file. Note that ideally we would use
// the type checker to resolve this, but we can't because these utilities are set up to
// operate on individual files, not the entire program.
const filePath = (0, path_1.join)((0, path_1.dirname)(bootstapFilePath), node.moduleSpecifier.text + '.ts');
const importedSourceFile = (0, util_1.getSourceFile)(tree, filePath);
const resolvedVariable = findAppConfigFromVariableName(importedSourceFile, (specifier.propertyName || specifier.name).text);
if (resolvedVariable) {
return { filePath, node: resolvedVariable };
}
}
}
const variableInSameFile = findAppConfigFromVariableName(sourceFile, identifier.text);
return variableInSameFile ? { filePath: bootstapFilePath, node: variableInSameFile } : null;
}
/**
* Finds an app config within the top-level variables of a file.
* @param sourceFile File in which to search for the config.
* @param variableName Name of the variable containing the config.
*/
function findAppConfigFromVariableName(sourceFile, variableName) {
for (const node of sourceFile.statements) {
if (typescript_1.default.isVariableStatement(node)) {
for (const decl of node.declarationList.declarations) {
if (typescript_1.default.isIdentifier(decl.name) &&
decl.name.text === variableName &&
decl.initializer &&
typescript_1.default.isObjectLiteralExpression(decl.initializer)) {
return decl.initializer;
}
}
}
}
return null;
}

View file

@ -0,0 +1,53 @@
/**
* @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.io/license
*/
import { Rule } from '@angular-devkit/schematics';
/** Generated code that hasn't been interpolated yet. */
export interface PendingCode {
/** Code that will be inserted. */
expression: string;
/** Imports that need to be added to the file in which the code is inserted. */
imports: PendingImports;
}
/** Map keeping track of imports and aliases under which they're referred to in an expresion. */
type PendingImports = Map<string, Map<string, string>>;
/**
* Callback invoked by a Rule that produces the code
* that needs to be inserted somewhere in the app.
*/
export type CodeBlockCallback = (block: CodeBlock) => PendingCode;
/**
* Utility class used to generate blocks of code that
* can be inserted by the devkit into a user's app.
*/
export declare class CodeBlock {
private _imports;
/** Function used to tag a code block in order to produce a `PendingCode` object. */
code: (strings: TemplateStringsArray, ...params: unknown[]) => PendingCode;
/**
* Used inside of a code block to mark external symbols and which module they should be imported
* from. When the code is inserted, the required import statements will be produced automatically.
* @param symbolName Name of the external symbol.
* @param moduleName Module from which the symbol should be imported.
*/
external: (symbolName: string, moduleName: string) => string;
/**
* Produces the necessary rules to transform a `PendingCode` object into valid code.
* @param initialCode Code pending transformed.
* @param filePath Path of the file in which the code will be inserted.
*/
static transformPendingCode(initialCode: PendingCode, filePath: string): {
code: {
/** Code that will be inserted. */
expression: string;
/** Imports that need to be added to the file in which the code is inserted. */
imports: PendingImports;
};
rules: Rule[];
};
}
export {};

View file

@ -0,0 +1,80 @@
"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.io/license
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodeBlock = void 0;
const typescript_1 = __importDefault(require("../../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
const ast_utils_1 = require("../ast-utils");
const change_1 = require("../change");
/** Counter used to generate unique IDs. */
let uniqueIdCounter = 0;
/**
* Utility class used to generate blocks of code that
* can be inserted by the devkit into a user's app.
*/
class CodeBlock {
_imports = new Map();
// Note: the methods here are defined as arrow function so that they can be destructured by
// consumers without losing their context. This makes the API more concise.
/** Function used to tag a code block in order to produce a `PendingCode` object. */
code = (strings, ...params) => {
return {
expression: strings.map((part, index) => part + (params[index] || '')).join(''),
imports: this._imports,
};
};
/**
* Used inside of a code block to mark external symbols and which module they should be imported
* from. When the code is inserted, the required import statements will be produced automatically.
* @param symbolName Name of the external symbol.
* @param moduleName Module from which the symbol should be imported.
*/
external = (symbolName, moduleName) => {
if (!this._imports.has(moduleName)) {
this._imports.set(moduleName, new Map());
}
const symbolsPerModule = this._imports.get(moduleName);
if (!symbolsPerModule.has(symbolName)) {
symbolsPerModule.set(symbolName, `@@__SCHEMATIC_PLACEHOLDER_${uniqueIdCounter++}__@@`);
}
return symbolsPerModule.get(symbolName);
};
/**
* Produces the necessary rules to transform a `PendingCode` object into valid code.
* @param initialCode Code pending transformed.
* @param filePath Path of the file in which the code will be inserted.
*/
static transformPendingCode(initialCode, filePath) {
const code = { ...initialCode };
const rules = [];
code.imports.forEach((symbols, moduleName) => {
symbols.forEach((placeholder, symbolName) => {
rules.push((tree) => {
const recorder = tree.beginUpdate(filePath);
const sourceFile = typescript_1.default.createSourceFile(filePath, tree.readText(filePath), typescript_1.default.ScriptTarget.Latest, true);
// Note that this could still technically clash if there's a top-level symbol called
// `${symbolName}_alias`, however this is unlikely. We can revisit this if it becomes
// a problem.
const alias = (0, ast_utils_1.hasTopLevelIdentifier)(sourceFile, symbolName, moduleName)
? symbolName + '_alias'
: undefined;
code.expression = code.expression.replace(new RegExp(placeholder, 'g'), alias || symbolName);
(0, change_1.applyToUpdateRecorder)(recorder, [
(0, ast_utils_1.insertImport)(sourceFile, filePath, symbolName, moduleName, false, alias),
]);
tree.commitUpdate(recorder);
});
});
});
return { code, rules };
}
}
exports.CodeBlock = CodeBlock;

View file

@ -0,0 +1,9 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export { addRootImport, addRootProvider } from './rules';
export { PendingCode, CodeBlockCallback, type CodeBlock } from './code_block';

View file

@ -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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.addRootProvider = exports.addRootImport = void 0;
var rules_1 = require("./rules");
Object.defineProperty(exports, "addRootImport", { enumerable: true, get: function () { return rules_1.addRootImport; } });
Object.defineProperty(exports, "addRootProvider", { enumerable: true, get: function () { return rules_1.addRootProvider; } });

View file

@ -0,0 +1,45 @@
/**
* @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.io/license
*/
import { Rule } from '@angular-devkit/schematics';
import { CodeBlockCallback } from './code_block';
/**
* Adds an import to the root of the project.
* @param project Name of the project to which to add the import.
* @param callback Function that generates the code block which should be inserted.
* @example
*
* ```ts
* import { Rule } from '@angular-devkit/schematics';
* import { addRootImport } from '@schematics/angular/utility';
*
* export default function(): Rule {
* return addRootImport('default', ({code, external}) => {
* return code`${external('MyModule', '@my/module')}.forRoot({})`;
* });
* }
* ```
*/
export declare function addRootImport(project: string, callback: CodeBlockCallback): Rule;
/**
* Adds a provider to the root of the project.
* @param project Name of the project to which to add the import.
* @param callback Function that generates the code block which should be inserted.
* @example
*
* ```ts
* import { Rule } from '@angular-devkit/schematics';
* import { addRootProvider } from '@schematics/angular/utility';
*
* export default function(): Rule {
* return addRootProvider('default', ({code, external}) => {
* return code`${external('provideLibrary', '@my/library')}({})`;
* });
* }
* ```
*/
export declare function addRootProvider(project: string, callback: CodeBlockCallback): Rule;

View file

@ -0,0 +1,188 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.addRootProvider = exports.addRootImport = void 0;
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const ast_utils_1 = require("../ast-utils");
const change_1 = require("../change");
const ng_ast_utils_1 = require("../ng-ast-utils");
const app_config_1 = require("./app_config");
const code_block_1 = require("./code_block");
const util_1 = require("./util");
/**
* Adds an import to the root of the project.
* @param project Name of the project to which to add the import.
* @param callback Function that generates the code block which should be inserted.
* @example
*
* ```ts
* import { Rule } from '@angular-devkit/schematics';
* import { addRootImport } from '@schematics/angular/utility';
*
* export default function(): Rule {
* return addRootImport('default', ({code, external}) => {
* return code`${external('MyModule', '@my/module')}.forRoot({})`;
* });
* }
* ```
*/
function addRootImport(project, callback) {
return getRootInsertionRule(project, callback, 'imports', {
name: 'importProvidersFrom',
module: '@angular/core',
});
}
exports.addRootImport = addRootImport;
/**
* Adds a provider to the root of the project.
* @param project Name of the project to which to add the import.
* @param callback Function that generates the code block which should be inserted.
* @example
*
* ```ts
* import { Rule } from '@angular-devkit/schematics';
* import { addRootProvider } from '@schematics/angular/utility';
*
* export default function(): Rule {
* return addRootProvider('default', ({code, external}) => {
* return code`${external('provideLibrary', '@my/library')}({})`;
* });
* }
* ```
*/
function addRootProvider(project, callback) {
return getRootInsertionRule(project, callback, 'providers');
}
exports.addRootProvider = addRootProvider;
/**
* Creates a rule that inserts code at the root of either a standalone or NgModule-based project.
* @param project Name of the project into which to inser tthe code.
* @param callback Function that generates the code block which should be inserted.
* @param ngModuleField Field of the root NgModule into which the code should be inserted, if the
* app is based on NgModule
* @param standaloneWrapperFunction Function with which to wrap the code if the app is standalone.
*/
function getRootInsertionRule(project, callback, ngModuleField, standaloneWrapperFunction) {
return async (host) => {
const mainFilePath = await (0, util_1.getMainFilePath)(host, project);
const codeBlock = new code_block_1.CodeBlock();
if ((0, ng_ast_utils_1.isStandaloneApp)(host, mainFilePath)) {
return (tree) => addProviderToStandaloneBootstrap(tree, callback(codeBlock), mainFilePath, standaloneWrapperFunction);
}
const modulePath = (0, ng_ast_utils_1.getAppModulePath)(host, mainFilePath);
const pendingCode = code_block_1.CodeBlock.transformPendingCode(callback(codeBlock), modulePath);
return (0, schematics_1.chain)([
...pendingCode.rules,
(tree) => {
const changes = (0, ast_utils_1.addSymbolToNgModuleMetadata)((0, util_1.getSourceFile)(tree, modulePath), modulePath, ngModuleField, pendingCode.code.expression,
// Explicitly set the import path to null since we deal with imports here separately.
null);
(0, util_1.applyChangesToFile)(tree, modulePath, changes);
},
]);
};
}
/**
* Adds a provider to the root of a standalone project.
* @param host Tree of the root rule.
* @param pendingCode Code that should be inserted.
* @param mainFilePath Path to the project's main file.
* @param wrapperFunction Optional function with which to wrap the provider.
*/
function addProviderToStandaloneBootstrap(host, pendingCode, mainFilePath, wrapperFunction) {
const bootstrapCall = (0, util_1.findBootstrapApplicationCall)(host, mainFilePath);
const fileToEdit = (0, app_config_1.findAppConfig)(bootstrapCall, host, mainFilePath)?.filePath || mainFilePath;
const { code, rules } = code_block_1.CodeBlock.transformPendingCode(pendingCode, fileToEdit);
return (0, schematics_1.chain)([
...rules,
() => {
let wrapped;
let additionalRules;
if (wrapperFunction) {
const block = new code_block_1.CodeBlock();
const result = code_block_1.CodeBlock.transformPendingCode(block.code `${block.external(wrapperFunction.name, wrapperFunction.module)}(${code.expression})`, fileToEdit);
wrapped = result.code;
additionalRules = result.rules;
}
else {
wrapped = code;
additionalRules = [];
}
return (0, schematics_1.chain)([
...additionalRules,
(tree) => insertStandaloneRootProvider(tree, mainFilePath, wrapped.expression),
]);
},
]);
}
/**
* Inserts a string expression into the root of a standalone project.
* @param tree File tree used to modify the project.
* @param mainFilePath Path to the main file of the project.
* @param expression Code expression to be inserted.
*/
function insertStandaloneRootProvider(tree, mainFilePath, expression) {
const bootstrapCall = (0, util_1.findBootstrapApplicationCall)(tree, mainFilePath);
const appConfig = (0, app_config_1.findAppConfig)(bootstrapCall, tree, mainFilePath);
if (bootstrapCall.arguments.length === 0) {
throw new schematics_1.SchematicsException(`Cannot add provider to invalid bootstrapApplication call in ${bootstrapCall.getSourceFile().fileName}`);
}
if (appConfig) {
addProvidersExpressionToAppConfig(tree, appConfig, expression);
return;
}
const newAppConfig = `, {\n${core_1.tags.indentBy(2) `providers: [${expression}]`}\n}`;
let targetCall;
if (bootstrapCall.arguments.length === 1) {
targetCall = bootstrapCall;
}
else if ((0, util_1.isMergeAppConfigCall)(bootstrapCall.arguments[1])) {
targetCall = bootstrapCall.arguments[1];
}
else {
throw new schematics_1.SchematicsException(`Cannot statically analyze bootstrapApplication call in ${bootstrapCall.getSourceFile().fileName}`);
}
(0, util_1.applyChangesToFile)(tree, mainFilePath, [
(0, ast_utils_1.insertAfterLastOccurrence)(targetCall.arguments, newAppConfig, mainFilePath, targetCall.getEnd() - 1),
]);
}
/**
* Adds a string expression to an app config object.
* @param tree File tree used to modify the project.
* @param appConfig Resolved configuration object of the project.
* @param expression Code expression to be inserted.
*/
function addProvidersExpressionToAppConfig(tree, appConfig, expression) {
const { node, filePath } = appConfig;
const configProps = node.properties;
const providersLiteral = (0, util_1.findProvidersLiteral)(node);
// If there's a `providers` property, we can add the provider
// to it, otherwise we need to declare it ourselves.
if (providersLiteral) {
(0, util_1.applyChangesToFile)(tree, filePath, [
(0, ast_utils_1.insertAfterLastOccurrence)(providersLiteral.elements, (providersLiteral.elements.length === 0 ? '' : ', ') + expression, filePath, providersLiteral.getStart() + 1),
]);
}
else {
const prop = core_1.tags.indentBy(2) `providers: [${expression}]`;
let toInsert;
let insertPosition;
if (configProps.length === 0) {
toInsert = '\n' + prop + '\n';
insertPosition = node.getEnd() - 1;
}
else {
const hasTrailingComma = configProps.hasTrailingComma;
toInsert = (hasTrailingComma ? '' : ',') + '\n' + prop;
insertPosition = configProps[configProps.length - 1].getEnd() + (hasTrailingComma ? 1 : 0);
}
(0, util_1.applyChangesToFile)(tree, filePath, [new change_1.InsertChange(filePath, insertPosition, toInsert)]);
}
}

View file

@ -0,0 +1,35 @@
/**
* @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.io/license
*/
import { Tree } from '@angular-devkit/schematics';
import ts from '../../third_party/github.com/Microsoft/TypeScript/lib/typescript';
import { Change } from '../change';
/**
* Finds the main file of a project.
* @param tree File tree for the project.
* @param projectName Name of the project in which to search.
*/
export declare function getMainFilePath(tree: Tree, projectName: string): Promise<string>;
/**
* Gets a TypeScript source file at a specific path.
* @param tree File tree of a project.
* @param path Path to the file.
*/
export declare function getSourceFile(tree: Tree, path: string): ts.SourceFile;
/** Finds the call to `bootstrapApplication` within a file. */
export declare function findBootstrapApplicationCall(tree: Tree, mainFilePath: string): ts.CallExpression;
/**
* Applies a set of changes to a file.
* @param tree File tree of the project.
* @param path Path to the file that is being changed.
* @param changes Changes that should be applied to the file.
*/
export declare function applyChangesToFile(tree: Tree, path: string, changes: Change[]): void;
/** Checks whether a node is a call to `mergeApplicationConfig`. */
export declare function isMergeAppConfigCall(node: ts.Node): node is ts.CallExpression;
/** Finds the `providers` array literal within an application config. */
export declare function findProvidersLiteral(config: ts.ObjectLiteralExpression): ts.ArrayLiteralExpression | null;

View file

@ -0,0 +1,135 @@
"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.io/license
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findProvidersLiteral = exports.isMergeAppConfigCall = exports.applyChangesToFile = exports.findBootstrapApplicationCall = exports.getSourceFile = exports.getMainFilePath = void 0;
const schematics_1 = require("@angular-devkit/schematics");
const typescript_1 = __importDefault(require("../../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
const change_1 = require("../change");
const project_targets_1 = require("../project-targets");
const workspace_1 = require("../workspace");
const workspace_models_1 = require("../workspace-models");
/**
* Finds the main file of a project.
* @param tree File tree for the project.
* @param projectName Name of the project in which to search.
*/
async function getMainFilePath(tree, projectName) {
const workspace = await (0, workspace_1.getWorkspace)(tree);
const project = workspace.projects.get(projectName);
const buildTarget = project?.targets.get('build');
if (!buildTarget) {
throw (0, project_targets_1.targetBuildNotFoundError)();
}
const options = buildTarget.options;
return buildTarget.builder === workspace_models_1.Builders.Application ? options.browser : options.main;
}
exports.getMainFilePath = getMainFilePath;
/**
* Gets a TypeScript source file at a specific path.
* @param tree File tree of a project.
* @param path Path to the file.
*/
function getSourceFile(tree, path) {
const content = tree.readText(path);
const source = typescript_1.default.createSourceFile(path, content, typescript_1.default.ScriptTarget.Latest, true);
return source;
}
exports.getSourceFile = getSourceFile;
/** Finds the call to `bootstrapApplication` within a file. */
function findBootstrapApplicationCall(tree, mainFilePath) {
const sourceFile = getSourceFile(tree, mainFilePath);
const localName = findImportLocalName(sourceFile, 'bootstrapApplication', '@angular/platform-browser');
if (localName) {
let result = null;
sourceFile.forEachChild(function walk(node) {
if (typescript_1.default.isCallExpression(node) &&
typescript_1.default.isIdentifier(node.expression) &&
node.expression.text === localName) {
result = node;
}
if (!result) {
node.forEachChild(walk);
}
});
if (result) {
return result;
}
}
throw new schematics_1.SchematicsException(`Could not find bootstrapApplication call in ${mainFilePath}`);
}
exports.findBootstrapApplicationCall = findBootstrapApplicationCall;
/**
* Finds the local name of an imported symbol. Could be the symbol name itself or its alias.
* @param sourceFile File within which to search for the import.
* @param name Actual name of the import, not its local alias.
* @param moduleName Name of the module from which the symbol is imported.
*/
function findImportLocalName(sourceFile, name, moduleName) {
for (const node of sourceFile.statements) {
// Only look for top-level imports.
if (!typescript_1.default.isImportDeclaration(node) ||
!typescript_1.default.isStringLiteral(node.moduleSpecifier) ||
node.moduleSpecifier.text !== moduleName) {
continue;
}
// Filter out imports that don't have the right shape.
if (!node.importClause ||
!node.importClause.namedBindings ||
!typescript_1.default.isNamedImports(node.importClause.namedBindings)) {
continue;
}
// Look through the elements of the declaration for the specific import.
for (const element of node.importClause.namedBindings.elements) {
if ((element.propertyName || element.name).text === name) {
// The local name is always in `name`.
return element.name.text;
}
}
}
return null;
}
/**
* Applies a set of changes to a file.
* @param tree File tree of the project.
* @param path Path to the file that is being changed.
* @param changes Changes that should be applied to the file.
*/
function applyChangesToFile(tree, path, changes) {
if (changes.length > 0) {
const recorder = tree.beginUpdate(path);
(0, change_1.applyToUpdateRecorder)(recorder, changes);
tree.commitUpdate(recorder);
}
}
exports.applyChangesToFile = applyChangesToFile;
/** Checks whether a node is a call to `mergeApplicationConfig`. */
function isMergeAppConfigCall(node) {
if (!typescript_1.default.isCallExpression(node)) {
return false;
}
const localName = findImportLocalName(node.getSourceFile(), 'mergeApplicationConfig', '@angular/core');
return !!localName && typescript_1.default.isIdentifier(node.expression) && node.expression.text === localName;
}
exports.isMergeAppConfigCall = isMergeAppConfigCall;
/** Finds the `providers` array literal within an application config. */
function findProvidersLiteral(config) {
for (const prop of config.properties) {
if (typescript_1.default.isPropertyAssignment(prop) &&
typescript_1.default.isIdentifier(prop.name) &&
prop.name.text === 'providers' &&
typescript_1.default.isArrayLiteralExpression(prop.initializer)) {
return prop.initializer;
}
}
return null;
}
exports.findProvidersLiteral = findProvidersLiteral;

View file

@ -0,0 +1,10 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export declare const htmlSelectorRe: RegExp;
export declare function validateHtmlSelector(selector: string): void;
export declare function validateClassName(className: string): void;

View file

@ -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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateClassName = exports.validateHtmlSelector = exports.htmlSelectorRe = void 0;
const schematics_1 = require("@angular-devkit/schematics");
// Must start with a letter, and must contain only alphanumeric characters or dashes.
// When adding a dash the segment after the dash must also start with a letter.
exports.htmlSelectorRe = /^[a-zA-Z][.0-9a-zA-Z]*((:?-[0-9]+)*|(:?-[a-zA-Z][.0-9a-zA-Z]*(:?-[0-9]+)*)*)$/;
// See: https://github.com/tc39/proposal-regexp-unicode-property-escapes/blob/fe6d07fad74cd0192d154966baa1e95e7cda78a1/README.md#other-examples
const ecmaIdentifierNameRegExp = /^(?:[$_\p{ID_Start}])(?:[$_\u200C\u200D\p{ID_Continue}])*$/u;
function validateHtmlSelector(selector) {
if (selector && !exports.htmlSelectorRe.test(selector)) {
throw new schematics_1.SchematicsException(`Selector "${selector}" is invalid.`);
}
}
exports.validateHtmlSelector = validateHtmlSelector;
function validateClassName(className) {
if (!ecmaIdentifierNameRegExp.test(className)) {
throw new schematics_1.SchematicsException(`Class name "${className}" is invalid.`);
}
}
exports.validateClassName = validateClassName;

View file

@ -0,0 +1,165 @@
/**
* @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.io/license
*/
export declare enum ProjectType {
Application = "application",
Library = "library"
}
/**
* An enum of the official Angular builders.
* Each enum value provides the fully qualified name of the associated builder.
* This enum can be used when analyzing the `builder` fields of project configurations from the
* `angular.json` workspace file.
*/
export declare enum Builders {
Application = "@angular-devkit/build-angular:application",
AppShell = "@angular-devkit/build-angular:app-shell",
Server = "@angular-devkit/build-angular:server",
Browser = "@angular-devkit/build-angular:browser",
SsrDevServer = "@angular-devkit/build-angular:ssr-dev-server",
Prerender = "@angular-devkit/build-angular:prerender",
BrowserEsbuild = "@angular-devkit/build-angular:browser-esbuild",
Karma = "@angular-devkit/build-angular:karma",
TsLint = "@angular-devkit/build-angular:tslint",
NgPackagr = "@angular-devkit/build-angular:ng-packagr",
DevServer = "@angular-devkit/build-angular:dev-server",
ExtractI18n = "@angular-devkit/build-angular:extract-i18n",
Protractor = "@angular-devkit/build-angular:protractor"
}
export interface FileReplacements {
replace: string;
with: string;
}
export interface BrowserBuilderBaseOptions {
main: string;
tsConfig: string;
fileReplacements?: FileReplacements[];
outputPath?: string;
index?: string;
polyfills: string;
assets?: (object | string)[];
styles?: (object | string)[];
scripts?: (object | string)[];
sourceMap?: boolean;
}
export type OutputHashing = 'all' | 'media' | 'none' | 'bundles';
export interface BrowserBuilderOptions extends BrowserBuilderBaseOptions {
serviceWorker?: boolean;
optimization?: boolean;
outputHashing?: OutputHashing;
resourcesOutputPath?: string;
namedChunks?: boolean;
aot?: boolean;
extractLicenses?: boolean;
vendorChunk?: boolean;
buildOptimizer?: boolean;
ngswConfigPath?: string;
budgets?: {
type: string;
maximumWarning?: string;
maximumError?: string;
}[];
webWorkerTsConfig?: string;
}
export interface ServeBuilderOptions {
/**
* @deprecated not used since version 17.0.0. Use the property "buildTarget" instead.
*/
browserTarget: string;
buildTarget?: string;
}
export interface LibraryBuilderOptions {
tsConfig: string;
project: string;
}
export interface ServerBuilderOptions {
outputPath: string;
tsConfig: string;
main: string;
fileReplacements?: FileReplacements[];
optimization?: boolean | {
scripts?: boolean;
styles?: boolean;
};
sourceMap?: boolean | {
scripts?: boolean;
styles?: boolean;
hidden?: boolean;
vendor?: boolean;
};
}
export interface AppShellBuilderOptions {
browserTarget: string;
serverTarget: string;
route: string;
}
export interface TestBuilderOptions extends Partial<BrowserBuilderBaseOptions> {
karmaConfig: string;
}
export interface ExtractI18nOptions {
browserTarget: string;
}
export interface E2EOptions {
protractorConfig: string;
devServerTarget: string;
}
export interface BuilderTarget<TBuilder extends Builders, TOptions> {
builder: TBuilder;
options: TOptions;
configurations?: {
production: Partial<TOptions>;
[key: string]: Partial<TOptions>;
};
}
export type LibraryBuilderTarget = BuilderTarget<Builders.NgPackagr, LibraryBuilderOptions>;
export type BrowserBuilderTarget = BuilderTarget<Builders.Browser, BrowserBuilderOptions>;
export type ServerBuilderTarget = BuilderTarget<Builders.Server, ServerBuilderOptions>;
export type AppShellBuilderTarget = BuilderTarget<Builders.AppShell, AppShellBuilderOptions>;
export type TestBuilderTarget = BuilderTarget<Builders.Karma, TestBuilderOptions>;
export type ServeBuilderTarget = BuilderTarget<Builders.DevServer, ServeBuilderOptions>;
export type ExtractI18nBuilderTarget = BuilderTarget<Builders.ExtractI18n, ExtractI18nOptions>;
export type E2EBuilderTarget = BuilderTarget<Builders.Protractor, E2EOptions>;
interface WorkspaceCLISchema {
warnings?: Record<string, boolean>;
schematicCollections?: string[];
}
export interface WorkspaceSchema {
version: 1;
cli?: WorkspaceCLISchema;
projects: {
[key: string]: WorkspaceProject<ProjectType.Application | ProjectType.Library>;
};
}
export interface WorkspaceProject<TProjectType extends ProjectType = ProjectType.Application> {
/**
* Project type.
*/
projectType: ProjectType;
root: string;
sourceRoot: string;
prefix: string;
cli?: WorkspaceCLISchema;
/**
* Tool options.
*/
architect?: WorkspaceTargets<TProjectType>;
/**
* Tool options.
*/
targets?: WorkspaceTargets<TProjectType>;
}
export interface WorkspaceTargets<TProjectType extends ProjectType = ProjectType.Application> {
build?: TProjectType extends ProjectType.Library ? LibraryBuilderTarget : BrowserBuilderTarget;
server?: ServerBuilderTarget;
test?: TestBuilderTarget;
serve?: ServeBuilderTarget;
e2e?: E2EBuilderTarget;
'app-shell'?: AppShellBuilderTarget;
'extract-i18n'?: ExtractI18nBuilderTarget;
[key: string]: any;
}
export {};

View file

@ -0,0 +1,37 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Builders = exports.ProjectType = void 0;
var ProjectType;
(function (ProjectType) {
ProjectType["Application"] = "application";
ProjectType["Library"] = "library";
})(ProjectType || (exports.ProjectType = ProjectType = {}));
/**
* An enum of the official Angular builders.
* Each enum value provides the fully qualified name of the associated builder.
* This enum can be used when analyzing the `builder` fields of project configurations from the
* `angular.json` workspace file.
*/
var Builders;
(function (Builders) {
Builders["Application"] = "@angular-devkit/build-angular:application";
Builders["AppShell"] = "@angular-devkit/build-angular:app-shell";
Builders["Server"] = "@angular-devkit/build-angular:server";
Builders["Browser"] = "@angular-devkit/build-angular:browser";
Builders["SsrDevServer"] = "@angular-devkit/build-angular:ssr-dev-server";
Builders["Prerender"] = "@angular-devkit/build-angular:prerender";
Builders["BrowserEsbuild"] = "@angular-devkit/build-angular:browser-esbuild";
Builders["Karma"] = "@angular-devkit/build-angular:karma";
Builders["TsLint"] = "@angular-devkit/build-angular:tslint";
Builders["NgPackagr"] = "@angular-devkit/build-angular:ng-packagr";
Builders["DevServer"] = "@angular-devkit/build-angular:dev-server";
Builders["ExtractI18n"] = "@angular-devkit/build-angular:extract-i18n";
Builders["Protractor"] = "@angular-devkit/build-angular:protractor";
})(Builders || (exports.Builders = Builders = {}));

View file

@ -0,0 +1,64 @@
/**
* @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.io/license
*/
import { json, workspaces } from '@angular-devkit/core';
import { Rule, Tree } from '@angular-devkit/schematics';
export type WorkspaceDefinition = workspaces.WorkspaceDefinition;
export type ProjectDefinition = workspaces.ProjectDefinition;
export type TargetDefinition = workspaces.TargetDefinition;
/**
* A {@link workspaces.WorkspaceHost} backed by a Schematics {@link Tree} instance.
*/
export declare class TreeWorkspaceHost implements workspaces.WorkspaceHost {
private readonly tree;
constructor(tree: Tree);
readFile(path: string): Promise<string>;
writeFile(path: string, data: string): Promise<void>;
isDirectory(path: string): Promise<boolean>;
isFile(path: string): Promise<boolean>;
}
/**
* Updates the workspace file (`angular.json`) found within the root of the schematic's tree.
* The workspace object model can be directly modified within the provided updater function
* with changes being written to the workspace file after the updater function returns.
* The spacing and overall layout of the file (including comments) will be maintained where
* possible when updating the file.
*
* @param updater An update function that can be used to modify the object model for the
* workspace. A {@link WorkspaceDefinition} is provided as the first argument to the function.
*/
export declare function updateWorkspace(updater: (workspace: WorkspaceDefinition) => void | Rule | PromiseLike<void | Rule>): Rule;
/**
* Reads a workspace file (`angular.json`) from the provided {@link Tree} instance.
*
* @param tree A schematics {@link Tree} instance used to access the workspace file.
* @param path The path where a workspace file should be found. If a file is specified, the file
* path will be used. If a directory is specified, the file `angular.json` will be used from
* within the specified directory. Defaults to `/angular.json`.
* @returns A {@link WorkspaceDefinition} representing the workspace found at the specified path.
*/
export declare function getWorkspace(tree: Tree, path?: string): Promise<WorkspaceDefinition>;
/**
* Writes a workspace file (`angular.json`) to the provided {@link Tree} instance.
* The spacing and overall layout of an exisitng file (including comments) will be maintained where
* possible when writing the file.
*
* @param tree A schematics {@link Tree} instance used to access the workspace file.
* @param workspace The {@link WorkspaceDefinition} to write.
* @param path The path where a workspace file should be written. If a file is specified, the file
* path will be used. If not provided, the definition's underlying file path stored during reading
* will be used.
*/
export declare function writeWorkspace(tree: Tree, workspace: WorkspaceDefinition, path?: string): Promise<void>;
/**
* Build a default project path for generating.
* @param project The project which will have its default path generated.
*/
export declare function buildDefaultPath(project: workspaces.ProjectDefinition): string;
export declare function createDefaultPath(tree: Tree, projectName: string): Promise<string>;
export declare function allWorkspaceTargets(workspace: workspaces.WorkspaceDefinition): Iterable<[string, workspaces.TargetDefinition, string, workspaces.ProjectDefinition]>;
export declare function allTargetOptions(target: workspaces.TargetDefinition, skipBaseOptions?: boolean): Iterable<[string | undefined, Record<string, json.JsonValue | undefined>]>;

134
my-app/node_modules/@schematics/angular/utility/workspace.js generated vendored Executable file
View file

@ -0,0 +1,134 @@
"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.io/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.allTargetOptions = exports.allWorkspaceTargets = exports.createDefaultPath = exports.buildDefaultPath = exports.writeWorkspace = exports.getWorkspace = exports.updateWorkspace = exports.TreeWorkspaceHost = void 0;
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const workspace_models_1 = require("./workspace-models");
const DEFAULT_WORKSPACE_PATH = '/angular.json';
/**
* A {@link workspaces.WorkspaceHost} backed by a Schematics {@link Tree} instance.
*/
class TreeWorkspaceHost {
tree;
constructor(tree) {
this.tree = tree;
}
async readFile(path) {
return this.tree.readText(path);
}
async writeFile(path, data) {
if (this.tree.exists(path)) {
this.tree.overwrite(path, data);
}
else {
this.tree.create(path, data);
}
}
async isDirectory(path) {
// approximate a directory check
return !this.tree.exists(path) && this.tree.getDir(path).subfiles.length > 0;
}
async isFile(path) {
return this.tree.exists(path);
}
}
exports.TreeWorkspaceHost = TreeWorkspaceHost;
/**
* Updates the workspace file (`angular.json`) found within the root of the schematic's tree.
* The workspace object model can be directly modified within the provided updater function
* with changes being written to the workspace file after the updater function returns.
* The spacing and overall layout of the file (including comments) will be maintained where
* possible when updating the file.
*
* @param updater An update function that can be used to modify the object model for the
* workspace. A {@link WorkspaceDefinition} is provided as the first argument to the function.
*/
function updateWorkspace(updater) {
return async (host) => {
const workspace = await getWorkspace(host);
const result = await updater(workspace);
await core_1.workspaces.writeWorkspace(workspace, new TreeWorkspaceHost(host));
return result || schematics_1.noop;
};
}
exports.updateWorkspace = updateWorkspace;
// TODO: This should be renamed `readWorkspace` once deep imports are restricted (already exported from `utility` with that name)
/**
* Reads a workspace file (`angular.json`) from the provided {@link Tree} instance.
*
* @param tree A schematics {@link Tree} instance used to access the workspace file.
* @param path The path where a workspace file should be found. If a file is specified, the file
* path will be used. If a directory is specified, the file `angular.json` will be used from
* within the specified directory. Defaults to `/angular.json`.
* @returns A {@link WorkspaceDefinition} representing the workspace found at the specified path.
*/
async function getWorkspace(tree, path = DEFAULT_WORKSPACE_PATH) {
const host = new TreeWorkspaceHost(tree);
const { workspace } = await core_1.workspaces.readWorkspace(path, host);
return workspace;
}
exports.getWorkspace = getWorkspace;
/**
* Writes a workspace file (`angular.json`) to the provided {@link Tree} instance.
* The spacing and overall layout of an exisitng file (including comments) will be maintained where
* possible when writing the file.
*
* @param tree A schematics {@link Tree} instance used to access the workspace file.
* @param workspace The {@link WorkspaceDefinition} to write.
* @param path The path where a workspace file should be written. If a file is specified, the file
* path will be used. If not provided, the definition's underlying file path stored during reading
* will be used.
*/
async function writeWorkspace(tree, workspace, path) {
const host = new TreeWorkspaceHost(tree);
return core_1.workspaces.writeWorkspace(workspace, host, path);
}
exports.writeWorkspace = writeWorkspace;
/**
* Build a default project path for generating.
* @param project The project which will have its default path generated.
*/
function buildDefaultPath(project) {
const root = project.sourceRoot ? `/${project.sourceRoot}/` : `/${project.root}/src/`;
const projectDirName = project.extensions['projectType'] === workspace_models_1.ProjectType.Application ? 'app' : 'lib';
return `${root}${projectDirName}`;
}
exports.buildDefaultPath = buildDefaultPath;
async function createDefaultPath(tree, projectName) {
const workspace = await getWorkspace(tree);
const project = workspace.projects.get(projectName);
if (!project) {
throw new Error(`Project "${projectName}" does not exist.`);
}
return buildDefaultPath(project);
}
exports.createDefaultPath = createDefaultPath;
function* allWorkspaceTargets(workspace) {
for (const [projectName, project] of workspace.projects) {
for (const [targetName, target] of project.targets) {
yield [targetName, target, projectName, project];
}
}
}
exports.allWorkspaceTargets = allWorkspaceTargets;
function* allTargetOptions(target, skipBaseOptions = false) {
if (!skipBaseOptions && target.options) {
yield [undefined, target.options];
}
if (!target.configurations) {
return;
}
for (const [name, options] of Object.entries(target.configurations)) {
if (options !== undefined) {
yield [name, options];
}
}
}
exports.allTargetOptions = allTargetOptions;