@angular-devkit/build-angular 13.0.0-next.6 → 13.0.0-next.7
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/package.json +14 -14
- package/src/babel/plugins/adjust-static-class-members.js +2 -2
- package/src/babel/plugins/adjust-typescript-enums.js +8 -2
- package/src/babel/plugins/pure-toplevel-functions.js +2 -2
- package/src/babel/presets/application.d.ts +14 -0
- package/src/babel/presets/application.js +42 -36
- package/src/babel/webpack-loader.js +50 -5
- package/src/builders/app-shell/index.js +9 -9
- package/src/builders/browser/index.js +42 -52
- package/src/builders/dev-server/index.js +23 -23
- package/src/builders/extract-i18n/index.js +33 -21
- package/src/builders/extract-i18n/ivy-extract-loader.js +34 -8
- package/src/builders/karma/find-tests.js +5 -5
- package/src/builders/karma/index.js +14 -14
- package/src/builders/ng-packagr/index.js +4 -4
- package/src/builders/protractor/index.js +4 -4
- package/src/builders/server/index.js +16 -16
- package/src/sass/worker.js +2 -2
- package/src/utils/build-browser-features.js +2 -2
- package/src/utils/bundle-calculator.js +4 -4
- package/src/utils/cache-path.js +2 -2
- package/src/utils/check-port.js +1 -1
- package/src/utils/copy-assets.js +1 -1
- package/src/utils/delete-output-dir.js +1 -1
- package/src/utils/i18n-inlining.js +1 -1
- package/src/utils/i18n-options.js +26 -50
- package/src/utils/index-file/augment-index-html.js +2 -2
- package/src/utils/index-file/index-html-generator.js +3 -3
- package/src/utils/index-file/inline-fonts.js +4 -4
- package/src/utils/load-esm.d.ts +22 -0
- package/src/utils/load-esm.js +37 -0
- package/src/utils/load-translations.js +21 -8
- package/src/utils/normalize-asset-patterns.js +8 -8
- package/src/utils/normalize-builder-schema.js +4 -4
- package/src/utils/normalize-file-replacements.js +10 -10
- package/src/utils/output-paths.js +3 -3
- package/src/utils/package-chunk-sort.js +1 -1
- package/src/utils/process-bundle.d.ts +0 -1
- package/src/utils/process-bundle.js +44 -12
- package/src/utils/read-tsconfig.js +6 -8
- package/src/utils/run-module-as-observable-fork.js +2 -2
- package/src/utils/service-worker.js +16 -9
- package/src/utils/spinner.js +2 -2
- package/src/utils/version.js +1 -1
- package/src/utils/webpack-browser-config.js +11 -11
- package/src/webpack/configs/browser.js +1 -1
- package/src/webpack/configs/common.js +16 -17
- package/src/webpack/configs/dev-server.d.ts +1 -1
- package/src/webpack/configs/dev-server.js +22 -10
- package/src/webpack/configs/server.js +2 -2
- package/src/webpack/configs/styles.js +4 -4
- package/src/webpack/configs/test.js +2 -2
- package/src/webpack/configs/typescript.js +1 -1
- package/src/webpack/configs/worker.js +1 -1
- package/src/webpack/plugins/any-component-style-budget-checker.js +4 -4
- package/src/webpack/plugins/common-js-usage-warn-plugin.js +2 -2
- package/src/webpack/plugins/css-optimizer-plugin.js +1 -1
- package/src/webpack/plugins/dedupe-module-resolve-plugin.js +1 -1
- package/src/webpack/plugins/esbuild-executor.js +1 -1
- package/src/webpack/plugins/hmr/hmr-accept.js +3 -3
- package/src/webpack/plugins/hmr/hmr-loader.js +1 -1
- package/src/webpack/plugins/index-html-webpack-plugin.js +6 -6
- package/src/webpack/plugins/javascript-optimizer-worker.js +2 -2
- package/src/webpack/plugins/karma/karma.js +4 -4
- package/src/webpack/plugins/postcss-cli-resources.js +1 -1
- package/src/webpack/plugins/scripts-webpack-plugin.js +1 -1
- package/src/webpack/plugins/single-test-transform.js +1 -1
- package/src/webpack/utils/stats.js +6 -6
|
@@ -33,9 +33,9 @@ const rxjs_1 = require("rxjs");
|
|
|
33
33
|
const operators_1 = require("rxjs/operators");
|
|
34
34
|
async function initialize(options, root) {
|
|
35
35
|
const packager = (await Promise.resolve().then(() => __importStar(require('ng-packagr')))).ngPackagr();
|
|
36
|
-
packager.forProject(path_1.resolve(root, options.project));
|
|
36
|
+
packager.forProject((0, path_1.resolve)(root, options.project));
|
|
37
37
|
if (options.tsConfig) {
|
|
38
|
-
packager.withTsConfig(path_1.resolve(root, options.tsConfig));
|
|
38
|
+
packager.withTsConfig((0, path_1.resolve)(root, options.tsConfig));
|
|
39
39
|
}
|
|
40
40
|
return packager;
|
|
41
41
|
}
|
|
@@ -43,7 +43,7 @@ async function initialize(options, root) {
|
|
|
43
43
|
* @experimental Direct usage of this function is considered experimental.
|
|
44
44
|
*/
|
|
45
45
|
function execute(options, context) {
|
|
46
|
-
return rxjs_1.from(initialize(options, context.workspaceRoot)).pipe(operators_1.switchMap((packager) => (options.watch ? packager.watch() : packager.build())), operators_1.mapTo({ success: true }), operators_1.catchError((err) => rxjs_1.of({ success: false, error: err.message })));
|
|
46
|
+
return (0, rxjs_1.from)(initialize(options, context.workspaceRoot)).pipe((0, operators_1.switchMap)((packager) => (options.watch ? packager.watch() : packager.build())), (0, operators_1.mapTo)({ success: true }), (0, operators_1.catchError)((err) => (0, rxjs_1.of)({ success: false, error: err.message })));
|
|
47
47
|
}
|
|
48
48
|
exports.execute = execute;
|
|
49
|
-
exports.default = architect_1.createBuilder(execute);
|
|
49
|
+
exports.default = (0, architect_1.createBuilder)(execute);
|
|
@@ -45,8 +45,8 @@ function runProtractor(root, options) {
|
|
|
45
45
|
// TODO: Protractor manages process.exit itself, so this target will allways quit the
|
|
46
46
|
// process. To work around this we run it in a subprocess.
|
|
47
47
|
// https://github.com/angular/protractor/issues/4160
|
|
48
|
-
return utils_1.runModuleAsObservableFork(root, 'protractor/built/launcher', 'init', [
|
|
49
|
-
path_1.resolve(root, options.protractorConfig),
|
|
48
|
+
return (0, utils_1.runModuleAsObservableFork)(root, 'protractor/built/launcher', 'init', [
|
|
49
|
+
(0, path_1.resolve)(root, options.protractorConfig),
|
|
50
50
|
additionalProtractorConfig,
|
|
51
51
|
]).toPromise();
|
|
52
52
|
}
|
|
@@ -97,7 +97,7 @@ async function execute(options, context) {
|
|
|
97
97
|
let baseUrl = options.baseUrl;
|
|
98
98
|
let server;
|
|
99
99
|
if (options.devServerTarget) {
|
|
100
|
-
const target = architect_1.targetFromTargetString(options.devServerTarget);
|
|
100
|
+
const target = (0, architect_1.targetFromTargetString)(options.devServerTarget);
|
|
101
101
|
const serverOptions = await context.getTargetOptions(target);
|
|
102
102
|
const overrides = {
|
|
103
103
|
watch: false,
|
|
@@ -160,4 +160,4 @@ async function execute(options, context) {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
exports.execute = execute;
|
|
163
|
-
exports.default = architect_1.createBuilder(execute);
|
|
163
|
+
exports.default = (0, architect_1.createBuilder)(execute);
|
|
@@ -47,7 +47,7 @@ const stats_1 = require("../../webpack/utils/stats");
|
|
|
47
47
|
function execute(options, context, transforms = {}) {
|
|
48
48
|
const root = context.workspaceRoot;
|
|
49
49
|
// Check Angular version.
|
|
50
|
-
version_1.assertCompatibleAngularVersion(root);
|
|
50
|
+
(0, version_1.assertCompatibleAngularVersion)(root);
|
|
51
51
|
const baseOutputPath = path.resolve(root, options.outputPath);
|
|
52
52
|
let outputPaths;
|
|
53
53
|
if (typeof options.bundleDependencies === 'string') {
|
|
@@ -67,28 +67,28 @@ function execute(options, context, transforms = {}) {
|
|
|
67
67
|
`);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
return rxjs_1.from(initialize(options, context, transforms.webpackConfiguration)).pipe(operators_1.concatMap(({ config, i18n, target }) => {
|
|
71
|
-
return build_webpack_1.runWebpack(config, context, {
|
|
70
|
+
return (0, rxjs_1.from)(initialize(options, context, transforms.webpackConfiguration)).pipe((0, operators_1.concatMap)(({ config, i18n, target }) => {
|
|
71
|
+
return (0, build_webpack_1.runWebpack)(config, context, {
|
|
72
72
|
webpackFactory: require('webpack'),
|
|
73
73
|
logging: (stats, config) => {
|
|
74
74
|
if (options.verbose) {
|
|
75
75
|
context.logger.info(stats.toString(config.stats));
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
|
-
}).pipe(operators_1.concatMap(async (output) => {
|
|
78
|
+
}).pipe((0, operators_1.concatMap)(async (output) => {
|
|
79
79
|
const { emittedFiles = [], outputPath, webpackStats } = output;
|
|
80
80
|
if (!webpackStats) {
|
|
81
81
|
throw new Error('Webpack stats build result is required.');
|
|
82
82
|
}
|
|
83
83
|
let success = output.success;
|
|
84
84
|
if (success && i18n.shouldInline) {
|
|
85
|
-
outputPaths = output_paths_1.ensureOutputPaths(baseOutputPath, i18n);
|
|
86
|
-
success = await i18n_inlining_1.i18nInlineEmittedFiles(context, emittedFiles, i18n, baseOutputPath, Array.from(outputPaths.values()), [], outputPath, target <= typescript_1.ScriptTarget.ES5, options.i18nMissingTranslation);
|
|
85
|
+
outputPaths = (0, output_paths_1.ensureOutputPaths)(baseOutputPath, i18n);
|
|
86
|
+
success = await (0, i18n_inlining_1.i18nInlineEmittedFiles)(context, emittedFiles, i18n, baseOutputPath, Array.from(outputPaths.values()), [], outputPath, target <= typescript_1.ScriptTarget.ES5, options.i18nMissingTranslation);
|
|
87
87
|
}
|
|
88
|
-
stats_1.webpackStatsLogger(context.logger, webpackStats, config);
|
|
88
|
+
(0, stats_1.webpackStatsLogger)(context.logger, webpackStats, config);
|
|
89
89
|
return { ...output, success };
|
|
90
90
|
}));
|
|
91
|
-
}), operators_1.map((output) => {
|
|
91
|
+
}), (0, operators_1.map)((output) => {
|
|
92
92
|
if (!output.success) {
|
|
93
93
|
return output;
|
|
94
94
|
}
|
|
@@ -101,27 +101,27 @@ function execute(options, context, transforms = {}) {
|
|
|
101
101
|
}));
|
|
102
102
|
}
|
|
103
103
|
exports.execute = execute;
|
|
104
|
-
exports.default = architect_1.createBuilder(execute);
|
|
104
|
+
exports.default = (0, architect_1.createBuilder)(execute);
|
|
105
105
|
async function initialize(options, context, webpackConfigurationTransform) {
|
|
106
106
|
const originalOutputPath = options.outputPath;
|
|
107
|
-
const { config, i18n, target } = await webpack_browser_config_1.generateI18nBrowserWebpackConfigFromContext({
|
|
107
|
+
const { config, i18n, target } = await (0, webpack_browser_config_1.generateI18nBrowserWebpackConfigFromContext)({
|
|
108
108
|
...options,
|
|
109
109
|
buildOptimizer: false,
|
|
110
110
|
aot: true,
|
|
111
111
|
platform: 'server',
|
|
112
112
|
}, context, (wco) => [
|
|
113
|
-
configs_1.getCommonConfig(wco),
|
|
114
|
-
configs_1.getServerConfig(wco),
|
|
115
|
-
configs_1.getStylesConfig(wco),
|
|
116
|
-
configs_1.getStatsConfig(wco),
|
|
117
|
-
configs_1.getTypeScriptConfig(wco),
|
|
113
|
+
(0, configs_1.getCommonConfig)(wco),
|
|
114
|
+
(0, configs_1.getServerConfig)(wco),
|
|
115
|
+
(0, configs_1.getStylesConfig)(wco),
|
|
116
|
+
(0, configs_1.getStatsConfig)(wco),
|
|
117
|
+
(0, configs_1.getTypeScriptConfig)(wco),
|
|
118
118
|
]);
|
|
119
119
|
let transformedConfig;
|
|
120
120
|
if (webpackConfigurationTransform) {
|
|
121
121
|
transformedConfig = await webpackConfigurationTransform(config);
|
|
122
122
|
}
|
|
123
123
|
if (options.deleteOutputPath) {
|
|
124
|
-
utils_1.deleteOutputDir(context.workspaceRoot, originalOutputPath);
|
|
124
|
+
(0, utils_1.deleteOutputDir)(context.workspaceRoot, originalOutputPath);
|
|
125
125
|
}
|
|
126
126
|
return { config: transformedConfig || config, i18n, target };
|
|
127
127
|
}
|
package/src/sass/worker.js
CHANGED
|
@@ -29,11 +29,11 @@ worker_threads_1.parentPort.on('message', ({ id, hasImporter, options }) => {
|
|
|
29
29
|
const { fromImport } = this;
|
|
30
30
|
workerImporterPort.postMessage({ id, url, prev, fromImport });
|
|
31
31
|
Atomics.wait(importerSignal, 0, 0);
|
|
32
|
-
return (_a = worker_threads_1.receiveMessageOnPort(workerImporterPort)) === null || _a === void 0 ? void 0 : _a.message;
|
|
32
|
+
return (_a = (0, worker_threads_1.receiveMessageOnPort)(workerImporterPort)) === null || _a === void 0 ? void 0 : _a.message;
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
// The synchronous Sass render function can be up to two times faster than the async variant
|
|
36
|
-
const result = sass_1.renderSync(options);
|
|
36
|
+
const result = (0, sass_1.renderSync)(options);
|
|
37
37
|
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage({ id, result });
|
|
38
38
|
}
|
|
39
39
|
catch (error) {
|
|
@@ -28,7 +28,7 @@ class BuildBrowserFeatures {
|
|
|
28
28
|
'last 2 iOS major versions',
|
|
29
29
|
'Firefox ESR',
|
|
30
30
|
];
|
|
31
|
-
this.supportedBrowsers = browserslist_1.default(undefined, { path: this.projectRoot });
|
|
31
|
+
this.supportedBrowsers = (0, browserslist_1.default)(undefined, { path: this.projectRoot });
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* True, when a browser feature is supported partially or fully.
|
|
@@ -39,7 +39,7 @@ class BuildBrowserFeatures {
|
|
|
39
39
|
// a: feature is partially supported
|
|
40
40
|
// x: feature is prefixed
|
|
41
41
|
const criteria = ['y', 'a'];
|
|
42
|
-
const data = caniuse_lite_1.feature(caniuse_lite_1.features[featureId]);
|
|
42
|
+
const data = (0, caniuse_lite_1.feature)(caniuse_lite_1.features[featureId]);
|
|
43
43
|
return !this.supportedBrowsers.some((browser) => {
|
|
44
44
|
const [agentId, version] = browser.split(' ');
|
|
45
45
|
const browserData = data.stats[agentId];
|
|
@@ -259,10 +259,10 @@ function* checkThresholds(thresholds, size, label) {
|
|
|
259
259
|
if (size <= threshold.limit) {
|
|
260
260
|
continue;
|
|
261
261
|
}
|
|
262
|
-
const sizeDifference = stats_1.formatSize(size - threshold.limit);
|
|
262
|
+
const sizeDifference = (0, stats_1.formatSize)(size - threshold.limit);
|
|
263
263
|
yield {
|
|
264
264
|
severity: threshold.severity,
|
|
265
|
-
message: `${label} exceeded maximum budget. Budget ${stats_1.formatSize(threshold.limit)} was not met by ${sizeDifference} with a total of ${stats_1.formatSize(size)}.`,
|
|
265
|
+
message: `${label} exceeded maximum budget. Budget ${(0, stats_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, stats_1.formatSize)(size)}.`,
|
|
266
266
|
};
|
|
267
267
|
break;
|
|
268
268
|
}
|
|
@@ -270,10 +270,10 @@ function* checkThresholds(thresholds, size, label) {
|
|
|
270
270
|
if (size >= threshold.limit) {
|
|
271
271
|
continue;
|
|
272
272
|
}
|
|
273
|
-
const sizeDifference = stats_1.formatSize(threshold.limit - size);
|
|
273
|
+
const sizeDifference = (0, stats_1.formatSize)(threshold.limit - size);
|
|
274
274
|
yield {
|
|
275
275
|
severity: threshold.severity,
|
|
276
|
-
message: `${label} failed to meet minimum budget. Budget ${stats_1.formatSize(threshold.limit)} was not met by ${sizeDifference} with a total of ${stats_1.formatSize(size)}.`,
|
|
276
|
+
message: `${label} failed to meet minimum budget. Budget ${(0, stats_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, stats_1.formatSize)(size)}.`,
|
|
277
277
|
};
|
|
278
278
|
break;
|
|
279
279
|
}
|
package/src/utils/cache-path.js
CHANGED
|
@@ -17,8 +17,8 @@ const path_1 = require("path");
|
|
|
17
17
|
const environment_options_1 = require("./environment-options");
|
|
18
18
|
function findCachePath(name) {
|
|
19
19
|
if (environment_options_1.cachingBasePath) {
|
|
20
|
-
return path_1.resolve(environment_options_1.cachingBasePath, name);
|
|
20
|
+
return (0, path_1.resolve)(environment_options_1.cachingBasePath, name);
|
|
21
21
|
}
|
|
22
|
-
return find_cache_dir_1.default({ name }) || os_1.tmpdir();
|
|
22
|
+
return (0, find_cache_dir_1.default)({ name }) || (0, os_1.tmpdir)();
|
|
23
23
|
}
|
|
24
24
|
exports.findCachePath = findCachePath;
|
package/src/utils/check-port.js
CHANGED
|
@@ -49,7 +49,7 @@ async function checkPort(port, host) {
|
|
|
49
49
|
reject(createInUseError(port));
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
|
-
inquirer_1.prompt({
|
|
52
|
+
(0, inquirer_1.prompt)({
|
|
53
53
|
type: 'confirm',
|
|
54
54
|
name: 'useDifferent',
|
|
55
55
|
message: `Port ${port} is already in use.\nWould you like to use a different port?`,
|
package/src/utils/copy-assets.js
CHANGED
|
@@ -34,7 +34,7 @@ const fs = __importStar(require("fs"));
|
|
|
34
34
|
const glob_1 = __importDefault(require("glob"));
|
|
35
35
|
const path = __importStar(require("path"));
|
|
36
36
|
function globAsync(pattern, options) {
|
|
37
|
-
return new Promise((resolve, reject) => glob_1.default(pattern, options, (e, m) => (e ? reject(e) : resolve(m))));
|
|
37
|
+
return new Promise((resolve, reject) => (0, glob_1.default)(pattern, options, (e, m) => (e ? reject(e) : resolve(m))));
|
|
38
38
|
}
|
|
39
39
|
async function copyAssets(entries, basePaths, root, changed) {
|
|
40
40
|
const defaultIgnore = ['.gitkeep', '**/.DS_Store', '**/Thumbs.db'];
|
|
@@ -33,7 +33,7 @@ const path_1 = require("path");
|
|
|
33
33
|
* Delete an output directory, but error out if it's the root of the project.
|
|
34
34
|
*/
|
|
35
35
|
function deleteOutputDir(root, outputPath) {
|
|
36
|
-
const resolvedOutputPath = path_1.resolve(root, outputPath);
|
|
36
|
+
const resolvedOutputPath = (0, path_1.resolve)(root, outputPath);
|
|
37
37
|
if (resolvedOutputPath === root) {
|
|
38
38
|
throw new Error('Output path MUST not be project root directory!');
|
|
39
39
|
}
|
|
@@ -86,7 +86,7 @@ async function i18nInlineEmittedFiles(context, emittedFiles, i18n, baseOutputPat
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
// Copy any non-processed files into the output locations
|
|
89
|
-
await copy_assets_1.copyAssets([
|
|
89
|
+
await (0, copy_assets_1.copyAssets)([
|
|
90
90
|
{
|
|
91
91
|
glob: '**/*',
|
|
92
92
|
input: emittedPath,
|
|
@@ -6,33 +6,22 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
-
if (mod && mod.__esModule) return mod;
|
|
23
|
-
var result = {};
|
|
24
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
-
__setModuleDefault(result, mod);
|
|
26
|
-
return result;
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
11
|
};
|
|
28
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
13
|
exports.configureI18nBuild = exports.createI18nOptions = void 0;
|
|
30
14
|
const core_1 = require("@angular-devkit/core");
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const module_1 = __importDefault(require("module"));
|
|
17
|
+
const os_1 = __importDefault(require("os"));
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
34
19
|
const read_tsconfig_1 = require("../utils/read-tsconfig");
|
|
35
20
|
const load_translations_1 = require("./load-translations");
|
|
21
|
+
/**
|
|
22
|
+
* The base module location used to search for locale specific data.
|
|
23
|
+
*/
|
|
24
|
+
const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global';
|
|
36
25
|
function normalizeTranslationFileOption(option, locale, expectObjectInError) {
|
|
37
26
|
if (typeof option === 'string') {
|
|
38
27
|
return [option];
|
|
@@ -132,18 +121,17 @@ async function configureI18nBuild(context, options) {
|
|
|
132
121
|
throw new Error('The builder requires a target.');
|
|
133
122
|
}
|
|
134
123
|
const buildOptions = { ...options };
|
|
135
|
-
const tsConfig = await read_tsconfig_1.readTsconfig(buildOptions.tsConfig, context.workspaceRoot);
|
|
124
|
+
const tsConfig = await (0, read_tsconfig_1.readTsconfig)(buildOptions.tsConfig, context.workspaceRoot);
|
|
136
125
|
const metadata = await context.getProjectMetadata(context.target);
|
|
137
126
|
const i18n = createI18nOptions(metadata, buildOptions.localize);
|
|
138
127
|
// No additional processing needed if no inlining requested and no source locale defined.
|
|
139
128
|
if (!i18n.shouldInline && !i18n.hasDefinedSourceLocale) {
|
|
140
129
|
return { buildOptions, i18n };
|
|
141
130
|
}
|
|
142
|
-
const projectRoot =
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
131
|
+
const projectRoot = path_1.default.join(context.workspaceRoot, metadata.root || '');
|
|
132
|
+
// The trailing slash is required to signal that the path is a directory and not a file.
|
|
133
|
+
const projectRequire = module_1.default.createRequire(projectRoot + '/');
|
|
134
|
+
const localeResolver = (locale) => projectRequire.resolve(path_1.default.join(LOCALE_DATA_BASE_MODULE, locale));
|
|
147
135
|
// Load locale data and translations (if present)
|
|
148
136
|
let loader;
|
|
149
137
|
const usedFormats = new Set();
|
|
@@ -151,11 +139,11 @@ async function configureI18nBuild(context, options) {
|
|
|
151
139
|
if (!i18n.inlineLocales.has(locale) && locale !== i18n.sourceLocale) {
|
|
152
140
|
continue;
|
|
153
141
|
}
|
|
154
|
-
let localeDataPath = findLocaleDataPath(locale,
|
|
142
|
+
let localeDataPath = findLocaleDataPath(locale, localeResolver);
|
|
155
143
|
if (!localeDataPath) {
|
|
156
144
|
const [first] = locale.split('-');
|
|
157
145
|
if (first) {
|
|
158
|
-
localeDataPath = findLocaleDataPath(first.toLowerCase(),
|
|
146
|
+
localeDataPath = findLocaleDataPath(first.toLowerCase(), localeResolver);
|
|
159
147
|
if (localeDataPath) {
|
|
160
148
|
context.logger.warn(`Locale data for '${locale}' cannot be found. Using locale data for '${first}'.`);
|
|
161
149
|
}
|
|
@@ -171,10 +159,10 @@ async function configureI18nBuild(context, options) {
|
|
|
171
159
|
continue;
|
|
172
160
|
}
|
|
173
161
|
if (!loader) {
|
|
174
|
-
loader = await load_translations_1.createTranslationLoader();
|
|
162
|
+
loader = await (0, load_translations_1.createTranslationLoader)();
|
|
175
163
|
}
|
|
176
164
|
for (const file of desc.files) {
|
|
177
|
-
const loadResult = loader(
|
|
165
|
+
const loadResult = loader(path_1.default.join(context.workspaceRoot, file.path));
|
|
178
166
|
for (const diagnostics of loadResult.diagnostics.messages) {
|
|
179
167
|
if (diagnostics.type === 'error') {
|
|
180
168
|
throw new Error(`Error parsing translation file '${file.path}': ${diagnostics.message}`);
|
|
@@ -210,12 +198,12 @@ async function configureI18nBuild(context, options) {
|
|
|
210
198
|
}
|
|
211
199
|
// If inlining store the output in a temporary location to facilitate post-processing
|
|
212
200
|
if (i18n.shouldInline) {
|
|
213
|
-
const tempPath =
|
|
201
|
+
const tempPath = fs_1.default.mkdtempSync(path_1.default.join(fs_1.default.realpathSync(os_1.default.tmpdir()), 'angular-cli-i18n-'));
|
|
214
202
|
buildOptions.outputPath = tempPath;
|
|
215
203
|
// Remove temporary directory used for i18n processing
|
|
216
204
|
process.on('exit', () => {
|
|
217
205
|
try {
|
|
218
|
-
|
|
206
|
+
fs_1.default.rmdirSync(tempPath, { recursive: true, maxRetries: 3 });
|
|
219
207
|
}
|
|
220
208
|
catch { }
|
|
221
209
|
});
|
|
@@ -223,29 +211,17 @@ async function configureI18nBuild(context, options) {
|
|
|
223
211
|
return { buildOptions, i18n };
|
|
224
212
|
}
|
|
225
213
|
exports.configureI18nBuild = configureI18nBuild;
|
|
226
|
-
function
|
|
214
|
+
function findLocaleDataPath(locale, resolver) {
|
|
215
|
+
// Remove private use subtags
|
|
216
|
+
const scrubbedLocale = locale.replace(/-x(-[a-zA-Z0-9]{1,8})+$/, '');
|
|
227
217
|
try {
|
|
228
|
-
|
|
229
|
-
const localesPath = path.join(commonPath, 'locales/global');
|
|
230
|
-
if (!fs.existsSync(localesPath)) {
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
return localesPath;
|
|
218
|
+
return resolver(scrubbedLocale);
|
|
234
219
|
}
|
|
235
220
|
catch {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
function findLocaleDataPath(locale, basePath) {
|
|
240
|
-
// Remove private use subtags
|
|
241
|
-
const scrubbedLocale = locale.replace(/-x(-[a-zA-Z0-9]{1,8})+$/, '');
|
|
242
|
-
const localeDataPath = path.join(basePath, scrubbedLocale + '.js');
|
|
243
|
-
if (!fs.existsSync(localeDataPath)) {
|
|
244
221
|
if (scrubbedLocale === 'en-US') {
|
|
245
222
|
// fallback to known existing en-US locale data as of 9.0
|
|
246
|
-
return findLocaleDataPath('en-US-POSIX',
|
|
223
|
+
return findLocaleDataPath('en-US-POSIX', resolver);
|
|
247
224
|
}
|
|
248
225
|
return null;
|
|
249
226
|
}
|
|
250
|
-
return localeDataPath;
|
|
251
227
|
}
|
|
@@ -72,7 +72,7 @@ async function augmentIndexHtml(params) {
|
|
|
72
72
|
}
|
|
73
73
|
linkTags.push(`<link ${attrs.join(' ')}>`);
|
|
74
74
|
}
|
|
75
|
-
const { rewriter, transformedContent } = await html_rewriting_stream_1.htmlRewritingStream(html);
|
|
75
|
+
const { rewriter, transformedContent } = await (0, html_rewriting_stream_1.htmlRewritingStream)(html);
|
|
76
76
|
const baseTagExists = html.includes('<base');
|
|
77
77
|
rewriter
|
|
78
78
|
.on('startTag', (tag) => {
|
|
@@ -128,7 +128,7 @@ async function augmentIndexHtml(params) {
|
|
|
128
128
|
exports.augmentIndexHtml = augmentIndexHtml;
|
|
129
129
|
function generateSriAttributes(content) {
|
|
130
130
|
const algo = 'sha384';
|
|
131
|
-
const hash = crypto_1.createHash(algo).update(content, 'utf8').digest('base64');
|
|
131
|
+
const hash = (0, crypto_1.createHash)(algo).update(content, 'utf8').digest('base64');
|
|
132
132
|
return `integrity="${algo}-${hash}"`;
|
|
133
133
|
}
|
|
134
134
|
function updateAttribute(tag, name, value) {
|
|
@@ -47,7 +47,7 @@ class IndexHtmlGenerator {
|
|
|
47
47
|
this.plugins = [augmentIndexHtmlPlugin(this), ...extraPlugins, postTransformPlugin(this)];
|
|
48
48
|
}
|
|
49
49
|
async process(options) {
|
|
50
|
-
let content = strip_bom_1.stripBom(await this.readIndex(this.options.indexPath));
|
|
50
|
+
let content = (0, strip_bom_1.stripBom)(await this.readIndex(this.options.indexPath));
|
|
51
51
|
const warnings = [];
|
|
52
52
|
const errors = [];
|
|
53
53
|
for (const plugin of this.plugins) {
|
|
@@ -83,7 +83,7 @@ function augmentIndexHtmlPlugin(generator) {
|
|
|
83
83
|
const { deployUrl, crossOrigin, sri = false, entrypoints } = generator.options;
|
|
84
84
|
return async (html, options) => {
|
|
85
85
|
const { lang, baseHref, outputPath = '', files } = options;
|
|
86
|
-
return augment_index_html_1.augmentIndexHtml({
|
|
86
|
+
return (0, augment_index_html_1.augmentIndexHtml)({
|
|
87
87
|
html,
|
|
88
88
|
baseHref,
|
|
89
89
|
deployUrl,
|
|
@@ -91,7 +91,7 @@ function augmentIndexHtmlPlugin(generator) {
|
|
|
91
91
|
sri,
|
|
92
92
|
lang,
|
|
93
93
|
entrypoints,
|
|
94
|
-
loadOutputFile: (filePath) => generator.readAsset(path_1.join(outputPath, filePath)),
|
|
94
|
+
loadOutputFile: (filePath) => generator.readAsset((0, path_1.join)(outputPath, filePath)),
|
|
95
95
|
files,
|
|
96
96
|
});
|
|
97
97
|
};
|
|
@@ -40,7 +40,7 @@ const environment_options_1 = require("../environment-options");
|
|
|
40
40
|
const html_rewriting_stream_1 = require("./html-rewriting-stream");
|
|
41
41
|
const cacheFontsPath = environment_options_1.cachingDisabled
|
|
42
42
|
? undefined
|
|
43
|
-
: cache_path_1.findCachePath('angular-build-fonts');
|
|
43
|
+
: (0, cache_path_1.findCachePath)('angular-build-fonts');
|
|
44
44
|
const packageVersion = require('../../../package.json').version;
|
|
45
45
|
const SUPPORTED_PROVIDERS = {
|
|
46
46
|
'fonts.googleapis.com': {
|
|
@@ -59,7 +59,7 @@ class InlineFontsProcessor {
|
|
|
59
59
|
const hrefList = [];
|
|
60
60
|
const existingPreconnect = new Set();
|
|
61
61
|
// Collector link tags with href
|
|
62
|
-
const { rewriter: collectorStream } = await html_rewriting_stream_1.htmlRewritingStream(content);
|
|
62
|
+
const { rewriter: collectorStream } = await (0, html_rewriting_stream_1.htmlRewritingStream)(content);
|
|
63
63
|
collectorStream.on('startTag', (tag) => {
|
|
64
64
|
const { tagName, attrs } = tag;
|
|
65
65
|
if (tagName !== 'link') {
|
|
@@ -115,7 +115,7 @@ class InlineFontsProcessor {
|
|
|
115
115
|
return content;
|
|
116
116
|
}
|
|
117
117
|
// Replace link with style tag.
|
|
118
|
-
const { rewriter, transformedContent } = await html_rewriting_stream_1.htmlRewritingStream(content);
|
|
118
|
+
const { rewriter, transformedContent } = await (0, html_rewriting_stream_1.htmlRewritingStream)(content);
|
|
119
119
|
rewriter.on('startTag', (tag) => {
|
|
120
120
|
const { tagName, attrs } = tag;
|
|
121
121
|
switch (tagName) {
|
|
@@ -156,7 +156,7 @@ class InlineFontsProcessor {
|
|
|
156
156
|
let agent;
|
|
157
157
|
const httpsProxy = (_a = process.env.HTTPS_PROXY) !== null && _a !== void 0 ? _a : process.env.https_proxy;
|
|
158
158
|
if (httpsProxy) {
|
|
159
|
-
agent = https_proxy_agent_1.default(httpsProxy);
|
|
159
|
+
agent = (0, https_proxy_agent_1.default)(httpsProxy);
|
|
160
160
|
}
|
|
161
161
|
const data = await new Promise((resolve, reject) => {
|
|
162
162
|
let rawResponse = '';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
/// <reference types="node" />
|
|
9
|
+
import { URL } from 'url';
|
|
10
|
+
/**
|
|
11
|
+
* This uses a dynamic import to load a module which may be ESM.
|
|
12
|
+
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
|
|
13
|
+
* will currently, unconditionally downlevel dynamic import into a require call.
|
|
14
|
+
* require calls cannot load ESM code and will result in a runtime error. To workaround
|
|
15
|
+
* this, a Function constructor is used to prevent TypeScript from changing the dynamic import.
|
|
16
|
+
* Once TypeScript provides support for keeping the dynamic import this workaround can
|
|
17
|
+
* be dropped.
|
|
18
|
+
*
|
|
19
|
+
* @param modulePath The path of the module to load.
|
|
20
|
+
* @returns A Promise that resolves to the dynamically imported module.
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadEsmModule<T>(modulePath: string | URL): Promise<T>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC 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
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.loadEsmModule = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* This uses a dynamic import to load a module which may be ESM.
|
|
13
|
+
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
|
|
14
|
+
* will currently, unconditionally downlevel dynamic import into a require call.
|
|
15
|
+
* require calls cannot load ESM code and will result in a runtime error. To workaround
|
|
16
|
+
* this, a Function constructor is used to prevent TypeScript from changing the dynamic import.
|
|
17
|
+
* Once TypeScript provides support for keeping the dynamic import this workaround can
|
|
18
|
+
* be dropped.
|
|
19
|
+
*
|
|
20
|
+
* @param modulePath The path of the module to load.
|
|
21
|
+
* @returns A Promise that resolves to the dynamically imported module.
|
|
22
|
+
*/
|
|
23
|
+
async function loadEsmModule(modulePath) {
|
|
24
|
+
try {
|
|
25
|
+
return (await new Function('modulePath', `return import(modulePath);`)(modulePath));
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
// Temporary workaround to handle directory imports for current packages. ESM does not support
|
|
29
|
+
// directory imports.
|
|
30
|
+
// TODO_ESM: Remove once FW packages are fully ESM with defined `exports` package.json fields
|
|
31
|
+
if (e.code !== 'ERR_UNSUPPORTED_DIR_IMPORT') {
|
|
32
|
+
throw e;
|
|
33
|
+
}
|
|
34
|
+
return (await new Function('modulePath', `return import(modulePath);`)(modulePath + '/index.js'));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.loadEsmModule = loadEsmModule;
|
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.createTranslationLoader = void 0;
|
|
30
30
|
const crypto_1 = require("crypto");
|
|
31
31
|
const fs = __importStar(require("fs"));
|
|
32
|
+
const load_esm_1 = require("./load-esm");
|
|
32
33
|
async function createTranslationLoader() {
|
|
33
34
|
const { parsers, diagnostics } = await importParsers();
|
|
34
35
|
return (path) => {
|
|
@@ -38,7 +39,7 @@ async function createTranslationLoader() {
|
|
|
38
39
|
const analysis = analyze(parser, path, content);
|
|
39
40
|
if (analysis.canParse) {
|
|
40
41
|
const { locale, translations } = parser.parse(path, content, analysis.hint);
|
|
41
|
-
const integrity = 'sha256-' + crypto_1.createHash('sha256').update(content).digest('base64');
|
|
42
|
+
const integrity = 'sha256-' + (0, crypto_1.createHash)('sha256').update(content).digest('base64');
|
|
42
43
|
return { format, locale, translations, diagnostics, integrity };
|
|
43
44
|
}
|
|
44
45
|
else {
|
|
@@ -66,16 +67,28 @@ async function createTranslationLoader() {
|
|
|
66
67
|
}
|
|
67
68
|
exports.createTranslationLoader = createTranslationLoader;
|
|
68
69
|
async function importParsers() {
|
|
70
|
+
// All the localize usages are setup to first try the ESM entry point then fallback to the deep imports.
|
|
71
|
+
// This provides interim compatibility while the framework is transitioned to bundled ESM packages.
|
|
72
|
+
// TODO_ESM: Remove all deep imports once `@angular/localize` is published with the `tools` entry point
|
|
73
|
+
let localizeToolsModule;
|
|
69
74
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
75
|
+
// Load ESM `@angular/localize/tools` using the TypeScript dynamic import workaround.
|
|
76
|
+
// Once TypeScript provides support for keeping the dynamic import this workaround can be
|
|
77
|
+
// changed to a direct dynamic import.
|
|
78
|
+
// TODO_ESM: The type needs to be manually constructed until the tools entry point exists
|
|
79
|
+
localizeToolsModule = await (0, load_esm_1.loadEsmModule)('@angular/localize/tools');
|
|
80
|
+
}
|
|
81
|
+
catch { }
|
|
82
|
+
try {
|
|
83
|
+
const { Diagnostics } = localizeToolsModule !== null && localizeToolsModule !== void 0 ? localizeToolsModule : (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/diagnostics'))));
|
|
84
|
+
const diagnostics = new Diagnostics();
|
|
72
85
|
const parsers = {
|
|
73
|
-
arb: new (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/arb_translation_parser')))).ArbTranslationParser(),
|
|
74
|
-
json: new (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/simple_json_translation_parser')))).SimpleJsonTranslationParser(),
|
|
75
|
-
xlf: new (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/xliff1_translation_parser')))).Xliff1TranslationParser(),
|
|
76
|
-
xlf2: new (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/xliff2_translation_parser')))).Xliff2TranslationParser(),
|
|
86
|
+
arb: new (localizeToolsModule !== null && localizeToolsModule !== void 0 ? localizeToolsModule : (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/arb_translation_parser'))))).ArbTranslationParser(),
|
|
87
|
+
json: new (localizeToolsModule !== null && localizeToolsModule !== void 0 ? localizeToolsModule : (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/simple_json_translation_parser'))))).SimpleJsonTranslationParser(),
|
|
88
|
+
xlf: new (localizeToolsModule !== null && localizeToolsModule !== void 0 ? localizeToolsModule : (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/xliff1_translation_parser'))))).Xliff1TranslationParser(),
|
|
89
|
+
xlf2: new (localizeToolsModule !== null && localizeToolsModule !== void 0 ? localizeToolsModule : (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/xliff2_translation_parser'))))).Xliff2TranslationParser(),
|
|
77
90
|
// The name ('xmb') needs to match the AOT compiler option
|
|
78
|
-
xmb: new (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/xtb_translation_parser')))).XtbTranslationParser(),
|
|
91
|
+
xmb: new (localizeToolsModule !== null && localizeToolsModule !== void 0 ? localizeToolsModule : (await Promise.resolve().then(() => __importStar(require('@angular/localize/src/tools/src/translate/translation_files/translation_parsers/xtb_translation_parser'))))).XtbTranslationParser(),
|
|
79
92
|
};
|
|
80
93
|
return { parsers, diagnostics };
|
|
81
94
|
}
|
|
@@ -18,16 +18,16 @@ class MissingAssetSourceRootException extends core_1.BaseException {
|
|
|
18
18
|
exports.MissingAssetSourceRootException = MissingAssetSourceRootException;
|
|
19
19
|
function normalizeAssetPatterns(assetPatterns, root, projectRoot, maybeSourceRoot) {
|
|
20
20
|
// When sourceRoot is not available, we default to ${projectRoot}/src.
|
|
21
|
-
const sourceRoot = maybeSourceRoot || core_1.join(projectRoot, 'src');
|
|
22
|
-
const resolvedSourceRoot = core_1.resolve(root, sourceRoot);
|
|
21
|
+
const sourceRoot = maybeSourceRoot || (0, core_1.join)(projectRoot, 'src');
|
|
22
|
+
const resolvedSourceRoot = (0, core_1.resolve)(root, sourceRoot);
|
|
23
23
|
if (assetPatterns.length === 0) {
|
|
24
24
|
return [];
|
|
25
25
|
}
|
|
26
26
|
return assetPatterns.map((assetPattern) => {
|
|
27
27
|
// Normalize string asset patterns to objects.
|
|
28
28
|
if (typeof assetPattern === 'string') {
|
|
29
|
-
const assetPath = core_1.normalize(assetPattern);
|
|
30
|
-
const resolvedAssetPath = core_1.resolve(root, assetPath);
|
|
29
|
+
const assetPath = (0, core_1.normalize)(assetPattern);
|
|
30
|
+
const resolvedAssetPath = (0, core_1.resolve)(root, assetPath);
|
|
31
31
|
// Check if the string asset is within sourceRoot.
|
|
32
32
|
if (!resolvedAssetPath.startsWith(resolvedSourceRoot)) {
|
|
33
33
|
throw new MissingAssetSourceRootException(assetPattern);
|
|
@@ -35,7 +35,7 @@ function normalizeAssetPatterns(assetPatterns, root, projectRoot, maybeSourceRoo
|
|
|
35
35
|
let glob, input;
|
|
36
36
|
let isDirectory = false;
|
|
37
37
|
try {
|
|
38
|
-
isDirectory = fs_1.statSync(core_1.getSystemPath(resolvedAssetPath)).isDirectory();
|
|
38
|
+
isDirectory = (0, fs_1.statSync)((0, core_1.getSystemPath)(resolvedAssetPath)).isDirectory();
|
|
39
39
|
}
|
|
40
40
|
catch {
|
|
41
41
|
isDirectory = true;
|
|
@@ -48,12 +48,12 @@ function normalizeAssetPatterns(assetPatterns, root, projectRoot, maybeSourceRoo
|
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
50
|
// Files are their own glob.
|
|
51
|
-
glob = core_1.basename(assetPath);
|
|
51
|
+
glob = (0, core_1.basename)(assetPath);
|
|
52
52
|
// Input directory is their original dirname.
|
|
53
|
-
input = core_1.dirname(assetPath);
|
|
53
|
+
input = (0, core_1.dirname)(assetPath);
|
|
54
54
|
}
|
|
55
55
|
// Output directory for both is the relative path from source root to input.
|
|
56
|
-
const output = core_1.relative(resolvedSourceRoot, core_1.resolve(root, input));
|
|
56
|
+
const output = (0, core_1.relative)(resolvedSourceRoot, (0, core_1.resolve)(root, input));
|
|
57
57
|
// Return the asset pattern in object format.
|
|
58
58
|
return { glob, input, output };
|
|
59
59
|
}
|