feat(nx): remove @nrwl/bazel package
This commit is contained in:
parent
a5bc37c60d
commit
b8ee3ba478
@ -45,7 +45,6 @@
|
|||||||
- [Affected support for uncommitted changes](https://github.com/nrwl/nx/commit/113b51bd330c2af058675386e482d38f170a6688)
|
- [Affected support for uncommitted changes](https://github.com/nrwl/nx/commit/113b51bd330c2af058675386e482d38f170a6688)
|
||||||
- [Extend circular dependency check](https://github.com/nrwl/nx/commit/fff9659c3a108b613c6db89bcca4072494fbe85f)
|
- [Extend circular dependency check](https://github.com/nrwl/nx/commit/fff9659c3a108b613c6db89bcca4072494fbe85f)
|
||||||
- [Add lint checks ensuring the integrity of the workspace](https://github.com/nrwl/nx/commit/ce553b732e8ca004e1ecf53cf54bcadb6ba1f7f3)
|
- [Add lint checks ensuring the integrity of the workspace](https://github.com/nrwl/nx/commit/ce553b732e8ca004e1ecf53cf54bcadb6ba1f7f3)
|
||||||
- [Add ability to create bazel workspace](https://github.com/nrwl/nx/commit/5a26f241b1e8b8b87e2ab4da941d3d3c4c480046)
|
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ If you find a bug in the source code or a mistake in the documentation, you can
|
|||||||
|
|
||||||
After cloning the project run: `yarn`.
|
After cloning the project run: `yarn`.
|
||||||
|
|
||||||
After that run `yarn build` to build the `bazel`, `nx`, and `schematics` packages.
|
After that run `yarn build` to build the `nx`, and `schematics` packages.
|
||||||
|
|
||||||
After that run `yarn linknpm`.
|
After that run `yarn linknpm`.
|
||||||
|
|
||||||
|
|||||||
@ -15,10 +15,10 @@
|
|||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://hubs.ly/H0g97pW0" target="_blank">
|
<a href="https://hubs.ly/H0g97pW0" target="_blank">
|
||||||
<img
|
<img
|
||||||
width="728"
|
width="728"
|
||||||
src="https://images.ctfassets.net/8eyogtwep6d2/40ASb6l6MR7V0w5ntqZ2yi/b4d439fcf56e50085d1f76df1bee41af/monorepo-banner-angularconsole.png"
|
src="https://images.ctfassets.net/8eyogtwep6d2/40ASb6l6MR7V0w5ntqZ2yi/b4d439fcf56e50085d1f76df1bee41af/monorepo-banner-angularconsole.png"
|
||||||
alt="Our Newest Enterprise Angular Book">
|
alt="Our Newest Enterprise Angular Book">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
Bazel Commands
|
|
||||||
|
|
||||||
## Add new app
|
|
||||||
|
|
||||||
node_modules/.bin/ng generate app [name]
|
|
||||||
|
|
||||||
Example: node_modules/.bin/ng generate app test
|
|
||||||
|
|
||||||
## Add new component
|
|
||||||
|
|
||||||
node_modules/.bin/ng generate component [name] --directory=[dir]
|
|
||||||
|
|
||||||
Example: node_modules/.bin/ng generate component friends --directory=myDir
|
|
||||||
|
|
||||||
- must manually import the component's Bazel rule in the consuming Bazel rule
|
|
||||||
|
|
||||||
## Add new lib
|
|
||||||
|
|
||||||
node_modules/.bin/ng generate lib [name]
|
|
||||||
|
|
||||||
Example: node_modules/.bin/ng generate lib mylib
|
|
||||||
|
|
||||||
- must manually import the lib's Bazel rule in the consuming Bazel rule
|
|
||||||
|
|
||||||
## Run dev server
|
|
||||||
|
|
||||||
ibazel run apps/[app specific path]]/src:devserver (anything between apps/\*\*/src points to a specific app)
|
|
||||||
|
|
||||||
Example: ibazel run apps/my-dir/my-app/src:devserver
|
|
||||||
|
|
||||||
## Run prod server
|
|
||||||
|
|
||||||
bazel run apps/[app specific path]]/src:prodserver (anything between apps/\*\*/src points to a specific app)
|
|
||||||
|
|
||||||
Example: bazel run apps/my-dir/my-app/src:prodserver
|
|
||||||
|
|
||||||
## Run unit tests
|
|
||||||
|
|
||||||
ibazel test //libs/mylib/src:test
|
|
||||||
|
|
||||||
- currently works for libs
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@nrwl/bazel",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"description": "Nrwl Extensions for Angular: Bazel Schematics",
|
|
||||||
"main": "index.js",
|
|
||||||
"types": "index.d.js",
|
|
||||||
"author": "Victor Savkin",
|
|
||||||
"license": "MIT",
|
|
||||||
"schematics": "./src/collection.json",
|
|
||||||
"dependencies": {
|
|
||||||
"@ngrx/schematics": "6.0.1",
|
|
||||||
"app-root-path": "^2.0.1",
|
|
||||||
"npm-run-all": "4.1.2",
|
|
||||||
"semver": "5.4.1",
|
|
||||||
"tmp": "0.0.33",
|
|
||||||
"yargs-parser": "10.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@schematics/angular": "0.7.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "nx-bazel",
|
|
||||||
"version": "0.1",
|
|
||||||
"extends": "@schematics/angular",
|
|
||||||
"schematics": {
|
|
||||||
"application": {
|
|
||||||
"factory": "./collection/application",
|
|
||||||
"schema": "./collection/application/schema.json",
|
|
||||||
"description": "Create a Bazel workspace."
|
|
||||||
},
|
|
||||||
"app": {
|
|
||||||
"factory": "./collection/app",
|
|
||||||
"schema": "./collection/app/schema.json",
|
|
||||||
"description": "Create an application."
|
|
||||||
},
|
|
||||||
"lib": {
|
|
||||||
"factory": "./collection/lib",
|
|
||||||
"schema": "./collection/lib/schema.json",
|
|
||||||
"description": "Create a library"
|
|
||||||
},
|
|
||||||
"module": {
|
|
||||||
"aliases": ["m"],
|
|
||||||
"factory": "./collection/module",
|
|
||||||
"schema": "./collection/module/schema.json",
|
|
||||||
"description": "Create a Module"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
load("@angular//:index.bzl", "ng_module")
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
|
|
||||||
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
ng_module(
|
|
||||||
name = "<%= sourceDir %>",
|
|
||||||
srcs = glob(["main.ts"]),
|
|
||||||
deps = [
|
|
||||||
"//apps/<%= fullName %>/src/app",
|
|
||||||
"@rxjs",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Needed because the devserver only loads static files that appear under this
|
|
||||||
# package.
|
|
||||||
genrule(
|
|
||||||
name = "zone.js",
|
|
||||||
srcs = ["//:node_modules/zone.js/dist/zone.min.js"],
|
|
||||||
outs = ["zone.min.js"],
|
|
||||||
cmd = "cp $< $@",
|
|
||||||
)
|
|
||||||
|
|
||||||
STATIC_FILES = [
|
|
||||||
"favicon.ico",
|
|
||||||
"index.html",
|
|
||||||
"styles.css",
|
|
||||||
":zone.js",
|
|
||||||
]
|
|
||||||
|
|
||||||
ts_devserver(
|
|
||||||
name = "devserver",
|
|
||||||
data = ["//apps/<%= fullName %>/src/assets"],
|
|
||||||
entry_module = "<%= workspaceName %>/apps/<%= fullName %>/src/main",
|
|
||||||
scripts = ["//:angular_bundles"],
|
|
||||||
serving_path = "/bundle.min.js",
|
|
||||||
static_files = STATIC_FILES,
|
|
||||||
deps = [":<%= sourceDir %>"],
|
|
||||||
)
|
|
||||||
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "rollup_bundle", "nodejs_binary")
|
|
||||||
|
|
||||||
rollup_bundle(
|
|
||||||
name = "bundle",
|
|
||||||
entry_point = "<%= workspaceName %>/apps/<%= fullName %>/src/main",
|
|
||||||
deps = [":<%= sourceDir %>"],
|
|
||||||
)
|
|
||||||
|
|
||||||
nodejs_binary(
|
|
||||||
name = "prodserver",
|
|
||||||
args = ["./apps/<%= fullName %>/src"],
|
|
||||||
data = STATIC_FILES + [
|
|
||||||
":bundle",
|
|
||||||
"//apps/<%= fullName %>/src/assets",
|
|
||||||
],
|
|
||||||
entry_point = "http-server/bin/http-server",
|
|
||||||
)
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "assets",
|
|
||||||
srcs = glob(["*"]),
|
|
||||||
)
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.3 KiB |
@ -1,17 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title><%= utils.classify(name) %></title>
|
|
||||||
<base href="/">
|
|
||||||
|
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<<%= prefix %>-root></<%= prefix %>-root>
|
|
||||||
<script src="/zone.min.js"></script>
|
|
||||||
<script src="/bundle.min.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { enableProdMode } from '@angular/core';
|
|
||||||
import { platformBrowser } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
import {AppModuleNgFactory} from './app/app.module.ngfactory';
|
|
||||||
|
|
||||||
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory)
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
/**
|
|
||||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
|
||||||
* You can add your own extra polyfills to this file.
|
|
||||||
*
|
|
||||||
* This file is divided into 2 sections:
|
|
||||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
|
||||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
|
||||||
* file.
|
|
||||||
*
|
|
||||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
|
||||||
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
|
||||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
|
||||||
*
|
|
||||||
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* BROWSER POLYFILLS
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
|
||||||
// import 'core-js/es6/symbol';
|
|
||||||
// import 'core-js/es6/object';
|
|
||||||
// import 'core-js/es6/function';
|
|
||||||
// import 'core-js/es6/parse-int';
|
|
||||||
// import 'core-js/es6/parse-float';
|
|
||||||
// import 'core-js/es6/number';
|
|
||||||
// import 'core-js/es6/math';
|
|
||||||
// import 'core-js/es6/string';
|
|
||||||
// import 'core-js/es6/date';
|
|
||||||
// import 'core-js/es6/array';
|
|
||||||
// import 'core-js/es6/regexp';
|
|
||||||
// import 'core-js/es6/map';
|
|
||||||
// import 'core-js/es6/weak-map';
|
|
||||||
// import 'core-js/es6/set';
|
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
|
||||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following for the Reflect API. */
|
|
||||||
// import 'core-js/es6/reflect';
|
|
||||||
|
|
||||||
|
|
||||||
/** Evergreen browsers require these. **/
|
|
||||||
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
|
|
||||||
import 'core-js/es7/reflect';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Required to support Web Animations `@angular/platform-browser/animations`.
|
|
||||||
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
|
|
||||||
**/
|
|
||||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* Zone JS is required by Angular itself.
|
|
||||||
*/
|
|
||||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* APPLICATION IMPORTS
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Date, currency, decimal and percent pipes.
|
|
||||||
* Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
|
|
||||||
*/
|
|
||||||
// import 'intl'; // Run `npm install --save intl`.
|
|
||||||
/**
|
|
||||||
* Need to import at least one locale-data with intl.
|
|
||||||
*/
|
|
||||||
// import 'intl/locale-data/jsonp/en';
|
|
||||||
@ -1 +0,0 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "<%= offsetFromRoot %>tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "<%= offsetFromRoot %>dist/out-tsc/apps/<%= fullName %>",
|
|
||||||
"module": "es2015"
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"**/*.ts"
|
|
||||||
/* add all lazy-loaded libraries here: "<%= offsetFromRoot %>libs/my-lib/index.ts" */
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/*.spec.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import { AppPage } from './app.po';
|
|
||||||
|
|
||||||
describe('<%= utils.dasherize(name) %> App', () => {
|
|
||||||
let page: AppPage;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new AppPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display welcome message', () => {
|
|
||||||
page.navigateTo();
|
|
||||||
expect(page.text()).toContain('Welcome');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
|
||||||
|
|
||||||
export class AppPage {
|
|
||||||
navigateTo() {
|
|
||||||
return browser.get('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return browser.findElement(by.css('body')).getText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "<%= offsetFromRoot %>tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "<%= offsetFromRoot %>dist/out-tsc/e2e/<%= fullName %>",
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es5",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"jasminewd2",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"../**/*.ts"
|
|
||||||
/* add all lazy-loaded libraries here: "<%= offsetFromRoot %>libs/my-lib/index.ts" */
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/*.spec.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,307 +0,0 @@
|
|||||||
import {
|
|
||||||
apply,
|
|
||||||
branchAndMerge,
|
|
||||||
chain,
|
|
||||||
externalSchematic,
|
|
||||||
mergeWith,
|
|
||||||
noop,
|
|
||||||
Rule,
|
|
||||||
template,
|
|
||||||
Tree,
|
|
||||||
url
|
|
||||||
} from '@angular-devkit/schematics';
|
|
||||||
import { Schema } from './schema';
|
|
||||||
import { strings } from '@angular-devkit/core';
|
|
||||||
import {
|
|
||||||
addImportToModule,
|
|
||||||
insert,
|
|
||||||
addImportToTestBed,
|
|
||||||
updateJsonInTree
|
|
||||||
} from '../../utils/ast-utils';
|
|
||||||
import { toFileName } from '../../utils/name-utils';
|
|
||||||
import * as ts from 'typescript';
|
|
||||||
import {
|
|
||||||
addBootstrapToModule,
|
|
||||||
insertImport
|
|
||||||
} from '@schematics/angular/utility/ast-utils';
|
|
||||||
import { addApp, readCliConfigFile } from '../../utils/fileutils';
|
|
||||||
import { offsetFromRoot } from '../../utils/common';
|
|
||||||
import { formatFiles } from '../../utils/rules/format-files';
|
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
|
||||||
fullName: string;
|
|
||||||
fullPath: string;
|
|
||||||
workspaceName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addBootstrap(path: string): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const modulePath = `${path}/app/app.module.ts`;
|
|
||||||
const moduleSource = host.read(modulePath)!.toString('utf-8');
|
|
||||||
const sourceFile = ts.createSourceFile(
|
|
||||||
modulePath,
|
|
||||||
moduleSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
insert(host, modulePath, [
|
|
||||||
insertImport(
|
|
||||||
sourceFile,
|
|
||||||
modulePath,
|
|
||||||
'BrowserModule',
|
|
||||||
'@angular/platform-browser'
|
|
||||||
),
|
|
||||||
...addImportToModule(sourceFile, modulePath, 'BrowserModule'),
|
|
||||||
...addBootstrapToModule(
|
|
||||||
sourceFile,
|
|
||||||
modulePath,
|
|
||||||
'AppComponent',
|
|
||||||
'./app.component'
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function addNxModule(path: string): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const modulePath = `${path}/app/app.module.ts`;
|
|
||||||
const moduleSource = host.read(modulePath)!.toString('utf-8');
|
|
||||||
const sourceFile = ts.createSourceFile(
|
|
||||||
modulePath,
|
|
||||||
moduleSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
insert(host, modulePath, [
|
|
||||||
insertImport(sourceFile, modulePath, 'NxModule', '@nrwl/nx'),
|
|
||||||
...addImportToModule(sourceFile, modulePath, 'NxModule.forRoot()')
|
|
||||||
]);
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function addAppToAngularCliJson(options: NormalizedSchema): Rule {
|
|
||||||
return updateJsonInTree('.angular-cli.json', angularCliJson => {
|
|
||||||
angularCliJson.apps = addApp(angularCliJson.apps, {
|
|
||||||
name: options.fullName,
|
|
||||||
root: options.fullPath,
|
|
||||||
outDir: `dist/apps/${options.fullName}`,
|
|
||||||
assets: ['assets', 'favicon.ico'],
|
|
||||||
index: 'index.html',
|
|
||||||
main: 'main.ts',
|
|
||||||
polyfills: 'polyfills.ts',
|
|
||||||
test: `${offsetFromRoot(options.fullPath)}test.js`,
|
|
||||||
tsconfig: `tsconfig.app.json`,
|
|
||||||
testTsconfig: `${offsetFromRoot(options.fullPath)}tsconfig.spec.json`,
|
|
||||||
prefix: options.prefix,
|
|
||||||
styles: [`styles.${options.style}`],
|
|
||||||
scripts: [],
|
|
||||||
environmentSource: 'environments/environment.ts',
|
|
||||||
environments: {
|
|
||||||
dev: 'environments/environment.ts',
|
|
||||||
prod: 'environments/environment.prod.ts'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
angularCliJson.lint = [
|
|
||||||
...(angularCliJson.lint || []),
|
|
||||||
{
|
|
||||||
project: `${options.fullPath}/tsconfig.app.json`,
|
|
||||||
exclude: '**/node_modules/**'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
project: `apps/${options.fullName}/e2e/tsconfig.e2e.json`,
|
|
||||||
exclude: '**/node_modules/**'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return angularCliJson;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addRouterRootConfiguration(path: string): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const modulePath = `${path}/app/app.module.ts`;
|
|
||||||
const moduleSource = host.read(modulePath)!.toString('utf-8');
|
|
||||||
const sourceFile = ts.createSourceFile(
|
|
||||||
modulePath,
|
|
||||||
moduleSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
insert(host, modulePath, [
|
|
||||||
insertImport(sourceFile, modulePath, 'RouterModule', '@angular/router'),
|
|
||||||
...addImportToModule(
|
|
||||||
sourceFile,
|
|
||||||
modulePath,
|
|
||||||
`RouterModule.forRoot([], {initialNavigation: 'enabled'})`
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
|
|
||||||
const componentSpecPath = `${path}/app/app.component.spec.ts`;
|
|
||||||
const componentSpecSource = host.read(componentSpecPath)!.toString('utf-8');
|
|
||||||
const componentSpecSourceFile = ts.createSourceFile(
|
|
||||||
componentSpecPath,
|
|
||||||
componentSpecSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
insert(host, componentSpecPath, [
|
|
||||||
insertImport(
|
|
||||||
componentSpecSourceFile,
|
|
||||||
componentSpecPath,
|
|
||||||
'RouterTestingModule',
|
|
||||||
'@angular/router/testing'
|
|
||||||
),
|
|
||||||
...addImportToTestBed(
|
|
||||||
componentSpecSourceFile,
|
|
||||||
componentSpecPath,
|
|
||||||
`RouterTestingModule`
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const staticComponentContent = `
|
|
||||||
<div style="text-align:center">
|
|
||||||
<h1>
|
|
||||||
Welcome to an Angular CLI app built with Nrwl Nx!
|
|
||||||
</h1>
|
|
||||||
<img width="450" src="assets/nx-logo.png">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Nx</h2>
|
|
||||||
|
|
||||||
An open source toolkit for enterprise Angular applications.
|
|
||||||
|
|
||||||
Nx is designed to help you create and build enterprise grade Angular applications. It provides an opinionated approach to application project structure and patterns.
|
|
||||||
|
|
||||||
<h2>Quick Start & Documentation</h2>
|
|
||||||
|
|
||||||
<a href="https://nrwl.io/nx">Watch a 5-minute video on how to get started with Nx.</a>`;
|
|
||||||
|
|
||||||
function updateComponentTemplate(options: NormalizedSchema): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const content = options.routing
|
|
||||||
? `${staticComponentContent}\n<router-outlet></router-outlet>`
|
|
||||||
: staticComponentContent;
|
|
||||||
host.overwrite(`${options.fullPath}/app/app.component.html`, content);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function addBazelBuildFile(path: string): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const ngModule = `package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load("@angular//:index.bzl", "ng_module")
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_web_test")
|
|
||||||
|
|
||||||
ng_module(
|
|
||||||
name = "app",
|
|
||||||
srcs = glob(
|
|
||||||
["*.ts"],
|
|
||||||
exclude = ["*.spec.ts"],
|
|
||||||
),
|
|
||||||
assets = [
|
|
||||||
"app.component.css",
|
|
||||||
"app.component.html",
|
|
||||||
],
|
|
||||||
deps = [
|
|
||||||
"@rxjs",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ts_library(
|
|
||||||
name = "test_lib",
|
|
||||||
testonly = 1,
|
|
||||||
srcs = glob(["*.spec.ts"]),
|
|
||||||
deps = [
|
|
||||||
":app",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ts_web_test(
|
|
||||||
name = "test",
|
|
||||||
bootstrap = ["//:angular_bootstrap_scripts"],
|
|
||||||
deps = [
|
|
||||||
":test_lib",
|
|
||||||
"//:angular_bundles",
|
|
||||||
"//:angular_test_bundles",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
`;
|
|
||||||
|
|
||||||
host.create(`${path}/app/BUILD.bazel`, ngModule);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function(schema: Schema): Rule {
|
|
||||||
let npmScope = schema.npmScope;
|
|
||||||
if (!npmScope) {
|
|
||||||
npmScope = readCliConfigFile().project.npmScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = normalizeOptions(schema);
|
|
||||||
const templateSource = apply(url('./files'), [
|
|
||||||
template({
|
|
||||||
utils: strings,
|
|
||||||
dot: '.',
|
|
||||||
tmpl: '',
|
|
||||||
offsetFromRoot: offsetFromRoot(options.fullPath),
|
|
||||||
...(options as object),
|
|
||||||
npmScope
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
|
|
||||||
const selector = `${options.prefix}-root`;
|
|
||||||
|
|
||||||
return chain([
|
|
||||||
branchAndMerge(chain([mergeWith(templateSource)])),
|
|
||||||
externalSchematic('@schematics/angular', 'module', {
|
|
||||||
name: 'app',
|
|
||||||
commonModule: false,
|
|
||||||
flat: true,
|
|
||||||
routing: false,
|
|
||||||
sourceDir: options.fullPath,
|
|
||||||
spec: false
|
|
||||||
}),
|
|
||||||
externalSchematic('@schematics/angular', 'component', {
|
|
||||||
name: 'app',
|
|
||||||
selector: selector,
|
|
||||||
sourceDir: options.fullPath,
|
|
||||||
flat: true,
|
|
||||||
inlineStyle: options.inlineStyle,
|
|
||||||
inlineTemplate: options.inlineTemplate,
|
|
||||||
spec: !options.skipTests,
|
|
||||||
styleext: options.style,
|
|
||||||
viewEncapsulation: options.viewEncapsulation,
|
|
||||||
changeDetection: options.changeDetection
|
|
||||||
}),
|
|
||||||
updateComponentTemplate(options),
|
|
||||||
addBootstrap(options.fullPath),
|
|
||||||
addNxModule(options.fullPath),
|
|
||||||
addAppToAngularCliJson(options),
|
|
||||||
addBazelBuildFile(options.fullPath),
|
|
||||||
addAppToAngularCliJson(options),
|
|
||||||
options.routing ? addRouterRootConfiguration(options.fullPath) : noop(),
|
|
||||||
formatFiles(options)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeOptions(options: Schema): NormalizedSchema {
|
|
||||||
const name = toFileName(options.name);
|
|
||||||
const fullName = options.directory
|
|
||||||
? `${toFileName(options.directory)}/${name}`
|
|
||||||
: name;
|
|
||||||
const fullPath = `apps/${fullName}/src`;
|
|
||||||
const workspaceName = readCliConfigFile().project.name;
|
|
||||||
return {
|
|
||||||
...options,
|
|
||||||
sourceDir: 'src',
|
|
||||||
name,
|
|
||||||
fullName,
|
|
||||||
fullPath,
|
|
||||||
workspaceName
|
|
||||||
};
|
|
||||||
}
|
|
||||||
15
packages/bazel/src/collection/app/schema.d.ts
vendored
15
packages/bazel/src/collection/app/schema.d.ts
vendored
@ -1,15 +0,0 @@
|
|||||||
export interface Schema {
|
|
||||||
name: string;
|
|
||||||
skipFormat: boolean;
|
|
||||||
npmScope?: string;
|
|
||||||
directory?: string;
|
|
||||||
sourceDir?: string;
|
|
||||||
inlineStyle?: boolean;
|
|
||||||
inlineTemplate?: boolean;
|
|
||||||
viewEncapsulation?: 'Emulated' | 'Native' | 'None';
|
|
||||||
changeDetection?: 'Default' | 'OnPush';
|
|
||||||
routing?: boolean;
|
|
||||||
skipTests?: boolean;
|
|
||||||
prefix?: string;
|
|
||||||
style?: string;
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/schema",
|
|
||||||
"id": "application",
|
|
||||||
"title": "Create an application",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Application name"
|
|
||||||
},
|
|
||||||
"npmScope": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Calculated stuff"
|
|
||||||
},
|
|
||||||
"directory": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "A directory where the app is placed"
|
|
||||||
},
|
|
||||||
"inlineStyle": {
|
|
||||||
"description": "Specifies if the style will be in the ts file.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"alias": "is"
|
|
||||||
},
|
|
||||||
"inlineTemplate": {
|
|
||||||
"description": "Specifies if the template will be in the ts file.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"alias": "it"
|
|
||||||
},
|
|
||||||
"viewEncapsulation": {
|
|
||||||
"description": "Specifies the view encapsulation strategy.",
|
|
||||||
"enum": ["Emulated", "Native", "None"],
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"changeDetection": {
|
|
||||||
"description": "Specifies the change detection strategy.",
|
|
||||||
"enum": ["Default", "OnPush"],
|
|
||||||
"type": "string",
|
|
||||||
"default": "Default"
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"skipFormat": {
|
|
||||||
"description": "Skip formatting files",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"skipTests": {
|
|
||||||
"description": "Skip creating spec files.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"alias": "st"
|
|
||||||
},
|
|
||||||
"prefix": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The prefix to apply to generated selectors.",
|
|
||||||
"default": "app",
|
|
||||||
"alias": "p"
|
|
||||||
},
|
|
||||||
"style": {
|
|
||||||
"description": "The file extension to be used for style files.",
|
|
||||||
"type": "string",
|
|
||||||
"default": "css"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["name"]
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
|
||||||
import * as path from 'path';
|
|
||||||
import { Tree, VirtualTree } from '@angular-devkit/schematics';
|
|
||||||
|
|
||||||
import { readJsonInTree } from '../../utils/ast-utils';
|
|
||||||
|
|
||||||
describe('application', () => {
|
|
||||||
const schematicRunner = new SchematicTestRunner(
|
|
||||||
'@nrwl/bazel',
|
|
||||||
path.join(__dirname, '../../collection.json')
|
|
||||||
);
|
|
||||||
|
|
||||||
let appTree: Tree;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
appTree = new VirtualTree();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should generate files', () => {
|
|
||||||
const tree = schematicRunner.runSchematic(
|
|
||||||
'application',
|
|
||||||
{ name: 'myApp', directory: 'my-app' },
|
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(tree.files).toEqual([
|
|
||||||
'/my-app/BUILD.bazel',
|
|
||||||
'/my-app/README.md',
|
|
||||||
'/my-app/WORKSPACE',
|
|
||||||
'/my-app/.angular-cli.json',
|
|
||||||
'/my-app/.editorconfig',
|
|
||||||
'/my-app/.gitignore',
|
|
||||||
'/my-app/apps/.gitkeep',
|
|
||||||
'/my-app/karma.conf.js',
|
|
||||||
'/my-app/libs/.gitkeep',
|
|
||||||
'/my-app/ngc.tsconfig.json',
|
|
||||||
'/my-app/package.json',
|
|
||||||
'/my-app/protractor.conf.js',
|
|
||||||
'/my-app/test.js',
|
|
||||||
'/my-app/tools/bazel.rc',
|
|
||||||
'/my-app/tsconfig.json',
|
|
||||||
'/my-app/tsconfig.spec.json',
|
|
||||||
'/my-app/tslint.json'
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update package.json', () => {
|
|
||||||
const tree = schematicRunner.runSchematic(
|
|
||||||
'application',
|
|
||||||
{ name: 'myApp', directory: 'my-app' },
|
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const packageJson = readJsonInTree(tree, '/my-app/package.json');
|
|
||||||
|
|
||||||
expect(packageJson.devDependencies['@nrwl/schematics']).toBeDefined();
|
|
||||||
expect(packageJson.dependencies['@nrwl/nx']).toBeDefined();
|
|
||||||
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
|
||||||
expect(packageJson.dependencies['@ngrx/effects']).toBeDefined();
|
|
||||||
expect(packageJson.dependencies['@ngrx/router-store']).toBeDefined();
|
|
||||||
expect(packageJson.dependencies['@ngrx/store-devtools']).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
exports_files(["tsconfig.json"])
|
|
||||||
|
|
||||||
# NOTE: this will move to node_modules/BUILD in a later release
|
|
||||||
filegroup(
|
|
||||||
name = "node_modules",
|
|
||||||
# NB: rxjs is not in this list, because we build it from sources using the
|
|
||||||
# label @rxjs//:rxjs
|
|
||||||
srcs = glob(["/".join([
|
|
||||||
"node_modules",
|
|
||||||
pkg,
|
|
||||||
"**",
|
|
||||||
ext,
|
|
||||||
]) for pkg in [
|
|
||||||
"@angular",
|
|
||||||
"@nrwl",
|
|
||||||
"@ngrx",
|
|
||||||
"tsickle",
|
|
||||||
"tsutils",
|
|
||||||
"typescript",
|
|
||||||
"@types",
|
|
||||||
] for ext in [
|
|
||||||
"*.js",
|
|
||||||
"*.json",
|
|
||||||
"*.d.ts",
|
|
||||||
]] + [
|
|
||||||
"node_modules/http-server/**",
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
|
|
||||||
ANGULAR_TESTING = [
|
|
||||||
"node_modules/@angular/*/bundles/*-testing.umd.js",
|
|
||||||
# We use AOT, so the compiler and the dynamic platform-browser should be
|
|
||||||
# visible only in tests
|
|
||||||
"node_modules/@angular/compiler/bundles/*.umd.js",
|
|
||||||
"node_modules/@angular/platform-browser-dynamic/bundles/*.umd.js",
|
|
||||||
]
|
|
||||||
|
|
||||||
# TODO: it's messy for users to need to specify the following
|
|
||||||
# Angular dependency lists. It should live somewhere else.
|
|
||||||
# See https://github.com/angular/angular/issues/21048
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "angular_bundles",
|
|
||||||
srcs = glob(
|
|
||||||
[
|
|
||||||
"node_modules/@angular/*/bundles/*.umd.js",
|
|
||||||
|
|
||||||
"node_modules/@ngrx/store/bundles/store.umd.js",
|
|
||||||
"node_modules/@ngrx/router-store/bundles/router-store.umd.js",
|
|
||||||
"node_modules/@ngrx/effects/bundles/effects.umd.js",
|
|
||||||
|
|
||||||
"node_modules/@nrwl/nx/bundles/nrwl-nx.umd.js",
|
|
||||||
],
|
|
||||||
exclude = ANGULAR_TESTING + [
|
|
||||||
"node_modules/@angular/bazel/**/*",
|
|
||||||
"node_modules/@angular/cli/**/*",
|
|
||||||
"node_modules/@angular/compiler-cli/**/*",
|
|
||||||
"node_modules/@angular/language-service/**/*",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "angular_test_bundles",
|
|
||||||
testonly = 1,
|
|
||||||
srcs = glob(ANGULAR_TESTING),
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "angular_bootstrap_scripts",
|
|
||||||
# do not sort
|
|
||||||
srcs = [
|
|
||||||
"//:node_modules/zone.js/dist/zone.min.js",
|
|
||||||
"//:node_modules/zone.js/dist/async-test.js",
|
|
||||||
"//:node_modules/zone.js/dist/sync-test.js",
|
|
||||||
"//:node_modules/zone.js/dist/proxy.min.js",
|
|
||||||
"//:node_modules/zone.js/dist/jasmine-patch.js",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
# <%= utils.classify(name) %>
|
|
||||||
|
|
||||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) using [Nrwl Nx](https://nrwl.io/nx).
|
|
||||||
|
|
||||||
## Nrwl Extensions for Angular (Nx)
|
|
||||||
|
|
||||||
<a href="https://nrwl.io/nx"><img src="https://preview.ibb.co/mW6sdw/nx_logo.png"></a>
|
|
||||||
|
|
||||||
Nx is an open source toolkit for enterprise Angular applications.
|
|
||||||
|
|
||||||
Nx is designed to help you create and build enterprise grade Angular applications. It provides an opinionated approach to application project structure and patterns.
|
|
||||||
|
|
||||||
## Quick Start & Documentation
|
|
||||||
|
|
||||||
[Watch a 5-minute video on how to get started with Nx.](http://nrwl.io/nx)
|
|
||||||
|
|
||||||
## Generate your first application
|
|
||||||
|
|
||||||
Run `ng generate app myapp` to generate an application. When using Nx, you can create multiple applications and libraries in the same CLI workspace. Read more [here](http://nrwl.io/nx).
|
|
||||||
|
|
||||||
## Development server
|
|
||||||
|
|
||||||
Run `ng serve --app=myapp` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
|
||||||
|
|
||||||
## Code scaffolding
|
|
||||||
|
|
||||||
Run `ng generate component component-name --app=myapp` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
Run `ng build --app=myapp` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
|
||||||
|
|
||||||
## Running unit tests
|
|
||||||
|
|
||||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
||||||
|
|
||||||
## Running end-to-end tests
|
|
||||||
|
|
||||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
|
||||||
Before running the tests make sure you are serving the app via `ng serve`.
|
|
||||||
|
|
||||||
## Further help
|
|
||||||
|
|
||||||
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).
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
workspace(name = "<%= name %>")
|
|
||||||
|
|
||||||
####################################
|
|
||||||
# The Bazel buildtools repo contains tools like the BUILD file formatter, buildifier
|
|
||||||
http_archive(
|
|
||||||
name = "com_github_bazelbuild_buildtools",
|
|
||||||
sha256 = "4d8d6244320dd751590f9100cf39fd7a4b75cd901e1f3ffdfd6f048328883695",
|
|
||||||
# Note, this commit matches the version of buildifier in angular/ngcontainer
|
|
||||||
url = "https://github.com/bazelbuild/buildtools/archive/b3b620e8bcff18ed3378cd3f35ebeb7016d71f71.zip",
|
|
||||||
)
|
|
||||||
|
|
||||||
####################################
|
|
||||||
# Fetch and install the NodeJS rules
|
|
||||||
http_archive(
|
|
||||||
name = "build_bazel_rules_nodejs",
|
|
||||||
sha256 = "e9bc013417272b17f302dc169ad597f05561bb277451f010043f4da493417607",
|
|
||||||
strip_prefix = "rules_nodejs-0.4.1",
|
|
||||||
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.4.1.zip",
|
|
||||||
)
|
|
||||||
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
|
|
||||||
|
|
||||||
node_repositories(package_json = ["//:package.json"])
|
|
||||||
|
|
||||||
####################################
|
|
||||||
# Fetch and install the Sass rules
|
|
||||||
git_repository(
|
|
||||||
name = "io_bazel_rules_sass",
|
|
||||||
remote = "https://github.com/bazelbuild/rules_sass.git",
|
|
||||||
tag = "0.0.3",
|
|
||||||
)
|
|
||||||
|
|
||||||
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_repositories")
|
|
||||||
|
|
||||||
sass_repositories()
|
|
||||||
|
|
||||||
####################################
|
|
||||||
# Fetch and install the TypeScript rules
|
|
||||||
http_archive(
|
|
||||||
name = "build_bazel_rules_typescript",
|
|
||||||
sha256 = "a2c81776a4a492ff9f878f9705639f5647bef345f7f3e1da09c9eeb8dec80485",
|
|
||||||
strip_prefix = "rules_typescript-0.10.1",
|
|
||||||
url = "https://github.com/bazelbuild/rules_typescript/archive/0.10.1.zip",
|
|
||||||
)
|
|
||||||
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
|
|
||||||
|
|
||||||
ts_setup_workspace()
|
|
||||||
|
|
||||||
# Some of the TypeScript is written in Go.
|
|
||||||
# Bazel doesn't support transitive WORKSPACE deps, so we must repeat them here.
|
|
||||||
http_archive(
|
|
||||||
name = "io_bazel_rules_go",
|
|
||||||
sha256 = "4b14d8dd31c6dbaf3ff871adcd03f28c3274e42abc855cb8fb4d01233c0154dc",
|
|
||||||
url = "https://github.com/bazelbuild/rules_go/releases/download/0.10.1/rules_go-0.10.1.tar.gz",
|
|
||||||
)
|
|
||||||
|
|
||||||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
|
||||||
|
|
||||||
go_rules_dependencies()
|
|
||||||
|
|
||||||
go_register_toolchains()
|
|
||||||
|
|
||||||
####################################
|
|
||||||
# Tell Bazel about some workspaces that were installed from npm.
|
|
||||||
local_repository(
|
|
||||||
name = "angular",
|
|
||||||
path = "node_modules/@angular/bazel",
|
|
||||||
)
|
|
||||||
|
|
||||||
local_repository(
|
|
||||||
name = "rxjs",
|
|
||||||
path = "node_modules/rxjs/src",
|
|
||||||
)
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "<%= angularCliSchema %>",
|
|
||||||
"project": {
|
|
||||||
"name": "<%= utils.dasherize(name) %>",
|
|
||||||
"npmScope": "<%= npmScope %>",
|
|
||||||
"latestMigration": "<%= latestMigration %>"
|
|
||||||
},
|
|
||||||
"e2e": {
|
|
||||||
"protractor": {
|
|
||||||
"config": "./protractor.conf.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": [
|
|
||||||
{
|
|
||||||
"project": "./tsconfig.spec.json",
|
|
||||||
"exclude": "**/node_modules/**"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"test": {
|
|
||||||
"karma": {
|
|
||||||
"config": "./karma.conf.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"apps": [
|
|
||||||
{
|
|
||||||
"name": "$workspaceRoot",
|
|
||||||
"root": ".",
|
|
||||||
"appRoot": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"defaults": {
|
|
||||||
"schematics": {
|
|
||||||
"collection": "@nrwl/bazel"
|
|
||||||
},
|
|
||||||
"styleExt": "<%= style %>",<% if (!minimal) { %>
|
|
||||||
"component": {}<% } else { %>
|
|
||||||
"component": {
|
|
||||||
"spec": false,
|
|
||||||
"inlineStyle": true,
|
|
||||||
"inlineTemplate": true
|
|
||||||
},
|
|
||||||
"directive": {
|
|
||||||
"spec": false
|
|
||||||
},
|
|
||||||
"class": {
|
|
||||||
"spec": false
|
|
||||||
},
|
|
||||||
"guard": {
|
|
||||||
"spec": false
|
|
||||||
},
|
|
||||||
"module": {
|
|
||||||
"spec": false
|
|
||||||
},
|
|
||||||
"pipe": {
|
|
||||||
"spec": false
|
|
||||||
},
|
|
||||||
"service": {
|
|
||||||
"spec": false
|
|
||||||
} <% } %>
|
|
||||||
},
|
|
||||||
"warnings": {
|
|
||||||
"typescriptMismatch": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
# Editor configuration, see http://editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
max_line_length = off
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# compiled output
|
|
||||||
/dist
|
|
||||||
/tmp
|
|
||||||
/out-tsc
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
|
|
||||||
# IDEs and editors
|
|
||||||
/.idea
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
.c9/
|
|
||||||
*.launch
|
|
||||||
.settings/
|
|
||||||
*.sublime-workspace
|
|
||||||
|
|
||||||
# IDE - VSCode
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/.sass-cache
|
|
||||||
/connect.lock
|
|
||||||
/coverage
|
|
||||||
/libpeerconnection.log
|
|
||||||
npm-debug.log
|
|
||||||
testem.log
|
|
||||||
/typings
|
|
||||||
|
|
||||||
# e2e
|
|
||||||
/e2e/*.js
|
|
||||||
/e2e/*.map
|
|
||||||
|
|
||||||
# System Files
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
@ -1 +0,0 @@
|
|||||||
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
// Karma configuration file, see link for more information
|
|
||||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
|
||||||
|
|
||||||
const { makeSureNoAppIsSelected } = require('@nrwl/schematics/src/utils/cli-config-utils');
|
|
||||||
// Nx only supports running unit tests for all apps and libs.
|
|
||||||
makeSureNoAppIsSelected();
|
|
||||||
|
|
||||||
module.exports = function (config) {
|
|
||||||
config.set({
|
|
||||||
basePath: '',
|
|
||||||
frameworks: ['jasmine', '@angular/cli'],
|
|
||||||
plugins: [
|
|
||||||
require('karma-jasmine'),
|
|
||||||
require('karma-chrome-launcher'),
|
|
||||||
require('karma-jasmine-html-reporter'),
|
|
||||||
require('karma-coverage-istanbul-reporter'),
|
|
||||||
require('@angular/cli/plugins/karma')
|
|
||||||
],
|
|
||||||
client:{
|
|
||||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
|
||||||
},
|
|
||||||
coverageIstanbulReporter: {
|
|
||||||
reports: [ 'html', 'lcovonly' ],
|
|
||||||
fixWebpackSourcePaths: true
|
|
||||||
},
|
|
||||||
angularCli: {
|
|
||||||
environment: 'dev'
|
|
||||||
},
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
|
||||||
port: 9876,
|
|
||||||
colors: true,
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
autoWatch: true,
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
singleRun: false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
// WORKAROUND https://github.com/angular/angular/issues/18810
|
|
||||||
// This file is required to run ngc on angular libraries, to write files like
|
|
||||||
// node_modules/@angular/core/core.ngsummary.json
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": [
|
|
||||||
"dom",
|
|
||||||
"es2015"
|
|
||||||
],
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"types": []
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"node_modules/@angular/**/*",
|
|
||||||
"node_modules/@nrwl/**/*",
|
|
||||||
"node_modules/@ngrx/**/*",
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules/@angular/bazel/**",
|
|
||||||
"node_modules/@angular/router/**",
|
|
||||||
"node_modules/@angular/cli/**",
|
|
||||||
"node_modules/@angular/compiler-cli/**",
|
|
||||||
"node_modules/@angular/tsc-wrapped/**",
|
|
||||||
"node_modules/@nrwl/bazel/**",
|
|
||||||
"node_modules/@nrwl/schematics/**",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "<%= utils.dasherize(name) %>",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"scripts": {
|
|
||||||
"ng": "ng",
|
|
||||||
"start": "ng serve",
|
|
||||||
"build": "ng build",
|
|
||||||
"test": "ng test",
|
|
||||||
"lint": "ng lint",
|
|
||||||
"e2e": "ng e2e",
|
|
||||||
"affected:apps": "./node_modules/.bin/nx affected:apps",
|
|
||||||
"affected:build": "./node_modules/.bin/nx affected:build",
|
|
||||||
"affected:e2e": "./node_modules/.bin/nx affected:e2e",
|
|
||||||
"affected:dep-graph": "./node_modules/.bin/nx affected:dep-graph",
|
|
||||||
"format": "./node_modules/.bin/nx format:write",
|
|
||||||
"format:write": "./node_modules/.bin/nx format:write",
|
|
||||||
"format:check": "./node_modules/.bin/nx format:check",
|
|
||||||
"update": "./node_modules/.bin/nx update",
|
|
||||||
"update:check": "./node_modules/.bin/nx update:check",
|
|
||||||
"update:skip": "./node_modules/.bin/nx update:skip",
|
|
||||||
"dep-graph": "./node_modules/.bin/nx dep-graph",
|
|
||||||
"postinstall": "ngc -p ngc.tsconfig.json"
|
|
||||||
},
|
|
||||||
"private": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@angular/animations": "<%= angularVersion %>",
|
|
||||||
"@angular/bazel": "angular/bazel-builds#d09df98b39658463fdfe3567b25a20cdd7130661",
|
|
||||||
"@angular/common": "<%= angularVersion %>",
|
|
||||||
"@angular/compiler": "<%= angularVersion %>",
|
|
||||||
"@angular/core": "<%= angularVersion %>",
|
|
||||||
"@angular/forms": "<%= angularVersion %>",
|
|
||||||
"@angular/platform-browser": "<%= angularVersion %>",
|
|
||||||
"@angular/platform-browser-dynamic": "<%= angularVersion %>",
|
|
||||||
"@angular/router": "<%= angularVersion %>",
|
|
||||||
"concurrently": "3.5.1",
|
|
||||||
"core-js": "^2.4.1",
|
|
||||||
"rxjs": "<%= rxjsVersion %>",
|
|
||||||
"zone.js": "^0.8.19",
|
|
||||||
"@nrwl/nx": "<%= nxVersion %>",
|
|
||||||
"@ngrx/effects": "<%= ngrxVersion %>",
|
|
||||||
"@ngrx/router-store": "<%= ngrxVersion %>",
|
|
||||||
"@ngrx/store": "<%= ngrxVersion %>",
|
|
||||||
"@ngrx/store-devtools": "<%= ngrxVersion %>"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@angular/cli": "<%= angularCliVersion %>",
|
|
||||||
"@angular/compiler-cli": "<%= angularVersion %>",
|
|
||||||
"@nrwl/schematics": "<%= schematicsVersion %>",
|
|
||||||
"@nrwl/bazel": "<%= schematicsVersion %>",
|
|
||||||
"@angular/language-service": "<%= angularVersion %>",
|
|
||||||
"@bazel/ibazel": "^0.3.1",<% if (!minimal) { %>
|
|
||||||
"@types/jasmine": "~2.8.3",
|
|
||||||
"@types/jasminewd2": "~2.0.2",
|
|
||||||
"@types/node": "~6.0.60",
|
|
||||||
"codelyzer": "^4.0.1",
|
|
||||||
"jasmine-core": "~2.8.0",
|
|
||||||
"jasmine-spec-reporter": "~4.2.1",
|
|
||||||
"karma": "~2.0.0",
|
|
||||||
"karma-chrome-launcher": "~2.2.0",
|
|
||||||
"karma-coverage-istanbul-reporter": "^1.2.1",
|
|
||||||
"karma-jasmine": "~1.1.0",
|
|
||||||
"karma-jasmine-html-reporter": "^0.2.2",
|
|
||||||
"protractor": "~5.1.2",
|
|
||||||
"ts-node": "~4.1.0",
|
|
||||||
"tslint": "~5.9.1",<%
|
|
||||||
} %>
|
|
||||||
"typescript": "<%= typescriptVersion %>",
|
|
||||||
"prettier": "<%= prettierVersion %>",
|
|
||||||
"http-server": "0.11.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
// Protractor configuration file, see link for more information
|
|
||||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
|
||||||
|
|
||||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
|
||||||
const { getAppDirectoryUsingCliConfig } = require('@nrwl/schematics/src/utils/cli-config-utils');
|
|
||||||
const appDir = getAppDirectoryUsingCliConfig();
|
|
||||||
|
|
||||||
exports.config = {
|
|
||||||
allScriptsTimeout: 11000,
|
|
||||||
specs: [
|
|
||||||
appDir + '/e2e/**/*.e2e-spec.ts'
|
|
||||||
],
|
|
||||||
capabilities: {
|
|
||||||
'browserName': 'chrome'
|
|
||||||
},
|
|
||||||
directConnect: true,
|
|
||||||
baseUrl: 'http://localhost:8080/',
|
|
||||||
framework: 'jasmine',
|
|
||||||
jasmineNodeOpts: {
|
|
||||||
showColors: true,
|
|
||||||
defaultTimeoutInterval: 30000,
|
|
||||||
print: function() {}
|
|
||||||
},
|
|
||||||
onPrepare() {
|
|
||||||
require('ts-node').register({
|
|
||||||
project: appDir + '/e2e/tsconfig.e2e.json'
|
|
||||||
});
|
|
||||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
|
||||||
require('zone.js/dist/zone-testing');
|
|
||||||
const getTestBed = require('@angular/core/testing').getTestBed;
|
|
||||||
const BrowserDynamicTestingModule = require('@angular/platform-browser-dynamic/testing').BrowserDynamicTestingModule;
|
|
||||||
const platformBrowserDynamicTesting = require('@angular/platform-browser-dynamic/testing').platformBrowserDynamicTesting;
|
|
||||||
|
|
||||||
// Prevent Karma from running prematurely.
|
|
||||||
__karma__.loaded = function () {};
|
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
|
||||||
getTestBed().initTestEnvironment(
|
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting()
|
|
||||||
);
|
|
||||||
// Then we find all the tests.
|
|
||||||
const contextApps = require.context('./apps', true, /\.spec\.ts$/);
|
|
||||||
// And load the modules.
|
|
||||||
contextApps.keys().map(contextApps);
|
|
||||||
|
|
||||||
const contextLibs = require.context('./libs', true, /\.spec\.ts$/);
|
|
||||||
// And load the modules.
|
|
||||||
contextLibs.keys().map(contextLibs);
|
|
||||||
|
|
||||||
// Finally, start Karma to run the tests.
|
|
||||||
__karma__.start();
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# Make TypeScript compilation fast, by keeping a few copies of the compiler
|
|
||||||
# running as daemons, and cache SourceFile AST's to reduce parse time.
|
|
||||||
build --strategy=TypeScriptCompile=worker
|
|
||||||
|
|
||||||
# Don't create bazel-* symlinks in the WORKSPACE directory.
|
|
||||||
# These require .gitignore and may scare users.
|
|
||||||
# Also, it's a workaround for https://github.com/bazelbuild/rules_typescript/issues/12
|
|
||||||
# which affects the common case of having `tsconfig.json` in the WORKSPACE directory.
|
|
||||||
#
|
|
||||||
# Instead, you should run `bazel info bazel-bin` to find out where the outputs went.
|
|
||||||
build --symlink_prefix=dist/
|
|
||||||
|
|
||||||
test --test_output=errors
|
|
||||||
|
|
||||||
# Workaround https://github.com/bazelbuild/bazel/issues/3645
|
|
||||||
# Limit Bazel to consuming 3072K of RAM
|
|
||||||
build:ci --local_resources=3072,2.0,1.0
|
|
||||||
|
|
||||||
build:ci --noshow_progress
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"compileOnSave": false,
|
|
||||||
"compilerOptions": {
|
|
||||||
"sourceMap": true,
|
|
||||||
"declaration": false,
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"target": "es5",
|
|
||||||
"lib": [
|
|
||||||
"es2017",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "./dist/out-tsc/spec",
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es5",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"**/*.ts"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/e2e/*.ts",
|
|
||||||
"**/*.e2e-spec.ts",
|
|
||||||
"**/*.po.ts",
|
|
||||||
"node_modules",
|
|
||||||
"tmp"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
{
|
|
||||||
"rulesDirectory": [
|
|
||||||
"node_modules/codelyzer",
|
|
||||||
"node_modules/@nrwl/schematics/src/tslint"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"arrow-return-shorthand": true,
|
|
||||||
"callable-types": true,
|
|
||||||
"class-name": true,
|
|
||||||
"forin": true,
|
|
||||||
"deprecation": {
|
|
||||||
"severity": "warn"
|
|
||||||
},
|
|
||||||
"import-blacklist": [
|
|
||||||
true,
|
|
||||||
"rxjs",
|
|
||||||
"rxjs/Rx"
|
|
||||||
],
|
|
||||||
"interface-over-type-literal": true,
|
|
||||||
"member-access": false,
|
|
||||||
"member-ordering": [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"order": [
|
|
||||||
"static-field",
|
|
||||||
"instance-field",
|
|
||||||
"static-method",
|
|
||||||
"instance-method"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-arg": true,
|
|
||||||
"no-bitwise": true,
|
|
||||||
"no-console": [
|
|
||||||
true,
|
|
||||||
"debug",
|
|
||||||
"info",
|
|
||||||
"time",
|
|
||||||
"timeEnd",
|
|
||||||
"trace"
|
|
||||||
],
|
|
||||||
"no-construct": true,
|
|
||||||
"no-debugger": true,
|
|
||||||
"no-duplicate-super": true,
|
|
||||||
"no-empty": false,
|
|
||||||
"no-empty-interface": true,
|
|
||||||
"no-eval": true,
|
|
||||||
"no-inferrable-types": [
|
|
||||||
true,
|
|
||||||
"ignore-params"
|
|
||||||
],
|
|
||||||
"no-misused-new": true,
|
|
||||||
"no-non-null-assertion": true,
|
|
||||||
"no-shadowed-variable": true,
|
|
||||||
"no-string-literal": false,
|
|
||||||
"no-string-throw": true,
|
|
||||||
"no-switch-case-fall-through": true,
|
|
||||||
"no-unnecessary-initializer": true,
|
|
||||||
"no-unused-expression": true,
|
|
||||||
"no-use-before-declare": true,
|
|
||||||
"no-var-keyword": true,
|
|
||||||
"object-literal-sort-keys": false,
|
|
||||||
"prefer-const": true,
|
|
||||||
"radix": true,
|
|
||||||
"triple-equals": [
|
|
||||||
true,
|
|
||||||
"allow-null-check"
|
|
||||||
],
|
|
||||||
"unified-signatures": true,
|
|
||||||
"variable-name": false,
|
|
||||||
"directive-selector": [
|
|
||||||
true,
|
|
||||||
"attribute",
|
|
||||||
"app",
|
|
||||||
"camelCase"
|
|
||||||
],
|
|
||||||
"component-selector": [
|
|
||||||
true,
|
|
||||||
"element",
|
|
||||||
"app",
|
|
||||||
"kebab-case"
|
|
||||||
],
|
|
||||||
"no-output-on-prefix": true,
|
|
||||||
"use-input-property-decorator": true,
|
|
||||||
"use-output-property-decorator": true,
|
|
||||||
"use-host-property-decorator": true,
|
|
||||||
"no-input-rename": true,
|
|
||||||
"no-output-rename": true,
|
|
||||||
"use-life-cycle-interface": true,
|
|
||||||
"use-pipe-transform-interface": true,
|
|
||||||
"component-class-suffix": true,
|
|
||||||
"directive-class-suffix": true,
|
|
||||||
|
|
||||||
"nx-enforce-module-boundaries": [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"lazyLoad": [],
|
|
||||||
"allow": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
import {
|
|
||||||
apply,
|
|
||||||
branchAndMerge,
|
|
||||||
chain,
|
|
||||||
mergeWith,
|
|
||||||
Rule,
|
|
||||||
SchematicContext,
|
|
||||||
template,
|
|
||||||
Tree,
|
|
||||||
url
|
|
||||||
} from '@angular-devkit/schematics';
|
|
||||||
import { Schema } from './schema';
|
|
||||||
import { strings } from '@angular-devkit/core';
|
|
||||||
import {
|
|
||||||
NodePackageInstallTask,
|
|
||||||
RepositoryInitializerTask
|
|
||||||
} from '@angular-devkit/schematics/tasks';
|
|
||||||
import { libVersions } from '../../lib-versions';
|
|
||||||
|
|
||||||
export default function(options: Schema): Rule {
|
|
||||||
if (!/^\w+$/.test(options.name)) {
|
|
||||||
throw new Error(
|
|
||||||
`${options.name} is invalid for a bazel workspace.\n` +
|
|
||||||
'Your workspace name must contain only alphanumeric characters and underscores.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (host: Tree, context: SchematicContext) => {
|
|
||||||
addTasks(options, context);
|
|
||||||
const npmScope = options.npmScope ? options.npmScope : options.name;
|
|
||||||
const templateSource = apply(url('./files'), [
|
|
||||||
template({
|
|
||||||
utils: strings,
|
|
||||||
dot: '.',
|
|
||||||
...libVersions,
|
|
||||||
...(options as object),
|
|
||||||
npmScope
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
return chain([branchAndMerge(chain([mergeWith(templateSource)]))])(
|
|
||||||
host,
|
|
||||||
context
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function addTasks(options: Schema, context: SchematicContext) {
|
|
||||||
let packageTask;
|
|
||||||
if (!options.skipInstall) {
|
|
||||||
packageTask = context.addTask(
|
|
||||||
new NodePackageInstallTask(options.directory)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!options.skipGit) {
|
|
||||||
context.addTask(
|
|
||||||
new RepositoryInitializerTask(options.directory, options.commit),
|
|
||||||
packageTask ? [packageTask] : []
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
export interface Schema {
|
|
||||||
name: string;
|
|
||||||
directory: string;
|
|
||||||
npmScope?: string;
|
|
||||||
prefix?: string;
|
|
||||||
style?: string;
|
|
||||||
minimal?: boolean;
|
|
||||||
skipInstall?: boolean;
|
|
||||||
commit?: { name: string; email: string; message?: string };
|
|
||||||
skipGit?: boolean;
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/schema",
|
|
||||||
"id": "workspace",
|
|
||||||
"title": "Create an empty workspace",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Workspace name"
|
|
||||||
},
|
|
||||||
"directory": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The directory name to create the app in.",
|
|
||||||
"alias": "dir"
|
|
||||||
},
|
|
||||||
"npmScope": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Npm scope for importing libs."
|
|
||||||
},
|
|
||||||
"skipInstall": {
|
|
||||||
"description": "Skip installing dependency packages.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"skipGit": {
|
|
||||||
"description": "Skip initializing a git repository.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"alias": "sg"
|
|
||||||
},
|
|
||||||
"commit": {
|
|
||||||
"description": "Initial repository commit information.",
|
|
||||||
"default": null,
|
|
||||||
"oneOf": [
|
|
||||||
{ "type": "null" },
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"email": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "email"
|
|
||||||
},
|
|
||||||
"message": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["name", "email"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"prefix": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The prefix to apply to generated selectors.",
|
|
||||||
"default": "app",
|
|
||||||
"alias": "p"
|
|
||||||
},
|
|
||||||
"style": {
|
|
||||||
"description": "The file extension to be used for style files.",
|
|
||||||
"type": "string",
|
|
||||||
"default": "css"
|
|
||||||
},
|
|
||||||
"minimal": {
|
|
||||||
"description": "Should create a minimal app.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["name", "directory"]
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
# TODO: Make this private when we can import from the root index.ts
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load("@angular//:index.bzl", "ng_module")
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_web_test")
|
|
||||||
|
|
||||||
ng_module(
|
|
||||||
name = "<%= sourceDir %>",
|
|
||||||
srcs = glob(
|
|
||||||
["*.ts"],
|
|
||||||
exclude = ["*.spec.ts"],
|
|
||||||
),
|
|
||||||
deps = [
|
|
||||||
"@rxjs",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ts_library(
|
|
||||||
name = "test_lib",
|
|
||||||
testonly = 1,
|
|
||||||
srcs = glob(["*.spec.ts"]),
|
|
||||||
deps = [
|
|
||||||
":<%= sourceDir %>",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ts_web_test(
|
|
||||||
name = "test",
|
|
||||||
bootstrap = ["//:angular_bootstrap_scripts"],
|
|
||||||
deps = [
|
|
||||||
":test_lib",
|
|
||||||
"//:angular_bundles",
|
|
||||||
"//:angular_test_bundles",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { <%= className %> } from './<%=fileName%>';
|
|
||||||
|
|
||||||
describe('<%= className %>', () => {
|
|
||||||
it('should work', () => {
|
|
||||||
expect(new <%= className %>()).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
export class <%= className %> {
|
|
||||||
}
|
|
||||||
@ -1,289 +0,0 @@
|
|||||||
import {
|
|
||||||
apply,
|
|
||||||
branchAndMerge,
|
|
||||||
chain,
|
|
||||||
mergeWith,
|
|
||||||
noop,
|
|
||||||
Rule,
|
|
||||||
template,
|
|
||||||
Tree,
|
|
||||||
url
|
|
||||||
} from '@angular-devkit/schematics';
|
|
||||||
import { insertImport } from '@schematics/angular/utility/ast-utils';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as ts from 'typescript';
|
|
||||||
|
|
||||||
import {
|
|
||||||
addGlobal,
|
|
||||||
addImportToModule,
|
|
||||||
addIncludeToTsConfig,
|
|
||||||
addReexport,
|
|
||||||
addRoute,
|
|
||||||
getAngularCliConfig,
|
|
||||||
insert
|
|
||||||
} from '../../utils/ast-utils';
|
|
||||||
import { offsetFromRoot } from '../../utils/common';
|
|
||||||
import {
|
|
||||||
names,
|
|
||||||
toClassName,
|
|
||||||
toFileName,
|
|
||||||
toPropertyName
|
|
||||||
} from '../../utils/name-utils';
|
|
||||||
import { Schema } from './schema';
|
|
||||||
import { formatFiles } from '../../utils/rules/format-files';
|
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
|
||||||
name: string;
|
|
||||||
fullName: string;
|
|
||||||
fullPath: string;
|
|
||||||
tags?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeOptions(options: Schema): NormalizedSchema {
|
|
||||||
const name = toFileName(options.name);
|
|
||||||
const fullName = options.directory
|
|
||||||
? `${toFileName(options.directory)}/${name}`
|
|
||||||
: name;
|
|
||||||
const fullPath = `libs/${fullName}/src`;
|
|
||||||
return { ...options, sourceDir: 'src', name, fullName, fullPath };
|
|
||||||
}
|
|
||||||
|
|
||||||
function addLazyLoadedRouterConfiguration(modulePath: string): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const moduleSource = host.read(modulePath)!.toString('utf-8');
|
|
||||||
const sourceFile = ts.createSourceFile(
|
|
||||||
modulePath,
|
|
||||||
moduleSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
insert(host, modulePath, [
|
|
||||||
insertImport(sourceFile, modulePath, 'RouterModule', '@angular/router'),
|
|
||||||
...addImportToModule(
|
|
||||||
sourceFile,
|
|
||||||
modulePath,
|
|
||||||
`
|
|
||||||
RouterModule.forChild([
|
|
||||||
/* {path: '', pathMatch: 'full', component: InsertYourComponentHere} */
|
|
||||||
]) `
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function addRouterConfiguration(
|
|
||||||
schema: NormalizedSchema,
|
|
||||||
indexFilePath: string,
|
|
||||||
moduleFileName: string,
|
|
||||||
modulePath: string
|
|
||||||
): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const indexSource = host.read(indexFilePath)!.toString('utf-8');
|
|
||||||
const indexSourceFile = ts.createSourceFile(
|
|
||||||
indexFilePath,
|
|
||||||
indexSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
const moduleSource = host.read(modulePath)!.toString('utf-8');
|
|
||||||
const moduleSourceFile = ts.createSourceFile(
|
|
||||||
modulePath,
|
|
||||||
moduleSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
const constName = `${toPropertyName(schema.name)}Routes`;
|
|
||||||
|
|
||||||
insert(host, modulePath, [
|
|
||||||
insertImport(
|
|
||||||
moduleSourceFile,
|
|
||||||
modulePath,
|
|
||||||
'RouterModule, Route',
|
|
||||||
'@angular/router'
|
|
||||||
),
|
|
||||||
...addImportToModule(moduleSourceFile, modulePath, `RouterModule`),
|
|
||||||
...addGlobal(
|
|
||||||
moduleSourceFile,
|
|
||||||
modulePath,
|
|
||||||
`export const ${constName}: Route[] = [];`
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
insert(host, indexFilePath, [
|
|
||||||
...addReexport(indexSourceFile, indexFilePath, moduleFileName, constName)
|
|
||||||
]);
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function addLoadChildren(schema: NormalizedSchema): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const json = getAngularCliConfig(host);
|
|
||||||
|
|
||||||
const moduleSource = host.read(schema.parentModule)!.toString('utf-8');
|
|
||||||
const sourceFile = ts.createSourceFile(
|
|
||||||
schema.parentModule,
|
|
||||||
moduleSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
const loadChildren = `@${json.project.npmScope}/${toFileName(
|
|
||||||
schema.fullName
|
|
||||||
)}#${toClassName(schema.name)}Module`;
|
|
||||||
insert(host, schema.parentModule, [
|
|
||||||
...addRoute(
|
|
||||||
schema.parentModule,
|
|
||||||
sourceFile,
|
|
||||||
`{path: '${toFileName(schema.name)}', loadChildren: '${loadChildren}'}`
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
|
|
||||||
const tsConfig = findClosestTsConfigApp(host, schema.parentModule);
|
|
||||||
if (tsConfig) {
|
|
||||||
const tsConfigAppSource = host.read(tsConfig)!.toString('utf-8');
|
|
||||||
const tsConfigAppFile = ts.createSourceFile(
|
|
||||||
tsConfig,
|
|
||||||
tsConfigAppSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
const offset = offsetFromRoot(path.dirname(tsConfig));
|
|
||||||
insert(host, tsConfig, [
|
|
||||||
...addIncludeToTsConfig(
|
|
||||||
tsConfig,
|
|
||||||
tsConfigAppFile,
|
|
||||||
`\n , "${offset}libs/${schema.fullName}/index.ts"\n`
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
|
|
||||||
const e2e = `${path.dirname(
|
|
||||||
path.dirname(tsConfig)
|
|
||||||
)}/e2e/tsconfig.e2e.json`;
|
|
||||||
if (host.exists(e2e)) {
|
|
||||||
const tsConfigE2ESource = host.read(e2e)!.toString('utf-8');
|
|
||||||
const tsConfigE2EFile = ts.createSourceFile(
|
|
||||||
e2e,
|
|
||||||
tsConfigE2ESource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
insert(host, e2e, [
|
|
||||||
...addIncludeToTsConfig(
|
|
||||||
e2e,
|
|
||||||
tsConfigE2EFile,
|
|
||||||
`\n , "${offset}libs/${schema.fullName}/index.ts"\n`
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// we should warn the user about not finding the config
|
|
||||||
}
|
|
||||||
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function findClosestTsConfigApp(
|
|
||||||
host: Tree,
|
|
||||||
parentModule: string
|
|
||||||
): string | null {
|
|
||||||
const dir = path.parse(parentModule).dir;
|
|
||||||
if (host.exists(`${dir}/tsconfig.app.json`)) {
|
|
||||||
return `${dir}/tsconfig.app.json`;
|
|
||||||
} else if (dir != '') {
|
|
||||||
return findClosestTsConfigApp(host, dir);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addChildren(schema: NormalizedSchema): Rule {
|
|
||||||
return (host: Tree) => {
|
|
||||||
const json = getAngularCliConfig(host);
|
|
||||||
|
|
||||||
const moduleSource = host.read(schema.parentModule)!.toString('utf-8');
|
|
||||||
const sourceFile = ts.createSourceFile(
|
|
||||||
schema.parentModule,
|
|
||||||
moduleSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
const constName = `${toPropertyName(schema.name)}Routes`;
|
|
||||||
const importPath = `@${json.project.npmScope}/${toFileName(
|
|
||||||
schema.fullName
|
|
||||||
)}`;
|
|
||||||
|
|
||||||
insert(host, schema.parentModule, [
|
|
||||||
insertImport(sourceFile, schema.parentModule, constName, importPath),
|
|
||||||
...addRoute(
|
|
||||||
schema.parentModule,
|
|
||||||
sourceFile,
|
|
||||||
`{path: '${toFileName(schema.name)}', children: ${constName}}`
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateLibSchema(schema) {
|
|
||||||
const options = normalizeOptions(schema);
|
|
||||||
const moduleFileName = `${toFileName(options.name)}.module`;
|
|
||||||
const modulePath = `${options.fullPath}/${moduleFileName}.ts`;
|
|
||||||
const indexFile = `libs/${toFileName(options.fullName)}/index.ts`;
|
|
||||||
|
|
||||||
if (options.routing && options.nomodule) {
|
|
||||||
throw new Error(`nomodule and routing cannot be used together`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options.routing && options.lazy) {
|
|
||||||
throw new Error(`routing must be set`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const routingRules: Array<Rule> = [
|
|
||||||
options.routing && options.lazy
|
|
||||||
? addLazyLoadedRouterConfiguration(modulePath)
|
|
||||||
: noop(),
|
|
||||||
options.routing && options.lazy && options.parentModule
|
|
||||||
? addLoadChildren(options)
|
|
||||||
: noop(),
|
|
||||||
|
|
||||||
options.routing && !options.lazy
|
|
||||||
? addRouterConfiguration(options, indexFile, moduleFileName, modulePath)
|
|
||||||
: noop(),
|
|
||||||
options.routing && !options.lazy && options.parentModule
|
|
||||||
? addChildren(options)
|
|
||||||
: noop()
|
|
||||||
];
|
|
||||||
|
|
||||||
const templateSource = apply(
|
|
||||||
url(options.nomodule ? './files' : './ngfiles'),
|
|
||||||
[
|
|
||||||
template({
|
|
||||||
...names(options.name),
|
|
||||||
dot: '.',
|
|
||||||
tmpl: '',
|
|
||||||
...(options as object)
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
options,
|
|
||||||
moduleFileName,
|
|
||||||
modulePath,
|
|
||||||
indexFile,
|
|
||||||
templateSource,
|
|
||||||
routingRules
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function(schema: Schema): Rule {
|
|
||||||
const { templateSource, routingRules } = validateLibSchema(schema);
|
|
||||||
|
|
||||||
return chain([
|
|
||||||
branchAndMerge(chain([mergeWith(templateSource)])),
|
|
||||||
...routingRules,
|
|
||||||
formatFiles(schema)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
# TODO: Make this private when we can import from the root index.ts
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load("@angular//:index.bzl", "ng_module")
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_web_test")
|
|
||||||
|
|
||||||
ng_module(
|
|
||||||
name = "<%= sourceDir %>",
|
|
||||||
srcs = glob(
|
|
||||||
["*.ts"],
|
|
||||||
exclude = ["*.spec.ts"],
|
|
||||||
),
|
|
||||||
deps = [
|
|
||||||
"@rxjs",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ts_library(
|
|
||||||
name = "test_lib",
|
|
||||||
testonly = 1,
|
|
||||||
srcs = glob(["*.spec.ts"]),
|
|
||||||
deps = [
|
|
||||||
":<%= sourceDir %>",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ts_web_test(
|
|
||||||
name = "test",
|
|
||||||
bootstrap = ["//:angular_bootstrap_scripts"],
|
|
||||||
deps = [
|
|
||||||
":test_lib",
|
|
||||||
"//:angular_bundles",
|
|
||||||
"//:angular_test_bundles",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { <%= className %>Module } from './<%=fileName%>.module';
|
|
||||||
|
|
||||||
describe('<%= className %>Module', () => {
|
|
||||||
it('should work', () => {
|
|
||||||
expect(new <%= className %>Module()).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [CommonModule]
|
|
||||||
})
|
|
||||||
export class <%= className %>Module {
|
|
||||||
}
|
|
||||||
15
packages/bazel/src/collection/lib/schema.d.ts
vendored
15
packages/bazel/src/collection/lib/schema.d.ts
vendored
@ -1,15 +0,0 @@
|
|||||||
export interface Schema {
|
|
||||||
name: string;
|
|
||||||
skipFormat: boolean;
|
|
||||||
directory?: string;
|
|
||||||
sourceDir?: string;
|
|
||||||
nomodule: boolean;
|
|
||||||
|
|
||||||
spec?: boolean;
|
|
||||||
flat?: boolean;
|
|
||||||
commonModule?: boolean;
|
|
||||||
|
|
||||||
routing?: boolean;
|
|
||||||
lazy?: boolean;
|
|
||||||
parentModule?: string;
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/schema",
|
|
||||||
"id": "library",
|
|
||||||
"title": "Create a library",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Library name"
|
|
||||||
},
|
|
||||||
"directory": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "A directory where the app is placed"
|
|
||||||
},
|
|
||||||
"nomodule": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Generate a simple TS library when set to true."
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Add router configuration. See lazy for more information."
|
|
||||||
},
|
|
||||||
"skipFormat": {
|
|
||||||
"description": "Skip formatting files",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"lazy": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Add RouterModule.forChild when set to true, and a simple array of routes when set to false."
|
|
||||||
},
|
|
||||||
"parentModule": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["name"]
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load("@angular//:index.bzl", "ng_module")
|
|
||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
|
|
||||||
|
|
||||||
ng_module(
|
|
||||||
name = "<%= dasherize(name) %>",
|
|
||||||
srcs = glob(
|
|
||||||
["*.ts"],
|
|
||||||
exclude = ["*.spec.ts"],
|
|
||||||
),
|
|
||||||
deps = [
|
|
||||||
"@rxjs",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ts_library(
|
|
||||||
name = "test_lib",
|
|
||||||
testonly = 1,
|
|
||||||
srcs = glob(["*.spec.ts"]),
|
|
||||||
deps = [
|
|
||||||
":<%= dasherize(name) %>",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import { normalize, strings } from '@angular-devkit/core';
|
|
||||||
import {
|
|
||||||
apply,
|
|
||||||
branchAndMerge,
|
|
||||||
chain,
|
|
||||||
externalSchematic,
|
|
||||||
mergeWith,
|
|
||||||
move,
|
|
||||||
Rule,
|
|
||||||
SchematicContext,
|
|
||||||
SchematicsException,
|
|
||||||
template,
|
|
||||||
Tree,
|
|
||||||
url,
|
|
||||||
TaskConfigurationGenerator,
|
|
||||||
TaskConfiguration
|
|
||||||
} from '@angular-devkit/schematics';
|
|
||||||
|
|
||||||
import { Schema } from './schema';
|
|
||||||
import { formatFiles } from '../../utils/rules/format-files';
|
|
||||||
|
|
||||||
export default function(schema: Schema): Rule {
|
|
||||||
schema.path = schema.path ? normalize(schema.path) : schema.path;
|
|
||||||
const sourceDir = schema.sourceDir;
|
|
||||||
if (!sourceDir) {
|
|
||||||
throw new SchematicsException(`sourceDir option is required.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const templateSource = apply(url('./files'), [
|
|
||||||
template({
|
|
||||||
...strings,
|
|
||||||
'if-flat': (s: string) => (schema.flat ? '' : s),
|
|
||||||
...schema
|
|
||||||
}),
|
|
||||||
move(sourceDir)
|
|
||||||
]);
|
|
||||||
|
|
||||||
return chain([
|
|
||||||
branchAndMerge(chain([mergeWith(templateSource)])),
|
|
||||||
externalSchematic('@schematics/angular', 'module', schema),
|
|
||||||
formatFiles(schema)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
55
packages/bazel/src/collection/module/schema.d.ts
vendored
55
packages/bazel/src/collection/module/schema.d.ts
vendored
@ -1,55 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface Schema {
|
|
||||||
/**
|
|
||||||
* The name of the module.
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Skip formatting of files
|
|
||||||
*/
|
|
||||||
skipFormat: boolean;
|
|
||||||
/**
|
|
||||||
* The path to create the module.
|
|
||||||
*/
|
|
||||||
path?: string;
|
|
||||||
/**
|
|
||||||
* The path of the source directory.
|
|
||||||
*/
|
|
||||||
sourceDir?: string;
|
|
||||||
/**
|
|
||||||
* The root of the application.
|
|
||||||
*/
|
|
||||||
appRoot?: string;
|
|
||||||
/**
|
|
||||||
* Generates a routing module.
|
|
||||||
*/
|
|
||||||
routing?: boolean;
|
|
||||||
/**
|
|
||||||
* The scope for the generated routing.
|
|
||||||
*/
|
|
||||||
routingScope?: 'Child' | 'Root';
|
|
||||||
/**
|
|
||||||
* Specifies if a spec file is generated.
|
|
||||||
*/
|
|
||||||
spec?: boolean;
|
|
||||||
/**
|
|
||||||
* Flag to indicate if a dir is created.
|
|
||||||
*/
|
|
||||||
flat?: boolean;
|
|
||||||
/**
|
|
||||||
* Flag to control whether the CommonModule is imported.
|
|
||||||
*/
|
|
||||||
commonModule?: boolean;
|
|
||||||
/**
|
|
||||||
* Allows specification of the declaring module.
|
|
||||||
*/
|
|
||||||
module?: string;
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/schema",
|
|
||||||
"id": "module",
|
|
||||||
"title": "NX Module Options Schema",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The name of the module."
|
|
||||||
},
|
|
||||||
"path": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "path",
|
|
||||||
"description": "The path to create the module.",
|
|
||||||
"default": "app",
|
|
||||||
"visible": false
|
|
||||||
},
|
|
||||||
"sourceDir": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "path",
|
|
||||||
"description": "The path of the source directory.",
|
|
||||||
"default": "src",
|
|
||||||
"visible": false
|
|
||||||
},
|
|
||||||
"appRoot": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "path",
|
|
||||||
"description": "The root of the application.",
|
|
||||||
"visible": false
|
|
||||||
},
|
|
||||||
"routing": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Generates a routing module.",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"routingScope": {
|
|
||||||
"enum": ["Child", "Root"],
|
|
||||||
"type": "string",
|
|
||||||
"description": "The scope for the generated routing.",
|
|
||||||
"default": "Child"
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"flat": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Flag to indicate if a dir is created.",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"commonModule": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Flag to control whether the CommonModule is imported.",
|
|
||||||
"default": true,
|
|
||||||
"visible": false
|
|
||||||
},
|
|
||||||
"skipFormat": {
|
|
||||||
"description": "Skip formatting files",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"module": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Allows specification of the declaring module.",
|
|
||||||
"alias": "m"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["name"]
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
export const angularCliVersion = '1.7.1';
|
|
||||||
export const angularVersion = '5.2.7';
|
|
||||||
export const angularJsVersion = '1.6.6';
|
|
||||||
export const ngrxVersion = '5.1.0';
|
|
||||||
export const ngrxStoreFreezeVersion = '^0.2.1';
|
|
||||||
export const routerStoreVersion = '5.0.1';
|
|
||||||
export const nxVersion = '*';
|
|
||||||
export const schematicsVersion = '*';
|
|
||||||
export const angularCliSchema =
|
|
||||||
'./node_modules/@nrwl/schematics/src/schema.json';
|
|
||||||
export const latestMigration = '20180313-add-tags';
|
|
||||||
export const prettierVersion = '1.10.2';
|
|
||||||
export const typescriptVersion = '2.6.2';
|
|
||||||
export const rxjsVersion = '^5.5.6';
|
|
||||||
export const devKitCoreVersion = '^0.0.29';
|
|
||||||
export const devKitSchematicsVersion = '0.0.52';
|
|
||||||
export const schematicsAngularVersion = '0.1.17';
|
|
||||||
|
|
||||||
export const libVersions = {
|
|
||||||
angularVersion,
|
|
||||||
angularCliVersion,
|
|
||||||
angularJsVersion,
|
|
||||||
ngrxVersion,
|
|
||||||
ngrxStoreFreezeVersion,
|
|
||||||
nxVersion,
|
|
||||||
schematicsVersion,
|
|
||||||
prettierVersion,
|
|
||||||
angularCliSchema,
|
|
||||||
latestMigration,
|
|
||||||
typescriptVersion,
|
|
||||||
rxjsVersion,
|
|
||||||
devKitCoreVersion,
|
|
||||||
devKitSchematicsVersion,
|
|
||||||
schematicsAngularVersion,
|
|
||||||
routerStoreVersion
|
|
||||||
};
|
|
||||||
@ -1,686 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/schema",
|
|
||||||
"id": "https://github.com/nrwl/nx/blob/master/packages/bazel/src/schema.json",
|
|
||||||
"title": "Nrwl Nx Config Schema",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"$schema": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"project": {
|
|
||||||
"description": "The global configuration of the project.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"description": "The name of the project.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"latestMigration": {
|
|
||||||
"description": "Npm scope for importing libs.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"ejected": {
|
|
||||||
"description": "Whether or not this project was ejected.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"apps": {
|
|
||||||
"description": "Properties of the different applications in this project.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"tags": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Project tags",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"default": []
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Name of the app."
|
|
||||||
},
|
|
||||||
"appRoot": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Directory where app files are placed.",
|
|
||||||
"default": "app"
|
|
||||||
},
|
|
||||||
"appShell": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "AppShell configuration.",
|
|
||||||
"properties": {
|
|
||||||
"app": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Index or name of the related AppShell app."
|
|
||||||
},
|
|
||||||
"route": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Default AppShell route to render."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The root directory of the app."
|
|
||||||
},
|
|
||||||
"outDir": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "dist/",
|
|
||||||
"description": "The output directory for build results."
|
|
||||||
},
|
|
||||||
"assets": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "List of application assets.",
|
|
||||||
"items": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"glob": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "",
|
|
||||||
"description": "The pattern to match."
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "",
|
|
||||||
"description": "The dir to search within."
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "",
|
|
||||||
"description": "The output path (relative to the outDir)."
|
|
||||||
},
|
|
||||||
"allowOutsideOutDir": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Allow assets to be copied outside the outDir.",
|
|
||||||
"default": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"default": []
|
|
||||||
},
|
|
||||||
"budgets": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Threshold definitions for bundle sizes.",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"bundle",
|
|
||||||
"initial",
|
|
||||||
"allScript",
|
|
||||||
"all",
|
|
||||||
"anyScript",
|
|
||||||
"any"
|
|
||||||
],
|
|
||||||
"description": "The type of budget"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The name of the bundle"
|
|
||||||
},
|
|
||||||
"baseline": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The baseline size for comparison."
|
|
||||||
},
|
|
||||||
"maximumWarning": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The maximum threshold for warning relative to the baseline."
|
|
||||||
},
|
|
||||||
"maximumError": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The maximum threshold for error relative to the baseline."
|
|
||||||
},
|
|
||||||
"minimumWarning": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The minimum threshold for warning relative to the baseline."
|
|
||||||
},
|
|
||||||
"minimumError": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The minimum threshold for error relative to the baseline."
|
|
||||||
},
|
|
||||||
"warning": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The threshold for warning relative to the baseline (min & max)."
|
|
||||||
},
|
|
||||||
"error": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The threshold for error relative to the baseline (min & max)."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"default": []
|
|
||||||
},
|
|
||||||
"deployUrl": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "URL where files will be deployed."
|
|
||||||
},
|
|
||||||
"baseHref": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Base url for the application being built."
|
|
||||||
},
|
|
||||||
"platform": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": ["browser", "server"],
|
|
||||||
"default": "browser",
|
|
||||||
"description": "The runtime platform of the app."
|
|
||||||
},
|
|
||||||
"index": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "index.html",
|
|
||||||
"description": "The name of the start HTML file."
|
|
||||||
},
|
|
||||||
"main": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The name of the main entry-point file."
|
|
||||||
},
|
|
||||||
"polyfills": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The name of the polyfills file."
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The name of the test entry-point file."
|
|
||||||
},
|
|
||||||
"tsconfig": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "tsconfig.app.json",
|
|
||||||
"description": "The name of the TypeScript configuration file."
|
|
||||||
},
|
|
||||||
"testTsconfig": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The name of the TypeScript configuration file for unit tests."
|
|
||||||
},
|
|
||||||
"prefix": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The prefix to apply to generated selectors."
|
|
||||||
},
|
|
||||||
"serviceWorker": {
|
|
||||||
"description": "Experimental support for a service worker from @angular/service-worker.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"styles": {
|
|
||||||
"description": "Global styles to be included in the build.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"input": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"stylePreprocessorOptions": {
|
|
||||||
"description": "Options to pass to style preprocessors",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"includePaths": {
|
|
||||||
"description": "Paths to include. Paths will be resolved to project root.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"default": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"description": "Global scripts to be included in the build.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"input": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": true,
|
|
||||||
"required": ["input"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"environmentSource": {
|
|
||||||
"description": "Source file for environment config.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"environments": {
|
|
||||||
"description": "Name and corresponding file for environment config.",
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"e2e": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "Configuration for end-to-end tests.",
|
|
||||||
"properties": {
|
|
||||||
"protractor": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"config": {
|
|
||||||
"description": "Path to the config file.",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"description": "Properties to be passed to TSLint.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"files": {
|
|
||||||
"description": "File glob(s) to lint.",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default": []
|
|
||||||
},
|
|
||||||
"project": {
|
|
||||||
"description": "Location of the tsconfig.json project file. Will also use as files to lint if 'files' property not present.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"tslintConfig": {
|
|
||||||
"description": "Location of the tslint.json configuration.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"exclude": {
|
|
||||||
"description": "File glob(s) to ignore.",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["project"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"description": "Configuration for unit tests.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"karma": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"config": {
|
|
||||||
"description": "Path to the karma config file.",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"codeCoverage": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"exclude": {
|
|
||||||
"description": "Globs to exclude from code coverage.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"default": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"defaults": {
|
|
||||||
"description": "Specify the default values for generating.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"styleExt": {
|
|
||||||
"description": "The file extension to be used for style files.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"poll": {
|
|
||||||
"description": "How often to check for file updates.",
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"lintFix": {
|
|
||||||
"description": "Use lint to fix files after generation",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"class": {
|
|
||||||
"description": "Options for generating a class.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"spec": {
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"component": {
|
|
||||||
"description": "Options for generating a component.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"flat": {
|
|
||||||
"description": "Flag to indicate if a dir is created.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"inlineStyle": {
|
|
||||||
"description": "Specifies if the style will be in the ts file.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"inlineTemplate": {
|
|
||||||
"description": "Specifies if the template will be in the ts file.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"viewEncapsulation": {
|
|
||||||
"description": "Specifies the view encapsulation strategy.",
|
|
||||||
"enum": ["Emulated", "Native", "None"],
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"changeDetection": {
|
|
||||||
"description": "Specifies the change detection strategy.",
|
|
||||||
"enum": ["Default", "OnPush"],
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"directive": {
|
|
||||||
"description": "Options for generating a directive.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"flat": {
|
|
||||||
"description": "Flag to indicate if a dir is created.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"guard": {
|
|
||||||
"description": "Options for generating a guard.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"flat": {
|
|
||||||
"description": "Flag to indicate if a dir is created.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interface": {
|
|
||||||
"description": "Options for generating an interface.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"prefix": {
|
|
||||||
"description": "Prefix to apply to interface names. (i.e. I)",
|
|
||||||
"type": "string",
|
|
||||||
"default": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"module": {
|
|
||||||
"description": "Options for generating a module.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"flat": {
|
|
||||||
"description": "Flag to indicate if a dir is created.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pipe": {
|
|
||||||
"description": "Options for generating a pipe.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"flat": {
|
|
||||||
"description": "Flag to indicate if a dir is created.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"service": {
|
|
||||||
"description": "Options for generating a service.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"flat": {
|
|
||||||
"description": "Flag to indicate if a dir is created.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"description": "Specifies if a spec file is generated.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"description": "Properties to be passed to the build command.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"sourcemaps": {
|
|
||||||
"description": "Output sourcemaps.",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"baseHref": {
|
|
||||||
"description": "Base url for the application being built.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"progress": {
|
|
||||||
"description": "The ssl key used by the server.",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"poll": {
|
|
||||||
"description": "Enable and define the file watching poll time period (milliseconds).",
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"deleteOutputPath": {
|
|
||||||
"description": "Delete output path before build.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"preserveSymlinks": {
|
|
||||||
"description": "Do not use the real path when resolving modules.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"showCircularDependencies": {
|
|
||||||
"description": "Show circular dependency warnings on builds.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"commonChunk": {
|
|
||||||
"description": "Use a separate bundle containing code used across multiple bundles.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"namedChunks": {
|
|
||||||
"description": "Use file name for lazy loaded chunks.",
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"serve": {
|
|
||||||
"description": "Properties to be passed to the serve command.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"port": {
|
|
||||||
"description": "The port the application will be served on.",
|
|
||||||
"type": "number",
|
|
||||||
"default": 4200
|
|
||||||
},
|
|
||||||
"host": {
|
|
||||||
"description": "The host the application will be served on.",
|
|
||||||
"type": "string",
|
|
||||||
"default": "localhost"
|
|
||||||
},
|
|
||||||
"ssl": {
|
|
||||||
"description": "Enables ssl for the application.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"sslKey": {
|
|
||||||
"description": "The ssl key used by the server.",
|
|
||||||
"type": "string",
|
|
||||||
"default": "ssl/server.key"
|
|
||||||
},
|
|
||||||
"sslCert": {
|
|
||||||
"description": "The ssl certificate used by the server.",
|
|
||||||
"type": "string",
|
|
||||||
"default": "ssl/server.crt"
|
|
||||||
},
|
|
||||||
"proxyConfig": {
|
|
||||||
"description": "Proxy configuration file.",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schematics": {
|
|
||||||
"description": "Properties about schematics.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"collection": {
|
|
||||||
"description": "The schematics collection to use.",
|
|
||||||
"type": "string",
|
|
||||||
"default": "@schematics/angular"
|
|
||||||
},
|
|
||||||
"newApp": {
|
|
||||||
"description": "The new app schematic.",
|
|
||||||
"type": "string",
|
|
||||||
"default": "application"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"packageManager": {
|
|
||||||
"description": "Specify which package manager tool to use.",
|
|
||||||
"enum": ["npm", "cnpm", "yarn", "default"],
|
|
||||||
"default": "default",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"warnings": {
|
|
||||||
"description": "Allow people to disable console warnings.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"hmrWarning": {
|
|
||||||
"description": "Show a warning when the user enabled the --hmr option.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"nodeDeprecation": {
|
|
||||||
"description": "Show a warning when the node version is incompatible.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"packageDeprecation": {
|
|
||||||
"description": "Show a warning when the user installed angular-cli.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"versionMismatch": {
|
|
||||||
"description": "Show a warning when the global version is newer than the local one.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"typescriptMismatch": {
|
|
||||||
"description": "Show a warning when the TypeScript version is incompatible",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"servePathDefault": {
|
|
||||||
"description": "Show a warning when deploy-url/base-href use unsupported serve path values.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
@ -1,671 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
import { Tree, Rule } from '@angular-devkit/schematics';
|
|
||||||
import {
|
|
||||||
findNodes,
|
|
||||||
getDecoratorMetadata,
|
|
||||||
getSourceNodes
|
|
||||||
} from '@schematics/angular/utility/ast-utils';
|
|
||||||
import {
|
|
||||||
Change,
|
|
||||||
InsertChange,
|
|
||||||
NoopChange,
|
|
||||||
RemoveChange
|
|
||||||
} from '@schematics/angular/utility/change';
|
|
||||||
import * as ts from 'typescript';
|
|
||||||
import { toFileName } from './name-utils';
|
|
||||||
import * as path from 'path';
|
|
||||||
import { serializeJson } from '../utils/fileutils';
|
|
||||||
|
|
||||||
// This should be moved to @schematics/angular once it allows to pass custom expressions as providers
|
|
||||||
function _addSymbolToNgModuleMetadata(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
ngModulePath: string,
|
|
||||||
metadataField: string,
|
|
||||||
expression: string
|
|
||||||
): Change[] {
|
|
||||||
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
|
||||||
let node: any = nodes[0]; // tslint:disable-line:no-any
|
|
||||||
|
|
||||||
// Find the decorator declaration.
|
|
||||||
if (!node) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// Get all the children property assignment of object literals.
|
|
||||||
const matchingProperties: ts.ObjectLiteralElement[] = (node as ts.ObjectLiteralExpression).properties
|
|
||||||
.filter(prop => prop.kind == ts.SyntaxKind.PropertyAssignment)
|
|
||||||
// Filter out every fields that's not "metadataField". Also handles string literals
|
|
||||||
// (but not expressions).
|
|
||||||
.filter((prop: ts.PropertyAssignment) => {
|
|
||||||
const name = prop.name;
|
|
||||||
switch (name.kind) {
|
|
||||||
case ts.SyntaxKind.Identifier:
|
|
||||||
return (name as ts.Identifier).getText(source) == metadataField;
|
|
||||||
case ts.SyntaxKind.StringLiteral:
|
|
||||||
return (name as ts.StringLiteral).text == metadataField;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the last node of the array literal.
|
|
||||||
if (!matchingProperties) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if (matchingProperties.length == 0) {
|
|
||||||
// We haven't found the field in the metadata declaration. Insert a new field.
|
|
||||||
const expr = node as ts.ObjectLiteralExpression;
|
|
||||||
let position: number;
|
|
||||||
let toInsert: string;
|
|
||||||
if (expr.properties.length == 0) {
|
|
||||||
position = expr.getEnd() - 1;
|
|
||||||
toInsert = ` ${metadataField}: [${expression}]\n`;
|
|
||||||
} else {
|
|
||||||
node = expr.properties[expr.properties.length - 1];
|
|
||||||
position = node.getEnd();
|
|
||||||
// Get the indentation of the last element, if any.
|
|
||||||
const text = node.getFullText(source);
|
|
||||||
if (text.match('^\r?\r?\n')) {
|
|
||||||
toInsert = `,${
|
|
||||||
text.match(/^\r?\n\s+/)[0]
|
|
||||||
}${metadataField}: [${expression}]`;
|
|
||||||
} else {
|
|
||||||
toInsert = `, ${metadataField}: [${expression}]`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const newMetadataProperty = new InsertChange(
|
|
||||||
ngModulePath,
|
|
||||||
position,
|
|
||||||
toInsert
|
|
||||||
);
|
|
||||||
return [newMetadataProperty];
|
|
||||||
}
|
|
||||||
|
|
||||||
const assignment = matchingProperties[0] as ts.PropertyAssignment;
|
|
||||||
|
|
||||||
// If it's not an array, nothing we can do really.
|
|
||||||
if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrLiteral = assignment.initializer as ts.ArrayLiteralExpression;
|
|
||||||
if (arrLiteral.elements.length == 0) {
|
|
||||||
// Forward the property.
|
|
||||||
node = arrLiteral;
|
|
||||||
} else {
|
|
||||||
node = arrLiteral.elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node) {
|
|
||||||
console.log(
|
|
||||||
'No app module found. Please add your new class to your component.'
|
|
||||||
);
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(node)) {
|
|
||||||
const nodeArray = (node as {}) as Array<ts.Node>;
|
|
||||||
const symbolsArray = nodeArray.map(node => node.getText());
|
|
||||||
if (symbolsArray.includes(expression)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
node = node[node.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
let toInsert: string;
|
|
||||||
let position = node.getEnd();
|
|
||||||
if (node.kind == ts.SyntaxKind.ObjectLiteralExpression) {
|
|
||||||
// We haven't found the field in the metadata declaration. Insert a new
|
|
||||||
// field.
|
|
||||||
const expr = node as ts.ObjectLiteralExpression;
|
|
||||||
if (expr.properties.length == 0) {
|
|
||||||
position = expr.getEnd() - 1;
|
|
||||||
toInsert = ` ${metadataField}: [${expression}]\n`;
|
|
||||||
} else {
|
|
||||||
node = expr.properties[expr.properties.length - 1];
|
|
||||||
position = node.getEnd();
|
|
||||||
// Get the indentation of the last element, if any.
|
|
||||||
const text = node.getFullText(source);
|
|
||||||
if (text.match('^\r?\r?\n')) {
|
|
||||||
toInsert = `,${
|
|
||||||
text.match(/^\r?\n\s+/)[0]
|
|
||||||
}${metadataField}: [${expression}]`;
|
|
||||||
} else {
|
|
||||||
toInsert = `, ${metadataField}: [${expression}]`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (node.kind == ts.SyntaxKind.ArrayLiteralExpression) {
|
|
||||||
// We found the field but it's empty. Insert it just before the `]`.
|
|
||||||
position--;
|
|
||||||
toInsert = `${expression}`;
|
|
||||||
} else {
|
|
||||||
// Get the indentation of the last element, if any.
|
|
||||||
const text = node.getFullText(source);
|
|
||||||
if (text.match(/^\r?\n/)) {
|
|
||||||
toInsert = `,${text.match(/^\r?\n(\r?)\s+/)[0]}${expression}`;
|
|
||||||
} else {
|
|
||||||
toInsert = `, ${expression}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const insert = new InsertChange(ngModulePath, position, toInsert);
|
|
||||||
return [insert];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addParameterToConstructor(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
opts: { className: string; param: string }
|
|
||||||
): Change[] {
|
|
||||||
const clazz = findClass(source, opts.className);
|
|
||||||
const constructor = clazz.members.filter(
|
|
||||||
m => m.kind === ts.SyntaxKind.Constructor
|
|
||||||
)[0];
|
|
||||||
if (constructor) {
|
|
||||||
throw new Error('Should be tested');
|
|
||||||
} else {
|
|
||||||
const methodHeader = `constructor(${opts.param})`;
|
|
||||||
return addMethod(source, modulePath, {
|
|
||||||
className: opts.className,
|
|
||||||
methodHeader,
|
|
||||||
body: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addMethod(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
opts: { className: string; methodHeader: string; body: string }
|
|
||||||
): Change[] {
|
|
||||||
const clazz = findClass(source, opts.className);
|
|
||||||
const body = opts.body
|
|
||||||
? `
|
|
||||||
${opts.methodHeader} {
|
|
||||||
${offset(opts.body, 1, false)}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
: `
|
|
||||||
${opts.methodHeader} {}
|
|
||||||
`;
|
|
||||||
|
|
||||||
return [new InsertChange(modulePath, clazz.end - 1, offset(body, 1, true))];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeFromNgModule(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
property: string
|
|
||||||
): Change[] {
|
|
||||||
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
|
||||||
let node: any = nodes[0]; // tslint:disable-line:no-any
|
|
||||||
|
|
||||||
// Find the decorator declaration.
|
|
||||||
if (!node) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all the children property assignment of object literals.
|
|
||||||
const matchingProperty = getMatchingProperty(source, property);
|
|
||||||
if (matchingProperty) {
|
|
||||||
return [
|
|
||||||
new RemoveChange(
|
|
||||||
modulePath,
|
|
||||||
matchingProperty.pos,
|
|
||||||
matchingProperty.getFullText(source)
|
|
||||||
)
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function findClass(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
className: string
|
|
||||||
): ts.ClassDeclaration {
|
|
||||||
const nodes = getSourceNodes(source);
|
|
||||||
|
|
||||||
const clazz = <any>(
|
|
||||||
nodes.filter(
|
|
||||||
n =>
|
|
||||||
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
|
||||||
(<any>n).name.text === className
|
|
||||||
)[0]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!clazz) {
|
|
||||||
throw new Error(`Cannot find class '${className}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function offset(
|
|
||||||
text: string,
|
|
||||||
numberOfTabs: number,
|
|
||||||
wrap: boolean
|
|
||||||
): string {
|
|
||||||
const lines = text
|
|
||||||
.trim()
|
|
||||||
.split('\n')
|
|
||||||
.map(line => {
|
|
||||||
let tabs = '';
|
|
||||||
for (let c = 0; c < numberOfTabs; ++c) {
|
|
||||||
tabs += ' ';
|
|
||||||
}
|
|
||||||
return `${tabs}${line}`;
|
|
||||||
})
|
|
||||||
.join('\n');
|
|
||||||
|
|
||||||
return wrap ? `\n${lines}\n` : lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addImportToModule(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
symbolName: string
|
|
||||||
): Change[] {
|
|
||||||
return _addSymbolToNgModuleMetadata(
|
|
||||||
source,
|
|
||||||
modulePath,
|
|
||||||
'imports',
|
|
||||||
symbolName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addImportToTestBed(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
specPath: string,
|
|
||||||
symbolName: string
|
|
||||||
): Change[] {
|
|
||||||
const allCalls: ts.CallExpression[] = <any>(
|
|
||||||
findNodes(source, ts.SyntaxKind.CallExpression)
|
|
||||||
);
|
|
||||||
|
|
||||||
const configureTestingModuleObjectLiterals = allCalls
|
|
||||||
.filter(c => c.expression.kind === ts.SyntaxKind.PropertyAccessExpression)
|
|
||||||
.filter(
|
|
||||||
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
|
|
||||||
)
|
|
||||||
.map(c =>
|
|
||||||
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
|
||||||
? c.arguments[0]
|
|
||||||
: null
|
|
||||||
);
|
|
||||||
|
|
||||||
if (configureTestingModuleObjectLiterals.length > 0) {
|
|
||||||
const startPosition = configureTestingModuleObjectLiterals[0]
|
|
||||||
.getFirstToken(source)
|
|
||||||
.getEnd();
|
|
||||||
return [
|
|
||||||
new InsertChange(specPath, startPosition, `imports: [${symbolName}], `)
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addReexport(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
reexportedFileName: string,
|
|
||||||
token: string
|
|
||||||
): Change[] {
|
|
||||||
const allExports = findNodes(source, ts.SyntaxKind.ExportDeclaration);
|
|
||||||
if (allExports.length > 0) {
|
|
||||||
const m = allExports.filter(
|
|
||||||
(e: ts.ExportDeclaration) =>
|
|
||||||
e.moduleSpecifier.getText(source).indexOf(reexportedFileName) > -1
|
|
||||||
);
|
|
||||||
if (m.length > 0) {
|
|
||||||
const mm: ts.ExportDeclaration = <any>m[0];
|
|
||||||
return [
|
|
||||||
new InsertChange(modulePath, mm.exportClause.end - 1, `, ${token} `)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getBootstrapComponent(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
moduleClassName: string
|
|
||||||
): string {
|
|
||||||
const bootstrap = getMatchingProperty(source, 'bootstrap');
|
|
||||||
if (!bootstrap) {
|
|
||||||
throw new Error(`Cannot find bootstrap components in '${moduleClassName}'`);
|
|
||||||
}
|
|
||||||
const c = bootstrap.getChildren();
|
|
||||||
const nodes = c[c.length - 1].getChildren();
|
|
||||||
|
|
||||||
const bootstrapComponent = nodes.slice(1, nodes.length - 1)[0];
|
|
||||||
if (!bootstrapComponent) {
|
|
||||||
throw new Error(`Cannot find bootstrap components in '${moduleClassName}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bootstrapComponent.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMatchingObjectLiteralElement(
|
|
||||||
node: any,
|
|
||||||
source: ts.SourceFile,
|
|
||||||
property: string
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
(node as ts.ObjectLiteralExpression).properties
|
|
||||||
.filter(prop => prop.kind == ts.SyntaxKind.PropertyAssignment)
|
|
||||||
// Filter out every fields that's not "metadataField". Also handles string literals
|
|
||||||
// (but not expressions).
|
|
||||||
.filter((prop: ts.PropertyAssignment) => {
|
|
||||||
const name = prop.name;
|
|
||||||
switch (name.kind) {
|
|
||||||
case ts.SyntaxKind.Identifier:
|
|
||||||
return (name as ts.Identifier).getText(source) === property;
|
|
||||||
case ts.SyntaxKind.StringLiteral:
|
|
||||||
return (name as ts.StringLiteral).text === property;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
})[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMatchingProperty(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
property: string
|
|
||||||
): ts.ObjectLiteralElement {
|
|
||||||
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
|
|
||||||
let node: any = nodes[0]; // tslint:disable-line:no-any
|
|
||||||
|
|
||||||
if (!node) return null;
|
|
||||||
|
|
||||||
// Get all the children property assignment of object literals.
|
|
||||||
return getMatchingObjectLiteralElement(node, source, property);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addRoute(
|
|
||||||
ngModulePath: string,
|
|
||||||
source: ts.SourceFile,
|
|
||||||
route: string
|
|
||||||
): Change[] {
|
|
||||||
const routes = getListOfRoutes(source);
|
|
||||||
if (!routes) return [];
|
|
||||||
|
|
||||||
if (routes.hasTrailingComma || routes.length === 0) {
|
|
||||||
return [new InsertChange(ngModulePath, routes.end, route)];
|
|
||||||
} else {
|
|
||||||
return [new InsertChange(ngModulePath, routes.end, `, ${route}`)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addIncludeToTsConfig(
|
|
||||||
tsConfigPath: string,
|
|
||||||
source: ts.SourceFile,
|
|
||||||
include: string
|
|
||||||
): Change[] {
|
|
||||||
const includeKeywordPos = source.text.indexOf('"include":');
|
|
||||||
if (includeKeywordPos > -1) {
|
|
||||||
const includeArrayEndPos = source.text.indexOf(']', includeKeywordPos);
|
|
||||||
return [new InsertChange(tsConfigPath, includeArrayEndPos, include)];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getListOfRoutes(source: ts.SourceFile): ts.NodeArray<ts.Expression> {
|
|
||||||
const imports: any = getMatchingProperty(source, 'imports');
|
|
||||||
|
|
||||||
if (imports.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
|
||||||
const a = imports.initializer as ts.ArrayLiteralExpression;
|
|
||||||
|
|
||||||
for (let e of a.elements) {
|
|
||||||
if (e.kind === 181) {
|
|
||||||
const ee = e as ts.CallExpression;
|
|
||||||
const text = ee.expression.getText(source);
|
|
||||||
if (
|
|
||||||
(text === 'RouterModule.forRoot' ||
|
|
||||||
text === 'RouterModule.forChild') &&
|
|
||||||
ee.arguments.length > 0
|
|
||||||
) {
|
|
||||||
const routes = ee.arguments[0];
|
|
||||||
if (routes.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
|
||||||
return (routes as ts.ArrayLiteralExpression).elements;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getImport(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
predicate: (a: any) => boolean
|
|
||||||
): { moduleSpec: string; bindings: string[] }[] {
|
|
||||||
const allImports = findNodes(source, ts.SyntaxKind.ImportDeclaration);
|
|
||||||
const matching = allImports.filter((i: ts.ImportDeclaration) =>
|
|
||||||
predicate(i.moduleSpecifier.getText())
|
|
||||||
);
|
|
||||||
|
|
||||||
return matching.map((i: ts.ImportDeclaration) => {
|
|
||||||
const moduleSpec = i.moduleSpecifier
|
|
||||||
.getText()
|
|
||||||
.substring(1, i.moduleSpecifier.getText().length - 1);
|
|
||||||
const t = i.importClause.namedBindings.getText();
|
|
||||||
const bindings = t
|
|
||||||
.replace('{', '')
|
|
||||||
.replace('}', '')
|
|
||||||
.split(',')
|
|
||||||
.map(q => q.trim());
|
|
||||||
return { moduleSpec, bindings };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addProviderToModule(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
symbolName: string
|
|
||||||
): Change[] {
|
|
||||||
return _addSymbolToNgModuleMetadata(
|
|
||||||
source,
|
|
||||||
modulePath,
|
|
||||||
'providers',
|
|
||||||
symbolName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addDeclarationToModule(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
symbolName: string
|
|
||||||
): Change[] {
|
|
||||||
return _addSymbolToNgModuleMetadata(
|
|
||||||
source,
|
|
||||||
modulePath,
|
|
||||||
'declarations',
|
|
||||||
symbolName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addEntryComponents(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
symbolName: string
|
|
||||||
): Change[] {
|
|
||||||
return _addSymbolToNgModuleMetadata(
|
|
||||||
source,
|
|
||||||
modulePath,
|
|
||||||
'entryComponents',
|
|
||||||
symbolName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addGlobal(
|
|
||||||
source: ts.SourceFile,
|
|
||||||
modulePath: string,
|
|
||||||
statement: string
|
|
||||||
): Change[] {
|
|
||||||
const allImports = findNodes(source, ts.SyntaxKind.ImportDeclaration);
|
|
||||||
if (allImports.length > 0) {
|
|
||||||
const lastImport = allImports[allImports.length - 1];
|
|
||||||
return [
|
|
||||||
new InsertChange(modulePath, lastImport.end + 1, `\n${statement}\n`)
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [new InsertChange(modulePath, 0, `${statement}\n`)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function insert(host: Tree, modulePath: string, changes: Change[]) {
|
|
||||||
const recorder = host.beginUpdate(modulePath);
|
|
||||||
for (const change of changes) {
|
|
||||||
if (change instanceof InsertChange) {
|
|
||||||
recorder.insertLeft(change.pos, change.toAdd);
|
|
||||||
} else if (change instanceof RemoveChange) {
|
|
||||||
recorder.remove((<any>change).pos - 1, (<any>change).toRemove.length + 1);
|
|
||||||
} else if (change instanceof NoopChange) {
|
|
||||||
// do nothing
|
|
||||||
} else {
|
|
||||||
throw new Error(`Unexpected Change '${change}'`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host.commitUpdate(recorder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is specifically for reading JSON files in a Tree
|
|
||||||
* @param host The host tree
|
|
||||||
* @param path The path to the JSON file
|
|
||||||
* @returns The JSON data in the file.
|
|
||||||
*/
|
|
||||||
export function readJsonInTree<T = any>(host: Tree, path: string): T {
|
|
||||||
if (!host.exists(path)) {
|
|
||||||
throw new Error(`Cannot find ${path}`);
|
|
||||||
}
|
|
||||||
return JSON.parse(host.read(path)!.toString('utf-8'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is specifically for updating JSON in a Tree
|
|
||||||
* @param path Path of JSON file in the Tree
|
|
||||||
* @param callback Manipulation of the JSON data
|
|
||||||
* @returns A rule which updates a JSON file file in a Tree
|
|
||||||
*/
|
|
||||||
export function updateJsonInTree<T = any, O = T>(
|
|
||||||
path: string,
|
|
||||||
callback: (json: T) => O
|
|
||||||
): Rule {
|
|
||||||
return (host: Tree): Tree => {
|
|
||||||
host.overwrite(path, serializeJson(callback(readJsonInTree(host, path))));
|
|
||||||
return host;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is specifically for getting the .angular-cli.json data from a Tree
|
|
||||||
* @param host The host tree
|
|
||||||
*/
|
|
||||||
export function getAngularCliConfig(host: Tree) {
|
|
||||||
return readJsonInTree(host, '.angular-cli.json');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAppConfig(host: Tree, name: string): any {
|
|
||||||
const angularCliJson = getAngularCliConfig(host);
|
|
||||||
const apps = angularCliJson.apps;
|
|
||||||
if (!apps || apps.length === 0) {
|
|
||||||
throw new Error(`Cannot find app '${name}'`);
|
|
||||||
}
|
|
||||||
if (name) {
|
|
||||||
const appConfig = apps.filter(a => a.name === name)[0];
|
|
||||||
if (!appConfig) {
|
|
||||||
throw new Error(`Cannot find app '${name}'`);
|
|
||||||
} else {
|
|
||||||
return appConfig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return apps[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function readBootstrapInfo(
|
|
||||||
host: Tree,
|
|
||||||
app: string
|
|
||||||
): {
|
|
||||||
moduleSpec: string;
|
|
||||||
modulePath: string;
|
|
||||||
mainPath: string;
|
|
||||||
moduleClassName: string;
|
|
||||||
moduleSource: ts.SourceFile;
|
|
||||||
bootstrapComponentClassName: string;
|
|
||||||
bootstrapComponentFileName: string;
|
|
||||||
} {
|
|
||||||
const config = getAppConfig(host, app);
|
|
||||||
const mainPath = path.join(config.root, config.main);
|
|
||||||
if (!host.exists(mainPath)) {
|
|
||||||
throw new Error('Main file cannot be located');
|
|
||||||
}
|
|
||||||
|
|
||||||
const mainSource = host.read(mainPath)!.toString('utf-8');
|
|
||||||
const main = ts.createSourceFile(
|
|
||||||
mainPath,
|
|
||||||
mainSource,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
const moduleImports = getImport(
|
|
||||||
main,
|
|
||||||
(s: string) => s.indexOf('.module') > -1
|
|
||||||
);
|
|
||||||
if (moduleImports.length !== 1) {
|
|
||||||
throw new Error(`main.ts can only import a single module`);
|
|
||||||
}
|
|
||||||
const moduleImport = moduleImports[0];
|
|
||||||
const moduleClassName = moduleImport.bindings.filter(b =>
|
|
||||||
b.endsWith('Module')
|
|
||||||
)[0];
|
|
||||||
|
|
||||||
const modulePath = `${path.join(
|
|
||||||
path.dirname(mainPath),
|
|
||||||
moduleImport.moduleSpec
|
|
||||||
)}.ts`;
|
|
||||||
if (!host.exists(modulePath)) {
|
|
||||||
throw new Error(`Cannot find '${modulePath}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const moduleSourceText = host.read(modulePath)!.toString('utf-8');
|
|
||||||
const moduleSource = ts.createSourceFile(
|
|
||||||
modulePath,
|
|
||||||
moduleSourceText,
|
|
||||||
ts.ScriptTarget.Latest,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
const bootstrapComponentClassName = getBootstrapComponent(
|
|
||||||
moduleSource,
|
|
||||||
moduleClassName
|
|
||||||
);
|
|
||||||
const bootstrapComponentFileName = `./${path.join(
|
|
||||||
path.dirname(moduleImport.moduleSpec),
|
|
||||||
`${toFileName(
|
|
||||||
bootstrapComponentClassName.substring(
|
|
||||||
0,
|
|
||||||
bootstrapComponentClassName.length - 9
|
|
||||||
)
|
|
||||||
)}.component`
|
|
||||||
)}`;
|
|
||||||
|
|
||||||
return {
|
|
||||||
moduleSpec: moduleImport.moduleSpec,
|
|
||||||
mainPath,
|
|
||||||
modulePath,
|
|
||||||
moduleSource,
|
|
||||||
moduleClassName,
|
|
||||||
bootstrapComponentClassName,
|
|
||||||
bootstrapComponentFileName
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import * as yargsParser from 'yargs-parser';
|
|
||||||
|
|
||||||
import { readJsonFile } from './fileutils';
|
|
||||||
|
|
||||||
export function getAppDirectoryUsingCliConfig() {
|
|
||||||
const cli = readJsonFile(process.cwd() + '/.angular-cli.json');
|
|
||||||
|
|
||||||
const appName = getAppName();
|
|
||||||
|
|
||||||
if (appName) {
|
|
||||||
const app = cli.apps.find(a => a.name === appName);
|
|
||||||
if (!app) {
|
|
||||||
console.error(`Cannot find app '${appName}'.`);
|
|
||||||
process.exit(1);
|
|
||||||
} else if (app.root.startsWith('libs')) {
|
|
||||||
console.error(`Cannot run e2e tests for a library.`);
|
|
||||||
process.exit(1);
|
|
||||||
} else {
|
|
||||||
return `apps/${appName}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`Please provide the app name using --app or -a.`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeSureNoAppIsSelected() {
|
|
||||||
if (getAppName()) {
|
|
||||||
console.error('Nx only supports running unit tests for all apps and libs.');
|
|
||||||
console.error('You cannot use -a or --app.');
|
|
||||||
console.error('Use fdescribe or fit to select a subset of tests to run.');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAppName() {
|
|
||||||
return yargsParser(process.argv, {
|
|
||||||
alias: {
|
|
||||||
app: ['a']
|
|
||||||
},
|
|
||||||
string: ['app']
|
|
||||||
}).app;
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
import { Options } from 'prettier';
|
|
||||||
import * as cosmiconfig from 'cosmiconfig';
|
|
||||||
|
|
||||||
export function offsetFromRoot(fullPathToSourceDir: string): string {
|
|
||||||
const parts = fullPathToSourceDir.split('/');
|
|
||||||
let offset = '';
|
|
||||||
for (let i = 0; i < parts.length; ++i) {
|
|
||||||
offset += '../';
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DEFAULT_NRWL_PRETTIER_CONFIG = {
|
|
||||||
singleQuote: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface ExistingPrettierConfig {
|
|
||||||
sourceFilepath: string;
|
|
||||||
config: Options;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resolveUserExistingPrettierConfig(): Promise<ExistingPrettierConfig | null> {
|
|
||||||
const explorer = cosmiconfig('prettier', {
|
|
||||||
sync: true,
|
|
||||||
cache: false,
|
|
||||||
rcExtensions: true,
|
|
||||||
stopDir: process.cwd(),
|
|
||||||
transform: result => {
|
|
||||||
if (result && result.config) {
|
|
||||||
delete result.config.$schema;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return Promise.resolve(explorer.load(process.cwd())).then(result => {
|
|
||||||
if (!result) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
sourceFilepath: result.filepath,
|
|
||||||
config: result.config
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import { addApp } from './fileutils';
|
|
||||||
|
|
||||||
describe('fileutils', () => {
|
|
||||||
describe('sortApps', () => {
|
|
||||||
it('should handle undefined', () => {
|
|
||||||
expect(addApp(undefined, { name: 'a' })).toEqual([{ name: 'a' }]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle an empty array', () => {
|
|
||||||
expect(addApp([], { name: 'a' })).toEqual([{ name: 'a' }]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should sort apps by name', () => {
|
|
||||||
expect(addApp([{ name: 'a' }, { name: 'b' }], { name: 'c' })).toEqual([
|
|
||||||
{ name: 'a' },
|
|
||||||
{ name: 'b' },
|
|
||||||
{ name: 'c' }
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should put workspaceRoot last', () => {
|
|
||||||
expect(
|
|
||||||
addApp([{ name: 'a' }, { name: 'z' }], { name: '$workspaceRoot' })
|
|
||||||
).toEqual([{ name: 'a' }, { name: 'z' }, { name: '$workspaceRoot' }]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prioritize apps with "main" defined', () => {
|
|
||||||
expect(
|
|
||||||
addApp([{ name: 'c' }, { name: 'a' }, { name: 'a', main: 'a' }], {
|
|
||||||
name: 'b',
|
|
||||||
main: 'b'
|
|
||||||
})
|
|
||||||
).toEqual([
|
|
||||||
{ name: 'a', main: 'a' },
|
|
||||||
{ name: 'b', main: 'b' },
|
|
||||||
{ name: 'a' },
|
|
||||||
{ name: 'c' }
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
export function writeToFile(path: string, str: string) {
|
|
||||||
fs.writeFileSync(path, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is specifically for updating a JSON file using the filesystem
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* If you are looking to update a JSON file in a tree, look for ./ast-utils#updateJsonInTree
|
|
||||||
* @param path Path of the JSON file on the filesystem
|
|
||||||
* @param callback Manipulation of the JSON data
|
|
||||||
*/
|
|
||||||
export function updateJsonFile(path: string, callback: (a: any) => any) {
|
|
||||||
const json = readJsonFile(path);
|
|
||||||
callback(json);
|
|
||||||
writeToFile(path, JSON.stringify(json, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addApp(apps: any[] | undefined, newApp: any): any[] {
|
|
||||||
if (!apps) {
|
|
||||||
apps = [];
|
|
||||||
}
|
|
||||||
apps.push(newApp);
|
|
||||||
|
|
||||||
apps.sort((a: any, b: any) => {
|
|
||||||
if (a.name === '$workspaceRoot') return 1;
|
|
||||||
if (b.name === '$workspaceRoot') return -1;
|
|
||||||
if (a.main && !b.main) return -1;
|
|
||||||
if (!a.main && b.main) return 1;
|
|
||||||
if (a.name > b.name) return 1;
|
|
||||||
return -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
return apps;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function serializeJson(json: any): string {
|
|
||||||
return `${JSON.stringify(json, null, 2)}\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is specifically for reading a JSON file from the filesystem
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* If you are looking to read a JSON file in a Tree, use ./ast-utils#readJsonInTree
|
|
||||||
* @param path Path of the JSON file on the filesystem
|
|
||||||
*/
|
|
||||||
export function readJsonFile(path: string): any {
|
|
||||||
return JSON.parse(fs.readFileSync(path, 'utf-8'));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function readCliConfigFile(): any {
|
|
||||||
return readJsonFile('.angular-cli.json');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function copyFile(file: string, target: string) {
|
|
||||||
const f = path.basename(file);
|
|
||||||
const source = fs.createReadStream(file);
|
|
||||||
const dest = fs.createWriteStream(path.resolve(target, f));
|
|
||||||
source.pipe(dest);
|
|
||||||
source.on('error', e => console.error(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
function directoryExists(name) {
|
|
||||||
try {
|
|
||||||
return fs.statSync(name).isDirectory();
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createDirectory(name: string) {
|
|
||||||
if (!directoryExists(name)) {
|
|
||||||
fs.mkdirSync(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
export function names(name: string): any {
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
className: toClassName(name),
|
|
||||||
propertyName: toPropertyName(name),
|
|
||||||
fileName: toFileName(name)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toClassName(str: string): string {
|
|
||||||
return toCapitalCase(toPropertyName(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toPropertyName(s: string): string {
|
|
||||||
return s
|
|
||||||
.replace(/(-|_|\.|\s)+(.)?/g, (_, __, chr) =>
|
|
||||||
chr ? chr.toUpperCase() : ''
|
|
||||||
)
|
|
||||||
.replace(/^([A-Z])/, m => m.toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toFileName(s: string): string {
|
|
||||||
return s
|
|
||||||
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(/[ _]/g, '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCapitalCase(s: string): string {
|
|
||||||
return s.charAt(0).toUpperCase() + s.substr(1);
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
import { readJsonInTree } from '../ast-utils';
|
|
||||||
import {
|
|
||||||
TaskConfigurationGenerator,
|
|
||||||
TaskConfiguration,
|
|
||||||
Tree,
|
|
||||||
SchematicContext,
|
|
||||||
Rule,
|
|
||||||
noop
|
|
||||||
} from '@angular-devkit/schematics';
|
|
||||||
|
|
||||||
class FormatFiles implements TaskConfigurationGenerator<any> {
|
|
||||||
toConfiguration(): TaskConfiguration<any> {
|
|
||||||
return {
|
|
||||||
name: 'node-package',
|
|
||||||
options: {
|
|
||||||
packageName: 'run format -- --untracked', // workaround. we should define a custom task executor.
|
|
||||||
quiet: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formatFiles(options: { skipFormat: boolean }): Rule {
|
|
||||||
if (options.skipFormat) {
|
|
||||||
return noop();
|
|
||||||
}
|
|
||||||
return (host: Tree, context: SchematicContext) => {
|
|
||||||
const packageJson = readJsonInTree(host, 'package.json');
|
|
||||||
if (packageJson.scripts && packageJson.scripts.format) {
|
|
||||||
context.addTask(new FormatFiles());
|
|
||||||
} else {
|
|
||||||
context.logger.warn(
|
|
||||||
'The "format" npm script is missing in your package.json'
|
|
||||||
);
|
|
||||||
context.logger.warn(
|
|
||||||
'Your files were not formated during this code generation'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
import { Tree } from '@angular-devkit/schematics';
|
|
||||||
|
|
||||||
export function createEmptyWorkspace(tree: Tree): Tree {
|
|
||||||
tree.create('/.angular-cli.json', JSON.stringify({}));
|
|
||||||
tree.create('/package.json', JSON.stringify({}));
|
|
||||||
tree.create(
|
|
||||||
'/tslint.json',
|
|
||||||
JSON.stringify({
|
|
||||||
rules: {
|
|
||||||
'nx-enforce-module-boundaries': [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
npmScope: '<%= npmScope %>',
|
|
||||||
lazyLoad: [],
|
|
||||||
allow: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createApp(tree: Tree, appName: string): Tree {
|
|
||||||
tree.create(
|
|
||||||
`/apps/${appName}/src/app/app.module.ts`,
|
|
||||||
`
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
@NgModule({
|
|
||||||
imports: [BrowserModule, RouterModule.forRoot([])],
|
|
||||||
declarations: [AppComponent],
|
|
||||||
bootstrap: [AppComponent]
|
|
||||||
})
|
|
||||||
export class AppModule {}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
tree.create(
|
|
||||||
`/apps/${appName}/src/main.ts`,
|
|
||||||
`
|
|
||||||
import { enableProdMode } from '@angular/core';
|
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
||||||
|
|
||||||
import { AppModule } from './app/app.module';
|
|
||||||
import { environment } from './environments/environment';
|
|
||||||
|
|
||||||
if (environment.production) {
|
|
||||||
enableProdMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
platformBrowserDynamic()
|
|
||||||
.bootstrapModule(AppModule)
|
|
||||||
.catch(err => console.log(err));
|
|
||||||
`
|
|
||||||
);
|
|
||||||
tree.create(
|
|
||||||
`/apps/${appName}/src/tsconfig.app.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
include: ['**/*.ts']
|
|
||||||
})
|
|
||||||
);
|
|
||||||
tree.create(
|
|
||||||
`/apps/${appName}/e2e/tsconfig.e2e.json`,
|
|
||||||
JSON.stringify({
|
|
||||||
include: ['../**/*.ts']
|
|
||||||
})
|
|
||||||
);
|
|
||||||
tree.overwrite(
|
|
||||||
'/.angular-cli.json',
|
|
||||||
JSON.stringify({
|
|
||||||
project: {
|
|
||||||
name: 'proj',
|
|
||||||
npmScope: 'proj'
|
|
||||||
},
|
|
||||||
apps: [
|
|
||||||
{
|
|
||||||
name: appName,
|
|
||||||
root: `apps/${appName}/src`,
|
|
||||||
main: 'main.ts',
|
|
||||||
index: 'index.html'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user