├── .husky
├── .gitignore
└── commit-msg
├── commitlint.config.js
├── .prettierrc.json
├── .npmignore
├── src
├── builders
│ └── build-schematics
│ │ ├── schema.json
│ │ └── index.ts
├── ng-generate
│ ├── add-schematic
│ │ ├── files
│ │ │ └── ng-add
│ │ │ │ ├── index.ts.template
│ │ │ │ └── index.spec.ts.template
│ │ ├── schema.json
│ │ ├── index.ts
│ │ └── index.spec.ts
│ ├── init
│ │ ├── schema.json
│ │ ├── index.ts
│ │ └── index.spec.ts
│ ├── generate-schematic
│ │ ├── files
│ │ │ └── __name@dasherize__
│ │ │ │ ├── index.ts.template
│ │ │ │ ├── schema.json.template
│ │ │ │ └── index.spec.ts.template
│ │ ├── schema.json
│ │ ├── index.ts
│ │ └── index.spec.ts
│ └── update-schematic
│ │ ├── files
│ │ └── __name@dasherize__
│ │ │ ├── index.ts.template
│ │ │ └── index.spec.ts.template
│ │ ├── schema.json
│ │ ├── index.ts
│ │ └── index.spec.ts
├── builders.json
├── collection.json
├── ng-add
│ ├── index.spec.ts
│ └── index.ts
└── utils
│ └── utils.ts
├── smoke-tests
├── angular10
│ ├── projects
│ │ └── lib1
│ │ │ ├── ng-package.json
│ │ │ ├── src
│ │ │ ├── public-api.ts
│ │ │ └── lib
│ │ │ │ ├── lib1.service.ts
│ │ │ │ ├── lib1.module.ts
│ │ │ │ └── lib1.component.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.lib.prod.json
│ │ │ ├── tslint.json
│ │ │ ├── tsconfig.lib.json
│ │ │ └── README.md
│ ├── .editorconfig
│ ├── package.json
│ ├── tsconfig.json
│ ├── .gitignore
│ ├── README.md
│ ├── angular.json
│ └── tslint.json
├── angular11
│ ├── projects
│ │ └── lib1
│ │ │ ├── ng-package.json
│ │ │ ├── src
│ │ │ ├── public-api.ts
│ │ │ └── lib
│ │ │ │ ├── lib1.service.ts
│ │ │ │ ├── lib1.module.ts
│ │ │ │ └── lib1.component.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.lib.prod.json
│ │ │ ├── tslint.json
│ │ │ ├── tsconfig.spec.json
│ │ │ ├── tsconfig.lib.json
│ │ │ └── README.md
│ ├── .editorconfig
│ ├── package.json
│ ├── tsconfig.json
│ ├── .gitignore
│ ├── README.md
│ ├── angular.json
│ └── tslint.json
├── angular12
│ ├── projects
│ │ └── lib1
│ │ │ ├── ng-package.json
│ │ │ ├── src
│ │ │ ├── public-api.ts
│ │ │ └── lib
│ │ │ │ ├── lib1.service.ts
│ │ │ │ ├── lib1.module.ts
│ │ │ │ └── lib1.component.ts
│ │ │ ├── package.json
│ │ │ ├── tsconfig.lib.prod.json
│ │ │ ├── tsconfig.lib.json
│ │ │ └── README.md
│ ├── .editorconfig
│ ├── package.json
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── README.md
│ └── angular.json
└── angular9
│ ├── projects
│ └── lib1
│ │ ├── ng-package.json
│ │ ├── src
│ │ ├── public-api.ts
│ │ └── lib
│ │ │ ├── lib1.service.ts
│ │ │ ├── lib1.module.ts
│ │ │ └── lib1.component.ts
│ │ ├── package.json
│ │ ├── tsconfig.lib.prod.json
│ │ ├── tslint.json
│ │ ├── tsconfig.spec.json
│ │ ├── tsconfig.lib.json
│ │ └── README.md
│ ├── .editorconfig
│ ├── package.json
│ ├── tsconfig.json
│ ├── .gitignore
│ ├── README.md
│ ├── angular.json
│ └── tslint.json
├── .gitignore
├── .prettierignore
├── jest.config.js
├── tsconfig.json
├── LICENCE
├── package.json
├── .github
└── workflows
│ └── main.yml
└── README.md
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = { extends: ['@commitlint/config-conventional'] };
2 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "tabWidth": 4,
4 | "printWidth": 120
5 | }
6 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx --no-install commitlint --edit "$1"
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Ignores TypeScript files, but keeps definitions.
2 | *.ts
3 | !*.d.ts
4 |
5 | # Ignore smoke tests
6 | smoke-tests/**/*
7 |
--------------------------------------------------------------------------------
/src/builders/build-schematics/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "SchematicsBuilderSchema",
3 | "title": "Schematics builder",
4 | "description": "",
5 | "properties": {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/lib1",
4 | "lib": {
5 | "entryFile": "src/public-api.ts"
6 | }
7 | }
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/src/public-api.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Public API Surface of lib1
3 | */
4 |
5 | export * from './lib/lib1.service';
6 | export * from './lib/lib1.component';
7 | export * from './lib/lib1.module';
8 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/lib1",
4 | "lib": {
5 | "entryFile": "src/public-api.ts"
6 | }
7 | }
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/src/public-api.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Public API Surface of lib1
3 | */
4 |
5 | export * from './lib/lib1.service';
6 | export * from './lib/lib1.component';
7 | export * from './lib/lib1.module';
8 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/lib1",
4 | "lib": {
5 | "entryFile": "src/public-api.ts"
6 | }
7 | }
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/src/public-api.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Public API Surface of lib1
3 | */
4 |
5 | export * from './lib/lib1.service';
6 | export * from './lib/lib1.component';
7 | export * from './lib/lib1.module';
8 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/lib1",
4 | "lib": {
5 | "entryFile": "src/public-api.ts"
6 | }
7 | }
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/src/public-api.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Public API Surface of lib1
3 | */
4 |
5 | export * from './lib/lib1.service';
6 | export * from './lib/lib1.component';
7 | export * from './lib/lib1.module';
8 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/src/lib/lib1.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 | export class Lib1Service {
7 |
8 | constructor() { }
9 | }
10 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/src/lib/lib1.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 | export class Lib1Service {
7 |
8 | constructor() { }
9 | }
10 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/src/lib/lib1.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 | export class Lib1Service {
7 |
8 | constructor() { }
9 | }
10 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/src/lib/lib1.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root'
5 | })
6 | export class Lib1Service {
7 |
8 | constructor() { }
9 | }
10 |
--------------------------------------------------------------------------------
/src/ng-generate/add-schematic/files/ng-add/index.ts.template:
--------------------------------------------------------------------------------
1 | import { noop, Tree } from "@angular-devkit/schematics";
2 |
3 | export function ngAdd(options: any) {
4 | return async (host: Tree) => {
5 | return noop();
6 | };
7 | }
8 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lib1",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^10.2.4",
6 | "@angular/core": "^10.2.4"
7 | },
8 | "dependencies": {
9 | "tslib": "^2.0.0"
10 | }
11 | }
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lib1",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^12.0.2",
6 | "@angular/core": "^12.0.2"
7 | },
8 | "dependencies": {
9 | "tslib": "^2.1.0"
10 | }
11 | }
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lib1",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^11.2.12",
6 | "@angular/core": "^11.2.12"
7 | },
8 | "dependencies": {
9 | "tslib": "^2.0.0"
10 | }
11 | }
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lib1",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^11.2.14",
6 | "@angular/core": "^11.2.14"
7 | },
8 | "dependencies": {
9 | "tslib": "^2.0.0"
10 | }
11 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Outputs
2 | src/**/*.js
3 | src/**/*.js.map
4 | src/**/*.d.ts
5 |
6 | # IDEs
7 | .idea/
8 | jsconfig.json
9 | .vscode/
10 |
11 | # Misc
12 | node_modules/
13 | npm-debug.log*
14 | yarn-error.log*
15 |
16 | # Mac OSX Finder files.
17 | **/.DS_Store
18 | .DS_Store
19 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Outputs
2 | src/**/*.js
3 | src/**/*.js.map
4 | src/**/*.d.ts
5 |
6 | # IDEs
7 | .idea/
8 | jsconfig.json
9 | .vscode/
10 |
11 | # Misc
12 | node_modules/
13 | npm-debug.log*
14 | yarn-error.log*
15 | *.json
16 |
17 | # Mac OSX Finder files.
18 | **/.DS_Store
19 | .DS_Store
20 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/src/lib/lib1.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Lib1Component } from './lib1.component';
3 |
4 |
5 |
6 | @NgModule({
7 | declarations: [Lib1Component],
8 | imports: [
9 | ],
10 | exports: [Lib1Component]
11 | })
12 | export class Lib1Module { }
13 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.lib.json",
4 | "compilerOptions": {
5 | "declarationMap": false
6 | },
7 | "angularCompilerOptions": {
8 | "enableIvy": false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.lib.json",
4 | "compilerOptions": {
5 | "declarationMap": false
6 | },
7 | "angularCompilerOptions": {
8 | "enableIvy": false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.lib.json",
4 | "compilerOptions": {
5 | "declarationMap": false
6 | },
7 | "angularCompilerOptions": {
8 | "enableIvy": false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.lib.json",
4 | "compilerOptions": {
5 | "declarationMap": false
6 | },
7 | "angularCompilerOptions": {
8 | "compilationMode": "partial"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/builders.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "@angular-devkit/architect/src/builders-schema.json",
3 | "builders": {
4 | "build-schematics": {
5 | "implementation": "./builders/build-schematics/index",
6 | "schema": "./builders/build-schematics/schema.json",
7 | "description": "Build schematics project"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/src/lib/lib1.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Lib1Component } from './lib1.component';
3 |
4 |
5 |
6 | @NgModule({
7 | declarations: [
8 | Lib1Component
9 | ],
10 | imports: [
11 | ],
12 | exports: [
13 | Lib1Component
14 | ]
15 | })
16 | export class Lib1Module { }
17 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/src/lib/lib1.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Lib1Component } from './lib1.component';
3 |
4 |
5 |
6 | @NgModule({
7 | declarations: [
8 | Lib1Component
9 | ],
10 | imports: [
11 | ],
12 | exports: [
13 | Lib1Component
14 | ]
15 | })
16 | export class Lib1Module { }
17 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/src/lib/lib1.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Lib1Component } from './lib1.component';
3 |
4 |
5 |
6 | @NgModule({
7 | declarations: [
8 | Lib1Component
9 | ],
10 | imports: [
11 | ],
12 | exports: [
13 | Lib1Component
14 | ]
15 | })
16 | export class Lib1Module { }
17 |
--------------------------------------------------------------------------------
/src/ng-generate/init/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "properties": {
3 | "path": {
4 | "type": "string",
5 | "format": "path",
6 | "description": "",
7 | "visible": false
8 | },
9 | "project": {
10 | "type": "string",
11 | "description": "Name of the Angular project",
12 | "minLength": 1
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": {
4 | "directive-selector": [
5 | true,
6 | "attribute",
7 | "lib",
8 | "camelCase"
9 | ],
10 | "component-selector": [
11 | true,
12 | "element",
13 | "lib",
14 | "kebab-case"
15 | ]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": {
4 | "directive-selector": [
5 | true,
6 | "attribute",
7 | "lib",
8 | "camelCase"
9 | ],
10 | "component-selector": [
11 | true,
12 | "element",
13 | "lib",
14 | "kebab-case"
15 | ]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": {
4 | "directive-selector": [
5 | true,
6 | "attribute",
7 | "lib",
8 | "camelCase"
9 | ],
10 | "component-selector": [
11 | true,
12 | "element",
13 | "lib",
14 | "kebab-case"
15 | ]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular11",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng"
6 | },
7 | "private": true,
8 | "dependencies": {
9 | "@angular/core": "~11.2.14"
10 | },
11 | "devDependencies": {
12 | "@angular/cli": "~11.2.13",
13 | "ngx-cli-toolkit": "../../",
14 | "typescript": "~4.1.5"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/ng-generate/generate-schematic/files/__name@dasherize__/index.ts.template:
--------------------------------------------------------------------------------
1 | import { noop, Tree } from "@angular-devkit/schematics";
2 |
3 | export interface <%= classify(name) %>Options {
4 | name: string;
5 | }
6 |
7 | export function <%= camelize(name) %>(options: <%= classify(name) %>Options) {
8 | return async (host: Tree) => {
9 | return noop();
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/src/lib/lib1.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'lib-lib1',
5 | template: `
6 |
7 | lib1 works!
8 |
9 | `,
10 | styles: [
11 | ]
12 | })
13 | export class Lib1Component implements OnInit {
14 |
15 | constructor() { }
16 |
17 | ngOnInit(): void {
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/src/lib/lib1.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'lib-lib1',
5 | template: `
6 |
7 | lib1 works!
8 |
9 | `,
10 | styles: [
11 | ]
12 | })
13 | export class Lib1Component implements OnInit {
14 |
15 | constructor() { }
16 |
17 | ngOnInit(): void {
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/src/lib/lib1.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'lib-lib1',
5 | template: `
6 |
7 | lib1 works!
8 |
9 | `,
10 | styles: [
11 | ]
12 | })
13 | export class Lib1Component implements OnInit {
14 |
15 | constructor() { }
16 |
17 | ngOnInit(): void {
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/src/lib/lib1.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'lib-lib1',
5 | template: `
6 |
7 | lib1 works!
8 |
9 | `,
10 | styles: [
11 | ]
12 | })
13 | export class Lib1Component implements OnInit {
14 |
15 | constructor() { }
16 |
17 | ngOnInit(): void {
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * For a detailed explanation regarding each configuration property and type check, visit:
3 | * https://jestjs.io/docs/en/configuration.html
4 | */
5 |
6 | module.exports = {
7 | preset: 'ts-jest',
8 | clearMocks: true,
9 | coverageDirectory: 'coverage',
10 | collectCoverageFrom: ['src/**/*.ts'],
11 | coverageProvider: 'v8',
12 | testEnvironment: 'node',
13 | };
14 |
--------------------------------------------------------------------------------
/src/ng-generate/update-schematic/files/__name@dasherize__/index.ts.template:
--------------------------------------------------------------------------------
1 | import { noop, SchematicContext, Tree } from "@angular-devkit/schematics";
2 |
3 | export interface <%= classify(name) %>Options {
4 | name: string;
5 | }
6 |
7 | export function <%= camelize(name) %>(options: <%= classify(name) %>Options) {
8 | return async (host: Tree, context: SchematicContext) => {
9 | return noop();
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular9",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng"
6 | },
7 | "private": true,
8 | "dependencies": {
9 | "@angular/core": "~9.1.13",
10 | "rxjs": "^6.5.5",
11 | "zone.js": "~0.10.3"
12 | },
13 | "devDependencies": {
14 | "@angular/cli": "~9.1.15",
15 | "ngx-cli-toolkit": "../../",
16 | "typescript": "~3.8.3"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts"
12 | ],
13 | "include": [
14 | "**/*.spec.ts",
15 | "**/*.d.ts"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts"
12 | ],
13 | "include": [
14 | "**/*.spec.ts",
15 | "**/*.d.ts"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/src/ng-generate/generate-schematic/files/__name@dasherize__/schema.json.template:
--------------------------------------------------------------------------------
1 | {
2 | "properties": {
3 | "name": {
4 | "type": "string",
5 | "description": "Name",
6 | "$default": {
7 | "$source": "argv",
8 | "index": 0
9 | }
10 | },
11 | "path": {
12 | "type": "string",
13 | "format": "path",
14 | "description": "",
15 | "visible": false
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular10",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve",
7 | "build": "ng build",
8 | "test": "ng test",
9 | "lint": "ng lint"
10 | },
11 | "private": true,
12 | "dependencies": {
13 | "@angular/core": "~10.2.4",
14 | "zone.js": "~0.10.3"
15 | },
16 | "devDependencies": {
17 | "@angular/cli": "~10.2.3",
18 | "ngx-cli-toolkit": "../../",
19 | "typescript": "~4.0.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular12",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve",
7 | "build": "ng build",
8 | "watch": "ng build --watch --configuration development",
9 | "test": "ng test"
10 | },
11 | "private": true,
12 | "dependencies": {
13 | "@angular/core": "~12.0.2"
14 | },
15 | "devDependencies": {
16 | "@angular/cli": "~12.0.2",
17 | "ngx-cli-toolkit": "../../",
18 | "typescript": "~4.2.3"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/lib",
6 | "target": "es2015",
7 | "declaration": true,
8 | "declarationMap": true,
9 | "inlineSources": true,
10 | "types": [],
11 | "lib": [
12 | "dom",
13 | "es2018"
14 | ]
15 | },
16 | "exclude": [
17 | "src/test.ts",
18 | "**/*.spec.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/src/ng-generate/generate-schematic/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "properties": {
3 | "name": {
4 | "type": "string",
5 | "description": "Name of the schematic",
6 | "x-prompt": "Name of the schematic",
7 | "$default": {
8 | "$source": "argv",
9 | "index": 0
10 | }
11 | },
12 | "description": {
13 | "type": "string",
14 | "x-prompt": "Schematic description"
15 | },
16 | "path": {
17 | "type": "string",
18 | "format": "path",
19 | "description": "",
20 | "visible": false
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/ng-generate/add-schematic/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "properties": {
3 | "save": {
4 | "type": "string",
5 | "x-prompt": {
6 | "message": "Save package as",
7 | "type": "list",
8 | "multiselect": false,
9 | "items": [
10 | { "value": "dependencies", "label": "dependency" },
11 | { "value": "devDependencies", "label": "devDependency" }
12 | ]
13 | }
14 | },
15 | "path": {
16 | "type": "string",
17 | "format": "path",
18 | "description": "",
19 | "visible": false
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "downlevelIteration": true,
9 | "experimentalDecorators": true,
10 | "moduleResolution": "node",
11 | "importHelpers": true,
12 | "target": "es2015",
13 | "module": "es2020",
14 | "lib": [
15 | "es2018",
16 | "dom"
17 | ],
18 | "paths": {
19 | "lib1": [
20 | "dist/lib1/lib1",
21 | "dist/lib1"
22 | ]
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/builders/build-schematics/index.ts:
--------------------------------------------------------------------------------
1 | import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
2 | import { Observable, of } from 'rxjs';
3 | import { json } from '@angular-devkit/core';
4 |
5 | interface SchematicsBuilderOptions {
6 | }
7 |
8 | export function buildSchematics(
9 | _options: SchematicsBuilderOptions,
10 | { logger }: BuilderContext
11 | ): Observable {
12 | logger.info('Noop');
13 | return of({
14 | success: true
15 | });
16 | }
17 |
18 | export default createBuilder(
19 | buildSchematics
20 | );
21 |
--------------------------------------------------------------------------------
/src/ng-generate/update-schematic/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "properties": {
3 | "name": {
4 | "type": "string",
5 | "description": "Name of the schematic",
6 | "x-prompt": "Name of the schematic",
7 | "$default": {
8 | "$source": "argv",
9 | "index": 0
10 | }
11 | },
12 | "description": {
13 | "type": "string",
14 | "x-prompt": "Schematic description"
15 | },
16 | "version": {
17 | "type": "string",
18 | "x-prompt": "Update version"
19 | },
20 | "path": {
21 | "type": "string",
22 | "format": "path",
23 | "description": "",
24 | "visible": false
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/lib",
6 | "target": "es2015",
7 | "declaration": true,
8 | "declarationMap": true,
9 | "inlineSources": true,
10 | "types": [],
11 | "lib": [
12 | "dom",
13 | "es2018"
14 | ]
15 | },
16 | "angularCompilerOptions": {
17 | "skipTemplateCodegen": true,
18 | "strictMetadataEmit": true,
19 | "enableResourceInlining": true
20 | },
21 | "exclude": [
22 | "src/test.ts",
23 | "**/*.spec.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/lib",
6 | "target": "es2015",
7 | "declaration": true,
8 | "declarationMap": true,
9 | "inlineSources": true,
10 | "types": [],
11 | "lib": [
12 | "dom",
13 | "es2018"
14 | ]
15 | },
16 | "angularCompilerOptions": {
17 | "skipTemplateCodegen": true,
18 | "strictMetadataEmit": true,
19 | "enableResourceInlining": true
20 | },
21 | "exclude": [
22 | "src/test.ts",
23 | "**/*.spec.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/lib",
6 | "target": "es2015",
7 | "declaration": true,
8 | "declarationMap": true,
9 | "inlineSources": true,
10 | "types": [],
11 | "lib": [
12 | "dom",
13 | "es2018"
14 | ]
15 | },
16 | "angularCompilerOptions": {
17 | "skipTemplateCodegen": true,
18 | "strictMetadataEmit": true,
19 | "enableResourceInlining": true
20 | },
21 | "exclude": [
22 | "src/test.ts",
23 | "**/*.spec.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/src/ng-generate/add-schematic/files/ng-add/index.spec.ts.template:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 |
5 | const collectionPath = path.join(__dirname, '../collection.json');
6 |
7 | describe('ng-add', () => {
8 | let runner: SchematicTestRunner;
9 | let tree: Tree;
10 |
11 | beforeEach(() => {
12 | runner = new SchematicTestRunner('schematics', collectionPath);
13 | tree = Tree.empty();
14 | })
15 |
16 | it('noop', async () => {
17 | await runner.runSchematicAsync('ng-add', {}, tree).toPromise();
18 | expect(true).toBe(true);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "downlevelIteration": true,
9 | "experimentalDecorators": true,
10 | "paths": {
11 | "lib1": [
12 | "dist/lib1/lib1",
13 | "dist/lib1"
14 | ]
15 | },
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "es2015",
20 | "lib": [
21 | "es2018",
22 | "dom"
23 | ]
24 | },
25 | "angularCompilerOptions": {
26 | "fullTemplateTypeCheck": true,
27 | "strictInjectionParameters": true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/ng-generate/generate-schematic/files/__name@dasherize__/index.spec.ts.template:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 |
5 | const collectionPath = path.join(__dirname, '<%= collectionJsonPath %>');
6 |
7 | describe('<%= dasherize(name) %>', () => {
8 | let runner: SchematicTestRunner;
9 | let tree: Tree;
10 |
11 | beforeEach(() => {
12 | runner = new SchematicTestRunner('schematics', collectionPath);
13 | tree = Tree.empty();
14 | });
15 |
16 | it('noop', async () => {
17 | await runner.runSchematicAsync('<%= dasherize(name) %>', {}, tree).toPromise();
18 | expect(true).toBe(true);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/src/ng-generate/update-schematic/files/__name@dasherize__/index.spec.ts.template:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 |
5 | const migrationsPath = path.join(__dirname, '<%= migrationsJsonPath %>');
6 |
7 | describe('<%= dasherize(name) %>', () => {
8 | let runner: SchematicTestRunner;
9 | let tree: Tree;
10 |
11 | beforeEach(() => {
12 | runner = new SchematicTestRunner('schematics', migrationsPath);
13 | tree = Tree.empty();
14 | });
15 |
16 | it('noop', async () => {
17 | await runner.runSchematicAsync('<%= dasherize(name) %>', {}, tree).toPromise();
18 | expect(true).toBe(true);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "sourceMap": true,
8 | "declaration": false,
9 | "downlevelIteration": true,
10 | "experimentalDecorators": true,
11 | "paths": {
12 | "lib1": [
13 | "dist/lib1/lib1",
14 | "dist/lib1"
15 | ]
16 | },
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "es2015",
20 | "module": "es2020",
21 | "lib": [
22 | "es2018",
23 | "dom"
24 | ]
25 | },
26 | "angularCompilerOptions": {
27 | "enableI18nLegacyMessageIdFormat": false
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | # Only exists if Bazel was run
8 | /bazel-out
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # profiling files
14 | chrome-profiler-events*.json
15 |
16 | # IDEs and editors
17 | /.idea
18 | .project
19 | .classpath
20 | .c9/
21 | *.launch
22 | .settings/
23 | *.sublime-workspace
24 |
25 | # IDE - VSCode
26 | .vscode/*
27 | !.vscode/settings.json
28 | !.vscode/tasks.json
29 | !.vscode/launch.json
30 | !.vscode/extensions.json
31 | .history/*
32 |
33 | # misc
34 | /.sass-cache
35 | /connect.lock
36 | /coverage
37 | /libpeerconnection.log
38 | npm-debug.log
39 | yarn-error.log
40 | testem.log
41 | /typings
42 |
43 | # System Files
44 | .DS_Store
45 | Thumbs.db
46 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "tsconfig",
4 | "lib": [
5 | "es2018",
6 | "dom"
7 | ],
8 | "declaration": true,
9 | "module": "commonjs",
10 | "moduleResolution": "node",
11 | "noEmitOnError": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "noImplicitAny": true,
14 | "noImplicitThis": true,
15 | "noUnusedParameters": true,
16 | "noUnusedLocals": true,
17 | "rootDir": "src/",
18 | "skipDefaultLibCheck": true,
19 | "skipLibCheck": true,
20 | "sourceMap": true,
21 | "strict": true,
22 | "target": "es6",
23 | "types": [
24 | "jest",
25 | "node"
26 | ]
27 | },
28 | "include": [
29 | "src/**/*"
30 | ],
31 | "exclude": [
32 | "src/*/files/**/*",
33 | "**/*.spec.ts",
34 | "smoke-tests/**/*"
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | # Only exists if Bazel was run
8 | /bazel-out
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # profiling files
14 | chrome-profiler-events*.json
15 | speed-measure-plugin*.json
16 |
17 | # IDEs and editors
18 | /.idea
19 | .project
20 | .classpath
21 | .c9/
22 | *.launch
23 | .settings/
24 | *.sublime-workspace
25 |
26 | # IDE - VSCode
27 | .vscode/*
28 | !.vscode/settings.json
29 | !.vscode/tasks.json
30 | !.vscode/launch.json
31 | !.vscode/extensions.json
32 | .history/*
33 |
34 | # misc
35 | /.sass-cache
36 | /connect.lock
37 | /coverage
38 | /libpeerconnection.log
39 | npm-debug.log
40 | yarn-error.log
41 | testem.log
42 | /typings
43 |
44 | # System Files
45 | .DS_Store
46 | Thumbs.db
47 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | # Only exists if Bazel was run
8 | /bazel-out
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # profiling files
14 | chrome-profiler-events*.json
15 | speed-measure-plugin*.json
16 |
17 | # IDEs and editors
18 | /.idea
19 | .project
20 | .classpath
21 | .c9/
22 | *.launch
23 | .settings/
24 | *.sublime-workspace
25 |
26 | # IDE - VSCode
27 | .vscode/*
28 | !.vscode/settings.json
29 | !.vscode/tasks.json
30 | !.vscode/launch.json
31 | !.vscode/extensions.json
32 | .history/*
33 |
34 | # misc
35 | /.sass-cache
36 | /connect.lock
37 | /coverage
38 | /libpeerconnection.log
39 | npm-debug.log
40 | yarn-error.log
41 | testem.log
42 | /typings
43 |
44 | # System Files
45 | .DS_Store
46 | Thumbs.db
47 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | # Only exists if Bazel was run
8 | /bazel-out
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # profiling files
14 | chrome-profiler-events*.json
15 | speed-measure-plugin*.json
16 |
17 | # IDEs and editors
18 | /.idea
19 | .project
20 | .classpath
21 | .c9/
22 | *.launch
23 | .settings/
24 | *.sublime-workspace
25 |
26 | # IDE - VSCode
27 | .vscode/*
28 | !.vscode/settings.json
29 | !.vscode/tasks.json
30 | !.vscode/launch.json
31 | !.vscode/extensions.json
32 | .history/*
33 |
34 | # misc
35 | /.sass-cache
36 | /connect.lock
37 | /coverage
38 | /libpeerconnection.log
39 | npm-debug.log
40 | yarn-error.log
41 | testem.log
42 | /typings
43 |
44 | # System Files
45 | .DS_Store
46 | Thumbs.db
47 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitReturns": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "sourceMap": true,
12 | "paths": {
13 | "lib1": [
14 | "dist/lib1/lib1",
15 | "dist/lib1"
16 | ]
17 | },
18 | "declaration": false,
19 | "downlevelIteration": true,
20 | "experimentalDecorators": true,
21 | "moduleResolution": "node",
22 | "importHelpers": true,
23 | "target": "es2017",
24 | "module": "es2020",
25 | "lib": [
26 | "es2018",
27 | "dom"
28 | ]
29 | },
30 | "angularCompilerOptions": {
31 | "enableI18nLegacyMessageIdFormat": false,
32 | "strictInjectionParameters": true,
33 | "strictInputAccessModifiers": true,
34 | "strictTemplates": true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/projects/lib1/README.md:
--------------------------------------------------------------------------------
1 | # Lib1
2 |
3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.2.4.
4 |
5 | ## Code scaffolding
6 |
7 | Run `ng generate component component-name --project lib1` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project lib1`.
8 | > Note: Don't forget to add `--project lib1` or else it will be added to the default project in your `angular.json` file.
9 |
10 | ## Build
11 |
12 | Run `ng build lib1` to build the project. The build artifacts will be stored in the `dist/` directory.
13 |
14 | ## Publishing
15 |
16 | After building your library with `ng build lib1`, go to the dist folder `cd dist/lib1` and run `npm publish`.
17 |
18 | ## Running unit tests
19 |
20 | Run `ng test lib1` to execute the unit tests via [Karma](https://karma-runner.github.io).
21 |
22 | ## Further help
23 |
24 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
25 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/projects/lib1/README.md:
--------------------------------------------------------------------------------
1 | # Lib1
2 |
3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.14.
4 |
5 | ## Code scaffolding
6 |
7 | Run `ng generate component component-name --project lib1` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project lib1`.
8 | > Note: Don't forget to add `--project lib1` or else it will be added to the default project in your `angular.json` file.
9 |
10 | ## Build
11 |
12 | Run `ng build lib1` to build the project. The build artifacts will be stored in the `dist/` directory.
13 |
14 | ## Publishing
15 |
16 | After building your library with `ng build lib1`, go to the dist folder `cd dist/lib1` and run `npm publish`.
17 |
18 | ## Running unit tests
19 |
20 | Run `ng test lib1` to execute the unit tests via [Karma](https://karma-runner.github.io).
21 |
22 | ## Further help
23 |
24 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
25 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/projects/lib1/README.md:
--------------------------------------------------------------------------------
1 | # Lib1
2 |
3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.0.2.
4 |
5 | ## Code scaffolding
6 |
7 | Run `ng generate component component-name --project lib1` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project lib1`.
8 | > Note: Don't forget to add `--project lib1` or else it will be added to the default project in your `angular.json` file.
9 |
10 | ## Build
11 |
12 | Run `ng build lib1` to build the project. The build artifacts will be stored in the `dist/` directory.
13 |
14 | ## Publishing
15 |
16 | After building your library with `ng build lib1`, go to the dist folder `cd dist/lib1` and run `npm publish`.
17 |
18 | ## Running unit tests
19 |
20 | Run `ng test lib1` to execute the unit tests via [Karma](https://karma-runner.github.io).
21 |
22 | ## Further help
23 |
24 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
25 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/projects/lib1/README.md:
--------------------------------------------------------------------------------
1 | # Lib1
2 |
3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.12.
4 |
5 | ## Code scaffolding
6 |
7 | Run `ng generate component component-name --project lib1` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project lib1`.
8 | > Note: Don't forget to add `--project lib1` or else it will be added to the default project in your `angular.json` file.
9 |
10 | ## Build
11 |
12 | Run `ng build lib1` to build the project. The build artifacts will be stored in the `dist/` directory.
13 |
14 | ## Publishing
15 |
16 | After building your library with `ng build lib1`, go to the dist folder `cd dist/lib1` and run `npm publish`.
17 |
18 | ## Running unit tests
19 |
20 | Run `ng test lib1` to execute the unit tests via [Karma](https://karma-runner.github.io).
21 |
22 | ## Further help
23 |
24 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
25 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Kai Röder
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/README.md:
--------------------------------------------------------------------------------
1 | # Angular10
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.2.3.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
28 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/README.md:
--------------------------------------------------------------------------------
1 | # Angular11
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.13.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
28 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/README.md:
--------------------------------------------------------------------------------
1 | # Angular9
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.15.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
28 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/README.md:
--------------------------------------------------------------------------------
1 | # Angular12
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.0.2.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
28 |
--------------------------------------------------------------------------------
/src/collection.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "ng-add": {
5 | "save": "devDependencies",
6 | "description": "Add and bootstrap ngx-cli-toolkit",
7 | "factory": "./ng-add/index#ngAdd"
8 | },
9 | "init": {
10 | "factory": "./ng-generate/init/index#initSchematicsProject",
11 | "description": "Initialize schematics project",
12 | "schema": "./ng-generate/init/schema.json"
13 | },
14 | "add-schematic": {
15 | "factory": "./ng-generate/add-schematic/index#createAddSchematic",
16 | "description": "Create ng-add schematic",
17 | "schema": "./ng-generate/add-schematic/schema.json"
18 | },
19 | "generate-schematic": {
20 | "factory": "./ng-generate/generate-schematic/index#createGenerateSchematic",
21 | "description": "Create ng-generate schematic",
22 | "schema": "./ng-generate/generate-schematic/schema.json"
23 | },
24 | "update-schematic": {
25 | "factory": "./ng-generate/update-schematic/index#createUpdateSchematic",
26 | "description": "Create ng-update schematic",
27 | "schema": "./ng-generate/update-schematic/schema.json"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ngx-cli-toolkit",
3 | "version": "0.4.0",
4 | "description": "A toolkit that helps with the setup and generation of schematics in projects.",
5 | "scripts": {
6 | "build": "tsc -p tsconfig.json",
7 | "build:watch": "tsc -p tsconfig.json --watch",
8 | "test": "jest",
9 | "release": "release-it"
10 | },
11 | "keywords": [
12 | "angular",
13 | "schematics",
14 | "utilities"
15 | ],
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/kroeder/ngx-cli-toolkit.git"
19 | },
20 | "author": "Kai Roeder",
21 | "license": "MIT",
22 | "schematics": "./src/collection.json",
23 | "builders": "./src/builders.json",
24 | "dependencies": {
25 | "@angular-devkit/architect": "^0.1301.2",
26 | "@angular-devkit/core": "^13.1.2",
27 | "@angular-devkit/schematics": "^13.1.2",
28 | "@schematics/angular": "^13.1.2",
29 | "rxjs": "^7.4.0"
30 | },
31 | "devDependencies": {
32 | "@commitlint/cli": "^12.1.1",
33 | "@commitlint/config-conventional": "^12.1.1",
34 | "@types/jest": "^26.0.23",
35 | "@types/node": "^14.18.2",
36 | "husky": "^6.0.0",
37 | "jest": "^26.6.3",
38 | "prettier": "2.2.1",
39 | "release-it": "^14.8.0",
40 | "ts-jest": "^26.5.5",
41 | "typescript": "~4.5.4"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/smoke-tests/angular12/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "cli": {
4 | "analytics": false
5 | },
6 | "version": 1,
7 | "newProjectRoot": "projects",
8 | "projects": {
9 | "lib1": {
10 | "projectType": "library",
11 | "root": "projects/lib1",
12 | "sourceRoot": "projects/lib1/src",
13 | "prefix": "lib",
14 | "architect": {
15 | "build": {
16 | "builder": "@angular-devkit/build-angular:ng-packagr",
17 | "options": {
18 | "project": "projects/lib1/ng-package.json"
19 | },
20 | "configurations": {
21 | "production": {
22 | "tsConfig": "projects/lib1/tsconfig.lib.prod.json"
23 | },
24 | "development": {
25 | "tsConfig": "projects/lib1/tsconfig.lib.json"
26 | }
27 | },
28 | "defaultConfiguration": "production"
29 | },
30 | "test": {
31 | "builder": "@angular-devkit/build-angular:karma",
32 | "options": {
33 | "main": "projects/lib1/src/test.ts",
34 | "tsConfig": "projects/lib1/tsconfig.spec.json",
35 | "karmaConfig": "projects/lib1/karma.conf.js"
36 | }
37 | }
38 | }
39 | }
40 | },
41 | "defaultProject": "lib1"
42 | }
43 |
--------------------------------------------------------------------------------
/src/ng-add/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 |
5 | const collectionPath = path.join(__dirname, '../collection.json');
6 |
7 | describe('ng-add', () => {
8 | it('should add devDependencies', async () => {
9 | const angularJson = {
10 | dependencies: {
11 | '@angular/core': '~11.2.11',
12 | },
13 | devDependencies: {},
14 | };
15 |
16 | const angularJsonExpected = {
17 | dependencies: {
18 | '@angular/core': '~11.2.11',
19 | },
20 | devDependencies: {
21 | '@angular-devkit/architect': '~0.1102.0',
22 | '@angular-devkit/core': '~11.2.0',
23 | '@angular-devkit/schematics': '~11.2.0',
24 | '@schematics/angular': '~11.2.0',
25 | },
26 | };
27 |
28 | const runner = new SchematicTestRunner('schematics', collectionPath);
29 | const tree = Tree.empty();
30 | tree.create('package.json', JSON.stringify(angularJson));
31 |
32 | await runner.runSchematicAsync('ng-add', {}, tree).toPromise();
33 |
34 | expect(JSON.parse(tree.read('package.json')!.toString())).toEqual(angularJsonExpected);
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: push
3 | jobs:
4 | prepare-smoke-tests:
5 | runs-on: ubuntu-latest
6 | outputs:
7 | dir: ${{ steps.set-dirs.outputs.dir }}
8 | steps:
9 | - uses: actions/checkout@v2
10 | - id: set-dirs
11 | run: |
12 | cd smoke-tests && echo "::set-output name=dir::$(ls -d */ | jq -R -s -c 'split("\n")[:-1]')"
13 | jest:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v2
17 | - name: Run tests
18 | run: |
19 | npm ci
20 | npm test
21 | smoke-test:
22 | runs-on: ubuntu-latest
23 | needs: [prepare-smoke-tests] # Depends on previous job
24 | strategy:
25 | matrix:
26 | dir: ${{fromJson(needs.prepare-smoke-tests.outputs.dir)}} # List matrix strategy from directories dynamically
27 | steps:
28 | - uses: actions/checkout@v2
29 | - name: Run tests
30 | run: |
31 | npm ci
32 | npm run build
33 | cd ./smoke-tests/${{matrix.dir}}
34 | npm install
35 | ./node_modules/.bin/ng generate ngx-cli-toolkit:ng-add
36 | cd ./projects/lib1
37 | ../../node_modules/.bin/ng generate ngx-cli-toolkit:init
38 | ../../node_modules/.bin/ng generate ngx-cli-toolkit:add-schematic --save dependencies
39 | ../../node_modules/.bin/ng generate ngx-cli-toolkit:update-schematic update1 --description foo --version 1.2.3
40 | ../../node_modules/.bin/ng generate ngx-cli-toolkit:generate-schematic generate1 --description foo
41 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "lib1": {
7 | "projectType": "library",
8 | "root": "projects/lib1",
9 | "sourceRoot": "projects/lib1/src",
10 | "prefix": "lib",
11 | "architect": {
12 | "build": {
13 | "builder": "@angular-devkit/build-angular:ng-packagr",
14 | "options": {
15 | "tsConfig": "projects/lib1/tsconfig.lib.json",
16 | "project": "projects/lib1/ng-package.json"
17 | },
18 | "configurations": {
19 | "production": {
20 | "tsConfig": "projects/lib1/tsconfig.lib.prod.json"
21 | }
22 | }
23 | },
24 | "test": {
25 | "builder": "@angular-devkit/build-angular:karma",
26 | "options": {
27 | "main": "projects/lib1/src/test.ts",
28 | "tsConfig": "projects/lib1/tsconfig.spec.json",
29 | "karmaConfig": "projects/lib1/karma.conf.js"
30 | }
31 | },
32 | "lint": {
33 | "builder": "@angular-devkit/build-angular:tslint",
34 | "options": {
35 | "tsConfig": [
36 | "projects/lib1/tsconfig.lib.json",
37 | "projects/lib1/tsconfig.spec.json"
38 | ],
39 | "exclude": [
40 | "**/node_modules/**"
41 | ]
42 | }
43 | }
44 | }
45 | }},
46 | "cli": {
47 | "analytics": false
48 | },
49 | "defaultProject": "lib1"
50 | }
--------------------------------------------------------------------------------
/smoke-tests/angular10/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "lib1": {
7 | "projectType": "library",
8 | "root": "projects/lib1",
9 | "sourceRoot": "projects/lib1/src",
10 | "prefix": "lib",
11 | "architect": {
12 | "build": {
13 | "builder": "@angular-devkit/build-angular:ng-packagr",
14 | "options": {
15 | "tsConfig": "projects/lib1/tsconfig.lib.json",
16 | "project": "projects/lib1/ng-package.json"
17 | },
18 | "configurations": {
19 | "production": {
20 | "tsConfig": "projects/lib1/tsconfig.lib.prod.json"
21 | }
22 | }
23 | },
24 | "test": {
25 | "builder": "@angular-devkit/build-angular:karma",
26 | "options": {
27 | "main": "projects/lib1/src/test.ts",
28 | "tsConfig": "projects/lib1/tsconfig.spec.json",
29 | "karmaConfig": "projects/lib1/karma.conf.js"
30 | }
31 | },
32 | "lint": {
33 | "builder": "@angular-devkit/build-angular:tslint",
34 | "options": {
35 | "tsConfig": [
36 | "projects/lib1/tsconfig.lib.json",
37 | "projects/lib1/tsconfig.spec.json"
38 | ],
39 | "exclude": [
40 | "**/node_modules/**"
41 | ]
42 | }
43 | }
44 | }
45 | }},
46 | "cli": {
47 | "analytics": false
48 | },
49 | "defaultProject": "lib1"
50 | }
--------------------------------------------------------------------------------
/smoke-tests/angular11/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "cli": {
4 | "analytics": false
5 | },
6 | "version": 1,
7 | "newProjectRoot": "projects",
8 | "projects": {
9 | "lib1": {
10 | "projectType": "library",
11 | "root": "projects/lib1",
12 | "sourceRoot": "projects/lib1/src",
13 | "prefix": "lib",
14 | "architect": {
15 | "build": {
16 | "builder": "@angular-devkit/build-angular:ng-packagr",
17 | "options": {
18 | "tsConfig": "projects/lib1/tsconfig.lib.json",
19 | "project": "projects/lib1/ng-package.json"
20 | },
21 | "configurations": {
22 | "production": {
23 | "tsConfig": "projects/lib1/tsconfig.lib.prod.json"
24 | }
25 | }
26 | },
27 | "test": {
28 | "builder": "@angular-devkit/build-angular:karma",
29 | "options": {
30 | "main": "projects/lib1/src/test.ts",
31 | "tsConfig": "projects/lib1/tsconfig.spec.json",
32 | "karmaConfig": "projects/lib1/karma.conf.js"
33 | }
34 | },
35 | "lint": {
36 | "builder": "@angular-devkit/build-angular:tslint",
37 | "options": {
38 | "tsConfig": [
39 | "projects/lib1/tsconfig.lib.json",
40 | "projects/lib1/tsconfig.spec.json"
41 | ],
42 | "exclude": [
43 | "**/node_modules/**"
44 | ]
45 | }
46 | }
47 | }
48 | }
49 | },
50 | "defaultProject": "lib1"
51 | }
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ngx-cli-toolkit - schematics for schematics
2 |
3 | This package provides schematics that can setup and generate schematics for your library.
4 | Creating `ng add`, `ng generate`, `ng update` or custom builders for the Angular CLI is
5 | not easy and often prevents you from solving your actual problems if you are not familiar with the
6 | bootstrapping process.
7 |
8 | **This package is in a very early stage, and most likely has bugs.**
9 |
10 | ## Support
11 |
12 | This package supports all LTS versions of Angular. ([Angular support policy and schedule](https://angular.io/guide/releases#support-policy-and-schedule))
13 |
14 | ## Schematics
15 |
16 | ### Install
17 |
18 | Run `ng add` to add this package as well as useful, schematics related, dependencies that are
19 | useful for creating schematics.
20 |
21 | ```shell
22 | ng add ngx-cli-toolkit
23 | ```
24 |
25 | ### Bootstrap schematics project
26 |
27 | The `init` schematic tries to discover the location of a package.json based on the directory the schematic was
28 | executed from.
29 |
30 | It will add the necessary schematic fields to the package.json as well as create json files that manage
31 | the `ng update` and `ng generate` schematics in your project.
32 |
33 | ```shell
34 | ng generate ngx-cli-toolkit:init
35 | ```
36 |
37 | **Example for an Angular library project:**
38 |
39 | Inside Angular workspaces, the `--project` flag can be used to locate the root directory of a project.
40 |
41 | ```shell
42 | ng generate library awesome-library
43 | ng generate ngx-cli-toolkit:init --project awesome-library
44 | ```
45 |
46 | ### Generating `ng-add`
47 |
48 | This creates a schematic that allows others to add your package using `ng add`.
49 |
50 | ```shell
51 | ng generate ngx-cli-toolkit:add-schematic
52 | ```
53 |
54 | ### Generating `ng-generate` schematics
55 |
56 | This creates a `ng generate` schematic.
57 |
58 | ```shell
59 | ng generate ngx-cli-toolkit:generate-schematic name-of-your-schematic
60 | ```
61 |
62 | ### Generating `ng-update` schematics
63 |
64 | This creates a `ng update` schematic.
65 |
66 | ```shell
67 | ng generate ngx-cli-toolkit:update-schematic name-of-your-schematic
68 | ```
69 |
--------------------------------------------------------------------------------
/src/ng-add/index.ts:
--------------------------------------------------------------------------------
1 | import { noop, Rule, SchematicContext, SchematicsException, Tree } from '@angular-devkit/schematics';
2 | import {
3 | addPackageJsonDependency,
4 | getPackageJsonDependency,
5 | NodeDependencyType,
6 | } from '@schematics/angular/utility/dependencies';
7 | import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
8 |
9 | export function ngAdd(_options: any): Rule {
10 | return (host: Tree, context: SchematicContext) => {
11 | addDependencies(host);
12 | context.addTask(new NodePackageInstallTask());
13 | return noop();
14 | };
15 | }
16 |
17 | const getCurrentInstalledAngularVersion = (host: Tree) => {
18 | const angularCore = getPackageJsonDependency(host, '@angular/core');
19 | if (!angularCore) {
20 | throw new SchematicsException(`Could not find @angular/core in package.json dependencies`);
21 | }
22 | return angularCore.version;
23 | };
24 |
25 | const addDependencies = (host: Tree) => {
26 | const angularVersion = getCurrentInstalledAngularVersion(host);
27 |
28 | const getVersion = (version: string) => {
29 | const versionSegments = version.split('.');
30 | return `${versionSegments[0]}.${versionSegments[1]}.0`;
31 | };
32 |
33 | const getDevBranchVersion = (version: string) => {
34 | const versionSegments = version.split('.');
35 | versionSegments[0] = versionSegments[0].replace('~', '').replace('^', '');
36 | return `~0.${versionSegments[0]}0${versionSegments[1]}.0`;
37 | };
38 |
39 | const devDependencies: { [key: string]: string } = {
40 | '@angular-devkit/architect': getDevBranchVersion(angularVersion),
41 | '@angular-devkit/core': getVersion(angularVersion),
42 | '@angular-devkit/schematics': getVersion(angularVersion),
43 | '@schematics/angular': getVersion(angularVersion),
44 | };
45 |
46 | for (const devDependenciesKey in devDependencies) {
47 | addPackageJsonDependency(host, {
48 | type: NodeDependencyType.Dev,
49 | name: devDependenciesKey,
50 | version: devDependencies[devDependenciesKey],
51 | });
52 | }
53 | };
54 |
--------------------------------------------------------------------------------
/src/ng-generate/add-schematic/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | apply,
3 | applyTemplates,
4 | chain,
5 | mergeWith,
6 | move,
7 | noop,
8 | SchematicsException,
9 | Tree,
10 | url,
11 | } from '@angular-devkit/schematics';
12 | import * as path from 'path';
13 | import { getCollectionJsonPath, getParsedPath } from '../../utils/utils';
14 | import { Location } from '@schematics/angular/utility/parse-name';
15 |
16 | export interface InitSchematicsProjectOptions {
17 | path: string;
18 | save: 'dependencies' | 'devDependencies' | '';
19 | }
20 |
21 | export function createAddSchematic(options: InitSchematicsProjectOptions) {
22 | return async (host: Tree) => {
23 | const parsedPath = getParsedPath(options.path, 'ng-add');
24 | const templateSource = apply(url('./files'), [applyTemplates({}), move(parsedPath.path)]);
25 |
26 | return chain([mergeWith(templateSource), updateCollectionJson(host, parsedPath, options)]);
27 | };
28 | }
29 |
30 | function updateCollectionJson(host: Tree, parsedPath: Location, options: InitSchematicsProjectOptions) {
31 | const collectionPath = getCollectionJsonPath(host, parsedPath);
32 | const collectionJsonBuffer = host.read(collectionPath);
33 | if (!collectionJsonBuffer) {
34 | throw new SchematicsException(`Could not read file '${collectionPath}'`);
35 | }
36 |
37 | const collectionJson = JSON.parse(collectionJsonBuffer.toString('utf8'));
38 | const relativePathToSchematic = path
39 | .relative(
40 | path.join(process.cwd(), path.dirname(collectionPath)),
41 | path.join(process.cwd(), parsedPath.path, 'ng-add', 'index')
42 | )
43 | .replace(/\\/g, '/');
44 |
45 | const updatedCollectionJson = {
46 | ...collectionJson,
47 | schematics: {
48 | 'ng-add': {
49 | save: options.save,
50 | description: 'Bootstrap package',
51 | factory: `${relativePathToSchematic}#ngAdd`,
52 | },
53 | ...collectionJson.schematics,
54 | },
55 | };
56 | host.overwrite(collectionPath, JSON.stringify(updatedCollectionJson, null, 2));
57 |
58 | return noop();
59 | }
60 |
--------------------------------------------------------------------------------
/src/utils/utils.ts:
--------------------------------------------------------------------------------
1 | import { SchematicsException, Tree } from '@angular-devkit/schematics';
2 | import { ProjectDefinition, WorkspaceDefinition } from '@angular-devkit/core/src/workspace';
3 | import * as path from 'path';
4 | import { Location, parseName } from '@schematics/angular/utility/parse-name';
5 |
6 | export function getParsedPath(path: string, dirName: string) {
7 | return parseName(path as string, dirName);
8 | }
9 |
10 | export function findPackageJson(host: Tree, parsedPath: Location) {
11 | const pathSegments = parsedPath.path.split('/');
12 | let pathToPackageJson: string;
13 | for (let i = 0; i < pathSegments.length; i++) {
14 | pathToPackageJson = `${pathSegments.join('/')}/package.json`;
15 | if (host.exists(pathToPackageJson)) {
16 | return pathToPackageJson;
17 | } else {
18 | pathSegments.pop();
19 | }
20 | }
21 | throw new SchematicsException(`Could not locate package.json based on path ${parsedPath.path}`);
22 | }
23 |
24 | export function readJson(host: Tree, path: string) {
25 | const jsonBuffer = host.read(path);
26 | if (!jsonBuffer) {
27 | throw new SchematicsException(`Could not read file '${path}'`);
28 | }
29 | return JSON.parse(jsonBuffer.toString('utf8'));
30 | }
31 |
32 | export function getMigrationsJsonPath(host: Tree, parsedPath: Location) {
33 | const packageJsonPath = findPackageJson(host, parsedPath);
34 | const packageJson = readJson(host, packageJsonPath);
35 | if (!packageJson?.['ng-update']?.migrations) {
36 | throw new SchematicsException(`Could not read 'ng-update.migrations' field from package.json. Try running 'ng g ngx-cli-toolkit:init'.`);
37 | }
38 | return path.join(removeLastSegmentOfPath(packageJsonPath), packageJson['ng-update'].migrations);
39 | }
40 |
41 | export function getCollectionJsonPath(host: Tree, parsedPath: Location) {
42 | const packageJsonPath = findPackageJson(host, parsedPath);
43 | const packageJson = readJson(host, packageJsonPath);
44 | if (!packageJson?.schematics) {
45 | throw new SchematicsException(`Could not read 'schematics' field from package.json. Try running 'ng g ngx-cli-toolkit:init'.`);
46 | }
47 | return path.join(removeLastSegmentOfPath(packageJsonPath), packageJson.schematics);
48 | }
49 |
50 | export async function getProject(workspace: WorkspaceDefinition, projectName: string) {
51 | if (workspace.projects.has(projectName)) {
52 | return workspace.projects.get(projectName) as ProjectDefinition;
53 | } else {
54 | throw new SchematicsException(`A project with the name '${projectName}' does not exists`);
55 | }
56 | }
57 |
58 | export function removeLastSegmentOfPath(path: string) {
59 | return path.substring(0, path.lastIndexOf('/'));
60 | }
61 |
--------------------------------------------------------------------------------
/src/ng-generate/update-schematic/index.ts:
--------------------------------------------------------------------------------
1 | import { apply, applyTemplates, chain, mergeWith, move, noop, Tree, url } from '@angular-devkit/schematics';
2 | import * as path from 'path';
3 | import { camelize, dasherize } from '@angular-devkit/core/src/utils/strings';
4 | import { strings } from '@angular-devkit/core';
5 | import { getMigrationsJsonPath, getParsedPath, readJson } from '../../utils/utils';
6 | import { Location } from '@schematics/angular/utility/parse-name';
7 |
8 | export interface UpdateSchematicOptions {
9 | name: string;
10 | path: string;
11 | description: string;
12 | version: string;
13 | }
14 |
15 | export function createUpdateSchematic(options: UpdateSchematicOptions) {
16 | return async (host: Tree) => {
17 | const parsedPath = getParsedPath(options.path, options.name);
18 |
19 | const generatedSchematicDir = path.join(__dirname, parsedPath.path, dasherize(options.name));
20 | const migrationsJson = path.join(__dirname, getMigrationsJsonPath(host, parsedPath));
21 | const relativePathToMigrationsJson = path.relative(generatedSchematicDir, migrationsJson);
22 |
23 | const templateSource = apply(url('./files'), [
24 | applyTemplates({
25 | name: options.name,
26 | migrationsJsonPath: relativePathToMigrationsJson.replace(/\\/g, '/'),
27 | camelize: strings.camelize,
28 | classify: strings.classify,
29 | dasherize: strings.dasherize,
30 | }),
31 | move(parsedPath.path),
32 | ]);
33 |
34 | return chain([mergeWith(templateSource), updateMigrationsJson(host, parsedPath, options)]);
35 | };
36 | }
37 |
38 | function updateMigrationsJson(host: Tree, parsedPath: Location, options: UpdateSchematicOptions) {
39 | const migrationsJsonPath = getMigrationsJsonPath(host, parsedPath);
40 | const migrationsJson = readJson(host, migrationsJsonPath);
41 | const schematicName = options.name;
42 |
43 | const relativePathToSchematic = path
44 | .relative(
45 | path.join(process.cwd(), path.dirname(migrationsJsonPath)),
46 | path.join(process.cwd(), parsedPath.path, schematicName, 'index')
47 | )
48 | .replace(/\\/g, '/');
49 |
50 | const updatedMigrationsJson = {
51 | ...migrationsJson,
52 | schematics: {
53 | ...migrationsJson.schematics,
54 | [dasherize(schematicName)]: {
55 | description: options.description,
56 | factory: `${relativePathToSchematic}#${camelize(options.name)}`,
57 | schema: `${relativePathToSchematic.replace('index', 'schema.json')}`,
58 | version: options.version,
59 | },
60 | },
61 | };
62 | host.overwrite(migrationsJsonPath, JSON.stringify(updatedMigrationsJson, null, 2));
63 |
64 | return noop();
65 | }
66 |
--------------------------------------------------------------------------------
/src/ng-generate/generate-schematic/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | apply,
3 | applyTemplates,
4 | chain,
5 | mergeWith,
6 | move,
7 | noop,
8 | SchematicsException,
9 | Tree,
10 | url,
11 | } from '@angular-devkit/schematics';
12 | import * as path from 'path';
13 | import { camelize, dasherize } from '@angular-devkit/core/src/utils/strings';
14 | import { strings } from '@angular-devkit/core';
15 | import { getCollectionJsonPath, getParsedPath } from '../../utils/utils';
16 | import { Location } from '@schematics/angular/utility/parse-name';
17 |
18 | export interface GenerateSchematicOptions {
19 | name: string;
20 | path: string;
21 | description: string;
22 | }
23 |
24 | export function createGenerateSchematic(options: GenerateSchematicOptions) {
25 | return async (host: Tree) => {
26 | const parsedPath = getParsedPath(options.path, options.name);
27 |
28 | const generatedSchematicDir = path.join(__dirname, parsedPath.path, dasherize(options.name));
29 | const collectionJsonPath = path.join(__dirname, getCollectionJsonPath(host, parsedPath));
30 | const relativePathToCollectionJson = path.relative(generatedSchematicDir, collectionJsonPath);
31 |
32 | const templateSource = apply(url('./files'), [
33 | applyTemplates({
34 | name: options.name,
35 | collectionJsonPath: relativePathToCollectionJson.replace(/\\/g, '/'),
36 | camelize: strings.camelize,
37 | classify: strings.classify,
38 | dasherize: strings.dasherize,
39 | }),
40 | move(parsedPath.path),
41 | ]);
42 |
43 | return chain([mergeWith(templateSource), updateCollectionJson(host, parsedPath, options)]);
44 | };
45 | }
46 |
47 | function updateCollectionJson(host: Tree, parsedPath: Location, options: GenerateSchematicOptions) {
48 | const collectionPath = getCollectionJsonPath(host, parsedPath);
49 | const collectionJsonBuffer = host.read(collectionPath);
50 | const schematicName = options.name;
51 | if (!collectionJsonBuffer) {
52 | throw new SchematicsException(`Could not read file '${collectionPath}'`);
53 | }
54 |
55 | const collectionJson = JSON.parse(collectionJsonBuffer.toString('utf8'));
56 | const relativePathToSchematic = path
57 | .relative(
58 | path.join(process.cwd(), path.dirname(collectionPath)),
59 | path.join(process.cwd(), parsedPath.path, schematicName, 'index')
60 | )
61 | .replace(/\\/g, '/');
62 |
63 | const updatedCollectionJson = {
64 | ...collectionJson,
65 | schematics: {
66 | ...collectionJson.schematics,
67 | [dasherize(schematicName)]: {
68 | description: options.description,
69 | factory: `${relativePathToSchematic}#${camelize(options.name)}`,
70 | schema: `${relativePathToSchematic.replace('index', 'schema.json')}`,
71 | },
72 | },
73 | };
74 | host.overwrite(collectionPath, JSON.stringify(updatedCollectionJson, null, 2));
75 |
76 | return noop();
77 | }
78 |
--------------------------------------------------------------------------------
/smoke-tests/angular9/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rulesDirectory": [
4 | "codelyzer"
5 | ],
6 | "rules": {
7 | "align": {
8 | "options": [
9 | "parameters",
10 | "statements"
11 | ]
12 | },
13 | "array-type": false,
14 | "arrow-return-shorthand": true,
15 | "curly": true,
16 | "deprecation": {
17 | "severity": "warning"
18 | },
19 | "eofline": true,
20 | "import-blacklist": [
21 | true,
22 | "rxjs/Rx"
23 | ],
24 | "import-spacing": true,
25 | "indent": {
26 | "options": [
27 | "spaces"
28 | ]
29 | },
30 | "max-classes-per-file": false,
31 | "max-line-length": [
32 | true,
33 | 140
34 | ],
35 | "member-ordering": [
36 | true,
37 | {
38 | "order": [
39 | "static-field",
40 | "instance-field",
41 | "static-method",
42 | "instance-method"
43 | ]
44 | }
45 | ],
46 | "no-console": [
47 | true,
48 | "debug",
49 | "info",
50 | "time",
51 | "timeEnd",
52 | "trace"
53 | ],
54 | "no-empty": false,
55 | "no-inferrable-types": [
56 | true,
57 | "ignore-params"
58 | ],
59 | "no-non-null-assertion": true,
60 | "no-redundant-jsdoc": true,
61 | "no-switch-case-fall-through": true,
62 | "no-var-requires": false,
63 | "object-literal-key-quotes": [
64 | true,
65 | "as-needed"
66 | ],
67 | "quotemark": [
68 | true,
69 | "single"
70 | ],
71 | "semicolon": {
72 | "options": [
73 | "always"
74 | ]
75 | },
76 | "space-before-function-paren": {
77 | "options": {
78 | "anonymous": "never",
79 | "asyncArrow": "always",
80 | "constructor": "never",
81 | "method": "never",
82 | "named": "never"
83 | }
84 | },
85 | "typedef-whitespace": {
86 | "options": [
87 | {
88 | "call-signature": "nospace",
89 | "index-signature": "nospace",
90 | "parameter": "nospace",
91 | "property-declaration": "nospace",
92 | "variable-declaration": "nospace"
93 | },
94 | {
95 | "call-signature": "onespace",
96 | "index-signature": "onespace",
97 | "parameter": "onespace",
98 | "property-declaration": "onespace",
99 | "variable-declaration": "onespace"
100 | }
101 | ]
102 | },
103 | "variable-name": {
104 | "options": [
105 | "ban-keywords",
106 | "check-format",
107 | "allow-pascal-case"
108 | ]
109 | },
110 | "whitespace": {
111 | "options": [
112 | "check-branch",
113 | "check-decl",
114 | "check-operator",
115 | "check-separator",
116 | "check-type",
117 | "check-typecast"
118 | ]
119 | },
120 | "component-class-suffix": true,
121 | "contextual-lifecycle": true,
122 | "directive-class-suffix": true,
123 | "no-conflicting-lifecycle": true,
124 | "no-host-metadata-property": true,
125 | "no-input-rename": true,
126 | "no-inputs-metadata-property": true,
127 | "no-output-native": true,
128 | "no-output-on-prefix": true,
129 | "no-output-rename": true,
130 | "no-outputs-metadata-property": true,
131 | "template-banana-in-box": true,
132 | "template-no-negated-async": true,
133 | "use-lifecycle-interface": true,
134 | "use-pipe-transform-interface": true
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/ng-generate/init/index.ts:
--------------------------------------------------------------------------------
1 | import { chain, noop, SchematicsException, Tree } from '@angular-devkit/schematics';
2 | import { getWorkspace, updateWorkspace } from '@schematics/angular/utility/workspace';
3 | import { WorkspaceDefinition } from '@angular-devkit/core/src/workspace';
4 | import * as path from 'path';
5 | import { findPackageJson, getParsedPath, getProject, removeLastSegmentOfPath } from "../../utils/utils";
6 | import { Location } from '@schematics/angular/utility/parse-name';
7 |
8 | export interface InitSchematicsProjectOptions {
9 | path: string;
10 | project?: string;
11 | }
12 |
13 | export function initSchematicsProject(options: InitSchematicsProjectOptions) {
14 | return async (host: Tree) => {
15 | if(options.project) {
16 | const workspace = await getWorkspace(host);
17 | options.path = (await getProject(workspace, options.project)).root;
18 | }
19 | const parsedPath = getParsedPath(options.path, 'schematics');
20 | const projectRoot = removeLastSegmentOfPath(findPackageJson(host, parsedPath));
21 | const schematicsDir = path.join(projectRoot, parsedPath.name);
22 | const relativePathToNodeModules = path.relative(path.join(process.cwd(), projectRoot, 'schematics'), path.join(process.cwd(), 'node_modules'));
23 |
24 | return chain([
25 | createSchematicsConfigurationFiles(host, schematicsDir, relativePathToNodeModules),
26 | // addBuilderToAngularJson(workspace, options.project),
27 | addSchematicsFieldsToPackageJson(host, parsedPath),
28 | ]);
29 | };
30 | }
31 |
32 | function createSchematicsConfigurationFiles(host: Tree, targetDir: string, nodeModulesPath: string) {
33 | const schemaPath = path
34 | .join(nodeModulesPath, '@angular-devkit/schematics/collection-schema.json')
35 | .replace(/\\/g, '/');
36 | host.create(
37 | path.join(targetDir, 'collection.json'),
38 | JSON.stringify(
39 | {
40 | $schema: schemaPath,
41 | schematics: {},
42 | },
43 | null,
44 | 2
45 | )
46 | );
47 |
48 | host.create(
49 | path.join(targetDir, 'migrations.json'),
50 | JSON.stringify(
51 | {
52 | $schema: schemaPath,
53 | schematics: {},
54 | },
55 | null,
56 | 2
57 | )
58 | );
59 |
60 | return noop();
61 | }
62 |
63 | // todo: builder not yet implemented
64 | // @ts-ignore
65 | function addBuilderToAngularJson(workspace: WorkspaceDefinition, projectName: string) {
66 | workspace.projects.get(projectName)?.targets.set('build-schematics', {
67 | builder: 'ngx-cli-toolkit:build-schematics',
68 | });
69 | return updateWorkspace(workspace);
70 | }
71 |
72 | function addSchematicsFieldsToPackageJson(host: Tree, parsedPath: Location) {
73 | const packageJsonPath = findPackageJson(host, parsedPath);
74 | const packageJsonBuffer = host.read(packageJsonPath);
75 | if (!packageJsonBuffer) {
76 | throw new SchematicsException(`Could not find package.json in '${packageJsonPath}'`);
77 | }
78 |
79 | const packageJson: object = JSON.parse(packageJsonBuffer.toString('utf8'));
80 | const updatedPackageJson = {
81 | ...packageJson,
82 | schematics: './schematics/collection.json',
83 | 'ng-update': {
84 | migrations: './schematics/migrations.json',
85 | packageGroup: [],
86 | },
87 | };
88 |
89 | host.overwrite(packageJsonPath, JSON.stringify(updatedPackageJson, null, 2));
90 |
91 | return noop();
92 | }
93 |
--------------------------------------------------------------------------------
/src/ng-generate/add-schematic/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 | import { PathLike } from 'fs';
5 | import { InitSchematicsProjectOptions } from './index';
6 |
7 | const testCollectionPath = path.join(__dirname, '../../collection.json');
8 |
9 | describe('ng-generate', () => {
10 | let tree: Tree;
11 | let runner: SchematicTestRunner;
12 |
13 | const angularJson = {
14 | version: 1,
15 | projects: {
16 | ui: {
17 | projectType: 'library',
18 | root: 'projects/ui',
19 | sourceRoot: 'projects/ui/src',
20 | architect: {
21 | build: {
22 | builder: '@angular-devkit/build-angular:ng-packagr',
23 | options: {
24 | tsConfig: 'projects/ui/tsconfig.lib.json',
25 | project: 'projects/ui/ng-package.json',
26 | },
27 | configurations: {
28 | production: {
29 | tsConfig: 'projects/ui/tsconfig.lib.prod.json',
30 | },
31 | },
32 | },
33 | },
34 | },
35 | defaultProject: 'ui',
36 | },
37 | };
38 |
39 | const collectionJson = {
40 | schematics: {},
41 | };
42 |
43 | const packageJson = {
44 | schematics: './schematics/collection.json',
45 | };
46 |
47 | const projectPath = 'projects/ui';
48 | const schematicsPath = `${projectPath}/schematics`;
49 |
50 | beforeEach(async () => {
51 | runner = new SchematicTestRunner('schematics', testCollectionPath);
52 | tree = Tree.empty();
53 | tree.create(path.join(projectPath, 'package.json'), JSON.stringify(packageJson));
54 | });
55 |
56 | it('should generate files', async () => {
57 | tree.create('angular.json', JSON.stringify(angularJson));
58 | tree.create(path.join(schematicsPath, 'collection.json'), JSON.stringify(collectionJson));
59 | const options: InitSchematicsProjectOptions = {
60 | save: 'dependencies',
61 | path: schematicsPath as string,
62 | };
63 |
64 | await runner.runSchematicAsync('add-schematic', options, tree).toPromise();
65 |
66 | expect(tree.exists(path.join(schematicsPath, 'ng-add', 'index.ts'))).toBe(true);
67 | expect(tree.exists(path.join(schematicsPath, 'ng-add', 'index.spec.ts'))).toBe(true);
68 | });
69 |
70 | it('should add collection.json entry', async () => {
71 | tree.create('angular.json', JSON.stringify(angularJson));
72 | tree.create(path.join(schematicsPath, 'collection.json'), JSON.stringify(collectionJson));
73 | await runner
74 | .runSchematicAsync(
75 | 'add-schematic',
76 | {
77 | project: 'ui',
78 | save: 'dependencies',
79 | path: schematicsPath as PathLike,
80 | },
81 | tree
82 | )
83 | .toPromise();
84 |
85 | const testCollectionJson = JSON.parse(
86 | tree.read(path.join(projectPath, packageJson.schematics))?.toString('utf8')!
87 | );
88 | const ngAddEntry = testCollectionJson.schematics['ng-add'];
89 |
90 | expect(ngAddEntry.save).toStrictEqual('dependencies');
91 | expect(ngAddEntry.factory).toStrictEqual('ng-add/index#ngAdd');
92 | });
93 | });
94 |
--------------------------------------------------------------------------------
/smoke-tests/angular10/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rulesDirectory": [
4 | "codelyzer"
5 | ],
6 | "rules": {
7 | "align": {
8 | "options": [
9 | "parameters",
10 | "statements"
11 | ]
12 | },
13 | "array-type": false,
14 | "arrow-return-shorthand": true,
15 | "curly": true,
16 | "deprecation": {
17 | "severity": "warning"
18 | },
19 | "eofline": true,
20 | "import-blacklist": [
21 | true,
22 | "rxjs/Rx"
23 | ],
24 | "import-spacing": true,
25 | "indent": {
26 | "options": [
27 | "spaces"
28 | ]
29 | },
30 | "max-classes-per-file": false,
31 | "max-line-length": [
32 | true,
33 | 140
34 | ],
35 | "member-ordering": [
36 | true,
37 | {
38 | "order": [
39 | "static-field",
40 | "instance-field",
41 | "static-method",
42 | "instance-method"
43 | ]
44 | }
45 | ],
46 | "no-console": [
47 | true,
48 | "debug",
49 | "info",
50 | "time",
51 | "timeEnd",
52 | "trace"
53 | ],
54 | "no-empty": false,
55 | "no-inferrable-types": [
56 | true,
57 | "ignore-params"
58 | ],
59 | "no-non-null-assertion": true,
60 | "no-redundant-jsdoc": true,
61 | "no-switch-case-fall-through": true,
62 | "no-var-requires": false,
63 | "object-literal-key-quotes": [
64 | true,
65 | "as-needed"
66 | ],
67 | "quotemark": [
68 | true,
69 | "single"
70 | ],
71 | "semicolon": {
72 | "options": [
73 | "always"
74 | ]
75 | },
76 | "space-before-function-paren": {
77 | "options": {
78 | "anonymous": "never",
79 | "asyncArrow": "always",
80 | "constructor": "never",
81 | "method": "never",
82 | "named": "never"
83 | }
84 | },
85 | "typedef": [
86 | true,
87 | "call-signature"
88 | ],
89 | "typedef-whitespace": {
90 | "options": [
91 | {
92 | "call-signature": "nospace",
93 | "index-signature": "nospace",
94 | "parameter": "nospace",
95 | "property-declaration": "nospace",
96 | "variable-declaration": "nospace"
97 | },
98 | {
99 | "call-signature": "onespace",
100 | "index-signature": "onespace",
101 | "parameter": "onespace",
102 | "property-declaration": "onespace",
103 | "variable-declaration": "onespace"
104 | }
105 | ]
106 | },
107 | "variable-name": {
108 | "options": [
109 | "ban-keywords",
110 | "check-format",
111 | "allow-pascal-case"
112 | ]
113 | },
114 | "whitespace": {
115 | "options": [
116 | "check-branch",
117 | "check-decl",
118 | "check-operator",
119 | "check-separator",
120 | "check-type",
121 | "check-typecast"
122 | ]
123 | },
124 | "component-class-suffix": true,
125 | "contextual-lifecycle": true,
126 | "directive-class-suffix": true,
127 | "no-conflicting-lifecycle": true,
128 | "no-host-metadata-property": true,
129 | "no-input-rename": true,
130 | "no-inputs-metadata-property": true,
131 | "no-output-native": true,
132 | "no-output-on-prefix": true,
133 | "no-output-rename": true,
134 | "no-outputs-metadata-property": true,
135 | "template-banana-in-box": true,
136 | "template-no-negated-async": true,
137 | "use-lifecycle-interface": true,
138 | "use-pipe-transform-interface": true
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/smoke-tests/angular11/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rulesDirectory": [
4 | "codelyzer"
5 | ],
6 | "rules": {
7 | "align": {
8 | "options": [
9 | "parameters",
10 | "statements"
11 | ]
12 | },
13 | "array-type": false,
14 | "arrow-return-shorthand": true,
15 | "curly": true,
16 | "deprecation": {
17 | "severity": "warning"
18 | },
19 | "eofline": true,
20 | "import-blacklist": [
21 | true,
22 | "rxjs/Rx"
23 | ],
24 | "import-spacing": true,
25 | "indent": {
26 | "options": [
27 | "spaces"
28 | ]
29 | },
30 | "max-classes-per-file": false,
31 | "max-line-length": [
32 | true,
33 | 140
34 | ],
35 | "member-ordering": [
36 | true,
37 | {
38 | "order": [
39 | "static-field",
40 | "instance-field",
41 | "static-method",
42 | "instance-method"
43 | ]
44 | }
45 | ],
46 | "no-console": [
47 | true,
48 | "debug",
49 | "info",
50 | "time",
51 | "timeEnd",
52 | "trace"
53 | ],
54 | "no-empty": false,
55 | "no-inferrable-types": [
56 | true,
57 | "ignore-params"
58 | ],
59 | "no-non-null-assertion": true,
60 | "no-redundant-jsdoc": true,
61 | "no-switch-case-fall-through": true,
62 | "no-var-requires": false,
63 | "object-literal-key-quotes": [
64 | true,
65 | "as-needed"
66 | ],
67 | "quotemark": [
68 | true,
69 | "single"
70 | ],
71 | "semicolon": {
72 | "options": [
73 | "always"
74 | ]
75 | },
76 | "space-before-function-paren": {
77 | "options": {
78 | "anonymous": "never",
79 | "asyncArrow": "always",
80 | "constructor": "never",
81 | "method": "never",
82 | "named": "never"
83 | }
84 | },
85 | "typedef": [
86 | true,
87 | "call-signature"
88 | ],
89 | "typedef-whitespace": {
90 | "options": [
91 | {
92 | "call-signature": "nospace",
93 | "index-signature": "nospace",
94 | "parameter": "nospace",
95 | "property-declaration": "nospace",
96 | "variable-declaration": "nospace"
97 | },
98 | {
99 | "call-signature": "onespace",
100 | "index-signature": "onespace",
101 | "parameter": "onespace",
102 | "property-declaration": "onespace",
103 | "variable-declaration": "onespace"
104 | }
105 | ]
106 | },
107 | "variable-name": {
108 | "options": [
109 | "ban-keywords",
110 | "check-format",
111 | "allow-pascal-case"
112 | ]
113 | },
114 | "whitespace": {
115 | "options": [
116 | "check-branch",
117 | "check-decl",
118 | "check-operator",
119 | "check-separator",
120 | "check-type",
121 | "check-typecast"
122 | ]
123 | },
124 | "component-class-suffix": true,
125 | "contextual-lifecycle": true,
126 | "directive-class-suffix": true,
127 | "no-conflicting-lifecycle": true,
128 | "no-host-metadata-property": true,
129 | "no-input-rename": true,
130 | "no-inputs-metadata-property": true,
131 | "no-output-native": true,
132 | "no-output-on-prefix": true,
133 | "no-output-rename": true,
134 | "no-outputs-metadata-property": true,
135 | "template-banana-in-box": true,
136 | "template-no-negated-async": true,
137 | "use-lifecycle-interface": true,
138 | "use-pipe-transform-interface": true
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/ng-generate/generate-schematic/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 | import { camelize } from '@angular-devkit/core/src/utils/strings';
5 | import { GenerateSchematicOptions } from './index';
6 |
7 | const testCollectionPath = path.join(__dirname, '../../collection.json');
8 |
9 | describe('ng-generate', () => {
10 | let tree: Tree;
11 | let runner: SchematicTestRunner;
12 |
13 | const angularJson = {
14 | version: 1,
15 | projects: {
16 | ui: {
17 | projectType: 'library',
18 | root: 'projects/ui',
19 | sourceRoot: 'projects/ui/src',
20 | architect: {
21 | build: {
22 | builder: '@angular-devkit/build-angular:ng-packagr',
23 | options: {
24 | tsConfig: 'projects/ui/tsconfig.lib.json',
25 | project: 'projects/ui/ng-package.json',
26 | },
27 | configurations: {
28 | production: {
29 | tsConfig: 'projects/ui/tsconfig.lib.prod.json',
30 | },
31 | },
32 | },
33 | },
34 | },
35 | defaultProject: 'ui',
36 | },
37 | };
38 |
39 | const collectionJson = {
40 | schematics: {},
41 | };
42 |
43 | const packageJson = {
44 | schematics: './schematics/collection.json',
45 | };
46 |
47 | const projectPath = 'projects/ui';
48 | const schematicsPath = `${projectPath}/schematics`;
49 |
50 | const newSchematicName = 'new-generate-schematic';
51 |
52 | beforeEach(async () => {
53 | runner = new SchematicTestRunner('schematics', testCollectionPath);
54 | tree = Tree.empty();
55 | tree.create(path.join(projectPath, 'package.json'), JSON.stringify(packageJson));
56 | });
57 |
58 | it('should generate files', async () => {
59 | tree.create('angular.json', JSON.stringify(angularJson));
60 | tree.create(path.join(schematicsPath, 'collection.json'), JSON.stringify(collectionJson));
61 | const options: GenerateSchematicOptions = {
62 | name: newSchematicName,
63 | description: 'A description',
64 | path: `${schematicsPath}/ng-generate` as string,
65 | };
66 | await runner.runSchematicAsync('generate-schematic', options, tree).toPromise();
67 |
68 | const pathToNewSchematic = path.join(schematicsPath, 'ng-generate', newSchematicName);
69 |
70 | expect(tree.exists(path.join(pathToNewSchematic, 'index.ts'))).toBe(true);
71 | expect(tree.exists(path.join(pathToNewSchematic, 'index.spec.ts'))).toBe(true);
72 | });
73 |
74 | it('should add collection.json entry', async () => {
75 | tree.create('angular.json', JSON.stringify(angularJson));
76 | tree.create(path.join(schematicsPath, 'collection.json'), JSON.stringify(collectionJson));
77 | const options: GenerateSchematicOptions = {
78 | name: newSchematicName,
79 | description: 'A description',
80 | path: `${schematicsPath}/ng-generate` as string,
81 | };
82 | await runner.runSchematicAsync('generate-schematic', options, tree).toPromise();
83 |
84 | const testCollectionJson = JSON.parse(
85 | tree.read(path.join(projectPath, packageJson.schematics))?.toString('utf8')!
86 | );
87 | const schematicsEntry = testCollectionJson.schematics[newSchematicName];
88 |
89 | expect(schematicsEntry.factory).toStrictEqual(
90 | `ng-generate/${newSchematicName}/index#${camelize(newSchematicName)}`
91 | );
92 | });
93 | });
94 |
--------------------------------------------------------------------------------
/src/ng-generate/update-schematic/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 | import { camelize } from '@angular-devkit/core/src/utils/strings';
5 | import { UpdateSchematicOptions } from "./index";
6 |
7 | const testCollectionPath = path.join(__dirname, '../../collection.json');
8 |
9 | describe('ng-update', () => {
10 | let tree: Tree;
11 | let runner: SchematicTestRunner;
12 |
13 | const angularJson = {
14 | version: 1,
15 | projects: {
16 | ui: {
17 | projectType: 'library',
18 | root: 'projects/ui',
19 | sourceRoot: 'projects/ui/src',
20 | architect: {
21 | build: {
22 | builder: '@angular-devkit/build-angular:ng-packagr',
23 | options: {
24 | tsConfig: 'projects/ui/tsconfig.lib.json',
25 | project: 'projects/ui/ng-package.json',
26 | },
27 | configurations: {
28 | production: {
29 | tsConfig: 'projects/ui/tsconfig.lib.prod.json',
30 | },
31 | },
32 | },
33 | },
34 | },
35 | defaultProject: 'ui',
36 | },
37 | };
38 |
39 | const migrationsJson = {
40 | schematics: {},
41 | };
42 |
43 | const packageJson = {
44 | 'ng-update': {
45 | migrations: './schematics/migrations.json',
46 | },
47 | };
48 |
49 | const projectPath = angularJson.projects.ui.root;
50 | const schematicsPath = `projects/ui/schematics`;
51 |
52 | const newSchematicName = 'new-update-schematic';
53 |
54 | beforeEach(async () => {
55 | runner = new SchematicTestRunner('schematics', testCollectionPath);
56 | tree = Tree.empty();
57 | tree.create(path.join(projectPath, 'package.json'), JSON.stringify(packageJson));
58 | });
59 |
60 | it('should generate files', async () => {
61 | tree.create('angular.json', JSON.stringify(angularJson));
62 | tree.create(path.join(schematicsPath, 'migrations.json'), JSON.stringify(migrationsJson));
63 | const options: UpdateSchematicOptions = {
64 | name: newSchematicName,
65 | version: '1.2.3',
66 | description: 'A description',
67 | path: `${schematicsPath}/ng-update` as string,
68 | };
69 | await runner
70 | .runSchematicAsync(
71 | 'update-schematic',
72 | options,
73 | tree
74 | )
75 | .toPromise();
76 |
77 | const pathToNewSchematic = path.join(schematicsPath, 'ng-update', newSchematicName);
78 |
79 | expect(tree.exists(path.join(pathToNewSchematic, 'index.ts'))).toBe(true);
80 | expect(tree.exists(path.join(pathToNewSchematic, 'index.spec.ts'))).toBe(true);
81 | });
82 |
83 | it('should add migrations.json entry', async () => {
84 | tree.create('angular.json', JSON.stringify(angularJson));
85 | tree.create(path.join(schematicsPath, 'migrations.json'), JSON.stringify(migrationsJson));
86 | const options: UpdateSchematicOptions = {
87 | name: newSchematicName,
88 | version: '1.2.3',
89 | description: 'A description',
90 | path: `${schematicsPath}/ng-update` as string,
91 | };
92 | await runner
93 | .runSchematicAsync(
94 | 'update-schematic',
95 | options,
96 | tree
97 | )
98 | .toPromise();
99 |
100 | const testCollectionJson = JSON.parse(
101 | tree.read(path.join(projectPath, packageJson['ng-update'].migrations))?.toString('utf8')!
102 | );
103 | const schematicsEntry = testCollectionJson.schematics[newSchematicName];
104 |
105 | expect(schematicsEntry.factory).toStrictEqual(
106 | `ng-update/${newSchematicName}/index#${camelize(newSchematicName)}`
107 | );
108 | });
109 | });
110 |
--------------------------------------------------------------------------------
/src/ng-generate/init/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
3 | import * as path from 'path';
4 | import { InitSchematicsProjectOptions } from './index';
5 |
6 | const collectionPath = path.join(__dirname, '../../collection.json');
7 |
8 | describe('ng-generate', () => {
9 | const angularJson = {
10 | version: 1,
11 | projects: {
12 | ui: {
13 | projectType: 'library',
14 | root: 'projects/ui',
15 | sourceRoot: 'projects/ui/src',
16 | architect: {
17 | build: {
18 | builder: '@angular-devkit/build-angular:ng-packagr',
19 | options: {
20 | tsConfig: 'projects/ui/tsconfig.lib.json',
21 | project: 'projects/ui/ng-package.json',
22 | },
23 | configurations: {
24 | production: {
25 | tsConfig: 'projects/ui/tsconfig.lib.prod.json',
26 | },
27 | },
28 | },
29 | },
30 | },
31 | defaultProject: 'ui',
32 | },
33 | };
34 |
35 | // @ts-ignore
36 | const angularJsonExpected = {
37 | version: 1,
38 | projects: {
39 | ui: {
40 | projectType: 'library',
41 | root: 'projects/ui',
42 | sourceRoot: 'projects/ui/src',
43 | architect: {
44 | build: {
45 | builder: '@angular-devkit/build-angular:ng-packagr',
46 | options: {
47 | tsConfig: 'projects/ui/tsconfig.lib.json',
48 | project: 'projects/ui/ng-package.json',
49 | },
50 | configurations: {
51 | production: {
52 | tsConfig: 'projects/ui/tsconfig.lib.prod.json',
53 | },
54 | },
55 | },
56 | 'build-schematics': {
57 | builder: 'ngx-cli-toolkit:build-schematics',
58 | },
59 | },
60 | },
61 | defaultProject: 'ui',
62 | },
63 | };
64 |
65 | const packageJson = {
66 | name: 'ui',
67 | version: '0.0.1',
68 | peerDependencies: {
69 | '@angular/common': '^11.2.13',
70 | '@angular/core': '^11.2.13',
71 | },
72 | dependencies: {
73 | tslib: '^2.0.0',
74 | },
75 | };
76 |
77 | const packageJsonExpected = {
78 | name: 'ui',
79 | version: '0.0.1',
80 | schematics: './schematics/collection.json',
81 | 'ng-update': {
82 | migrations: './schematics/migrations.json',
83 | packageGroup: [],
84 | },
85 | peerDependencies: {
86 | '@angular/common': '^11.2.13',
87 | '@angular/core': '^11.2.13',
88 | },
89 | dependencies: {
90 | tslib: '^2.0.0',
91 | },
92 | };
93 |
94 | let tree: Tree;
95 | let runner: SchematicTestRunner;
96 | let options: InitSchematicsProjectOptions;
97 | const projectUiPackageJsonPath = path.join(angularJson.projects.ui.root, 'package.json');
98 | const schematicsDirectoryPath = path.join(angularJson.projects.ui.root, 'schematics');
99 |
100 | beforeEach(async () => {
101 | runner = new SchematicTestRunner('schematics', collectionPath);
102 | tree = Tree.empty();
103 | tree.create('angular.json', JSON.stringify(angularJson));
104 | tree.create(projectUiPackageJsonPath, JSON.stringify(packageJson));
105 |
106 | options = {
107 | path: `${angularJson.projects.ui.root}/subdirectory` as string,
108 | };
109 | });
110 |
111 | it('should create migrations.json', async () => {
112 | await runner.runSchematicAsync('init', options, tree).toPromise();
113 | const expectedMigrationsJson = {
114 | $schema: '../../../node_modules/@angular-devkit/schematics/collection-schema.json',
115 | schematics: {},
116 | };
117 | const migrationJson = tree.read(path.join(schematicsDirectoryPath, 'migrations.json'))?.toString('utf8')!;
118 | expect(JSON.parse(migrationJson)).toMatchObject(expectedMigrationsJson);
119 | });
120 |
121 | it('should create collection.json', async () => {
122 | await runner.runSchematicAsync('init', options, tree).toPromise();
123 | const expectedCollectionJson = {
124 | $schema: '../../../node_modules/@angular-devkit/schematics/collection-schema.json',
125 | schematics: {},
126 | };
127 |
128 | const collectionJson = tree.read(path.join(schematicsDirectoryPath, 'collection.json'))?.toString('utf8')!;
129 | expect(JSON.parse(collectionJson)).toMatchObject(expectedCollectionJson);
130 | });
131 |
132 | // todo: enable after the implementation of the builder itself
133 | // it('should add `build-schematics` builder to angukar.json', () => {
134 | // expect(JSON.parse(tree.read('angular.json')?.toString('utf8')!)).toStrictEqual(angularJsonExpected);
135 | // });
136 |
137 | it('should add schematics entries in package.json', async () => {
138 | await runner.runSchematicAsync('init', options, tree).toPromise();
139 | expect(JSON.parse(tree.read(projectUiPackageJsonPath)?.toString('utf8')!)).toStrictEqual(packageJsonExpected);
140 | });
141 |
142 | it('should init project with the --project flag', async () => {
143 | let _options = { project: 'ui', path: '/' as string };
144 | await runner.runSchematicAsync('init', _options, tree).toPromise();
145 | expect(JSON.parse(tree.read(projectUiPackageJsonPath)?.toString('utf8')!)).toStrictEqual(packageJsonExpected);
146 | });
147 | });
148 |
--------------------------------------------------------------------------------