@angular/build 18.2.0-next.0 → 18.2.0-next.2
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 +10 -11
- package/src/builders/application/build-action.d.ts +3 -4
- package/src/builders/application/build-action.js +39 -5
- package/src/builders/application/execute-build.js +2 -0
- package/src/builders/application/index.d.ts +2 -1
- package/src/builders/application/index.js +12 -11
- package/src/builders/application/options.js +1 -1
- package/src/builders/application/results.d.ts +67 -0
- package/src/builders/application/results.js +17 -0
- package/src/builders/dev-server/vite-server.d.ts +2 -2
- package/src/builders/dev-server/vite-server.js +63 -46
- package/src/builders/extract-i18n/application-extraction.d.ts +2 -2
- package/src/builders/extract-i18n/application-extraction.js +26 -32
- package/src/builders/extract-i18n/builder.js +7 -7
- package/src/builders/extract-i18n/options.js +1 -1
- package/src/private.d.ts +1 -0
- package/src/private.js +3 -1
- package/src/tools/angular/transformers/jit-bootstrap-transformer.js +2 -3
- package/src/tools/angular/transformers/jit-resource-transformer.js +2 -1
- package/src/tools/esbuild/application-code-bundle.js +3 -0
- package/src/tools/esbuild/budget-stats.js +4 -1
- package/src/tools/esbuild/bundler-execution-result.d.ts +2 -0
- package/src/tools/esbuild/bundler-execution-result.js +2 -0
- package/src/tools/esbuild/loader-import-attribute-plugin.d.ts +9 -0
- package/src/tools/esbuild/loader-import-attribute-plugin.js +41 -0
- package/src/tools/esbuild/utils.js +12 -9
- package/src/tools/esbuild/wasm-plugin.js +3 -3
- package/src/tools/sass/lexer.js +1 -1
- package/src/tools/vite/id-prefix-plugin.d.ts +9 -0
- package/src/tools/vite/id-prefix-plugin.js +45 -0
- package/src/tools/vite/middlewares/assets-middleware.js +2 -1
- package/src/tools/vite/middlewares/index-html-middleware.js +4 -2
- package/src/utils/color.d.ts +2 -3
- package/src/utils/color.js +14 -50
- package/src/utils/index-file/inline-fonts.js +2 -1
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/spinner.d.ts +0 -20
- package/src/utils/spinner.js +0 -55
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "18.2.0-next.
|
|
3
|
+
"version": "18.2.0-next.2",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,30 +23,29 @@
|
|
|
23
23
|
"builders": "builders.json",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ampproject/remapping": "2.3.0",
|
|
26
|
-
"@angular-devkit/architect": "0.1802.0-next.
|
|
27
|
-
"@babel/core": "7.24.
|
|
26
|
+
"@angular-devkit/architect": "0.1802.0-next.2",
|
|
27
|
+
"@babel/core": "7.24.9",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.24.7",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
30
30
|
"@babel/plugin-syntax-import-attributes": "7.24.7",
|
|
31
|
-
"@inquirer/confirm": "3.1.
|
|
31
|
+
"@inquirer/confirm": "3.1.17",
|
|
32
32
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
33
|
-
"ansi-colors": "4.1.3",
|
|
34
33
|
"browserslist": "^4.23.0",
|
|
35
34
|
"critters": "0.0.24",
|
|
36
35
|
"esbuild": "0.23.0",
|
|
37
36
|
"fast-glob": "3.3.2",
|
|
38
37
|
"https-proxy-agent": "7.0.5",
|
|
38
|
+
"listr2": "8.2.3",
|
|
39
39
|
"lmdb": "3.0.12",
|
|
40
40
|
"magic-string": "0.30.10",
|
|
41
41
|
"mrmime": "2.0.0",
|
|
42
|
-
"ora": "5.4.1",
|
|
43
42
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
44
43
|
"picomatch": "4.0.2",
|
|
45
44
|
"piscina": "4.6.1",
|
|
46
|
-
"rollup": "4.
|
|
47
|
-
"sass": "1.77.
|
|
48
|
-
"semver": "7.6.
|
|
49
|
-
"vite": "5.3.
|
|
45
|
+
"rollup": "4.19.0",
|
|
46
|
+
"sass": "1.77.8",
|
|
47
|
+
"semver": "7.6.3",
|
|
48
|
+
"vite": "5.3.4",
|
|
50
49
|
"watchpack": "2.4.1"
|
|
51
50
|
},
|
|
52
51
|
"peerDependencies": {
|
|
@@ -79,7 +78,7 @@
|
|
|
79
78
|
"optional": true
|
|
80
79
|
}
|
|
81
80
|
},
|
|
82
|
-
"packageManager": "yarn@4.3.
|
|
81
|
+
"packageManager": "yarn@4.3.1",
|
|
83
82
|
"repository": {
|
|
84
83
|
"type": "git",
|
|
85
84
|
"url": "https://github.com/angular/angular-cli.git"
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
-
import { BuilderContext
|
|
8
|
+
import { BuilderContext } from '@angular-devkit/architect';
|
|
9
9
|
import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
|
|
10
10
|
import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result';
|
|
11
11
|
import { NormalizedCachedOptions } from '../../utils/normalize-cache';
|
|
12
12
|
import { NormalizedOutputOptions } from './options';
|
|
13
|
-
|
|
13
|
+
import { Result } from './results';
|
|
14
14
|
export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildState) => Promise<ExecutionResult>, options: {
|
|
15
15
|
workspaceRoot: string;
|
|
16
16
|
projectRoot: string;
|
|
@@ -29,5 +29,4 @@ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildSta
|
|
|
29
29
|
clearScreen?: boolean;
|
|
30
30
|
colors?: boolean;
|
|
31
31
|
jsonLogs?: boolean;
|
|
32
|
-
}): AsyncIterable<
|
|
33
|
-
export {};
|
|
32
|
+
}): AsyncIterable<Result>;
|
|
@@ -36,10 +36,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.runEsBuildBuildAction = runEsBuildBuildAction;
|
|
37
37
|
const node_fs_1 = require("node:fs");
|
|
38
38
|
const node_path_1 = __importDefault(require("node:path"));
|
|
39
|
+
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
39
40
|
const sass_language_1 = require("../../tools/esbuild/stylesheets/sass-language");
|
|
40
41
|
const utils_1 = require("../../tools/esbuild/utils");
|
|
41
42
|
const delete_output_dir_1 = require("../../utils/delete-output-dir");
|
|
42
43
|
const environment_options_1 = require("../../utils/environment-options");
|
|
44
|
+
const results_1 = require("./results");
|
|
43
45
|
// Watch workspace for package manager changes
|
|
44
46
|
const packageWatchFiles = [
|
|
45
47
|
// manifest can affect module resolution
|
|
@@ -167,18 +169,50 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
167
169
|
(0, sass_language_1.shutdownSassWorkerPool)();
|
|
168
170
|
}
|
|
169
171
|
}
|
|
170
|
-
async function writeAndEmitOutput(writeToFileSystem, { outputFiles,
|
|
172
|
+
async function writeAndEmitOutput(writeToFileSystem, { outputFiles, outputWithFiles, assetFiles, externalMetadata, htmlIndexPath, htmlBaseHref, }, outputOptions, writeToFileSystemFilter) {
|
|
173
|
+
if (!outputWithFiles.success) {
|
|
174
|
+
return {
|
|
175
|
+
kind: results_1.ResultKind.Failure,
|
|
176
|
+
errors: outputWithFiles.errors,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
171
179
|
if (writeToFileSystem) {
|
|
172
180
|
// Write output files
|
|
173
181
|
const outputFilesToWrite = writeToFileSystemFilter
|
|
174
182
|
? outputFiles.filter(writeToFileSystemFilter)
|
|
175
183
|
: outputFiles;
|
|
176
184
|
await (0, utils_1.writeResultFiles)(outputFilesToWrite, assetFiles, outputOptions);
|
|
177
|
-
|
|
185
|
+
// Currently unused other than indicating success if writing to disk.
|
|
186
|
+
return {
|
|
187
|
+
kind: results_1.ResultKind.Full,
|
|
188
|
+
files: {},
|
|
189
|
+
};
|
|
178
190
|
}
|
|
179
191
|
else {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
192
|
+
const result = {
|
|
193
|
+
kind: results_1.ResultKind.Full,
|
|
194
|
+
files: {},
|
|
195
|
+
detail: {
|
|
196
|
+
externalMetadata,
|
|
197
|
+
htmlIndexPath,
|
|
198
|
+
htmlBaseHref,
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
for (const file of outputWithFiles.assetFiles) {
|
|
202
|
+
result.files[file.destination] = {
|
|
203
|
+
type: bundler_context_1.BuildOutputFileType.Browser,
|
|
204
|
+
inputPath: file.source,
|
|
205
|
+
origin: 'disk',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
for (const file of outputWithFiles.outputFiles) {
|
|
209
|
+
result.files[file.path] = {
|
|
210
|
+
type: file.type,
|
|
211
|
+
contents: file.contents,
|
|
212
|
+
origin: 'memory',
|
|
213
|
+
hash: file.hash,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
183
217
|
}
|
|
184
218
|
}
|
|
@@ -101,6 +101,8 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
101
101
|
// Watch input index HTML file if configured
|
|
102
102
|
if (options.indexHtmlOptions) {
|
|
103
103
|
executionResult.extraWatchFiles.push(options.indexHtmlOptions.input);
|
|
104
|
+
executionResult.htmlIndexPath = options.indexHtmlOptions.output;
|
|
105
|
+
executionResult.htmlBaseHref = options.baseHref;
|
|
104
106
|
}
|
|
105
107
|
// Perform i18n translation inlining if enabled
|
|
106
108
|
if (i18nOptions.shouldInline) {
|
|
@@ -9,13 +9,14 @@ import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
|
|
|
9
9
|
import type { Plugin } from 'esbuild';
|
|
10
10
|
import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
|
|
11
11
|
import { ApplicationBuilderExtensions, ApplicationBuilderInternalOptions } from './options';
|
|
12
|
+
import { Result } from './results';
|
|
12
13
|
import { Schema as ApplicationBuilderOptions } from './schema';
|
|
13
14
|
export type { ApplicationBuilderOptions };
|
|
14
15
|
export declare function buildApplicationInternal(options: ApplicationBuilderInternalOptions, context: BuilderContext & {
|
|
15
16
|
signal?: AbortSignal;
|
|
16
17
|
}, infrastructureSettings?: {
|
|
17
18
|
write?: boolean;
|
|
18
|
-
}, extensions?: ApplicationBuilderExtensions): AsyncIterable<
|
|
19
|
+
}, extensions?: ApplicationBuilderExtensions): AsyncIterable<Result>;
|
|
19
20
|
export interface ApplicationBuilderOutput extends BuilderOutput {
|
|
20
21
|
outputFiles?: BuildOutputFile[];
|
|
21
22
|
assetFiles?: {
|
|
@@ -18,6 +18,7 @@ const version_1 = require("../../utils/version");
|
|
|
18
18
|
const build_action_1 = require("./build-action");
|
|
19
19
|
const execute_build_1 = require("./execute-build");
|
|
20
20
|
const options_1 = require("./options");
|
|
21
|
+
const results_1 = require("./results");
|
|
21
22
|
async function* buildApplicationInternal(options,
|
|
22
23
|
// TODO: Integrate abort signal support into builder system
|
|
23
24
|
context, infrastructureSettings, extensions) {
|
|
@@ -29,7 +30,9 @@ context, infrastructureSettings, extensions) {
|
|
|
29
30
|
// Determine project name from builder context target
|
|
30
31
|
const projectName = target?.project;
|
|
31
32
|
if (!projectName) {
|
|
32
|
-
|
|
33
|
+
context.logger.error(`The 'application' builder requires a target to be specified.`);
|
|
34
|
+
// Only the vite-based dev server current uses the errors value
|
|
35
|
+
yield { kind: results_1.ResultKind.Failure, errors: [] };
|
|
33
36
|
return;
|
|
34
37
|
}
|
|
35
38
|
const normalizedOptions = await (0, options_1.normalizeOptions)(context, projectName, options, extensions);
|
|
@@ -38,17 +41,13 @@ context, infrastructureSettings, extensions) {
|
|
|
38
41
|
if (writeServerBundles) {
|
|
39
42
|
const { browser, server } = normalizedOptions.outputOptions;
|
|
40
43
|
if (browser === '') {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
error: `'outputPath.browser' cannot be configured to an empty string when SSR is enabled.`,
|
|
44
|
-
};
|
|
44
|
+
context.logger.error(`'outputPath.browser' cannot be configured to an empty string when SSR is enabled.`);
|
|
45
|
+
yield { kind: results_1.ResultKind.Failure, errors: [] };
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
48
|
if (browser === server) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
error: `'outputPath.browser' and 'outputPath.server' cannot be configured to the same value.`,
|
|
51
|
-
};
|
|
49
|
+
context.logger.error(`'outputPath.browser' and 'outputPath.server' cannot be configured to the same value.`);
|
|
50
|
+
yield { kind: results_1.ResultKind.Failure, errors: [] };
|
|
52
51
|
return;
|
|
53
52
|
}
|
|
54
53
|
}
|
|
@@ -105,7 +104,7 @@ context, infrastructureSettings, extensions) {
|
|
|
105
104
|
signal,
|
|
106
105
|
});
|
|
107
106
|
}
|
|
108
|
-
function buildApplication(options, context, pluginsOrExtensions) {
|
|
107
|
+
async function* buildApplication(options, context, pluginsOrExtensions) {
|
|
109
108
|
let extensions;
|
|
110
109
|
if (pluginsOrExtensions && Array.isArray(pluginsOrExtensions)) {
|
|
111
110
|
extensions = {
|
|
@@ -115,6 +114,8 @@ function buildApplication(options, context, pluginsOrExtensions) {
|
|
|
115
114
|
else {
|
|
116
115
|
extensions = pluginsOrExtensions;
|
|
117
116
|
}
|
|
118
|
-
|
|
117
|
+
for await (const result of buildApplicationInternal(options, context, undefined, extensions)) {
|
|
118
|
+
yield { success: result.kind !== results_1.ResultKind.Failure };
|
|
119
|
+
}
|
|
119
120
|
}
|
|
120
121
|
exports.default = (0, architect_1.createBuilder)(buildApplication);
|
|
@@ -242,7 +242,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
|
|
|
242
242
|
plugins: extensions?.codePlugins?.length ? extensions?.codePlugins : undefined,
|
|
243
243
|
loaderExtensions,
|
|
244
244
|
jsonLogs: environment_options_1.useJSONBuildLogs,
|
|
245
|
-
colors: color_1.
|
|
245
|
+
colors: (0, color_1.supportColor)(),
|
|
246
246
|
clearScreen,
|
|
247
247
|
define,
|
|
248
248
|
};
|
|
@@ -0,0 +1,67 @@
|
|
|
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.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { BuildOutputFileType } from '../../tools/esbuild/bundler-context';
|
|
9
|
+
export declare enum ResultKind {
|
|
10
|
+
Failure = 0,
|
|
11
|
+
Full = 1,
|
|
12
|
+
Incremental = 2,
|
|
13
|
+
ComponentUpdate = 3
|
|
14
|
+
}
|
|
15
|
+
export type Result = FailureResult | FullResult | IncrementalResult | ComponentUpdateResult;
|
|
16
|
+
export interface BaseResult {
|
|
17
|
+
kind: ResultKind;
|
|
18
|
+
warnings?: ResultMessage[];
|
|
19
|
+
duration?: number;
|
|
20
|
+
detail?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface FailureResult extends BaseResult {
|
|
23
|
+
kind: ResultKind.Failure;
|
|
24
|
+
errors: ResultMessage[];
|
|
25
|
+
}
|
|
26
|
+
export interface FullResult extends BaseResult {
|
|
27
|
+
kind: ResultKind.Full;
|
|
28
|
+
files: Record<string, ResultFile>;
|
|
29
|
+
}
|
|
30
|
+
export interface IncrementalResult extends BaseResult {
|
|
31
|
+
kind: ResultKind.Incremental;
|
|
32
|
+
added: string[];
|
|
33
|
+
removed: string[];
|
|
34
|
+
modified: string[];
|
|
35
|
+
files: Record<string, ResultFile>;
|
|
36
|
+
}
|
|
37
|
+
export type ResultFile = DiskFile | MemoryFile;
|
|
38
|
+
export interface BaseResultFile {
|
|
39
|
+
origin: 'memory' | 'disk';
|
|
40
|
+
type: BuildOutputFileType;
|
|
41
|
+
}
|
|
42
|
+
export interface DiskFile extends BaseResultFile {
|
|
43
|
+
origin: 'disk';
|
|
44
|
+
inputPath: string;
|
|
45
|
+
}
|
|
46
|
+
export interface MemoryFile extends BaseResultFile {
|
|
47
|
+
origin: 'memory';
|
|
48
|
+
hash: string;
|
|
49
|
+
contents: Uint8Array;
|
|
50
|
+
}
|
|
51
|
+
export interface ResultMessage {
|
|
52
|
+
text: string;
|
|
53
|
+
location?: {
|
|
54
|
+
file: string;
|
|
55
|
+
line: number;
|
|
56
|
+
column: number;
|
|
57
|
+
} | null;
|
|
58
|
+
notes?: {
|
|
59
|
+
text: string;
|
|
60
|
+
}[];
|
|
61
|
+
}
|
|
62
|
+
export interface ComponentUpdateResult extends BaseResult {
|
|
63
|
+
kind: ResultKind.ComponentUpdate;
|
|
64
|
+
id: string;
|
|
65
|
+
type: 'style' | 'template';
|
|
66
|
+
content: string;
|
|
67
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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.dev/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ResultKind = void 0;
|
|
11
|
+
var ResultKind;
|
|
12
|
+
(function (ResultKind) {
|
|
13
|
+
ResultKind[ResultKind["Failure"] = 0] = "Failure";
|
|
14
|
+
ResultKind[ResultKind["Full"] = 1] = "Full";
|
|
15
|
+
ResultKind[ResultKind["Incremental"] = 2] = "Incremental";
|
|
16
|
+
ResultKind[ResultKind["ComponentUpdate"] = 3] = "ComponentUpdate";
|
|
17
|
+
})(ResultKind || (exports.ResultKind = ResultKind = {}));
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type { BuilderContext } from '@angular-devkit/architect';
|
|
9
9
|
import type { Plugin } from 'esbuild';
|
|
10
10
|
import type { Connect, DepOptimizationConfig, InlineConfig } from 'vite';
|
|
11
|
-
import {
|
|
11
|
+
import { Result } from '../application/results';
|
|
12
12
|
import { type ApplicationBuilderInternalOptions, type ExternalResultMetadata, JavaScriptTransformer } from './internal';
|
|
13
13
|
import type { NormalizedDevServerOptions } from './options';
|
|
14
14
|
import type { DevServerBuilderOutput } from './output';
|
|
@@ -19,7 +19,7 @@ interface OutputFileRecord {
|
|
|
19
19
|
updated: boolean;
|
|
20
20
|
servable: boolean;
|
|
21
21
|
}
|
|
22
|
-
export type BuilderAction = (options: ApplicationBuilderInternalOptions, context: BuilderContext, plugins?: Plugin[]) => AsyncIterable<
|
|
22
|
+
export type BuilderAction = (options: ApplicationBuilderInternalOptions, context: BuilderContext, plugins?: Plugin[]) => AsyncIterable<Result>;
|
|
23
23
|
export declare function serveWithVite(serverOptions: NormalizedDevServerOptions, builderName: string, builderAction: BuilderAction, context: BuilderContext, transformers?: {
|
|
24
24
|
indexHtml?: (content: string) => Promise<string>;
|
|
25
25
|
}, extensions?: {
|
|
@@ -42,8 +42,10 @@ const node_module_1 = require("node:module");
|
|
|
42
42
|
const node_path_1 = require("node:path");
|
|
43
43
|
const angular_memory_plugin_1 = require("../../tools/vite/angular-memory-plugin");
|
|
44
44
|
const i18n_locale_plugin_1 = require("../../tools/vite/i18n-locale-plugin");
|
|
45
|
+
const id_prefix_plugin_1 = require("../../tools/vite/id-prefix-plugin");
|
|
45
46
|
const utils_1 = require("../../utils");
|
|
46
47
|
const load_esm_1 = require("../../utils/load-esm");
|
|
48
|
+
const results_1 = require("../application/results");
|
|
47
49
|
const internal_1 = require("./internal");
|
|
48
50
|
/**
|
|
49
51
|
* Build options that are also present on the dev server but are only passed
|
|
@@ -76,12 +78,6 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
76
78
|
}
|
|
77
79
|
// Set all packages as external to support Vite's prebundle caching
|
|
78
80
|
browserOptions.externalPackages = serverOptions.prebundle;
|
|
79
|
-
const baseHref = browserOptions.baseHref;
|
|
80
|
-
if (serverOptions.servePath === undefined && baseHref !== undefined) {
|
|
81
|
-
// Remove trailing slash
|
|
82
|
-
serverOptions.servePath =
|
|
83
|
-
baseHref !== './' && baseHref[baseHref.length - 1] === '/' ? baseHref.slice(0, -1) : baseHref;
|
|
84
|
-
}
|
|
85
81
|
// The development server currently only supports a single locale when localizing.
|
|
86
82
|
// This matches the behavior of the Webpack-based development server but could be expanded in the future.
|
|
87
83
|
if (browserOptions.localize === true ||
|
|
@@ -100,15 +96,8 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
100
96
|
// In a development environment the additional scope information does not
|
|
101
97
|
// have a negative effect unlike production where final output size is relevant.
|
|
102
98
|
{ sourcemap: true, jit: true, thirdPartySourcemaps }, 1);
|
|
103
|
-
//
|
|
104
|
-
// TODO: Provide this info from the build results
|
|
99
|
+
// The index HTML path will be updated from the build results if provided by the builder
|
|
105
100
|
let htmlIndexPath = 'index.html';
|
|
106
|
-
if (browserOptions.index && typeof browserOptions.index !== 'boolean') {
|
|
107
|
-
htmlIndexPath =
|
|
108
|
-
typeof browserOptions.index === 'string'
|
|
109
|
-
? (0, node_path_1.basename)(browserOptions.index)
|
|
110
|
-
: browserOptions.index.output || 'index.html';
|
|
111
|
-
}
|
|
112
101
|
// dynamically import Vite for ESM compatibility
|
|
113
102
|
const { createServer, normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
|
|
114
103
|
let server;
|
|
@@ -130,24 +119,55 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
130
119
|
});
|
|
131
120
|
// TODO: Switch this to an architect schedule call when infrastructure settings are supported
|
|
132
121
|
for await (const result of builderAction(browserOptions, context, extensions?.buildPlugins)) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
122
|
+
switch (result.kind) {
|
|
123
|
+
case results_1.ResultKind.Failure:
|
|
124
|
+
if (result.errors.length && server) {
|
|
125
|
+
hadError = true;
|
|
126
|
+
server.hot.send({
|
|
127
|
+
type: 'error',
|
|
128
|
+
err: {
|
|
129
|
+
message: result.errors[0].text,
|
|
130
|
+
stack: '',
|
|
131
|
+
loc: result.errors[0].location ?? undefined,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
case results_1.ResultKind.Full:
|
|
137
|
+
if (result.detail?.['htmlIndexPath']) {
|
|
138
|
+
htmlIndexPath = result.detail['htmlIndexPath'];
|
|
139
|
+
}
|
|
140
|
+
if (serverOptions.servePath === undefined && result.detail?.['htmlBaseHref']) {
|
|
141
|
+
const baseHref = result.detail['htmlBaseHref'];
|
|
142
|
+
// Remove trailing slash
|
|
143
|
+
serverOptions.servePath =
|
|
144
|
+
baseHref !== './' && baseHref[baseHref.length - 1] === '/'
|
|
145
|
+
? baseHref.slice(0, -1)
|
|
146
|
+
: baseHref;
|
|
147
|
+
}
|
|
148
|
+
assetFiles.clear();
|
|
149
|
+
for (const [outputPath, file] of Object.entries(result.files)) {
|
|
150
|
+
if (file.origin === 'disk') {
|
|
151
|
+
assetFiles.set('/' + normalizePath(outputPath), normalizePath(file.inputPath));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Analyze result files for changes
|
|
155
|
+
analyzeResultFiles(normalizePath, htmlIndexPath, result.files, generatedFiles);
|
|
156
|
+
break;
|
|
157
|
+
case results_1.ResultKind.Incremental:
|
|
158
|
+
(0, node_assert_1.default)(server, 'Builder must provide an initial full build before incremental results.');
|
|
159
|
+
// TODO: Implement support -- application builder currently does not use
|
|
160
|
+
break;
|
|
161
|
+
case results_1.ResultKind.ComponentUpdate:
|
|
162
|
+
(0, node_assert_1.default)(serverOptions.hmr, 'Component updates are only supported with HMR enabled.');
|
|
163
|
+
// TODO: Implement support -- application builder currently does not use
|
|
164
|
+
break;
|
|
165
|
+
default:
|
|
166
|
+
context.logger.warn(`Unknown result kind [${result.kind}] provided by build.`);
|
|
167
|
+
continue;
|
|
149
168
|
}
|
|
150
|
-
|
|
169
|
+
// Clear existing error overlay on successful result
|
|
170
|
+
if (hadError && server) {
|
|
151
171
|
hadError = false;
|
|
152
172
|
// Send an empty update to clear the error overlay
|
|
153
173
|
server.hot.send({
|
|
@@ -155,18 +175,10 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
155
175
|
updates: [],
|
|
156
176
|
});
|
|
157
177
|
}
|
|
158
|
-
// Analyze result files for changes
|
|
159
|
-
analyzeResultFiles(normalizePath, htmlIndexPath, result.outputFiles, generatedFiles);
|
|
160
|
-
assetFiles.clear();
|
|
161
|
-
if (result.assetFiles) {
|
|
162
|
-
for (const asset of result.assetFiles) {
|
|
163
|
-
assetFiles.set('/' + normalizePath(asset.destination), normalizePath(asset.source));
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
178
|
// To avoid disconnecting the array objects from the option, these arrays need to be mutated instead of replaced.
|
|
167
179
|
let requiresServerRestart = false;
|
|
168
|
-
if (result.externalMetadata) {
|
|
169
|
-
const { implicitBrowser, implicitServer, explicit } = result.externalMetadata;
|
|
180
|
+
if (result.detail?.['externalMetadata']) {
|
|
181
|
+
const { implicitBrowser, implicitServer, explicit } = result.detail['externalMetadata'];
|
|
170
182
|
const implicitServerFiltered = implicitServer.filter((m) => removeNodeJsBuiltinModules(m) && removeAbsoluteUrls(m));
|
|
171
183
|
const implicitBrowserFiltered = implicitBrowser.filter(removeAbsoluteUrls);
|
|
172
184
|
if (browserOptions.ssr && serverOptions.prebundle !== false) {
|
|
@@ -301,22 +313,26 @@ function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logg
|
|
|
301
313
|
}
|
|
302
314
|
function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generatedFiles) {
|
|
303
315
|
const seen = new Set(['/index.html']);
|
|
304
|
-
for (const file of resultFiles) {
|
|
316
|
+
for (const [outputPath, file] of Object.entries(resultFiles)) {
|
|
317
|
+
if (file.origin === 'disk') {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
305
320
|
let filePath;
|
|
306
|
-
if (
|
|
321
|
+
if (outputPath === htmlIndexPath) {
|
|
307
322
|
// Convert custom index output path to standard index path for dev-server usage.
|
|
308
323
|
// This mimics the Webpack dev-server behavior.
|
|
309
324
|
filePath = '/index.html';
|
|
310
325
|
}
|
|
311
326
|
else {
|
|
312
|
-
filePath = '/' + normalizePath(
|
|
327
|
+
filePath = '/' + normalizePath(outputPath);
|
|
313
328
|
}
|
|
314
329
|
seen.add(filePath);
|
|
330
|
+
const servable = file.type === internal_1.BuildOutputFileType.Browser || file.type === internal_1.BuildOutputFileType.Media;
|
|
315
331
|
// Skip analysis of sourcemaps
|
|
316
332
|
if (filePath.endsWith('.map')) {
|
|
317
333
|
generatedFiles.set(filePath, {
|
|
318
334
|
contents: file.contents,
|
|
319
|
-
servable
|
|
335
|
+
servable,
|
|
320
336
|
size: file.contents.byteLength,
|
|
321
337
|
updated: false,
|
|
322
338
|
});
|
|
@@ -336,7 +352,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
336
352
|
size: file.contents.byteLength,
|
|
337
353
|
hash: file.hash,
|
|
338
354
|
updated: true,
|
|
339
|
-
servable
|
|
355
|
+
servable,
|
|
340
356
|
});
|
|
341
357
|
}
|
|
342
358
|
// Clear stale output files
|
|
@@ -441,6 +457,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
441
457
|
extensionMiddleware,
|
|
442
458
|
normalizePath,
|
|
443
459
|
}),
|
|
460
|
+
(0, id_prefix_plugin_1.createRemoveIdPrefixPlugin)(externalMetadata.explicit),
|
|
444
461
|
],
|
|
445
462
|
// Browser only optimizeDeps. (This does not run for SSR dependencies).
|
|
446
463
|
optimizeDeps: getDepOptimizationConfig({
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { ɵParsedMessage as LocalizeMessage } from '@angular/localize';
|
|
9
9
|
import type { MessageExtractor } from '@angular/localize/tools';
|
|
10
|
-
import type { BuilderContext
|
|
10
|
+
import type { BuilderContext } from '@angular-devkit/architect';
|
|
11
11
|
import type { ApplicationBuilderExtensions } from '../application/options';
|
|
12
12
|
import type { NormalizedExtractI18nOptions } from './options';
|
|
13
13
|
export declare function extractMessages(options: NormalizedExtractI18nOptions, builderName: string, context: BuilderContext, extractorConstructor: typeof MessageExtractor, extensions?: ApplicationBuilderExtensions): Promise<{
|
|
14
|
-
|
|
14
|
+
success: boolean;
|
|
15
15
|
basePath: string;
|
|
16
16
|
messages: LocalizeMessage[];
|
|
17
17
|
useLegacyIds: boolean;
|
|
@@ -11,9 +11,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.extractMessages = extractMessages;
|
|
14
|
-
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
16
15
|
const application_1 = require("../application");
|
|
16
|
+
const results_1 = require("../application/results");
|
|
17
17
|
async function extractMessages(options, builderName, context, extractorConstructor, extensions) {
|
|
18
18
|
const messages = [];
|
|
19
19
|
// Setup the build options for the application based on the buildTarget option
|
|
@@ -28,46 +28,30 @@ async function extractMessages(options, builderName, context, extractorConstruct
|
|
|
28
28
|
buildOptions.appShell = false;
|
|
29
29
|
buildOptions.prerender = false;
|
|
30
30
|
// Build the application with the build options
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
(0, node_assert_1.default)(builderResult !== undefined, 'Application builder did not provide a result.');
|
|
31
|
+
const builderResult = await first((0, application_1.buildApplicationInternal)(buildOptions, context, { write: false }, extensions));
|
|
32
|
+
let success = false;
|
|
33
|
+
if (!builderResult || builderResult.kind === results_1.ResultKind.Failure) {
|
|
34
|
+
context.logger.error('Application build failed.');
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
success: false,
|
|
42
|
-
error: err.message,
|
|
43
|
-
};
|
|
36
|
+
else if (builderResult.kind !== results_1.ResultKind.Full) {
|
|
37
|
+
context.logger.error('Application build did not provide a full output.');
|
|
44
38
|
}
|
|
45
|
-
|
|
46
|
-
// Output files are only present on a successful build.
|
|
47
|
-
if (builderResult.outputFiles) {
|
|
48
|
-
// Store the JS and JS map files for lookup during extraction
|
|
49
|
-
const files = new Map();
|
|
50
|
-
for (const outputFile of builderResult.outputFiles) {
|
|
51
|
-
if (outputFile.path.endsWith('.js')) {
|
|
52
|
-
files.set(outputFile.path, outputFile.text);
|
|
53
|
-
}
|
|
54
|
-
else if (outputFile.path.endsWith('.js.map')) {
|
|
55
|
-
files.set(outputFile.path, outputFile.text);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
39
|
+
else {
|
|
58
40
|
// Setup the localize message extractor based on the in-memory files
|
|
59
|
-
const extractor = setupLocalizeExtractor(extractorConstructor, files, context);
|
|
60
|
-
//
|
|
61
|
-
|
|
41
|
+
const extractor = setupLocalizeExtractor(extractorConstructor, builderResult.files, context);
|
|
42
|
+
// Extract messages from each output JavaScript file.
|
|
43
|
+
// Output files are only present on a successful build.
|
|
44
|
+
for (const filePath of Object.keys(builderResult.files)) {
|
|
62
45
|
if (!filePath.endsWith('.js')) {
|
|
63
46
|
continue;
|
|
64
47
|
}
|
|
65
48
|
const fileMessages = extractor.extractMessages(filePath);
|
|
66
49
|
messages.push(...fileMessages);
|
|
67
50
|
}
|
|
51
|
+
success = true;
|
|
68
52
|
}
|
|
69
53
|
return {
|
|
70
|
-
|
|
54
|
+
success,
|
|
71
55
|
basePath: context.workspaceRoot,
|
|
72
56
|
messages,
|
|
73
57
|
// Legacy i18n identifiers are not supported with the new application builder
|
|
@@ -75,6 +59,7 @@ async function extractMessages(options, builderName, context, extractorConstruct
|
|
|
75
59
|
};
|
|
76
60
|
}
|
|
77
61
|
function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
62
|
+
const textDecoder = new TextDecoder();
|
|
78
63
|
// Setup a virtual file system instance for the extractor
|
|
79
64
|
// * MessageExtractor itself uses readFile, relative and resolve
|
|
80
65
|
// * Internal SourceFileLoader (sourcemap support) uses dirname, exists, readFile, and resolve
|
|
@@ -82,7 +67,11 @@ function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
|
82
67
|
readFile(path) {
|
|
83
68
|
// Output files are stored as relative to the workspace root
|
|
84
69
|
const requestedPath = node_path_1.default.relative(context.workspaceRoot, path);
|
|
85
|
-
const
|
|
70
|
+
const file = files[requestedPath];
|
|
71
|
+
let content;
|
|
72
|
+
if (file?.origin === 'memory') {
|
|
73
|
+
content = textDecoder.decode(file.contents);
|
|
74
|
+
}
|
|
86
75
|
if (content === undefined) {
|
|
87
76
|
throw new Error('Unknown file requested: ' + requestedPath);
|
|
88
77
|
}
|
|
@@ -97,7 +86,7 @@ function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
|
97
86
|
exists(path) {
|
|
98
87
|
// Output files are stored as relative to the workspace root
|
|
99
88
|
const requestedPath = node_path_1.default.relative(context.workspaceRoot, path);
|
|
100
|
-
return files
|
|
89
|
+
return files[requestedPath] !== undefined;
|
|
101
90
|
},
|
|
102
91
|
dirname(path) {
|
|
103
92
|
return node_path_1.default.dirname(path);
|
|
@@ -128,3 +117,8 @@ function setupLocalizeExtractor(extractorConstructor, files, context) {
|
|
|
128
117
|
});
|
|
129
118
|
return extractor;
|
|
130
119
|
}
|
|
120
|
+
async function first(iterable) {
|
|
121
|
+
for await (const value of iterable) {
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -72,9 +72,8 @@ async function execute(options, context, extensions) {
|
|
|
72
72
|
// Extract messages based on configured builder
|
|
73
73
|
const { extractMessages } = await Promise.resolve().then(() => __importStar(require('./application-extraction')));
|
|
74
74
|
const extractionResult = await extractMessages(normalizedOptions, builderName, context, localizeToolsModule.MessageExtractor, extensions);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return extractionResult.builderResult;
|
|
75
|
+
if (!extractionResult.success) {
|
|
76
|
+
return { success: false };
|
|
78
77
|
}
|
|
79
78
|
// Perform duplicate message checks
|
|
80
79
|
const { checkDuplicateMessages } = localizeToolsModule;
|
|
@@ -128,12 +127,13 @@ async function createSerializer(localizeToolsModule, format, sourceLocale, baseP
|
|
|
128
127
|
case schema_1.Format.LegacyMigrate:
|
|
129
128
|
return new LegacyMessageIdMigrationSerializer(diagnostics);
|
|
130
129
|
case schema_1.Format.Arb:
|
|
131
|
-
|
|
130
|
+
return new ArbTranslationSerializer(sourceLocale,
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
basePath, {
|
|
132
133
|
relative(from, to) {
|
|
133
134
|
return node_path_1.default.relative(from, to);
|
|
134
135
|
},
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return new ArbTranslationSerializer(sourceLocale, basePath, fileSystem);
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
137
|
+
});
|
|
138
138
|
}
|
|
139
139
|
}
|
|
@@ -37,8 +37,8 @@ async function normalizeOptions(context, projectName, options) {
|
|
|
37
37
|
// Normalize xliff format extensions
|
|
38
38
|
let format = options.format;
|
|
39
39
|
switch (format) {
|
|
40
|
-
case undefined:
|
|
41
40
|
// Default format is xliff1
|
|
41
|
+
case undefined:
|
|
42
42
|
case schema_1.Format.Xlf:
|
|
43
43
|
case schema_1.Format.Xlif:
|
|
44
44
|
case schema_1.Format.Xliff:
|
package/src/private.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export { buildApplicationInternal } from './builders/application';
|
|
15
15
|
export type { ApplicationBuilderInternalOptions } from './builders/application/options';
|
|
16
|
+
export { type Result, type ResultFile, ResultKind } from './builders/application/results';
|
|
16
17
|
export { serveWithVite } from './builders/dev-server/vite-server';
|
|
17
18
|
export * from './tools/babel/plugins';
|
|
18
19
|
export type { ExternalResultMetadata } from './tools/esbuild/bundler-execution-result';
|
package/src/private.js
CHANGED
|
@@ -21,7 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.generateBuildStatsTable = exports.augmentAppWithServiceWorker = exports.purgeStaleBuildCache = exports.createTranslationLoader = exports.loadProxyConfiguration = exports.InlineCriticalCssProcessor = exports.IndexHtmlGenerator = exports.loadTranslations = exports.createI18nOptions = exports.deleteOutputDir = exports.checkPort = exports.createCompilerPlugin = exports.JavaScriptTransformer = exports.createJitResourceTransformer = exports.SourceFileCache = exports.SassWorkerImplementation = exports.transformSupportedBrowsersToTargets = exports.emitFilesToDisk = exports.serveWithVite = exports.buildApplicationInternal = void 0;
|
|
24
|
+
exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.generateBuildStatsTable = exports.augmentAppWithServiceWorker = exports.purgeStaleBuildCache = exports.createTranslationLoader = exports.loadProxyConfiguration = exports.InlineCriticalCssProcessor = exports.IndexHtmlGenerator = exports.loadTranslations = exports.createI18nOptions = exports.deleteOutputDir = exports.checkPort = exports.createCompilerPlugin = exports.JavaScriptTransformer = exports.createJitResourceTransformer = exports.SourceFileCache = exports.SassWorkerImplementation = exports.transformSupportedBrowsersToTargets = exports.emitFilesToDisk = exports.serveWithVite = exports.ResultKind = exports.buildApplicationInternal = void 0;
|
|
25
25
|
/**
|
|
26
26
|
* @fileoverview
|
|
27
27
|
* Private exports intended only for use with the @angular-devkit/build-angular package.
|
|
@@ -31,6 +31,8 @@ exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.
|
|
|
31
31
|
// Builders
|
|
32
32
|
var application_1 = require("./builders/application");
|
|
33
33
|
Object.defineProperty(exports, "buildApplicationInternal", { enumerable: true, get: function () { return application_1.buildApplicationInternal; } });
|
|
34
|
+
var results_1 = require("./builders/application/results");
|
|
35
|
+
Object.defineProperty(exports, "ResultKind", { enumerable: true, get: function () { return results_1.ResultKind; } });
|
|
34
36
|
var vite_server_1 = require("./builders/dev-server/vite-server");
|
|
35
37
|
Object.defineProperty(exports, "serveWithVite", { enumerable: true, get: function () { return vite_server_1.serveWithVite; } });
|
|
36
38
|
// Tools
|
|
@@ -98,9 +98,8 @@ function elideImports(sourceFile, removedNodes, getTypeChecker, compilerOptions)
|
|
|
98
98
|
let symbol;
|
|
99
99
|
switch (node.kind) {
|
|
100
100
|
case typescript_1.default.SyntaxKind.Identifier:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(parent);
|
|
101
|
+
if (node.parent && typescript_1.default.isShorthandPropertyAssignment(node.parent)) {
|
|
102
|
+
const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(node.parent);
|
|
104
103
|
if (shorthandSymbol) {
|
|
105
104
|
symbol = shorthandSymbol;
|
|
106
105
|
}
|
|
@@ -116,7 +116,7 @@ function visitComponentMetadata(nodeFactory, node, styleReplacements, resourceIm
|
|
|
116
116
|
return undefined;
|
|
117
117
|
}
|
|
118
118
|
return node;
|
|
119
|
-
case 'styleUrls':
|
|
119
|
+
case 'styleUrls': {
|
|
120
120
|
if (!typescript_1.default.isArrayLiteralExpression(node.initializer)) {
|
|
121
121
|
return node;
|
|
122
122
|
}
|
|
@@ -132,6 +132,7 @@ function visitComponentMetadata(nodeFactory, node, styleReplacements, resourceIm
|
|
|
132
132
|
styleReplacements.push(...externalStyles);
|
|
133
133
|
// The external styles will be added afterwards in combination with any inline styles
|
|
134
134
|
return undefined;
|
|
135
|
+
}
|
|
135
136
|
default:
|
|
136
137
|
// All other elements are passed through
|
|
137
138
|
return node;
|
|
@@ -23,6 +23,7 @@ const compiler_plugin_1 = require("./angular/compiler-plugin");
|
|
|
23
23
|
const compiler_plugin_options_1 = require("./compiler-plugin-options");
|
|
24
24
|
const external_packages_plugin_1 = require("./external-packages-plugin");
|
|
25
25
|
const i18n_locale_plugin_1 = require("./i18n-locale-plugin");
|
|
26
|
+
const loader_import_attribute_plugin_1 = require("./loader-import-attribute-plugin");
|
|
26
27
|
const rxjs_esm_resolution_plugin_1 = require("./rxjs-esm-resolution-plugin");
|
|
27
28
|
const sourcemap_ignorelist_plugin_1 = require("./sourcemap-ignorelist-plugin");
|
|
28
29
|
const utils_1 = require("./utils");
|
|
@@ -45,6 +46,7 @@ function createBrowserCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
45
46
|
target,
|
|
46
47
|
supported: (0, utils_1.getFeatureSupport)(target, zoneless),
|
|
47
48
|
plugins: [
|
|
49
|
+
(0, loader_import_attribute_plugin_1.createLoaderImportAttributePlugin)(),
|
|
48
50
|
(0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: sourceFileCache?.loadResultCache }),
|
|
49
51
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
50
52
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
@@ -146,6 +148,7 @@ function createServerCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
146
148
|
entryPoints,
|
|
147
149
|
supported: (0, utils_1.getFeatureSupport)(target, zoneless),
|
|
148
150
|
plugins: [
|
|
151
|
+
(0, loader_import_attribute_plugin_1.createLoaderImportAttributePlugin)(),
|
|
149
152
|
(0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: sourceFileCache?.loadResultCache }),
|
|
150
153
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
151
154
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
@@ -45,7 +45,10 @@ function generateBudgetStats(metafile, outputFiles, initialFiles) {
|
|
|
45
45
|
}
|
|
46
46
|
// Add component styles from metafile
|
|
47
47
|
// TODO: Provide this information directly from the AOT compiler
|
|
48
|
-
for (const entry of Object.
|
|
48
|
+
for (const [file, entry] of Object.entries(metafile.outputs)) {
|
|
49
|
+
if (!file.endsWith('.css')) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
49
52
|
// 'ng-component' is set by the angular plugin's component stylesheet bundler
|
|
50
53
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
54
|
const componentStyle = entry['ng-component'];
|
|
@@ -38,6 +38,8 @@ export declare class ExecutionResult {
|
|
|
38
38
|
logs: string[];
|
|
39
39
|
externalMetadata?: ExternalResultMetadata;
|
|
40
40
|
extraWatchFiles: string[];
|
|
41
|
+
htmlIndexPath?: string;
|
|
42
|
+
htmlBaseHref?: string;
|
|
41
43
|
constructor(rebuildContexts: BundlerContext[], codeBundleCache?: SourceFileCache | undefined);
|
|
42
44
|
addOutputFile(path: string, content: string | Uint8Array, type: BuildOutputFileType): void;
|
|
43
45
|
addAssets(assets: BuildOutputAsset[]): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
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.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import type { Plugin } from 'esbuild';
|
|
9
|
+
export declare function createLoaderImportAttributePlugin(): Plugin;
|
|
@@ -0,0 +1,41 @@
|
|
|
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.dev/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createLoaderImportAttributePlugin = createLoaderImportAttributePlugin;
|
|
11
|
+
const promises_1 = require("node:fs/promises");
|
|
12
|
+
const SUPPORTED_LOADERS = ['binary', 'file', 'text'];
|
|
13
|
+
function createLoaderImportAttributePlugin() {
|
|
14
|
+
return {
|
|
15
|
+
name: 'angular-loader-import-attributes',
|
|
16
|
+
setup(build) {
|
|
17
|
+
build.onLoad({ filter: /./ }, async (args) => {
|
|
18
|
+
const loader = args.with['loader'];
|
|
19
|
+
if (!loader) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
if (!SUPPORTED_LOADERS.includes(loader)) {
|
|
23
|
+
return {
|
|
24
|
+
errors: [
|
|
25
|
+
{
|
|
26
|
+
text: 'Unsupported loader import attribute',
|
|
27
|
+
notes: [
|
|
28
|
+
{ text: 'Attribute value must be one of: ' + SUPPORTED_LOADERS.join(', ') },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
contents: await (0, promises_1.readFile)(args.path),
|
|
36
|
+
loader,
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -27,6 +27,7 @@ exports.logMessages = logMessages;
|
|
|
27
27
|
exports.isZonelessApp = isZonelessApp;
|
|
28
28
|
exports.getEntryPointName = getEntryPointName;
|
|
29
29
|
const esbuild_1 = require("esbuild");
|
|
30
|
+
const listr2_1 = require("listr2");
|
|
30
31
|
const node_crypto_1 = require("node:crypto");
|
|
31
32
|
const node_fs_1 = require("node:fs");
|
|
32
33
|
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
@@ -34,7 +35,6 @@ const node_path_1 = require("node:path");
|
|
|
34
35
|
const node_url_1 = require("node:url");
|
|
35
36
|
const node_zlib_1 = require("node:zlib");
|
|
36
37
|
const semver_1 = require("semver");
|
|
37
|
-
const spinner_1 = require("../../utils/spinner");
|
|
38
38
|
const stats_table_1 = require("../../utils/stats-table");
|
|
39
39
|
const bundler_context_1 = require("./bundler-context");
|
|
40
40
|
function logBuildStats(metafile, outputFiles, initial, budgetFailures, colors, changedFiles, estimatedTransferSizes, ssrOutputEnabled, verbose) {
|
|
@@ -124,14 +124,17 @@ async function calculateEstimatedTransferSizes(outputFiles) {
|
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
126
|
async function withSpinner(text, action) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
let result;
|
|
128
|
+
const taskList = new listr2_1.Listr([
|
|
129
|
+
{
|
|
130
|
+
title: text,
|
|
131
|
+
async task() {
|
|
132
|
+
result = await action();
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
], { rendererOptions: { clearOutput: true } });
|
|
136
|
+
await taskList.run();
|
|
137
|
+
return result;
|
|
135
138
|
}
|
|
136
139
|
async function withNoProgress(text, action) {
|
|
137
140
|
return action();
|
|
@@ -35,7 +35,7 @@ function createWasmPlugin(options) {
|
|
|
35
35
|
return {
|
|
36
36
|
name: 'angular-wasm',
|
|
37
37
|
setup(build) {
|
|
38
|
-
build.onResolve({ filter:
|
|
38
|
+
build.onResolve({ filter: /\.wasm$/ }, async (args) => {
|
|
39
39
|
// Skip if already resolving the WASM file to avoid infinite resolution
|
|
40
40
|
if (args.pluginData?.[WASM_RESOLVE_SYMBOL]) {
|
|
41
41
|
return;
|
|
@@ -75,7 +75,7 @@ function createWasmPlugin(options) {
|
|
|
75
75
|
namespace: WASM_INIT_NAMESPACE,
|
|
76
76
|
};
|
|
77
77
|
});
|
|
78
|
-
build.onLoad({ filter:
|
|
78
|
+
build.onLoad({ filter: /\.wasm$/, namespace: WASM_INIT_NAMESPACE }, (0, load_result_cache_1.createCachedLoad)(cache, async (args) => {
|
|
79
79
|
// Ensure async mode is supported
|
|
80
80
|
if (!allowAsync) {
|
|
81
81
|
return {
|
|
@@ -155,7 +155,7 @@ function createWasmPlugin(options) {
|
|
|
155
155
|
watchFiles: [args.path],
|
|
156
156
|
};
|
|
157
157
|
}));
|
|
158
|
-
build.onLoad({ filter:
|
|
158
|
+
build.onLoad({ filter: /\.wasm$/, namespace: WASM_CONTENTS_NAMESPACE }, async (args) => {
|
|
159
159
|
const contents = args.pluginData.wasmContents ?? (await (0, promises_1.readFile)(args.path));
|
|
160
160
|
let loader = 'file';
|
|
161
161
|
if (args.with.loader) {
|
package/src/tools/sass/lexer.js
CHANGED
|
@@ -50,7 +50,7 @@ function* findUrls(contents) {
|
|
|
50
50
|
if (pos > 0) {
|
|
51
51
|
pos -= 2;
|
|
52
52
|
next();
|
|
53
|
-
if (!isWhitespace(current) && current !==
|
|
53
|
+
if (!isWhitespace(current) && current !== 0x002c && current !== 0x003a) {
|
|
54
54
|
// Skip - not a url token
|
|
55
55
|
pos += 3;
|
|
56
56
|
continue;
|
|
@@ -0,0 +1,9 @@
|
|
|
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.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import type { Plugin } from 'vite';
|
|
9
|
+
export declare function createRemoveIdPrefixPlugin(externals: string[]): Plugin;
|
|
@@ -0,0 +1,45 @@
|
|
|
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.dev/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createRemoveIdPrefixPlugin = createRemoveIdPrefixPlugin;
|
|
11
|
+
// NOTE: the implementation for this Vite plugin is roughly based on:
|
|
12
|
+
// https://github.com/MilanKovacic/vite-plugin-externalize-dependencies
|
|
13
|
+
const VITE_ID_PREFIX = '@id/';
|
|
14
|
+
const escapeRegexSpecialChars = (inputString) => {
|
|
15
|
+
return inputString.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
16
|
+
};
|
|
17
|
+
function createRemoveIdPrefixPlugin(externals) {
|
|
18
|
+
return {
|
|
19
|
+
name: 'angular-plugin-remove-id-prefix',
|
|
20
|
+
apply: 'serve',
|
|
21
|
+
configResolved: (resolvedConfig) => {
|
|
22
|
+
// don't do anything when the list of externals is empty
|
|
23
|
+
if (externals.length === 0) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const escapedExternals = externals.map(escapeRegexSpecialChars);
|
|
27
|
+
const prefixedExternalRegex = new RegExp(`${resolvedConfig.base}${VITE_ID_PREFIX}(${escapedExternals.join('|')})`, 'g');
|
|
28
|
+
// @ts-expect-error: Property 'push' does not exist on type 'readonly Plugin<any>[]'
|
|
29
|
+
// Reasoning:
|
|
30
|
+
// since the /@id/ prefix is added by Vite's import-analysis plugin,
|
|
31
|
+
// we must add our actual plugin dynamically, to ensure that it will run
|
|
32
|
+
// AFTER the import-analysis.
|
|
33
|
+
resolvedConfig.plugins.push({
|
|
34
|
+
name: 'angular-plugin-remove-id-prefix-transform',
|
|
35
|
+
transform: (code) => {
|
|
36
|
+
// don't do anything when code does not contain the Vite prefix
|
|
37
|
+
if (!code.includes(VITE_ID_PREFIX)) {
|
|
38
|
+
return code;
|
|
39
|
+
}
|
|
40
|
+
return code.replace(prefixedExternalRegex, (_, externalName) => externalName);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -69,7 +69,8 @@ function createAngularAssetsMiddleware(server, assets, outputFiles) {
|
|
|
69
69
|
if (!pathnameHasTrailingSlash) {
|
|
70
70
|
for (const assetPath of assets.keys()) {
|
|
71
71
|
if (pathname === assetPath.substring(0, assetPath.lastIndexOf('/'))) {
|
|
72
|
-
const
|
|
72
|
+
const { pathname, search, hash } = new URL(req.url, 'http://localhost');
|
|
73
|
+
const location = [pathname, '/', search, hash].join('');
|
|
73
74
|
res.statusCode = 301;
|
|
74
75
|
res.setHeader('Content-Type', 'text/html');
|
|
75
76
|
res.setHeader('Location', location);
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.createAngularIndexHtmlMiddleware = createAngularIndexHtmlMiddleware;
|
|
11
|
+
const node_path_1 = require("node:path");
|
|
11
12
|
const utils_1 = require("../utils");
|
|
12
13
|
function createAngularIndexHtmlMiddleware(server, outputFiles, indexHtmlTransformer) {
|
|
13
14
|
return function (req, res, next) {
|
|
@@ -18,11 +19,12 @@ function createAngularIndexHtmlMiddleware(server, outputFiles, indexHtmlTransfor
|
|
|
18
19
|
// Parse the incoming request.
|
|
19
20
|
// The base of the URL is unused but required to parse the URL.
|
|
20
21
|
const pathname = (0, utils_1.pathnameWithoutBasePath)(req.url, server.config.base);
|
|
21
|
-
|
|
22
|
+
const extension = (0, node_path_1.extname)(pathname);
|
|
23
|
+
if (extension !== '.html') {
|
|
22
24
|
next();
|
|
23
25
|
return;
|
|
24
26
|
}
|
|
25
|
-
const rawHtml = outputFiles.get(
|
|
27
|
+
const rawHtml = outputFiles.get(pathname)?.contents;
|
|
26
28
|
if (!rawHtml) {
|
|
27
29
|
next();
|
|
28
30
|
return;
|
package/src/utils/color.d.ts
CHANGED
|
@@ -5,6 +5,5 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
declare
|
|
10
|
-
export { colors };
|
|
8
|
+
export { color as colors, figures } from 'listr2';
|
|
9
|
+
export declare function supportColor(stream?: NodeJS.WritableStream): boolean;
|
package/src/utils/color.js
CHANGED
|
@@ -6,58 +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.dev/license
|
|
8
8
|
*/
|
|
9
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
-
}
|
|
15
|
-
Object.defineProperty(o, k2, desc);
|
|
16
|
-
}) : (function(o, m, k, k2) {
|
|
17
|
-
if (k2 === undefined) k2 = k;
|
|
18
|
-
o[k2] = m[k];
|
|
19
|
-
}));
|
|
20
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
-
}) : function(o, v) {
|
|
23
|
-
o["default"] = v;
|
|
24
|
-
});
|
|
25
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
26
|
-
if (mod && mod.__esModule) return mod;
|
|
27
|
-
var result = {};
|
|
28
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
29
|
-
__setModuleDefault(result, mod);
|
|
30
|
-
return result;
|
|
31
|
-
};
|
|
32
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.colors = void 0;
|
|
34
|
-
|
|
10
|
+
exports.figures = exports.colors = void 0;
|
|
11
|
+
exports.supportColor = supportColor;
|
|
35
12
|
const node_tty_1 = require("node:tty");
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
case 'true':
|
|
47
|
-
case '1':
|
|
48
|
-
case '2':
|
|
49
|
-
case '3':
|
|
50
|
-
return true;
|
|
51
|
-
default:
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
13
|
+
var listr2_1 = require("listr2");
|
|
14
|
+
Object.defineProperty(exports, "colors", { enumerable: true, get: function () { return listr2_1.color; } });
|
|
15
|
+
Object.defineProperty(exports, "figures", { enumerable: true, get: function () { return listr2_1.figures; } });
|
|
16
|
+
function supportColor(stream = process.stdout) {
|
|
17
|
+
if (stream instanceof node_tty_1.WriteStream) {
|
|
18
|
+
return stream.hasColors();
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
// The hasColors function does not rely on any instance state and should ideally be static
|
|
22
|
+
return node_tty_1.WriteStream.prototype.hasColors();
|
|
54
23
|
}
|
|
55
|
-
|
|
56
|
-
return process.
|
|
24
|
+
catch {
|
|
25
|
+
return process.env['FORCE_COLOR'] !== undefined && process.env['FORCE_COLOR'] !== '0';
|
|
57
26
|
}
|
|
58
|
-
return false;
|
|
59
27
|
}
|
|
60
|
-
// Create a separate instance to prevent unintended global changes to the color configuration
|
|
61
|
-
const colors = ansiColors.create();
|
|
62
|
-
exports.colors = colors;
|
|
63
|
-
colors.enabled = supportColor();
|
|
@@ -137,7 +137,7 @@ class InlineFontsProcessor {
|
|
|
137
137
|
rewriter.emitRaw(`<link rel="preconnect" href="${url}" crossorigin>`);
|
|
138
138
|
}
|
|
139
139
|
break;
|
|
140
|
-
case 'link':
|
|
140
|
+
case 'link': {
|
|
141
141
|
const hrefAttr = attrs.some(({ name, value }) => name === 'rel' && value === 'stylesheet') &&
|
|
142
142
|
attrs.find(({ name, value }) => name === 'href' && hrefsContent.has(value));
|
|
143
143
|
if (hrefAttr) {
|
|
@@ -149,6 +149,7 @@ class InlineFontsProcessor {
|
|
|
149
149
|
rewriter.emitStartTag(tag);
|
|
150
150
|
}
|
|
151
151
|
break;
|
|
152
|
+
}
|
|
152
153
|
default:
|
|
153
154
|
rewriter.emitStartTag(tag);
|
|
154
155
|
break;
|
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.normalizeCacheOptions = normalizeCacheOptions;
|
|
11
11
|
const node_path_1 = require("node:path");
|
|
12
12
|
/** Version placeholder is replaced during the build process with actual package version */
|
|
13
|
-
const VERSION = '18.2.0-next.
|
|
13
|
+
const VERSION = '18.2.0-next.2';
|
|
14
14
|
function hasCacheMetadata(value) {
|
|
15
15
|
return (!!value &&
|
|
16
16
|
typeof value === 'object' &&
|
package/src/utils/spinner.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
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.dev/license
|
|
7
|
-
*/
|
|
8
|
-
export declare class Spinner {
|
|
9
|
-
#private;
|
|
10
|
-
private readonly spinner;
|
|
11
|
-
/** When false, only fail messages will be displayed. */
|
|
12
|
-
enabled: boolean;
|
|
13
|
-
constructor(text?: string);
|
|
14
|
-
set text(text: string);
|
|
15
|
-
get isSpinning(): boolean;
|
|
16
|
-
succeed(text?: string): void;
|
|
17
|
-
fail(text?: string): void;
|
|
18
|
-
stop(): void;
|
|
19
|
-
start(text?: string): void;
|
|
20
|
-
}
|
package/src/utils/spinner.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
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.dev/license
|
|
8
|
-
*/
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.Spinner = void 0;
|
|
14
|
-
const ora_1 = __importDefault(require("ora"));
|
|
15
|
-
const color_1 = require("./color");
|
|
16
|
-
const tty_1 = require("./tty");
|
|
17
|
-
class Spinner {
|
|
18
|
-
spinner;
|
|
19
|
-
/** When false, only fail messages will be displayed. */
|
|
20
|
-
enabled = true;
|
|
21
|
-
#isTTY = (0, tty_1.isTTY)();
|
|
22
|
-
constructor(text) {
|
|
23
|
-
this.spinner = (0, ora_1.default)({
|
|
24
|
-
text: text === undefined ? undefined : text + '\n',
|
|
25
|
-
// The below 2 options are needed because otherwise CTRL+C will be delayed
|
|
26
|
-
// when the underlying process is sync.
|
|
27
|
-
hideCursor: false,
|
|
28
|
-
discardStdin: false,
|
|
29
|
-
isEnabled: this.#isTTY,
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
set text(text) {
|
|
33
|
-
this.spinner.text = text;
|
|
34
|
-
}
|
|
35
|
-
get isSpinning() {
|
|
36
|
-
return this.spinner.isSpinning || !this.#isTTY;
|
|
37
|
-
}
|
|
38
|
-
succeed(text) {
|
|
39
|
-
if (this.enabled) {
|
|
40
|
-
this.spinner.succeed(text);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
fail(text) {
|
|
44
|
-
this.spinner.fail(text && color_1.colors.redBright(text));
|
|
45
|
-
}
|
|
46
|
-
stop() {
|
|
47
|
-
this.spinner.stop();
|
|
48
|
-
}
|
|
49
|
-
start(text) {
|
|
50
|
-
if (this.enabled) {
|
|
51
|
-
this.spinner.start(text);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.Spinner = Spinner;
|