@schematics/angular 9.0.0-rc.6 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/application/files/src/test.ts.template +6 -1
- package/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template +1 -1
- package/e2e/files/src/app.po.ts.template +3 -3
- package/library/files/src/test.ts.template +6 -1
- package/library/index.js +4 -3
- package/migrations/update-9/index.js +2 -0
- package/migrations/update-9/ivy-libraries.js +9 -1
- package/migrations/update-9/update-app-tsconfigs.js +3 -2
- package/migrations/update-9/update-dependencies.js +10 -1
- package/migrations/update-9/update-i18n.d.ts +2 -0
- package/migrations/update-9/update-i18n.js +224 -0
- package/migrations/update-9/update-workspace-config.js +0 -167
- package/migrations/update-9/utils.d.ts +1 -0
- package/migrations/update-9/utils.js +6 -0
- package/package.json +3 -4
- package/pipe/files/__name@dasherize@if-flat__/__name@dasherize__.pipe.ts.template +1 -1
- package/service-worker/index.js +8 -3
- package/third_party/github.com/Microsoft/TypeScript/BUILD.bazel +2 -2
- package/third_party/github.com/Microsoft/TypeScript/lib/typescript.d.ts +695 -596
- package/third_party/github.com/Microsoft/TypeScript/lib/typescript.js +17719 -12353
- package/utility/ast-utils.d.ts +6 -0
- package/utility/ast-utils.js +36 -0
- package/utility/latest-versions.js +7 -7
- package/workspace/files/package.json.template +1 -1
- package/workspace/files/tsconfig.json.template +1 -1
|
@@ -7,7 +7,12 @@ import {
|
|
|
7
7
|
platformBrowserDynamicTesting
|
|
8
8
|
} from '@angular/platform-browser-dynamic/testing';
|
|
9
9
|
|
|
10
|
-
declare const require:
|
|
10
|
+
declare const require: {
|
|
11
|
+
context(path: string, deep?: boolean, filter?: RegExp): {
|
|
12
|
+
keys(): string[];
|
|
13
|
+
<T>(id: string): T;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
11
16
|
|
|
12
17
|
// First, initialize the Angular testing environment.
|
|
13
18
|
getTestBed().initTestEnvironment(
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { browser, by, element } from 'protractor';
|
|
2
2
|
|
|
3
3
|
export class AppPage {
|
|
4
|
-
navigateTo() {
|
|
5
|
-
return browser.get(browser.baseUrl) as Promise<
|
|
4
|
+
navigateTo(): Promise<unknown> {
|
|
5
|
+
return browser.get(browser.baseUrl) as Promise<unknown>;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
getTitleText() {
|
|
8
|
+
getTitleText(): Promise<string> {
|
|
9
9
|
return element(by.css('<%= rootSelector %> .content span')).getText() as Promise<string>;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -8,7 +8,12 @@ import {
|
|
|
8
8
|
platformBrowserDynamicTesting
|
|
9
9
|
} from '@angular/platform-browser-dynamic/testing';
|
|
10
10
|
|
|
11
|
-
declare const require:
|
|
11
|
+
declare const require: {
|
|
12
|
+
context(path: string, deep?: boolean, filter?: RegExp): {
|
|
13
|
+
keys(): string[];
|
|
14
|
+
<T>(id: string): T;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
12
17
|
|
|
13
18
|
// First, initialize the Angular testing environment.
|
|
14
19
|
getTestBed().initTestEnvironment(
|
package/library/index.js
CHANGED
|
@@ -27,7 +27,7 @@ function updateJsonFile(host, path, callback) {
|
|
|
27
27
|
}
|
|
28
28
|
return host;
|
|
29
29
|
}
|
|
30
|
-
function updateTsConfig(packageName,
|
|
30
|
+
function updateTsConfig(packageName, ...paths) {
|
|
31
31
|
return (host) => {
|
|
32
32
|
if (!host.exists('tsconfig.json')) {
|
|
33
33
|
return host;
|
|
@@ -39,7 +39,7 @@ function updateTsConfig(packageName, distRoot) {
|
|
|
39
39
|
if (!tsconfig.compilerOptions.paths[packageName]) {
|
|
40
40
|
tsconfig.compilerOptions.paths[packageName] = [];
|
|
41
41
|
}
|
|
42
|
-
tsconfig.compilerOptions.paths[packageName].push(
|
|
42
|
+
tsconfig.compilerOptions.paths[packageName].push(...paths);
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
45
|
}
|
|
@@ -150,6 +150,7 @@ function default_1(options) {
|
|
|
150
150
|
const folderName = `${scopeFolder}${core_1.strings.dasherize(options.name)}`;
|
|
151
151
|
const projectRoot = core_1.join(core_1.normalize(newProjectRoot), folderName);
|
|
152
152
|
const distRoot = `dist/${folderName}`;
|
|
153
|
+
const pathImportLib = `${distRoot}/${folderName.replace('/', '-')}`;
|
|
153
154
|
const sourceDir = `${projectRoot}/src/lib`;
|
|
154
155
|
const templateSource = schematics_1.apply(schematics_1.url('./files'), [
|
|
155
156
|
schematics_1.applyTemplates({
|
|
@@ -170,7 +171,7 @@ function default_1(options) {
|
|
|
170
171
|
schematics_1.mergeWith(templateSource),
|
|
171
172
|
addLibToWorkspaceFile(options, projectRoot, projectName),
|
|
172
173
|
options.skipPackageJson ? schematics_1.noop() : addDependenciesToPackageJson(),
|
|
173
|
-
options.skipTsConfig ? schematics_1.noop() : updateTsConfig(packageName, distRoot),
|
|
174
|
+
options.skipTsConfig ? schematics_1.noop() : updateTsConfig(packageName, pathImportLib, distRoot),
|
|
174
175
|
schematics_1.schematic('module', {
|
|
175
176
|
name: options.name,
|
|
176
177
|
commonModule: false,
|
|
@@ -15,12 +15,14 @@ const ngsw_config_1 = require("./ngsw-config");
|
|
|
15
15
|
const remove_tsickle_1 = require("./remove-tsickle");
|
|
16
16
|
const update_app_tsconfigs_1 = require("./update-app-tsconfigs");
|
|
17
17
|
const update_dependencies_1 = require("./update-dependencies");
|
|
18
|
+
const update_i18n_1 = require("./update-i18n");
|
|
18
19
|
const update_server_main_file_1 = require("./update-server-main-file");
|
|
19
20
|
const update_workspace_config_1 = require("./update-workspace-config");
|
|
20
21
|
function default_1() {
|
|
21
22
|
return () => {
|
|
22
23
|
return schematics_1.chain([
|
|
23
24
|
update_workspace_config_1.updateWorkspaceConfig(),
|
|
25
|
+
update_i18n_1.updateI18nConfig(),
|
|
24
26
|
ivy_libraries_1.updateLibraries(),
|
|
25
27
|
ngsw_config_1.updateNGSWConfig(),
|
|
26
28
|
update_app_tsconfigs_1.updateApplicationTsConfigs(),
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google Inc. All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.io/license
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const core_1 = require("@angular-devkit/core");
|
|
3
11
|
const config_1 = require("../../utility/config");
|
|
4
12
|
const json_utils_1 = require("../../utility/json-utils");
|
|
5
13
|
const workspace_models_1 = require("../../utility/workspace-models");
|
|
@@ -23,7 +31,7 @@ function updateLibraries() {
|
|
|
23
31
|
break;
|
|
24
32
|
}
|
|
25
33
|
const configurations = json_utils_1.findPropertyInAstObject(target, 'configurations');
|
|
26
|
-
const tsConfig =
|
|
34
|
+
const tsConfig = core_1.join(core_1.normalize(projectRoot.value), 'tsconfig.lib.prod.json');
|
|
27
35
|
if (!configurations || configurations.kind !== 'object') {
|
|
28
36
|
// Configurations doesn't exist.
|
|
29
37
|
json_utils_1.appendPropertyInAstObject(recorder, target, 'configurations', { production: { tsConfig } }, 10);
|
|
@@ -83,13 +83,14 @@ function updateTsConfig(tree, builderConfig, builderName, logger) {
|
|
|
83
83
|
const files = json_utils_1.findPropertyInAstObject(tsConfigAst, 'files');
|
|
84
84
|
if (!files) {
|
|
85
85
|
const newFiles = [];
|
|
86
|
+
const tsConfigDir = path_1.dirname(utils_1.forwardSlashPath(tsConfigPath));
|
|
86
87
|
const mainOption = json_utils_1.findPropertyInAstObject(option, 'main');
|
|
87
88
|
if (mainOption && mainOption.kind === 'string') {
|
|
88
|
-
newFiles.push(
|
|
89
|
+
newFiles.push(utils_1.forwardSlashPath(path_1.relative(tsConfigDir, utils_1.forwardSlashPath(mainOption.value))));
|
|
89
90
|
}
|
|
90
91
|
const polyfillsOption = json_utils_1.findPropertyInAstObject(option, 'polyfills');
|
|
91
92
|
if (polyfillsOption && polyfillsOption.kind === 'string') {
|
|
92
|
-
newFiles.push(
|
|
93
|
+
newFiles.push(utils_1.forwardSlashPath(path_1.relative(tsConfigDir, utils_1.forwardSlashPath(polyfillsOption.value))));
|
|
93
94
|
}
|
|
94
95
|
if (newFiles.length) {
|
|
95
96
|
recorder = tree.beginUpdate(tsConfigPath);
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const dependencies_1 = require("../../utility/dependencies");
|
|
4
4
|
const latest_versions_1 = require("../../utility/latest-versions");
|
|
5
5
|
function updateDependencies() {
|
|
6
|
-
return host => {
|
|
6
|
+
return (host, context) => {
|
|
7
7
|
const dependenciesToUpdate = {
|
|
8
8
|
'@angular-devkit/build-angular': latest_versions_1.latestVersions.DevkitBuildAngular,
|
|
9
9
|
'@angular-devkit/build-ng-packagr': latest_versions_1.latestVersions.DevkitBuildNgPackagr,
|
|
@@ -28,6 +28,15 @@ function updateDependencies() {
|
|
|
28
28
|
}
|
|
29
29
|
// `@angular/pwa` package is only needed when running `ng-add`.
|
|
30
30
|
dependencies_1.removePackageJsonDependency(host, '@angular/pwa');
|
|
31
|
+
// Check for @angular-devkit/schematics and @angular-devkit/core
|
|
32
|
+
for (const name of ['@angular-devkit/schematics', '@angular-devkit/core']) {
|
|
33
|
+
const current = dependencies_1.getPackageJsonDependency(host, name);
|
|
34
|
+
if (current) {
|
|
35
|
+
context.logger.info(`Package "${name}" found in the workspace package.json. ` +
|
|
36
|
+
'This package typically does not need to be installed manually. ' +
|
|
37
|
+
'If it is not being used by project code, it can be removed from the package.json.');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
31
40
|
};
|
|
32
41
|
}
|
|
33
42
|
exports.updateDependencies = updateDependencies;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path_1 = require("path");
|
|
4
|
+
const config_1 = require("../../utility/config");
|
|
5
|
+
const dependencies_1 = require("../../utility/dependencies");
|
|
6
|
+
const json_utils_1 = require("../../utility/json-utils");
|
|
7
|
+
const latest_versions_1 = require("../../utility/latest-versions");
|
|
8
|
+
const workspace_models_1 = require("../../utility/workspace-models");
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
function updateI18nConfig() {
|
|
11
|
+
return (tree, context) => {
|
|
12
|
+
// this is whole process of partial change writing and repeat loading/looping is only necessary
|
|
13
|
+
// to workaround underlying issues with the recorder and ast helper functions
|
|
14
|
+
const workspacePath = config_1.getWorkspacePath(tree);
|
|
15
|
+
let workspaceAst = utils_1.getWorkspace(tree);
|
|
16
|
+
// Update extract targets
|
|
17
|
+
const extractTargets = utils_1.getTargets(workspaceAst, 'extract-i18n', workspace_models_1.Builders.ExtractI18n);
|
|
18
|
+
if (extractTargets.length > 0) {
|
|
19
|
+
const recorder = tree.beginUpdate(workspacePath);
|
|
20
|
+
for (const { target, project } of extractTargets) {
|
|
21
|
+
addProjectI18NOptions(recorder, tree, target, project);
|
|
22
|
+
removeExtracti18nDeprecatedOptions(recorder, target);
|
|
23
|
+
}
|
|
24
|
+
tree.commitUpdate(recorder);
|
|
25
|
+
// workspace was changed so need to reload
|
|
26
|
+
workspaceAst = utils_1.getWorkspace(tree);
|
|
27
|
+
}
|
|
28
|
+
// Update base HREF values for existing configurations
|
|
29
|
+
let recorder = tree.beginUpdate(workspacePath);
|
|
30
|
+
for (const { target } of utils_1.getTargets(workspaceAst, 'build', workspace_models_1.Builders.Browser)) {
|
|
31
|
+
updateBaseHrefs(recorder, target);
|
|
32
|
+
}
|
|
33
|
+
for (const { target } of utils_1.getTargets(workspaceAst, 'test', workspace_models_1.Builders.Karma)) {
|
|
34
|
+
updateBaseHrefs(recorder, target);
|
|
35
|
+
}
|
|
36
|
+
tree.commitUpdate(recorder);
|
|
37
|
+
// Remove i18n format option
|
|
38
|
+
workspaceAst = utils_1.getWorkspace(tree);
|
|
39
|
+
recorder = tree.beginUpdate(workspacePath);
|
|
40
|
+
for (const { target } of utils_1.getTargets(workspaceAst, 'build', workspace_models_1.Builders.Browser)) {
|
|
41
|
+
removeFormatOption(recorder, target);
|
|
42
|
+
}
|
|
43
|
+
for (const { target } of utils_1.getTargets(workspaceAst, 'test', workspace_models_1.Builders.Karma)) {
|
|
44
|
+
removeFormatOption(recorder, target);
|
|
45
|
+
}
|
|
46
|
+
tree.commitUpdate(recorder);
|
|
47
|
+
// Add new i18n options to build target configurations
|
|
48
|
+
workspaceAst = utils_1.getWorkspace(tree);
|
|
49
|
+
recorder = tree.beginUpdate(workspacePath);
|
|
50
|
+
for (const { target } of utils_1.getTargets(workspaceAst, 'build', workspace_models_1.Builders.Browser)) {
|
|
51
|
+
addBuilderI18NOptions(recorder, target, context.logger);
|
|
52
|
+
}
|
|
53
|
+
tree.commitUpdate(recorder);
|
|
54
|
+
// Add new i18n options to test target configurations
|
|
55
|
+
workspaceAst = utils_1.getWorkspace(tree);
|
|
56
|
+
recorder = tree.beginUpdate(workspacePath);
|
|
57
|
+
for (const { target } of utils_1.getTargets(workspaceAst, 'test', workspace_models_1.Builders.Karma)) {
|
|
58
|
+
addBuilderI18NOptions(recorder, target, context.logger);
|
|
59
|
+
}
|
|
60
|
+
tree.commitUpdate(recorder);
|
|
61
|
+
return tree;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
exports.updateI18nConfig = updateI18nConfig;
|
|
65
|
+
function addProjectI18NOptions(recorder, tree, builderConfig, projectConfig) {
|
|
66
|
+
const browserConfig = utils_1.getProjectTarget(projectConfig, 'build', workspace_models_1.Builders.Browser);
|
|
67
|
+
if (!browserConfig || browserConfig.kind !== 'object') {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// browser builder options
|
|
71
|
+
let locales;
|
|
72
|
+
const options = utils_1.getAllOptions(browserConfig);
|
|
73
|
+
for (const option of options) {
|
|
74
|
+
const localeId = json_utils_1.findPropertyInAstObject(option, 'i18nLocale');
|
|
75
|
+
if (!localeId || localeId.kind !== 'string') {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const localeFile = json_utils_1.findPropertyInAstObject(option, 'i18nFile');
|
|
79
|
+
if (!localeFile || localeFile.kind !== 'string') {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const localIdValue = localeId.value;
|
|
83
|
+
const localeFileValue = localeFile.value;
|
|
84
|
+
const baseHref = json_utils_1.findPropertyInAstObject(option, 'baseHref');
|
|
85
|
+
let baseHrefValue;
|
|
86
|
+
if (baseHref) {
|
|
87
|
+
if (baseHref.kind === 'string' && baseHref.value !== `/${localIdValue}/`) {
|
|
88
|
+
baseHrefValue = baseHref.value;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// If the configuration does not contain a baseHref, ensure the main option value is used.
|
|
93
|
+
baseHrefValue = '';
|
|
94
|
+
}
|
|
95
|
+
if (!locales) {
|
|
96
|
+
locales = {
|
|
97
|
+
[localIdValue]: baseHrefValue === undefined
|
|
98
|
+
? localeFileValue
|
|
99
|
+
: {
|
|
100
|
+
translation: localeFileValue,
|
|
101
|
+
baseHref: baseHrefValue,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
locales[localIdValue] =
|
|
107
|
+
baseHrefValue === undefined
|
|
108
|
+
? localeFileValue
|
|
109
|
+
: {
|
|
110
|
+
translation: localeFileValue,
|
|
111
|
+
baseHref: baseHrefValue,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (locales) {
|
|
116
|
+
// Get sourceLocale from extract-i18n builder
|
|
117
|
+
const i18nOptions = utils_1.getAllOptions(builderConfig);
|
|
118
|
+
const sourceLocale = i18nOptions
|
|
119
|
+
.map(o => {
|
|
120
|
+
const sourceLocale = json_utils_1.findPropertyInAstObject(o, 'i18nLocale');
|
|
121
|
+
return sourceLocale && sourceLocale.value;
|
|
122
|
+
})
|
|
123
|
+
.find(x => !!x);
|
|
124
|
+
// Add i18n project configuration
|
|
125
|
+
json_utils_1.insertPropertyInAstObjectInOrder(recorder, projectConfig, 'i18n', {
|
|
126
|
+
locales,
|
|
127
|
+
// tslint:disable-next-line: no-any
|
|
128
|
+
sourceLocale: sourceLocale,
|
|
129
|
+
}, 6);
|
|
130
|
+
// Add @angular/localize if not already a dependency
|
|
131
|
+
if (!dependencies_1.getPackageJsonDependency(tree, '@angular/localize')) {
|
|
132
|
+
dependencies_1.addPackageJsonDependency(tree, {
|
|
133
|
+
name: '@angular/localize',
|
|
134
|
+
version: latest_versions_1.latestVersions.Angular,
|
|
135
|
+
type: dependencies_1.NodeDependencyType.Default,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function addBuilderI18NOptions(recorder, builderConfig, logger) {
|
|
141
|
+
const options = utils_1.getAllOptions(builderConfig);
|
|
142
|
+
for (const option of options) {
|
|
143
|
+
const localeId = json_utils_1.findPropertyInAstObject(option, 'i18nLocale');
|
|
144
|
+
const i18nFile = json_utils_1.findPropertyInAstObject(option, 'i18nFile');
|
|
145
|
+
const outputPath = json_utils_1.findPropertyInAstObject(option, 'outputPath');
|
|
146
|
+
if (localeId &&
|
|
147
|
+
localeId.kind === 'string' &&
|
|
148
|
+
i18nFile &&
|
|
149
|
+
outputPath &&
|
|
150
|
+
outputPath.kind === 'string') {
|
|
151
|
+
if (outputPath.value.match(new RegExp(`[/\\\\]${localeId.value}[/\\\\]?$`))) {
|
|
152
|
+
const newOutputPath = outputPath.value.replace(new RegExp(`[/\\\\]${localeId.value}[/\\\\]?$`), '');
|
|
153
|
+
const { start, end } = outputPath;
|
|
154
|
+
recorder.remove(start.offset, end.offset - start.offset);
|
|
155
|
+
recorder.insertLeft(start.offset, `"${newOutputPath}"`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
logger.warn(`Output path value "${outputPath.value}" for locale "${localeId.value}" is not supported with the new localization system. ` +
|
|
159
|
+
`With the current value, the localized output would be written to "${path_1.posix.join(outputPath.value, localeId.value)}". ` +
|
|
160
|
+
`Keeping existing options for the target configuration of locale "${localeId.value}".`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (localeId && localeId.kind === 'string') {
|
|
165
|
+
// add new localize option
|
|
166
|
+
json_utils_1.insertPropertyInAstObjectInOrder(recorder, option, 'localize', [localeId.value], 12);
|
|
167
|
+
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nLocale');
|
|
168
|
+
}
|
|
169
|
+
if (i18nFile) {
|
|
170
|
+
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nFile');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function removeFormatOption(recorder, builderConfig) {
|
|
175
|
+
const options = utils_1.getAllOptions(builderConfig);
|
|
176
|
+
for (const option of options) {
|
|
177
|
+
// The format is always auto-detected now
|
|
178
|
+
const i18nFormat = json_utils_1.findPropertyInAstObject(option, 'i18nFormat');
|
|
179
|
+
if (i18nFormat) {
|
|
180
|
+
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nFormat');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function updateBaseHrefs(recorder, builderConfig) {
|
|
185
|
+
const options = utils_1.getAllOptions(builderConfig);
|
|
186
|
+
const mainOptions = json_utils_1.findPropertyInAstObject(builderConfig, 'options');
|
|
187
|
+
const mainBaseHref = mainOptions &&
|
|
188
|
+
mainOptions.kind === 'object' &&
|
|
189
|
+
json_utils_1.findPropertyInAstObject(mainOptions, 'baseHref');
|
|
190
|
+
const hasMainBaseHref = !!mainBaseHref && mainBaseHref.kind === 'string' && mainBaseHref.value !== '/';
|
|
191
|
+
for (const option of options) {
|
|
192
|
+
const localeId = json_utils_1.findPropertyInAstObject(option, 'i18nLocale');
|
|
193
|
+
const i18nFile = json_utils_1.findPropertyInAstObject(option, 'i18nFile');
|
|
194
|
+
// localize base HREF values are controlled by the i18n configuration
|
|
195
|
+
const baseHref = json_utils_1.findPropertyInAstObject(option, 'baseHref');
|
|
196
|
+
if (localeId && i18nFile && baseHref) {
|
|
197
|
+
// if the main option set has a non-default base href,
|
|
198
|
+
// ensure that the augmented base href has the correct base value
|
|
199
|
+
if (hasMainBaseHref) {
|
|
200
|
+
const { start, end } = baseHref;
|
|
201
|
+
recorder.remove(start.offset, end.offset - start.offset);
|
|
202
|
+
recorder.insertLeft(start.offset, `"/"`);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
json_utils_1.removePropertyInAstObject(recorder, option, 'baseHref');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function removeExtracti18nDeprecatedOptions(recorder, builderConfig) {
|
|
211
|
+
const options = utils_1.getAllOptions(builderConfig);
|
|
212
|
+
for (const option of options) {
|
|
213
|
+
// deprecated options
|
|
214
|
+
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nLocale');
|
|
215
|
+
const i18nFormat = option.properties.find(({ key }) => key.value === 'i18nFormat');
|
|
216
|
+
if (i18nFormat) {
|
|
217
|
+
// i18nFormat has been changed to format
|
|
218
|
+
const key = i18nFormat.key;
|
|
219
|
+
const offset = key.start.offset + 1;
|
|
220
|
+
recorder.remove(offset, key.value.length);
|
|
221
|
+
recorder.insertLeft(offset, 'format');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const path_1 = require("path");
|
|
4
3
|
const config_1 = require("../../utility/config");
|
|
5
|
-
const dependencies_1 = require("../../utility/dependencies");
|
|
6
4
|
const json_utils_1 = require("../../utility/json-utils");
|
|
7
|
-
const latest_versions_1 = require("../../utility/latest-versions");
|
|
8
5
|
const workspace_models_1 = require("../../utility/workspace-models");
|
|
9
6
|
const utils_1 = require("./utils");
|
|
10
7
|
exports.ANY_COMPONENT_STYLE_BUDGET = {
|
|
@@ -21,183 +18,19 @@ function updateWorkspaceConfig() {
|
|
|
21
18
|
updateStyleOrScriptOption('scripts', recorder, target);
|
|
22
19
|
addAnyComponentStyleBudget(recorder, target);
|
|
23
20
|
updateAotOption(tree, recorder, target);
|
|
24
|
-
addBuilderI18NOptions(recorder, target, context.logger);
|
|
25
21
|
}
|
|
26
22
|
for (const { target } of utils_1.getTargets(workspace, 'test', workspace_models_1.Builders.Karma)) {
|
|
27
23
|
updateStyleOrScriptOption('styles', recorder, target);
|
|
28
24
|
updateStyleOrScriptOption('scripts', recorder, target);
|
|
29
|
-
addBuilderI18NOptions(recorder, target, context.logger);
|
|
30
25
|
}
|
|
31
26
|
for (const { target } of utils_1.getTargets(workspace, 'server', workspace_models_1.Builders.Server)) {
|
|
32
27
|
updateOptimizationOption(recorder, target);
|
|
33
28
|
}
|
|
34
|
-
for (const { target, project } of utils_1.getTargets(workspace, 'extract-i18n', workspace_models_1.Builders.ExtractI18n)) {
|
|
35
|
-
addProjectI18NOptions(recorder, tree, target, project);
|
|
36
|
-
removeExtracti18nDeprecatedOptions(recorder, target);
|
|
37
|
-
}
|
|
38
29
|
tree.commitUpdate(recorder);
|
|
39
30
|
return tree;
|
|
40
31
|
};
|
|
41
32
|
}
|
|
42
33
|
exports.updateWorkspaceConfig = updateWorkspaceConfig;
|
|
43
|
-
function addProjectI18NOptions(recorder, tree, builderConfig, projectConfig) {
|
|
44
|
-
const browserConfig = utils_1.getProjectTarget(projectConfig, 'build', workspace_models_1.Builders.Browser);
|
|
45
|
-
if (!browserConfig || browserConfig.kind !== 'object') {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
// browser builder options
|
|
49
|
-
let locales;
|
|
50
|
-
const options = utils_1.getAllOptions(browserConfig);
|
|
51
|
-
for (const option of options) {
|
|
52
|
-
const localeId = json_utils_1.findPropertyInAstObject(option, 'i18nLocale');
|
|
53
|
-
if (!localeId || localeId.kind !== 'string') {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const localeFile = json_utils_1.findPropertyInAstObject(option, 'i18nFile');
|
|
57
|
-
if (!localeFile || localeFile.kind !== 'string') {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
const localIdValue = localeId.value;
|
|
61
|
-
const localeFileValue = localeFile.value;
|
|
62
|
-
const baseHref = json_utils_1.findPropertyInAstObject(option, 'baseHref');
|
|
63
|
-
let baseHrefValue;
|
|
64
|
-
if (baseHref) {
|
|
65
|
-
if (baseHref.kind === 'string' && baseHref.value !== `/${localIdValue}/`) {
|
|
66
|
-
baseHrefValue = baseHref.value;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
// If the configuration does not contain a baseHref, ensure the main option value is used.
|
|
71
|
-
baseHrefValue = '';
|
|
72
|
-
}
|
|
73
|
-
if (!locales) {
|
|
74
|
-
locales = {
|
|
75
|
-
[localIdValue]: baseHrefValue === undefined
|
|
76
|
-
? localeFileValue
|
|
77
|
-
: {
|
|
78
|
-
translation: localeFileValue,
|
|
79
|
-
baseHref: baseHrefValue,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
locales[localIdValue] =
|
|
85
|
-
baseHrefValue === undefined
|
|
86
|
-
? localeFileValue
|
|
87
|
-
: {
|
|
88
|
-
translation: localeFileValue,
|
|
89
|
-
baseHref: baseHrefValue,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (locales) {
|
|
94
|
-
// Get sourceLocale from extract-i18n builder
|
|
95
|
-
const i18nOptions = utils_1.getAllOptions(builderConfig);
|
|
96
|
-
const sourceLocale = i18nOptions
|
|
97
|
-
.map(o => {
|
|
98
|
-
const sourceLocale = json_utils_1.findPropertyInAstObject(o, 'i18nLocale');
|
|
99
|
-
return sourceLocale && sourceLocale.value;
|
|
100
|
-
})
|
|
101
|
-
.find(x => !!x);
|
|
102
|
-
// Add i18n project configuration
|
|
103
|
-
json_utils_1.insertPropertyInAstObjectInOrder(recorder, projectConfig, 'i18n', {
|
|
104
|
-
locales,
|
|
105
|
-
// tslint:disable-next-line: no-any
|
|
106
|
-
sourceLocale: sourceLocale,
|
|
107
|
-
}, 6);
|
|
108
|
-
// Add @angular/localize if not already a dependency
|
|
109
|
-
if (!dependencies_1.getPackageJsonDependency(tree, '@angular/localize')) {
|
|
110
|
-
dependencies_1.addPackageJsonDependency(tree, {
|
|
111
|
-
name: '@angular/localize',
|
|
112
|
-
version: latest_versions_1.latestVersions.Angular,
|
|
113
|
-
type: dependencies_1.NodeDependencyType.Default,
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
function addBuilderI18NOptions(recorder, builderConfig, logger) {
|
|
119
|
-
const options = utils_1.getAllOptions(builderConfig);
|
|
120
|
-
const mainOptions = json_utils_1.findPropertyInAstObject(builderConfig, 'options');
|
|
121
|
-
const mainBaseHref = mainOptions &&
|
|
122
|
-
mainOptions.kind === 'object' &&
|
|
123
|
-
json_utils_1.findPropertyInAstObject(mainOptions, 'baseHref');
|
|
124
|
-
const hasMainBaseHref = !!mainBaseHref && mainBaseHref.kind === 'string' && mainBaseHref.value !== '/';
|
|
125
|
-
for (const option of options) {
|
|
126
|
-
const localeId = json_utils_1.findPropertyInAstObject(option, 'i18nLocale');
|
|
127
|
-
const i18nFile = json_utils_1.findPropertyInAstObject(option, 'i18nFile');
|
|
128
|
-
// The format is always auto-detected now
|
|
129
|
-
const i18nFormat = json_utils_1.findPropertyInAstObject(option, 'i18nFormat');
|
|
130
|
-
if (i18nFormat) {
|
|
131
|
-
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nFormat');
|
|
132
|
-
}
|
|
133
|
-
const outputPath = json_utils_1.findPropertyInAstObject(option, 'outputPath');
|
|
134
|
-
if (localeId &&
|
|
135
|
-
localeId.kind === 'string' &&
|
|
136
|
-
i18nFile &&
|
|
137
|
-
outputPath &&
|
|
138
|
-
outputPath.kind === 'string') {
|
|
139
|
-
// This first block was intended to remove the redundant output path field
|
|
140
|
-
// but due to defects in the recorder, removing the option will cause malformed json
|
|
141
|
-
// if (
|
|
142
|
-
// mainOutputPathValue &&
|
|
143
|
-
// outputPath.value.match(
|
|
144
|
-
// new RegExp(`[/\\\\]?${mainOutputPathValue}[/\\\\]${localeId.value}[/\\\\]?$`),
|
|
145
|
-
// )
|
|
146
|
-
// ) {
|
|
147
|
-
// removePropertyInAstObject(recorder, option, 'outputPath');
|
|
148
|
-
// } else
|
|
149
|
-
if (outputPath.value.match(new RegExp(`[/\\\\]${localeId.value}[/\\\\]?$`))) {
|
|
150
|
-
const newOutputPath = outputPath.value.replace(new RegExp(`[/\\\\]${localeId.value}[/\\\\]?$`), '');
|
|
151
|
-
const { start, end } = outputPath;
|
|
152
|
-
recorder.remove(start.offset, end.offset - start.offset);
|
|
153
|
-
recorder.insertLeft(start.offset, `"${newOutputPath}"`);
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
logger.warn(`Output path value "${outputPath.value}" for locale "${localeId.value}" is not supported with the new localization system. ` +
|
|
157
|
-
`With the current value, the localized output would be written to "${path_1.posix.join(outputPath.value, localeId.value)}". ` +
|
|
158
|
-
`Keeping existing options for the target configuration of locale "${localeId.value}".`);
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (localeId && localeId.kind === 'string') {
|
|
163
|
-
// add new localize option
|
|
164
|
-
json_utils_1.insertPropertyInAstObjectInOrder(recorder, option, 'localize', [localeId.value], 12);
|
|
165
|
-
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nLocale');
|
|
166
|
-
}
|
|
167
|
-
if (i18nFile) {
|
|
168
|
-
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nFile');
|
|
169
|
-
}
|
|
170
|
-
// localize base HREF values are controlled by the i18n configuration
|
|
171
|
-
const baseHref = json_utils_1.findPropertyInAstObject(option, 'baseHref');
|
|
172
|
-
if (localeId && i18nFile && baseHref) {
|
|
173
|
-
// if the main option set has a non-default base href,
|
|
174
|
-
// ensure that the augmented base href has the correct base value
|
|
175
|
-
if (hasMainBaseHref) {
|
|
176
|
-
const { start, end } = baseHref;
|
|
177
|
-
recorder.remove(start.offset, end.offset - start.offset);
|
|
178
|
-
recorder.insertLeft(start.offset, `"/"`);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
json_utils_1.removePropertyInAstObject(recorder, option, 'baseHref');
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function removeExtracti18nDeprecatedOptions(recorder, builderConfig) {
|
|
187
|
-
const options = utils_1.getAllOptions(builderConfig);
|
|
188
|
-
for (const option of options) {
|
|
189
|
-
// deprecated options
|
|
190
|
-
json_utils_1.removePropertyInAstObject(recorder, option, 'i18nLocale');
|
|
191
|
-
const i18nFormat = option.properties.find(({ key }) => key.value === 'i18nFormat');
|
|
192
|
-
if (i18nFormat) {
|
|
193
|
-
// i18nFormat has been changed to format
|
|
194
|
-
const key = i18nFormat.key;
|
|
195
|
-
const offset = key.start.offset + 1;
|
|
196
|
-
recorder.remove(offset, key.value.length);
|
|
197
|
-
recorder.insertLeft(offset, 'format');
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
34
|
function updateAotOption(tree, recorder, builderConfig) {
|
|
202
35
|
const options = json_utils_1.findPropertyInAstObject(builderConfig, 'options');
|
|
203
36
|
if (!options || options.kind !== 'object') {
|
|
@@ -19,3 +19,4 @@ export declare function getAllOptions(builderConfig: JsonAstObject, configuratio
|
|
|
19
19
|
export declare function getWorkspace(host: Tree): JsonAstObject;
|
|
20
20
|
export declare function readJsonFileAsAstObject(host: Tree, path: string): JsonAstObject | undefined;
|
|
21
21
|
export declare function isIvyEnabled(tree: Tree, tsConfigPath: string): boolean;
|
|
22
|
+
export declare function forwardSlashPath(path: string): string;
|
|
@@ -113,3 +113,9 @@ function isIvyEnabled(tree, tsConfigPath) {
|
|
|
113
113
|
return true;
|
|
114
114
|
}
|
|
115
115
|
exports.isIvyEnabled = isIvyEnabled;
|
|
116
|
+
// TS represents paths internally with '/' and expects paths to be in this format.
|
|
117
|
+
// angular.json expects paths with '/', but doesn't enforce them.
|
|
118
|
+
function forwardSlashPath(path) {
|
|
119
|
+
return path.replace(/\\/g, '/');
|
|
120
|
+
}
|
|
121
|
+
exports.forwardSlashPath = forwardSlashPath;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schematics/angular",
|
|
3
|
-
"version": "9.0.0
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "Schematics specific to Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
],
|
|
15
15
|
"schematics": "./collection.json",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@angular-devkit/core": "9.0.0
|
|
18
|
-
"@angular-devkit/schematics": "9.0.0
|
|
17
|
+
"@angular-devkit/core": "9.0.0",
|
|
18
|
+
"@angular-devkit/schematics": "9.0.0"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"engines": {
|
|
25
25
|
"node": ">= 10.13.0",
|
|
26
26
|
"npm": ">= 6.11.0",
|
|
27
|
-
"pnpm": ">= 3.2.0",
|
|
28
27
|
"yarn": ">= 1.13.0"
|
|
29
28
|
},
|
|
30
29
|
"author": "Angular Authors",
|