1 | {"version":3,"file":"standalone.js","sourceRoot":"","sources":["../../../../../modules/schematics/schematics-core/utility/standalone.ts"],"names":[],"mappings":"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","sourcesContent":["// copied from https://github.com/angular/angular-cli/blob/17.3.x/packages/schematics/angular/private/standalone.ts\nimport {\n SchematicsException,\n Tree,\n UpdateRecorder,\n} from '@angular-devkit/schematics';\nimport { dirname, join } from 'path';\nimport { insertImport } from './ast-utils';\nimport { InsertChange } from './change';\nimport * as ts from 'typescript';\n\n/** App config that was resolved to its source node. */\ninterface ResolvedAppConfig {\n /** Tree-relative path of the file containing the app config. */\n filePath: string;\n\n /** Node defining the app config. */\n node: ts.ObjectLiteralExpression;\n}\n\n/**\n * Checks whether a providers function is being called in a `bootstrapApplication` call.\n * @param tree File tree of the project.\n * @param filePath Path of the file in which to check.\n * @param functionName Name of the function to search for.\n * @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from\n * `@schematics/angular/utility` instead.\n */\nexport function callsProvidersFunction(\n tree: Tree,\n filePath: string,\n functionName: string\n): boolean {\n const sourceFile = createSourceFile(tree, filePath);\n const bootstrapCall = findBootstrapApplicationCall(sourceFile);\n const appConfig = bootstrapCall\n ? findAppConfig(bootstrapCall, tree, filePath)\n : null;\n const providersLiteral = appConfig\n ? findProvidersLiteral(appConfig.node)\n : null;\n\n return !!providersLiteral?.elements.some(\n (el) =>\n ts.isCallExpression(el) &&\n ts.isIdentifier(el.expression) &&\n el.expression.text === functionName\n );\n}\n\n/**\n * Adds a providers function call to the `bootstrapApplication` call.\n * @param tree File tree of the project.\n * @param filePath Path to the file that should be updated.\n * @param functionName Name of the function that should be called.\n * @param importPath Path from which to import the function.\n * @param args Arguments to use when calling the function.\n * @return The file path that the provider was added to.\n * @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from\n * `@schematics/angular/utility` instead.\n */\nexport function addFunctionalProvidersToStandaloneBootstrap(\n tree: Tree,\n filePath: string,\n functionName: string,\n importPath: string,\n args: ts.Expression[] = []\n): string {\n const sourceFile = createSourceFile(tree, filePath);\n const bootstrapCall = findBootstrapApplicationCall(sourceFile);\n const addImports = (file: ts.SourceFile, recorder: UpdateRecorder) => {\n const change = insertImport(file, file.getText(), functionName, importPath);\n\n if (change instanceof InsertChange) {\n recorder.insertLeft(change.pos, change.toAdd);\n }\n };\n\n if (!bootstrapCall) {\n throw new SchematicsException(\n `Could not find bootstrapApplication call in ${filePath}`\n );\n }\n\n const providersCall = ts.factory.createCallExpression(\n ts.factory.createIdentifier(functionName),\n undefined,\n args\n );\n\n // If there's only one argument, we have to create a new object literal.\n if (bootstrapCall.arguments.length === 1) {\n const recorder = tree.beginUpdate(filePath);\n addNewAppConfigToCall(bootstrapCall, providersCall, recorder);\n addImports(sourceFile, recorder);\n tree.commitUpdate(recorder);\n\n return filePath;\n }\n\n // If the config is a `mergeApplicationProviders` call, add another config to it.\n if (isMergeAppConfigCall(bootstrapCall.arguments[1])) {\n const recorder = tree.beginUpdate(filePath);\n addNewAppConfigToCall(bootstrapCall.arguments[1], providersCall, recorder);\n addImports(sourceFile, recorder);\n tree.commitUpdate(recorder);\n\n return filePath;\n }\n\n // Otherwise attempt to merge into the current config.\n const appConfig = findAppConfig(bootstrapCall, tree, filePath);\n\n if (!appConfig) {\n throw new SchematicsException(\n `Could not statically analyze config in bootstrapApplication call in ${filePath}`\n );\n }\n\n const { filePath: configFilePath, node: config } = appConfig;\n const recorder = tree.beginUpdate(configFilePath);\n const providersLiteral = findProvidersLiteral(config);\n\n addImports(config.getSourceFile(), recorder);\n\n if (providersLiteral) {\n // If there's a `providers` array, add the import to it.\n addElementToArray(providersLiteral, providersCall, recorder);\n } else {\n // Otherwise add a `providers` array to the existing object literal.\n addProvidersToObjectLiteral(config, providersCall, recorder);\n }\n\n tree.commitUpdate(recorder);\n\n return configFilePath;\n}\n\n/**\n * Finds the call to `bootstrapApplication` within a file.\n * @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from\n * `@schematics/angular/utility` instead.\n */\nexport function findBootstrapApplicationCall(\n sourceFile: ts.SourceFile\n): ts.CallExpression | null {\n const localName = findImportLocalName(\n sourceFile,\n 'bootstrapApplication',\n '@angular/platform-browser'\n );\n\n if (!localName) {\n return null;\n }\n\n let result: ts.CallExpression | null = null;\n\n sourceFile.forEachChild(function walk(node) {\n if (\n ts.isCallExpression(node) &&\n ts.isIdentifier(node.expression) &&\n node.expression.text === localName\n ) {\n result = node;\n }\n\n if (!result) {\n node.forEachChild(walk);\n }\n });\n\n return result;\n}\n\n/** Finds the `providers` array literal within an application config. */\nfunction findProvidersLiteral(\n config: ts.ObjectLiteralExpression\n): ts.ArrayLiteralExpression | null {\n for (const prop of config.properties) {\n if (\n ts.isPropertyAssignment(prop) &&\n ts.isIdentifier(prop.name) &&\n prop.name.text === 'providers' &&\n ts.isArrayLiteralExpression(prop.initializer)\n ) {\n return prop.initializer;\n }\n }\n\n return null;\n}\n\n/**\n * Resolves the node that defines the app config from a bootstrap call.\n * @param bootstrapCall Call for which to resolve the config.\n * @param tree File tree of the project.\n * @param filePath File path of the bootstrap call.\n */\nfunction findAppConfig(\n bootstrapCall: ts.CallExpression,\n tree: Tree,\n filePath: string\n): ResolvedAppConfig | null {\n if (bootstrapCall.arguments.length > 1) {\n const config = bootstrapCall.arguments[1];\n\n if (ts.isObjectLiteralExpression(config)) {\n return { filePath, node: config };\n }\n\n if (ts.isIdentifier(config)) {\n return resolveAppConfigFromIdentifier(config, tree, filePath);\n }\n }\n\n return null;\n}\n\n/**\n * Resolves the app config from an identifier referring to it.\n * @param identifier Identifier referring to the app config.\n * @param tree File tree of the project.\n * @param bootstapFilePath Path of the bootstrap call.\n */\nfunction resolveAppConfigFromIdentifier(\n identifier: ts.Identifier,\n tree: Tree,\n bootstapFilePath: string\n): ResolvedAppConfig | null {\n const sourceFile = identifier.getSourceFile();\n\n for (const node of sourceFile.statements) {\n // Only look at relative imports. This will break if the app uses a path\n // mapping to refer to the import, but in order to resolve those, we would\n // need knowledge about the entire program.\n if (\n !ts.isImportDeclaration(node) ||\n !node.importClause?.namedBindings ||\n !ts.isNamedImports(node.importClause.namedBindings) ||\n !ts.isStringLiteralLike(node.moduleSpecifier) ||\n !node.moduleSpecifier.text.startsWith('.')\n ) {\n continue;\n }\n\n for (const specifier of node.importClause.namedBindings.elements) {\n if (specifier.name.text !== identifier.text) {\n continue;\n }\n\n // Look for a variable with the imported name in the file. Note that ideally we would use\n // the type checker to resolve this, but we can't because these utilities are set up to\n // operate on individual files, not the entire program.\n const filePath = join(\n dirname(bootstapFilePath),\n node.moduleSpecifier.text + '.ts'\n );\n const importedSourceFile = createSourceFile(tree, filePath);\n const resolvedVariable = findAppConfigFromVariableName(\n importedSourceFile,\n (specifier.propertyName || specifier.name).text\n );\n\n if (resolvedVariable) {\n return { filePath, node: resolvedVariable };\n }\n }\n }\n\n const variableInSameFile = findAppConfigFromVariableName(\n sourceFile,\n identifier.text\n );\n\n return variableInSameFile\n ? { filePath: bootstapFilePath, node: variableInSameFile }\n : null;\n}\n\n/**\n * Finds an app config within the top-level variables of a file.\n * @param sourceFile File in which to search for the config.\n * @param variableName Name of the variable containing the config.\n */\nfunction findAppConfigFromVariableName(\n sourceFile: ts.SourceFile,\n variableName: string\n): ts.ObjectLiteralExpression | null {\n for (const node of sourceFile.statements) {\n if (ts.isVariableStatement(node)) {\n for (const decl of node.declarationList.declarations) {\n if (\n ts.isIdentifier(decl.name) &&\n decl.name.text === variableName &&\n decl.initializer &&\n ts.isObjectLiteralExpression(decl.initializer)\n ) {\n return decl.initializer;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Finds the local name of an imported symbol. Could be the symbol name itself or its alias.\n * @param sourceFile File within which to search for the import.\n * @param name Actual name of the import, not its local alias.\n * @param moduleName Name of the module from which the symbol is imported.\n */\nfunction findImportLocalName(\n sourceFile: ts.SourceFile,\n name: string,\n moduleName: string\n): string | null {\n for (const node of sourceFile.statements) {\n // Only look for top-level imports.\n if (\n !ts.isImportDeclaration(node) ||\n !ts.isStringLiteral(node.moduleSpecifier) ||\n node.moduleSpecifier.text !== moduleName\n ) {\n continue;\n }\n\n // Filter out imports that don't have the right shape.\n if (\n !node.importClause ||\n !node.importClause.namedBindings ||\n !ts.isNamedImports(node.importClause.namedBindings)\n ) {\n continue;\n }\n\n // Look through the elements of the declaration for the specific import.\n for (const element of node.importClause.namedBindings.elements) {\n if ((element.propertyName || element.name).text === name) {\n // The local name is always in `name`.\n return element.name.text;\n }\n }\n }\n\n return null;\n}\n\n/** Creates a source file from a file path within a project. */\nfunction createSourceFile(tree: Tree, filePath: string): ts.SourceFile {\n return ts.createSourceFile(\n filePath,\n tree.readText(filePath),\n ts.ScriptTarget.Latest,\n true\n );\n}\n\n/**\n * Creates a new app config object literal and adds it to a call expression as an argument.\n * @param call Call to which to add the config.\n * @param expression Expression that should inserted into the new config.\n * @param recorder Recorder to which to log the change.\n */\nfunction addNewAppConfigToCall(\n call: ts.CallExpression,\n expression: ts.Expression,\n recorder: UpdateRecorder\n): void {\n const newCall = ts.factory.updateCallExpression(\n call,\n call.expression,\n call.typeArguments,\n [\n ...call.arguments,\n ts.factory.createObjectLiteralExpression(\n [\n ts.factory.createPropertyAssignment(\n 'providers',\n ts.factory.createArrayLiteralExpression([expression])\n ),\n ],\n true\n ),\n ]\n );\n\n recorder.remove(call.getStart(), call.getWidth());\n recorder.insertRight(\n call.getStart(),\n ts\n .createPrinter()\n .printNode(ts.EmitHint.Unspecified, newCall, call.getSourceFile())\n );\n}\n\n/**\n * Adds an element to an array literal expression.\n * @param node Array to which to add the element.\n * @param element Element to be added.\n * @param recorder Recorder to which to log the change.\n */\nfunction addElementToArray(\n node: ts.ArrayLiteralExpression,\n element: ts.Expression,\n recorder: UpdateRecorder\n): void {\n const newLiteral = ts.factory.updateArrayLiteralExpression(node, [\n ...node.elements,\n element,\n ]);\n recorder.remove(node.getStart(), node.getWidth());\n recorder.insertRight(\n node.getStart(),\n ts\n .createPrinter()\n .printNode(ts.EmitHint.Unspecified, newLiteral, node.getSourceFile())\n );\n}\n\n/**\n * Adds a `providers` property to an object literal.\n * @param node Literal to which to add the `providers`.\n * @param expression Provider that should be part of the generated `providers` array.\n * @param recorder Recorder to which to log the change.\n */\nfunction addProvidersToObjectLiteral(\n node: ts.ObjectLiteralExpression,\n expression: ts.Expression,\n recorder: UpdateRecorder\n) {\n const newOptionsLiteral = ts.factory.updateObjectLiteralExpression(node, [\n ...node.properties,\n ts.factory.createPropertyAssignment(\n 'providers',\n ts.factory.createArrayLiteralExpression([expression])\n ),\n ]);\n recorder.remove(node.getStart(), node.getWidth());\n recorder.insertRight(\n node.getStart(),\n ts\n .createPrinter()\n .printNode(\n ts.EmitHint.Unspecified,\n newOptionsLiteral,\n node.getSourceFile()\n )\n );\n}\n\n/** Checks whether a node is a call to `mergeApplicationConfig`. */\nfunction isMergeAppConfigCall(node: ts.Node): node is ts.CallExpression {\n if (!ts.isCallExpression(node)) {\n return false;\n }\n\n const localName = findImportLocalName(\n node.getSourceFile(),\n 'mergeApplicationConfig',\n '@angular/core'\n );\n\n return (\n !!localName &&\n ts.isIdentifier(node.expression) &&\n node.expression.text === localName\n );\n}\n"]} |