-
-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
1,290 additions
and
145 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"schematics": { | ||
"ng-add": { | ||
"aliases": ["init"], | ||
"factory": "./ng-add/", | ||
"schema": "./ng-add/schema.json", | ||
"description": "Add error-tailor configuration for root module." | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { Tree } from '@angular-devkit/schematics'; | ||
import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; | ||
|
||
import { join } from 'path'; | ||
|
||
const angularJSON = { | ||
projects: { | ||
test: { | ||
sourceRoot: 'src', | ||
architect: { | ||
build: { | ||
options: { | ||
main: 'src/main.ts' | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
defaultProject: 'test' | ||
}; | ||
const appModule = ` | ||
import { NgModule } from '@angular/core'; | ||
@NgModule({declarations: [], imports: [], bootstrap: [], }) | ||
export class AppModule { } | ||
`; | ||
const main = ` | ||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; | ||
import { AppModule } from './app/app.module'; | ||
platformBrowserDynamic().bootstrapModule(AppModule); | ||
`; | ||
|
||
const collectionPath = join(__dirname, '../collection.json'); | ||
|
||
describe('Schematics', () => { | ||
let testTree: Tree; | ||
let runner: SchematicTestRunner; | ||
|
||
beforeEach(() => { | ||
testTree = Tree.empty(); | ||
testTree.create('./angular.json', JSON.stringify(angularJSON)); | ||
testTree.create('./package.json', JSON.stringify({ dependencies: {} })); | ||
testTree.create('./src/main.ts', main); | ||
testTree.create('./src/app/app.module.ts', appModule); | ||
|
||
runner = new SchematicTestRunner('schematics', collectionPath); | ||
}); | ||
|
||
describe('ng-add', () => { | ||
it('should add package to package.json and import it in app.module', async () => { | ||
const tree = await runner.runSchematicAsync('ng-add', {}, testTree).toPromise(); | ||
|
||
const appModuleModified = tree.readContent('./src/app/app.module.ts'); | ||
|
||
console.log(appModuleModified); | ||
|
||
expect(appModuleModified).toContain(`import { ErrorTailorModule, FORM_ERRORS } from '@ngneat/error-tailor';`); | ||
expect(appModuleModified).toContain(`imports: [ErrorTailorModule]`); | ||
expect(appModuleModified).toContain(`{ provide: FORM_ERRORS, useValue: { } }`); | ||
|
||
const packageJSONModified = JSON.parse(tree.readContent('./package.json')); | ||
|
||
expect(packageJSONModified).toEqual({ | ||
dependencies: { | ||
'@ngneat/error-tailor': '1.0.0' | ||
} | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { chain, Rule, SchematicContext, SchematicsException, Tree } from '@angular-devkit/schematics'; | ||
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; | ||
import { | ||
addPackageJsonDependency, | ||
getAppModulePath, | ||
getProjectFromWorkspace, | ||
getWorkspace, | ||
InsertChange, | ||
NodeDependency, | ||
NodeDependencyType, | ||
addModuleImportToRootModule | ||
} from 'schematics-utilities'; | ||
import * as ts from 'typescript'; | ||
|
||
import { Schema } from './schema'; | ||
import { addProviderToModule, applyChanges, getModuleFile, insertImport } from './utils'; | ||
|
||
function addPackageJsonDependencies(options: Schema): Rule { | ||
return (host: Tree, context: SchematicContext) => { | ||
const dependencies: NodeDependency[] = [ | ||
{ | ||
type: NodeDependencyType.Default, | ||
name: '@ngneat/error-tailor', | ||
version: '1.0.0' | ||
} | ||
]; | ||
|
||
dependencies.forEach(dependency => { | ||
addPackageJsonDependency(host, dependency); | ||
context.logger.log('info', `✅️ Added "${dependency.name}" into ${dependency.type}`); | ||
}); | ||
|
||
return host; | ||
}; | ||
} | ||
|
||
function installPackageJsonDependencies(): Rule { | ||
return (host: Tree, context: SchematicContext) => { | ||
context.addTask(new NodePackageInstallTask()); | ||
context.logger.log('info', `🔍 Installing package...`); | ||
|
||
return host; | ||
}; | ||
} | ||
|
||
function getTsSourceFile(host: Tree, path: string): ts.SourceFile { | ||
const buffer = host.read(path); | ||
if (!buffer) { | ||
throw new SchematicsException(`Could not read file (${path}).`); | ||
} | ||
const content = buffer.toString(); | ||
const source = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true); | ||
|
||
return source; | ||
} | ||
|
||
function injectImports(options: Schema): Rule { | ||
return (host: Tree, context: SchematicContext) => { | ||
const workspace = getWorkspace(host); | ||
const project = getProjectFromWorkspace(workspace, Object.keys(workspace.projects)[0]); | ||
const modulePath = getAppModulePath(host, (project as any).architect.build.options.main); | ||
|
||
const moduleSource = getTsSourceFile(host, modulePath); | ||
|
||
const change = insertImport(moduleSource, modulePath, 'ErrorTailorModule, FORM_ERRORS', '@ngneat/error-tailor'); | ||
|
||
if (change) { | ||
const recorder = host.beginUpdate(modulePath); | ||
recorder.insertLeft((change as InsertChange).pos, (change as InsertChange).toAdd); | ||
host.commitUpdate(recorder); | ||
} | ||
|
||
return host; | ||
}; | ||
} | ||
|
||
function addModuleToImports(options: Schema): Rule { | ||
return (host: Tree, context: SchematicContext) => { | ||
const workspace = getWorkspace(host); | ||
const project = getProjectFromWorkspace(workspace, Object.keys(workspace.projects)[0]); | ||
|
||
addModuleImportToRootModule(host, 'ErrorTailorModule', null as any, project); | ||
|
||
const provider = `{ provide: FORM_ERRORS, useValue: { } }`; | ||
|
||
const modulePath = getAppModulePath(host, project.architect.build.options.main); | ||
const module = getModuleFile(host, modulePath); | ||
const providerChanges = addProviderToModule(module, modulePath, provider, null); | ||
applyChanges(host, modulePath, providerChanges as InsertChange[]); | ||
|
||
context.logger.log('info', `🌈 @ngneat/error-tailor is imported`); | ||
|
||
return host; | ||
}; | ||
} | ||
|
||
function log(): Rule { | ||
return (host: Tree, context: SchematicContext) => { | ||
context.logger.log('info', `👏 @ngneat/error-tailor ready to use`); | ||
|
||
return host; | ||
}; | ||
} | ||
|
||
export default function errorTailorNgAdd(options: Schema): Rule { | ||
return chain([ | ||
addPackageJsonDependencies(options), | ||
installPackageJsonDependencies(), | ||
addModuleToImports(options), | ||
injectImports(options), | ||
log() | ||
]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"$schema": "http://json-schema.org/schema", | ||
"id": "SchematicsErrorTailorAdd", | ||
"title": "Add error-tailor to Your Project", | ||
"type": "object", | ||
"properties": {}, | ||
"required": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export interface Schema {} |
Oops, something went wrong.