UNPKG

@domoinc/ryuu-angular

Version:

Angular Schematic to add @domoinc/ryuu-proxy support

196 lines (180 loc) 6.37 kB
import { Rule, SchematicContext, Tree, mergeWith, apply, url, template, chain, forEach, FileEntry, } from '@angular-devkit/schematics'; import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { strings } from '@angular-devkit/core'; import { addPackageJsonDependency, NodeDependencyType, } from '@schematics/angular/utility/dependencies'; import { getProject, getWorkspace, parseJson } from './utils'; export interface Schema { project?: string; output?: string; } /** * Retrieves the contents of the tsconfig.json file from the given tree. * @param {Tree} tree - The tree object representing the file system. * @returns The contents of the tsconfig.json file as a JSON object, or an empty string if the file does not exist. */ const getTsConfig = (tree: Tree) => tree.readJson('tsconfig.json') ?? ''; /** * Retrieves the Angular configuration from the given tree. * @param {Tree} tree - The tree object representing the file system. * @returns The Angular configuration object if found, otherwise an empty string. */ const getAngularConfig = (tree: Tree) => tree.readJson('angular.json') ?? ''; /** * Updates the tsconfig.json file in the given tree by adding or modifying the compiler options. * @param {Tree} tree - The tree representing the file system. * @returns The updated tree. */ const updateTSConfig = () => { return (tree: Tree) => { const config: any = getTsConfig(tree); config.compilerOptions = { ...config.compilerOptions, resolveJsonModule: true, allowSyntheticDefaultImports: true, }; tree.overwrite('tsconfig.json', JSON.stringify(config, null, 2)); return tree; }; }; /** * Updates the angular.json file with the specified options. * @param {Schema} options - The options to update the angular.json file with. * @returns A function that takes in a Tree object and updates the angular.json file. */ const updateAngularJSON = (options: Schema) => { return (tree: Tree) => { const workspace = getWorkspace(tree); const project = getProject(workspace, options.project!); (project.architect!.build! .builder) = '@angular-builders/custom-webpack:browser'; (project.architect!.serve! .builder) = '@angular-builders/custom-webpack:dev-server'; (project.architect!.build!.options)['customWebpackConfig'] = { path: './extra-webpack.config.ts', }; // Options const mainSrc = project.architect!.build!.options!.browser ?? 'src/main.ts'; (project.architect!.build! .options!.main) = mainSrc; delete project.architect!.build!.options!.browser; // Remove browser option for Custom Webpack tree.overwrite('angular.json', JSON.stringify(workspace, null, 2)); return tree; }; }; /** * Retrieves the version number of the project from the package.json file in the given tree. * @param {Tree} tree - The tree object representing the project file structure. * @returns The version number of the project. */ const getProjectVersion = (tree: Tree) => { const packageBuffer = tree.read('package.json') ?? ''; const pack: any = parseJson(packageBuffer.toString()); return pack.version; }; /** * Copies Domo files to the specified tree directory. * @param {Tree} tree - The tree directory to copy the files to. * @param {Schema} options - The options for copying the files. * @returns A merged tree with the copied files. */ const copyDomoFiles = (tree: Tree, options: Schema) => { const version = getProjectVersion(tree); return mergeWith( apply(url('./files'), [ template({ ...options, version, ...strings, }), forEach((file: FileEntry) => { if (tree.exists(file.path)) return null; return file; }), ]), ); }; /** * Adds the specified dependencies to the package.json file. * @param {Tree} tree - The tree object representing the file system. * @returns A function that takes in a tree object and adds the dependencies to the package.json file. */ const addDepsToPackage = () => { return (tree: Tree) => { const deps: any = { '@angular-builders/custom-webpack': '^18.0.0', '@domoinc/ryuu-proxy': '^4.3.4', 'copy-webpack-plugin': '^11.0.0', }; Object.keys(deps).forEach((key) => { addPackageJsonDependency(tree, { name: key, type: NodeDependencyType.Dev, version: deps[key], }); }); }; }; /** * Adds helper scripts to the package.json file based on the provided options. * @param {Schema} options - The options object containing project information. * @returns {Tree} The updated tree with the modified package.json file. */ const addHelperScripts = (options: Schema) => { return (tree: Tree) => { const packageBuffer = tree.read('package.json') ?? ''; const pack: any = parseJson(packageBuffer.toString()); const distFolder = options.output ?? `dist/${options.project}`; pack.scripts = { ...pack.scripts, 'domo:upload': `npm run build && cd ${distFolder} && domo publish`, 'postdomo:upload': `cp ${distFolder}/manifest.json domo/`, }; tree.overwrite('package.json', JSON.stringify(pack, null, 2)); return tree; }; }; /** * Angular schematic rule that adds dependencies and configuration to an Angular project. * @param {any} _options - The options for the schematic. * @returns {Rule} - A rule function that modifies the project tree. */ export function ngAdd(options: any): Rule { return (tree: Tree, context: SchematicContext) => { context.addTask(new NodePackageInstallTask()); // Check for Project Name if (!options.project) { const config: any = getAngularConfig(tree); if (config.projects) { const projects = Object.keys(config.projects); const defaultProjectName = projects.length > 0 ? projects[0] : ''; const defaultProject = config.projects[defaultProjectName]; const buildOutput = defaultProject.architect!.build!.options!.outputPath; options = { ...options, project: defaultProjectName, output: buildOutput }; } } console.log('[ngAdd] options', options); return chain([ addDepsToPackage(), copyDomoFiles(tree, options), updateAngularJSON(options), updateTSConfig(), addHelperScripts(options), ]); }; }