NET-Web-API-w-Angular/my-app/node_modules/@schematics/angular/utility/standalone/rules.js

188 lines
8.2 KiB
JavaScript
Executable file

"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)]);
}
}