diff --git a/collection.json b/collection.json index 6e413a26..399f2435 100644 --- a/collection.json +++ b/collection.json @@ -3,7 +3,7 @@ "schematics": { "ng-add": { "description": "Builder to analyze package using source-map-explorer", - "factory": "./ng-add/index", + "factory": "./ng-add/index#ngAdd", "schema": "./ng-add/schema.json", "aliases": [ "install" diff --git a/ng-add/index.ts b/ng-add/index.ts index 1a1cc03c..d0f0f0a5 100644 --- a/ng-add/index.ts +++ b/ng-add/index.ts @@ -1,18 +1,17 @@ -import { Rule, SchematicContext, SchematicsException, Tree } from '@angular-devkit/schematics'; -import { getWorkspace, getWorkspacePath, ProjectType, WorkspaceProject } from 'schematics-utilities'; +import { TargetDefinition } from '@angular-devkit/core/src/workspace'; +import { chain, Rule, SchematicsException, Tree } from '@angular-devkit/schematics'; import { NgAddOptions } from './schema'; +import { getWorkspace, updateWorkspace } from './workspace'; -export function sourceMapBuilder(options: NgAddOptions): Rule { - return (tree: Tree, _context: SchematicContext) => { - // get the workspace details - const workspaceSchema = getWorkspace(tree); - const workspacePath: string = getWorkspacePath(tree); +export function ngAdd(options: NgAddOptions): Rule { + return async (host: Tree) => { + const workspace = await getWorkspace(host); - // getting project name + // Get project name if (!options.project) { - if (workspaceSchema && workspaceSchema.defaultProject) { - options.project = workspaceSchema.defaultProject; + if (workspace.extensions.defaultProject) { + options.project = workspace.extensions.defaultProject as string; } else { throw new SchematicsException( 'No Angular project selected and no default project in the workspace' @@ -21,45 +20,32 @@ export function sourceMapBuilder(options: NgAddOptions): Rule { } // Validating project name - const project: WorkspaceProject = workspaceSchema.projects[options.project]; + const project = workspace.projects.get(options.project); if (!project) { - throw new SchematicsException( - 'The specified Angular project is not defined in this workspace' - ); + throw new SchematicsException(`The specified Angular project is not defined in this workspace`); } // Checking if it is application - if (project.projectType !== 'application') { - throw new SchematicsException( - `source-map-analyzer requires an Angular project type of "application" in angular.json` - ); + if (project.extensions['projectType'] !== 'application') { + throw new SchematicsException(`source-map-analyzer requires an Angular project type of "application" in angular.json`); } + + const outputPath: string | undefined = project.targets.get('build')?.options?.outputPath as string; - // Getting output path from Angular.json - if ( - !project.architect || - !project.architect.build || - !project.architect.build.options || - !project.architect.build.options.outputPath - ) { - throw new SchematicsException( - `Cannot read the output path(architect.build.options.outputPath) of the Angular project "${options.project}" in angular.json` - ); + if (!outputPath) { + const message: string = `Cannot read the output path(architect.build.options.outputPath) of the Angular project "${options.project}" in angular.json`; + throw new SchematicsException(message); } - // adding deploy statement for builder - project.architect['analyze'] = { - "builder": "@ngx-builders/analyze:analyze", - "options": { - "outputPath": project.architect.build.options.outputPath + var targetDefinition: TargetDefinition = { + builder: "@ngx-builders/analyze:analyze", + options: { + outputPath: outputPath } } - tree.overwrite(workspacePath, JSON.stringify(workspaceSchema, null, 2)); - return tree; - }; -} + project.targets.add({ name: 'analyze', ...targetDefinition }); -export default function (options: NgAddOptions): Rule { - return sourceMapBuilder(options) + return chain([updateWorkspace(workspace)]); + }; } diff --git a/ng-add/schema.ts b/ng-add/schema.ts index 5f9af5a8..b597c694 100644 --- a/ng-add/schema.ts +++ b/ng-add/schema.ts @@ -1,5 +1,3 @@ export interface NgAddOptions { project: string | undefined; - siteID: string; - netlifyToken: string; } diff --git a/ng-add/workspace.ts b/ng-add/workspace.ts new file mode 100644 index 00000000..4c972690 --- /dev/null +++ b/ng-add/workspace.ts @@ -0,0 +1,64 @@ +import { virtualFs, workspaces } from '@angular-devkit/core'; +import { noop, Rule, SchematicsException, Tree } from '@angular-devkit/schematics'; + +/* Below code reference is taken from Angular CLI project. + https://github.com/angular/angular-cli/blob/master/packages/schematics/angular/utility/workspace.ts + + These methods are not part of public APIs so we should not be referencing those methods. + that's why added below method here. +*/ + +function createHost(tree: Tree): workspaces.WorkspaceHost { + return { + async readFile(path: string): Promise { + const data = tree.read(path); + if (!data) { + throw new SchematicsException('File not found.'); + } + return virtualFs.fileBufferToString(data); + }, + async writeFile(path: string, data: string): Promise { + return tree.overwrite(path, data); + }, + async isDirectory(path: string): Promise { + return !tree.exists(path) && tree.getDir(path).subfiles.length > 0; + }, + async isFile(path: string): Promise { + return tree.exists(path); + }, + }; +} + +export async function getWorkspace(tree: Tree, path = '/') : Promise { + const host = createHost(tree); + const { workspace } = await workspaces.readWorkspace(path, host); + return workspace; +} + +export function updateWorkspace( + updater: (workspace: workspaces.WorkspaceDefinition) => void | Rule | PromiseLike, + ): Rule; + export function updateWorkspace(workspace: workspaces.WorkspaceDefinition): Rule; + export function updateWorkspace( + updaterOrWorkspace: + | workspaces.WorkspaceDefinition + | ((workspace: workspaces.WorkspaceDefinition) => void | Rule | PromiseLike), + ): Rule { + return async (tree: Tree) => { + const host = createHost(tree); + + if (typeof updaterOrWorkspace === 'function') { + const { workspace } = await workspaces.readWorkspace('/', host); + + const result = await updaterOrWorkspace(workspace); + + await workspaces.writeWorkspace(workspace, host); + + return result || noop; + } else { + await workspaces.writeWorkspace(updaterOrWorkspace, host); + + return noop; + } + }; + } \ No newline at end of file diff --git a/package.json b/package.json index 5dbd743c..2773ab83 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@ngx-builders/analyze", - "version": "3.0.0", - "description": "", + "version": "3.0.1", + "description": "Angular Builder To Run Source Map Explorer", "main": "index.js", "builders": "./builders.json", "schematics": "./collection.json", @@ -43,6 +43,6 @@ "dependencies": { "@angular-devkit/architect": "0.1300.0", "@angular-devkit/core": "13.0.0", - "schematics-utilities": "2.0.3" + "@angular-devkit/schematics": "^13.0.0" } }