UNPKG

angular-server-side-configuration

Version:
170 lines (168 loc) 7.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ngAdd = ngAdd; const core_1 = require("@angular-devkit/core"); const schematics_1 = require("@angular-devkit/schematics"); const change_1 = require("@schematics/angular/utility/change"); const workspace_1 = require("@schematics/angular/utility/workspace"); function ngAdd(options) { return (0, schematics_1.chain)([ addNgsscTargetToWorkspace(options), addDescriptionToMainFile(options), addNgsscToPackageScripts(options), addPlaceholderToIndexHtml(options), ]); } function addNgsscTargetToWorkspace(options) { return (_host, context) => (0, workspace_1.updateWorkspace)((workspace) => { const project = workspace.projects.get(options.project); if (!project) { return; } const ngsscOptions = { additionalEnvironmentVariables: options.additionalEnvironmentVariables ? options.additionalEnvironmentVariables.split(',').map((e) => e.trim()) : [], }; if (options.experimentalBuilders) { const buildTarget = project.targets.get('build'); buildTarget.builder = 'angular-server-side-configuration:browser'; buildTarget.options = { ...buildTarget.options, ...ngsscOptions }; const serveTarget = project.targets.get('serve'); serveTarget.builder = 'angular-server-side-configuration:dev-server'; const target = project.targets.get('ngsscbuild'); if (target) { project.targets.delete('ngsscbuild'); } return; } const target = project.targets.get('ngsscbuild'); if (target) { context.logger.info(`Skipping adding ngsscbuild target to angular.json, as it already exists in project ${options.project}.`); return; } project.targets.add({ name: 'ngsscbuild', builder: 'angular-server-side-configuration:ngsscbuild', options: { ...ngsscOptions, buildTarget: `${options.project}:build`, }, configurations: { production: { buildTarget: `${options.project}:build:production`, }, }, }); }); } function addDescriptionToMainFile(options) { const noAppropriateInsertFileWarning = 'Unable to resolve appropriate file to insert import. Please follow documentation.'; return async (host, context) => { const { project } = await resolveWorkspace(options, host); const buildTarget = project.targets.get('build'); const mainFile = (0, core_1.normalize)(buildTarget?.options?.['main'] ?? buildTarget?.options?.['browser'] ?? ''); if (!mainFile) { context.logger.warn(noAppropriateInsertFileWarning); return; } const insertFile = [ (0, core_1.join)((0, core_1.dirname)(mainFile), 'environments/environment.prod.ts'), (0, core_1.join)((0, core_1.dirname)(mainFile), 'environments/environment.ts'), (0, core_1.join)((0, core_1.dirname)(mainFile), 'app/app.config.ts'), (0, core_1.join)((0, core_1.dirname)(mainFile), 'app/app.module.ts'), (0, core_1.join)((0, core_1.dirname)(mainFile), 'app/app.component.ts'), mainFile, ].find((f) => host.exists(f)); if (!insertFile) { context.logger.warn(noAppropriateInsertFileWarning); return; } const file = host.get(insertFile); if (!file) { context.logger.warn(noAppropriateInsertFileWarning); return; } else if (file.content.includes('angular-server-side-configuration')) { context.logger.info(`Skipping adding import to ${file.path}, since import was already detected.`); return; } const insertContent = `import 'angular-server-side-configuration/process'; /** * How to use angular-server-side-configuration: * * Use process.env['NAME_OF_YOUR_ENVIRONMENT_VARIABLE'] * * const stringValue = process.env['STRING_VALUE']; * const stringValueWithDefault = process.env['STRING_VALUE'] || 'defaultValue'; * const numberValue = Number(process.env['NUMBER_VALUE']); * const numberValueWithDefault = Number(process.env['NUMBER_VALUE'] || 10); * const booleanValue = process.env['BOOLEAN_VALUE'] === 'true'; * const booleanValueInverted = process.env['BOOLEAN_VALUE_INVERTED'] !== 'false'; * const complexValue = JSON.parse(process.env['COMPLEX_JSON_VALUE]); * * Please note that process.env[variable] cannot be resolved. Please directly use strings. */ `; const insertion = new change_1.InsertChange(file.path, 0, insertContent); const recorder = host.beginUpdate(file.path); recorder.insertLeft(insertion.pos, insertion.toAdd); host.commitUpdate(recorder); }; } function addNgsscToPackageScripts(options) { return (host, context) => { if (options.experimentalBuilders) { return; } const pkgPath = '/package.json'; const buffer = host.read(pkgPath); if (buffer === null) { throw new schematics_1.SchematicsException('Could not find package.json'); } const pkg = { scripts: {}, ...JSON.parse(buffer.toString()) }; if ('build:ngssc' in pkg.scripts) { context.logger.info(`Skipping adding script to package.json, as it already exists.`); return; } pkg.scripts['build:ngssc'] = `ng run ${options.project}:ngsscbuild:production`; host.overwrite(pkgPath, JSON.stringify(pkg, null, 2)); }; } function addPlaceholderToIndexHtml(options) { return async (host, context) => { const { project } = await resolveWorkspace(options, host); const build = project.targets.get('build'); if (!build) { throw new schematics_1.SchematicsException(`Expected a build target in project ${options.project}!`); } const indexPath = build.options?.['index'] || 'src/index.html'; const indexHtml = host.get(indexPath); if (!indexHtml) { throw new schematics_1.SchematicsException(`Expected index html ${indexPath} to exist!`); } const indexHtmlContent = indexHtml.content.toString(); if (/<!--\s*CONFIG\s*-->/.test(indexHtmlContent)) { context.logger.info(`Skipping adding placeholder to ${indexHtml.path}, as it already contains it.`); return; } const insertIndex = indexHtmlContent.includes('</title>') ? indexHtmlContent.indexOf('</title>') + 9 : indexHtmlContent.indexOf('</head>'); const insertion = new change_1.InsertChange(indexHtml.path, insertIndex, ' <!--CONFIG-->\n'); const recorder = host.beginUpdate(indexHtml.path); recorder.insertLeft(insertion.pos, insertion.toAdd); host.commitUpdate(recorder); }; } async function resolveWorkspace(options, host) { const workspace = await (0, workspace_1.getWorkspace)(host); const project = workspace.projects.get(options.project); if (!project) { throw new schematics_1.SchematicsException(`Project ${options.project} not found!`); } return { workspace, project }; } //# sourceMappingURL=index.js.map