Primeiro commit do projeto Angular
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2026 Google LLC. https://angular.dev/license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
# Angular CLI - The CLI tool for Angular.
|
||||
|
||||
The sources for this package are in the [Angular CLI](https://github.com/angular/angular-cli) repository. Please file issues and pull requests against that repository.
|
||||
|
||||
Usage information and reference details can be found in repository [README](https://github.com/angular/angular-cli/blob/main/README.md) file.
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
*
|
||||
* This file is used to bootstrap the CLI process by dynamically importing the main initialization code.
|
||||
* This is done to allow the main bin file (`ng`) to remain CommonJS so that older versions of Node.js
|
||||
* can be checked and validated prior to the execution of the CLI. This separate bootstrap file is
|
||||
* needed to allow the use of a dynamic import expression without crashing older versions of Node.js that
|
||||
* do not support dynamic import expressions and would otherwise throw a syntax error. This bootstrap file
|
||||
* is required from the main bin file only after the Node.js version is determined to be in the supported
|
||||
* range.
|
||||
*/
|
||||
|
||||
// Enable on-disk code caching if available (Node.js 22.8+)
|
||||
// Skip if running inside Bazel via a RUNFILES environment variable check and no explicit cache
|
||||
// location defined. The default cache location does not work well with Bazel's hermeticity requirements.
|
||||
if (!process.env['RUNFILES'] || process.env['NODE_COMPILE_CACHE']) {
|
||||
try {
|
||||
const { enableCompileCache } = require('node:module');
|
||||
|
||||
enableCompileCache?.();
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// Initialize the Angular CLI
|
||||
void import('../lib/init.js');
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable import/no-unassigned-import */
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
// Error if the external CLI appears to be used inside a google3 context.
|
||||
if (process.cwd().split(path.sep).includes('google3')) {
|
||||
console.error(
|
||||
'This is the external Angular CLI, but you appear to be running in google3. There is a separate, internal version of the CLI which should be used instead. See http://go/angular/cli.',
|
||||
);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
// Provide a title to the process in `ps`.
|
||||
// Due to an obscure Mac bug, do not start this title with any symbol.
|
||||
try {
|
||||
process.title = 'ng ' + Array.from(process.argv).slice(2).join(' ');
|
||||
} catch (_) {
|
||||
// If an error happened above, use the most basic title.
|
||||
process.title = 'ng';
|
||||
}
|
||||
|
||||
const rawCommandName = process.argv[2];
|
||||
if (rawCommandName === '--get-yargs-completions' || rawCommandName === 'completion') {
|
||||
// Skip Node.js supported checks when running ng completion.
|
||||
// A warning at this stage could cause a broken source action (`source <(ng completion script)`) when in the shell init script.
|
||||
require('./bootstrap');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// This node version check ensures that extremely old versions of node are not used.
|
||||
// These may not support ES2015 features such as const/let/async/await/etc.
|
||||
// These would then crash with a hard to diagnose error message.
|
||||
const [major, minor] = process.versions.node.split('.', 2).map((part) => Number(part));
|
||||
|
||||
if (major % 2 === 1) {
|
||||
// Allow new odd numbered releases with a warning (currently v17+)
|
||||
console.warn(
|
||||
'Node.js version ' +
|
||||
process.version +
|
||||
' detected.\n' +
|
||||
'Odd numbered Node.js versions will not enter LTS status and should not be used for production.' +
|
||||
' For more information, please see https://nodejs.org/en/about/previous-releases/.',
|
||||
);
|
||||
|
||||
require('./bootstrap');
|
||||
} else if (major < 20 || (major === 20 && minor < 19) || (major === 22 && minor < 12)) {
|
||||
// Error and exit if less than 20.19 or 22.12
|
||||
console.error(
|
||||
'Node.js version ' +
|
||||
process.version +
|
||||
' detected.\n' +
|
||||
'The Angular CLI requires a minimum Node.js version of v20.19 or v22.12.\n\n' +
|
||||
'Please update your Node.js version or visit https://nodejs.org/ for additional instructions.\n',
|
||||
);
|
||||
|
||||
process.exitCode = 3;
|
||||
} else {
|
||||
require('./bootstrap');
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
export { VERSION } from '../../src/utilities/version';
|
||||
export default function (options: {
|
||||
cliArgs: string[];
|
||||
}): Promise<number>;
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.VERSION = void 0;
|
||||
exports.default = default_1;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const node_util_1 = require("node:util");
|
||||
const command_module_1 = require("../../src/command-builder/command-module");
|
||||
const command_runner_1 = require("../../src/command-builder/command-runner");
|
||||
const color_1 = require("../../src/utilities/color");
|
||||
const environment_options_1 = require("../../src/utilities/environment-options");
|
||||
const log_file_1 = require("../../src/utilities/log-file");
|
||||
var version_1 = require("../../src/utilities/version");
|
||||
Object.defineProperty(exports, "VERSION", { enumerable: true, get: function () { return version_1.VERSION; } });
|
||||
const MIN_NODEJS_VERSION = [20, 19];
|
||||
/* eslint-disable no-console */
|
||||
async function default_1(options) {
|
||||
// This node version check ensures that the requirements of the project instance of the CLI are met
|
||||
const [major, minor] = process.versions.node.split('.').map((part) => Number(part));
|
||||
if (major < MIN_NODEJS_VERSION[0] ||
|
||||
(major === MIN_NODEJS_VERSION[0] && minor < MIN_NODEJS_VERSION[1])) {
|
||||
process.stderr.write(`Node.js version ${process.version} detected.\n` +
|
||||
`The Angular CLI requires a minimum of v${MIN_NODEJS_VERSION[0]}.${MIN_NODEJS_VERSION[1]}.\n\n` +
|
||||
'Please update your Node.js version or visit https://nodejs.org/ for additional instructions.\n');
|
||||
return 3;
|
||||
}
|
||||
const colorLevels = {
|
||||
info: (s) => s,
|
||||
debug: (s) => s,
|
||||
warn: (s) => color_1.colors.bold(color_1.colors.yellow(s)),
|
||||
error: (s) => color_1.colors.bold(color_1.colors.red(s)),
|
||||
fatal: (s) => color_1.colors.bold(color_1.colors.red(s)),
|
||||
};
|
||||
const logger = new core_1.logging.IndentLogger('cli-main-logger');
|
||||
const logInfo = console.log;
|
||||
const logError = console.error;
|
||||
const useColor = (0, color_1.supportColor)();
|
||||
const loggerFinished = logger.forEach((entry) => {
|
||||
if (!environment_options_1.ngDebug && entry.level === 'debug') {
|
||||
return;
|
||||
}
|
||||
const color = useColor ? colorLevels[entry.level] : node_util_1.stripVTControlCharacters;
|
||||
const message = color(entry.message);
|
||||
switch (entry.level) {
|
||||
case 'warn':
|
||||
case 'fatal':
|
||||
case 'error':
|
||||
logError(message);
|
||||
break;
|
||||
default:
|
||||
logInfo(message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
// Redirect console to logger
|
||||
console.info = console.log = function (...args) {
|
||||
logger.info((0, node_util_1.format)(...args));
|
||||
};
|
||||
console.warn = function (...args) {
|
||||
logger.warn((0, node_util_1.format)(...args));
|
||||
};
|
||||
console.error = function (...args) {
|
||||
logger.error((0, node_util_1.format)(...args));
|
||||
};
|
||||
try {
|
||||
return await (0, command_runner_1.runCommand)(options.cliArgs, logger);
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof command_module_1.CommandModuleError) {
|
||||
logger.fatal(`Error: ${err.message}`);
|
||||
}
|
||||
else if (err instanceof Error) {
|
||||
try {
|
||||
const logPath = (0, log_file_1.writeErrorToLogFile)(err);
|
||||
logger.fatal(`An unhandled exception occurred: ${err.message}\n` +
|
||||
`See "${logPath}" for further details.`);
|
||||
}
|
||||
catch (e) {
|
||||
logger.fatal(`An unhandled exception occurred: ${err.message}\n` +
|
||||
`Fatal error writing debug log file: ${e}`);
|
||||
if (err.stack) {
|
||||
logger.fatal(err.stack);
|
||||
}
|
||||
}
|
||||
return 127;
|
||||
}
|
||||
else if (typeof err === 'string') {
|
||||
logger.fatal(err);
|
||||
}
|
||||
else if (typeof err === 'number') {
|
||||
// Log nothing.
|
||||
}
|
||||
else {
|
||||
logger.fatal(`An unexpected error occurred: ${err}`);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
finally {
|
||||
logger.complete();
|
||||
await loggerFinished;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
||||
BIN
Binary file not shown.
+6150
File diff suppressed because it is too large
Load Diff
+1025
File diff suppressed because it is too large
Load Diff
+133
@@ -0,0 +1,133 @@
|
||||
"use strict";
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
|
||||
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AiConfig = exports.TypeSeparator = exports.Implement = exports.SchematicsAngularComponentStyle = exports.ChangeDetection = exports.ViewEncapsulation = exports.TestRunner = exports.SchematicsAngularApplicationStyle = exports.FileNameStyleGuide = exports.PackageManager = exports.Environment = void 0;
|
||||
/**
|
||||
* Configure in which environment disk cache is enabled.
|
||||
*/
|
||||
var Environment;
|
||||
(function (Environment) {
|
||||
Environment["All"] = "all";
|
||||
Environment["Ci"] = "ci";
|
||||
Environment["Local"] = "local";
|
||||
})(Environment || (exports.Environment = Environment = {}));
|
||||
/**
|
||||
* Specify which package manager tool to use.
|
||||
*
|
||||
* The package manager used to install dependencies.
|
||||
*/
|
||||
var PackageManager;
|
||||
(function (PackageManager) {
|
||||
PackageManager["Bun"] = "bun";
|
||||
PackageManager["Npm"] = "npm";
|
||||
PackageManager["Pnpm"] = "pnpm";
|
||||
PackageManager["Yarn"] = "yarn";
|
||||
})(PackageManager || (exports.PackageManager = PackageManager = {}));
|
||||
/**
|
||||
* The file naming convention to use for generated files. The '2025' style guide (default)
|
||||
* uses a concise format (e.g., `app.ts` for the root component), while the '2016' style
|
||||
* guide includes the type in the file name (e.g., `app.component.ts`). For more
|
||||
* information, see the Angular Style Guide (https://angular.dev/style-guide).
|
||||
*/
|
||||
var FileNameStyleGuide;
|
||||
(function (FileNameStyleGuide) {
|
||||
FileNameStyleGuide["The2016"] = "2016";
|
||||
FileNameStyleGuide["The2025"] = "2025";
|
||||
})(FileNameStyleGuide || (exports.FileNameStyleGuide = FileNameStyleGuide = {}));
|
||||
/**
|
||||
* The type of stylesheet files to be created for components in the application.
|
||||
*
|
||||
* The type of stylesheet files to be created for components in the initial project.
|
||||
*/
|
||||
var SchematicsAngularApplicationStyle;
|
||||
(function (SchematicsAngularApplicationStyle) {
|
||||
SchematicsAngularApplicationStyle["Css"] = "css";
|
||||
SchematicsAngularApplicationStyle["Less"] = "less";
|
||||
SchematicsAngularApplicationStyle["Sass"] = "sass";
|
||||
SchematicsAngularApplicationStyle["Scss"] = "scss";
|
||||
SchematicsAngularApplicationStyle["Tailwind"] = "tailwind";
|
||||
})(SchematicsAngularApplicationStyle || (exports.SchematicsAngularApplicationStyle = SchematicsAngularApplicationStyle = {}));
|
||||
/**
|
||||
* The unit testing runner to use.
|
||||
*/
|
||||
var TestRunner;
|
||||
(function (TestRunner) {
|
||||
TestRunner["Karma"] = "karma";
|
||||
TestRunner["Vitest"] = "vitest";
|
||||
})(TestRunner || (exports.TestRunner = TestRunner = {}));
|
||||
/**
|
||||
* Sets the view encapsulation mode for the application's components. This determines how
|
||||
* component styles are scoped and applied.
|
||||
*
|
||||
* Sets the view encapsulation mode for the component. This determines how the component's
|
||||
* styles are scoped and applied.
|
||||
*
|
||||
* Sets the view encapsulation mode for components in the initial project. This determines
|
||||
* how component styles are scoped and applied. Options include: `Emulated` (default, styles
|
||||
* are scoped to the component), `None` (styles are global), and `ShadowDom` (styles are
|
||||
* encapsulated using Shadow DOM).
|
||||
*/
|
||||
var ViewEncapsulation;
|
||||
(function (ViewEncapsulation) {
|
||||
ViewEncapsulation["Emulated"] = "Emulated";
|
||||
ViewEncapsulation["None"] = "None";
|
||||
ViewEncapsulation["ShadowDom"] = "ShadowDom";
|
||||
})(ViewEncapsulation || (exports.ViewEncapsulation = ViewEncapsulation = {}));
|
||||
/**
|
||||
* Configures the change detection strategy for the component.
|
||||
*/
|
||||
var ChangeDetection;
|
||||
(function (ChangeDetection) {
|
||||
ChangeDetection["Default"] = "Default";
|
||||
ChangeDetection["OnPush"] = "OnPush";
|
||||
})(ChangeDetection || (exports.ChangeDetection = ChangeDetection = {}));
|
||||
/**
|
||||
* Specify the type of stylesheet to be created for the component, or `none` to skip
|
||||
* creating a stylesheet.
|
||||
*/
|
||||
var SchematicsAngularComponentStyle;
|
||||
(function (SchematicsAngularComponentStyle) {
|
||||
SchematicsAngularComponentStyle["Css"] = "css";
|
||||
SchematicsAngularComponentStyle["Less"] = "less";
|
||||
SchematicsAngularComponentStyle["None"] = "none";
|
||||
SchematicsAngularComponentStyle["Sass"] = "sass";
|
||||
SchematicsAngularComponentStyle["Scss"] = "scss";
|
||||
})(SchematicsAngularComponentStyle || (exports.SchematicsAngularComponentStyle = SchematicsAngularComponentStyle = {}));
|
||||
var Implement;
|
||||
(function (Implement) {
|
||||
Implement["CanActivate"] = "CanActivate";
|
||||
Implement["CanActivateChild"] = "CanActivateChild";
|
||||
Implement["CanDeactivate"] = "CanDeactivate";
|
||||
Implement["CanMatch"] = "CanMatch";
|
||||
})(Implement || (exports.Implement = Implement = {}));
|
||||
/**
|
||||
* The separator character to use before the type within the generated file's name. For
|
||||
* example, if you set the option to `.`, the file will be named `example.guard.ts`.
|
||||
*
|
||||
* The separator character to use before the type within the generated file's name. For
|
||||
* example, if you set the option to `.`, the file will be named `example.interceptor.ts`.
|
||||
*
|
||||
* The separator character to use before the type within the generated file's name. For
|
||||
* example, if you set the option to `.`, the file will be named `example.pipe.ts`.
|
||||
*
|
||||
* The separator character to use before the type within the generated file's name. For
|
||||
* example, if you set the option to `.`, the file will be named `example.resolver.ts`.
|
||||
*/
|
||||
var TypeSeparator;
|
||||
(function (TypeSeparator) {
|
||||
TypeSeparator["Empty"] = "-";
|
||||
TypeSeparator["TypeSeparator"] = ".";
|
||||
})(TypeSeparator || (exports.TypeSeparator = TypeSeparator = {}));
|
||||
var AiConfig;
|
||||
(function (AiConfig) {
|
||||
AiConfig["Agents"] = "agents";
|
||||
AiConfig["Claude"] = "claude";
|
||||
AiConfig["Copilot"] = "copilot";
|
||||
AiConfig["Cursor"] = "cursor";
|
||||
AiConfig["Gemini"] = "gemini";
|
||||
AiConfig["Jetbrains"] = "jetbrains";
|
||||
AiConfig["None"] = "none";
|
||||
AiConfig["Windsurf"] = "windsurf";
|
||||
})(AiConfig || (exports.AiConfig = AiConfig = {}));
|
||||
//# sourceMappingURL=workspace-schema.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"workspace-schema.js","sourceRoot":"","sources":["workspace-schema.ts"],"names":[],"mappings":";AACA,mFAAmF;AACnF,oFAAoF;;;AA4DpF;;GAEG;AACH,IAAY,WAIX;AAJD,WAAY,WAAW;IACnB,0BAAW,CAAA;IACX,wBAAS,CAAA;IACT,8BAAe,CAAA;AACnB,CAAC,EAJW,WAAW,2BAAX,WAAW,QAItB;AAED;;;;GAIG;AACH,IAAY,cAKX;AALD,WAAY,cAAc;IACtB,6BAAW,CAAA;IACX,6BAAW,CAAA;IACX,+BAAa,CAAA;IACb,+BAAa,CAAA;AACjB,CAAC,EALW,cAAc,8BAAd,cAAc,QAKzB;AAqID;;;;;GAKG;AACH,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC1B,sCAAgB,CAAA;IAChB,sCAAgB,CAAA;AACpB,CAAC,EAHW,kBAAkB,kCAAlB,kBAAkB,QAG7B;AAED;;;;GAIG;AACH,IAAY,iCAMX;AAND,WAAY,iCAAiC;IACzC,gDAAW,CAAA;IACX,kDAAa,CAAA;IACb,kDAAa,CAAA;IACb,kDAAa,CAAA;IACb,0DAAqB,CAAA;AACzB,CAAC,EANW,iCAAiC,iDAAjC,iCAAiC,QAM5C;AAED;;GAEG;AACH,IAAY,UAGX;AAHD,WAAY,UAAU;IAClB,6BAAe,CAAA;IACf,+BAAiB,CAAA;AACrB,CAAC,EAHW,UAAU,0BAAV,UAAU,QAGrB;AAED;;;;;;;;;;;GAWG;AACH,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IACzB,0CAAqB,CAAA;IACrB,kCAAa,CAAA;IACb,4CAAuB,CAAA;AAC3B,CAAC,EAJW,iBAAiB,iCAAjB,iBAAiB,QAI5B;AAsJD;;GAEG;AACH,IAAY,eAGX;AAHD,WAAY,eAAe;IACvB,sCAAmB,CAAA;IACnB,oCAAiB,CAAA;AACrB,CAAC,EAHW,eAAe,+BAAf,eAAe,QAG1B;AAED;;;GAGG;AACH,IAAY,+BAMX;AAND,WAAY,+BAA+B;IACvC,8CAAW,CAAA;IACX,gDAAa,CAAA;IACb,gDAAa,CAAA;IACb,gDAAa,CAAA;IACb,gDAAa,CAAA;AACjB,CAAC,EANW,+BAA+B,+CAA/B,+BAA+B,QAM1C;AAwJD,IAAY,SAKX;AALD,WAAY,SAAS;IACjB,wCAA2B,CAAA;IAC3B,kDAAqC,CAAA;IACrC,4CAA+B,CAAA;IAC/B,kCAAqB,CAAA;AACzB,CAAC,EALW,SAAS,yBAAT,SAAS,QAKpB;AAED;;;;;;;;;;;;GAYG;AACH,IAAY,aAGX;AAHD,WAAY,aAAa;IACrB,4BAAW,CAAA;IACX,oCAAmB,CAAA;AACvB,CAAC,EAHW,aAAa,6BAAb,aAAa,QAGxB;AAyQD,IAAY,QASX;AATD,WAAY,QAAQ;IAChB,6BAAiB,CAAA;IACjB,6BAAiB,CAAA;IACjB,+BAAmB,CAAA;IACnB,6BAAiB,CAAA;IACjB,6BAAiB,CAAA;IACjB,mCAAuB,CAAA;IACvB,yBAAa,CAAA;IACb,iCAAqB,CAAA;AACzB,CAAC,EATW,QAAQ,wBAAR,QAAQ,QASnB"}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
export {};
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const promises_1 = require("node:fs/promises");
|
||||
const node_module_1 = require("node:module");
|
||||
const path = __importStar(require("node:path"));
|
||||
const semver_1 = require("semver");
|
||||
const color_1 = require("../src/utilities/color");
|
||||
const config_1 = require("../src/utilities/config");
|
||||
const environment_options_1 = require("../src/utilities/environment-options");
|
||||
const version_1 = require("../src/utilities/version");
|
||||
/**
|
||||
* Angular CLI versions prior to v14 may not exit correctly if not forcibly exited
|
||||
* via `process.exit()`. When bootstrapping, `forceExit` will be set to `true`
|
||||
* if the local CLI version is less than v14 to prevent the CLI from hanging on
|
||||
* exit in those cases.
|
||||
*/
|
||||
let forceExit = false;
|
||||
(async () => {
|
||||
/**
|
||||
* Disable Browserslist old data warning as otherwise with every release we'd need to update this dependency
|
||||
* which is cumbersome considering we pin versions and the warning is not user actionable.
|
||||
* `Browserslist: caniuse-lite is outdated. Please run next command `npm update`
|
||||
* See: https://github.com/browserslist/browserslist/blob/819c4337456996d19db6ba953014579329e9c6e1/node.js#L324
|
||||
*/
|
||||
process.env.BROWSERSLIST_IGNORE_OLD_DATA = '1';
|
||||
const rawCommandName = process.argv[2];
|
||||
/**
|
||||
* Disable CLI version mismatch checks and forces usage of the invoked CLI
|
||||
* instead of invoking the local installed version.
|
||||
*
|
||||
* When running `ng new` always favor the global version. As in some
|
||||
* cases orphan `node_modules` would cause the non global CLI to be used.
|
||||
* @see: https://github.com/angular/angular-cli/issues/14603
|
||||
*/
|
||||
if (environment_options_1.disableVersionCheck || rawCommandName === 'new') {
|
||||
return (await Promise.resolve().then(() => __importStar(require('./cli')))).default;
|
||||
}
|
||||
let cli;
|
||||
try {
|
||||
// No error implies a projectLocalCli, which will load whatever
|
||||
// version of ng-cli you have installed in a local package.json
|
||||
const cwdRequire = (0, node_module_1.createRequire)(process.cwd() + '/');
|
||||
const projectLocalCli = cwdRequire.resolve('@angular/cli');
|
||||
cli = await Promise.resolve(`${projectLocalCli}`).then(s => __importStar(require(s)));
|
||||
const globalVersion = new semver_1.SemVer(version_1.VERSION.full);
|
||||
// Older versions might not have the VERSION export
|
||||
let localVersion = cli.VERSION?.full;
|
||||
if (!localVersion) {
|
||||
try {
|
||||
const localPackageJson = await (0, promises_1.readFile)(path.join(path.dirname(projectLocalCli), '../../package.json'), 'utf-8');
|
||||
localVersion = JSON.parse(localPackageJson).version;
|
||||
}
|
||||
catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Version mismatch check skipped. Unable to retrieve local version: ' + error);
|
||||
}
|
||||
}
|
||||
// Ensure older versions of the CLI fully exit
|
||||
const localMajorVersion = (0, semver_1.major)(localVersion);
|
||||
if (localMajorVersion > 0 && localMajorVersion < 14) {
|
||||
forceExit = true;
|
||||
// Versions prior to 14 didn't implement completion command.
|
||||
if (rawCommandName === 'completion') {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
let isGlobalGreater = false;
|
||||
try {
|
||||
isGlobalGreater = localVersion > 0 && globalVersion.compare(localVersion) > 0;
|
||||
}
|
||||
catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Version mismatch check skipped. Unable to compare local version: ' + error);
|
||||
}
|
||||
// When using the completion command, don't show the warning as otherwise this will break completion.
|
||||
if (isGlobalGreater &&
|
||||
rawCommandName !== '--get-yargs-completions' &&
|
||||
rawCommandName !== 'completion') {
|
||||
// If using the update command and the global version is greater, use the newer update command
|
||||
// This allows improvements in update to be used in older versions that do not have bootstrapping
|
||||
if (rawCommandName === 'update' &&
|
||||
cli.VERSION &&
|
||||
cli.VERSION.major - globalVersion.major <= 1) {
|
||||
cli = await Promise.resolve().then(() => __importStar(require('./cli')));
|
||||
}
|
||||
else if (await (0, config_1.isWarningEnabled)('versionMismatch')) {
|
||||
// Otherwise, use local version and warn if global is newer than local
|
||||
const warning = `Your global Angular CLI version (${globalVersion}) is greater than your local ` +
|
||||
`version (${localVersion}). The local Angular CLI version is used.\n\n` +
|
||||
'To disable this warning use "ng config -g cli.warnings.versionMismatch false".';
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(color_1.colors.yellow(warning));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// If there is an error, resolve could not find the ng-cli
|
||||
// library from a package.json. Instead, include it from a relative
|
||||
// path to this script file (which is likely a globally installed
|
||||
// npm package). Most common cause for hitting this is `ng new`
|
||||
cli = await Promise.resolve().then(() => __importStar(require('./cli')));
|
||||
}
|
||||
if ('default' in cli) {
|
||||
cli = cli['default'];
|
||||
}
|
||||
return cli;
|
||||
})()
|
||||
.then((cli) => cli?.({
|
||||
cliArgs: process.argv.slice(2),
|
||||
}))
|
||||
.then((exitCode = 0) => {
|
||||
if (forceExit) {
|
||||
process.exit(exitCode);
|
||||
}
|
||||
process.exitCode = exitCode;
|
||||
})
|
||||
.catch((err) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Unknown error: ' + err.toString());
|
||||
process.exit(127);
|
||||
});
|
||||
//# sourceMappingURL=init.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"init.js","sourceRoot":"","sources":["init.ts"],"names":[],"mappings":"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"}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "@angular/cli",
|
||||
"version": "21.2.1",
|
||||
"description": "CLI tool for Angular",
|
||||
"main": "lib/cli/index.js",
|
||||
"bin": {
|
||||
"ng": "./bin/ng.js"
|
||||
},
|
||||
"keywords": [
|
||||
"Angular CLI",
|
||||
"Angular DevKit",
|
||||
"angular",
|
||||
"angular-cli",
|
||||
"devkit",
|
||||
"sdk"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular-cli.git"
|
||||
},
|
||||
"author": "Angular Authors",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/angular/angular-cli/issues"
|
||||
},
|
||||
"homepage": "https://github.com/angular/angular-cli",
|
||||
"dependencies": {
|
||||
"@angular-devkit/architect": "0.2102.1",
|
||||
"@angular-devkit/core": "21.2.1",
|
||||
"@angular-devkit/schematics": "21.2.1",
|
||||
"@inquirer/prompts": "7.10.1",
|
||||
"@listr2/prompt-adapter-inquirer": "3.0.5",
|
||||
"@modelcontextprotocol/sdk": "1.26.0",
|
||||
"@schematics/angular": "21.2.1",
|
||||
"@yarnpkg/lockfile": "1.1.0",
|
||||
"algoliasearch": "5.48.1",
|
||||
"ini": "6.0.0",
|
||||
"jsonc-parser": "3.3.1",
|
||||
"listr2": "9.0.5",
|
||||
"npm-package-arg": "13.0.2",
|
||||
"pacote": "21.3.1",
|
||||
"parse5-html-rewriting-stream": "8.0.0",
|
||||
"semver": "7.7.4",
|
||||
"yargs": "18.0.0",
|
||||
"zod": "4.3.6"
|
||||
},
|
||||
"ng-update": {
|
||||
"migrations": "@schematics/angular/migrations/migration-collection.json",
|
||||
"packageGroup": {
|
||||
"@angular/cli": "21.2.1",
|
||||
"@angular/build": "21.2.1",
|
||||
"@angular/ssr": "21.2.1",
|
||||
"@angular-devkit/architect": "0.2102.1",
|
||||
"@angular-devkit/build-angular": "21.2.1",
|
||||
"@angular-devkit/build-webpack": "0.2102.1",
|
||||
"@angular-devkit/core": "21.2.1",
|
||||
"@angular-devkit/schematics": "21.2.1"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@10.30.3",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
||||
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
||||
"yarn": ">= 1.13.0"
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { logging } from '@angular-devkit/core';
|
||||
import { EventCustomDimension, EventCustomMetric, PrimitiveTypes } from './analytics-parameters';
|
||||
export declare class AnalyticsCollector {
|
||||
private logger;
|
||||
private trackingEventsQueue;
|
||||
private readonly requestParameterStringified;
|
||||
private readonly userParameters;
|
||||
constructor(logger: logging.Logger, userId: string, packageManagerInfo: {
|
||||
name: string;
|
||||
version: string | undefined;
|
||||
});
|
||||
reportWorkspaceInfoEvent(parameters: Partial<Record<EventCustomMetric, string | boolean | number | undefined>>): void;
|
||||
reportRebuildRunEvent(parameters: Partial<Record<EventCustomMetric & EventCustomDimension, string | boolean | number | undefined>>): void;
|
||||
reportBuildRunEvent(parameters: Partial<Record<EventCustomMetric & EventCustomDimension, string | boolean | number | undefined>>): void;
|
||||
reportArchitectRunEvent(parameters: Partial<Record<EventCustomDimension, PrimitiveTypes>>): void;
|
||||
reportSchematicRunEvent(parameters: Partial<Record<EventCustomDimension, PrimitiveTypes>>): void;
|
||||
reportCommandRunEvent(command: string): void;
|
||||
private event;
|
||||
/**
|
||||
* Flush on an interval (if the event loop is waiting).
|
||||
*
|
||||
* @returns a method that when called will terminate the periodic
|
||||
* flush and call flush one last time.
|
||||
*/
|
||||
periodFlush(): () => Promise<void>;
|
||||
flush(): Promise<void>;
|
||||
private send;
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AnalyticsCollector = void 0;
|
||||
const node_crypto_1 = require("node:crypto");
|
||||
const https = __importStar(require("node:https"));
|
||||
const os = __importStar(require("node:os"));
|
||||
const querystring = __importStar(require("node:querystring"));
|
||||
const semver = __importStar(require("semver"));
|
||||
const environment_options_1 = require("../utilities/environment-options");
|
||||
const error_1 = require("../utilities/error");
|
||||
const version_1 = require("../utilities/version");
|
||||
const analytics_parameters_1 = require("./analytics-parameters");
|
||||
const TRACKING_ID_PROD = 'G-VETNJBW8L4';
|
||||
const TRACKING_ID_STAGING = 'G-TBMPRL1BTM';
|
||||
class AnalyticsCollector {
|
||||
logger;
|
||||
trackingEventsQueue;
|
||||
requestParameterStringified;
|
||||
userParameters;
|
||||
constructor(logger, userId, packageManagerInfo) {
|
||||
this.logger = logger;
|
||||
const requestParameters = {
|
||||
[analytics_parameters_1.RequestParameter.ProtocolVersion]: 2,
|
||||
[analytics_parameters_1.RequestParameter.ClientId]: userId,
|
||||
[analytics_parameters_1.RequestParameter.UserId]: userId,
|
||||
[analytics_parameters_1.RequestParameter.TrackingId]: /^\d+\.\d+\.\d+$/.test(version_1.VERSION.full) && version_1.VERSION.full !== '0.0.0'
|
||||
? TRACKING_ID_PROD
|
||||
: TRACKING_ID_STAGING,
|
||||
// Built-in user properties
|
||||
[analytics_parameters_1.RequestParameter.SessionId]: (0, node_crypto_1.randomUUID)(),
|
||||
[analytics_parameters_1.RequestParameter.UserAgentArchitecture]: os.arch(),
|
||||
[analytics_parameters_1.RequestParameter.UserAgentPlatform]: os.platform(),
|
||||
[analytics_parameters_1.RequestParameter.UserAgentPlatformVersion]: os.release(),
|
||||
[analytics_parameters_1.RequestParameter.UserAgentMobile]: 0,
|
||||
[analytics_parameters_1.RequestParameter.SessionEngaged]: 1,
|
||||
// The below is needed for tech details to be collected.
|
||||
[analytics_parameters_1.RequestParameter.UserAgentFullVersionList]: 'Google%20Chrome;111.0.5563.64|Not(A%3ABrand;8.0.0.0|Chromium;111.0.5563.64',
|
||||
};
|
||||
if (environment_options_1.ngDebug) {
|
||||
requestParameters[analytics_parameters_1.RequestParameter.DebugView] = 1;
|
||||
}
|
||||
this.requestParameterStringified = querystring.stringify(requestParameters);
|
||||
const parsedVersion = semver.parse(process.version);
|
||||
const packageManagerVersion = packageManagerInfo.version;
|
||||
this.userParameters = {
|
||||
// While architecture is being collect by GA as UserAgentArchitecture.
|
||||
// It doesn't look like there is a way to query this. Therefore we collect this as a custom user dimension too.
|
||||
[analytics_parameters_1.UserCustomDimension.OsArchitecture]: os.arch(),
|
||||
// While User ID is being collected by GA, this is not visible in reports/for filtering.
|
||||
[analytics_parameters_1.UserCustomDimension.UserId]: userId,
|
||||
[analytics_parameters_1.UserCustomDimension.NodeVersion]: parsedVersion
|
||||
? `${parsedVersion.major}.${parsedVersion.minor}.${parsedVersion.patch}`
|
||||
: 'other',
|
||||
[analytics_parameters_1.UserCustomDimension.NodeMajorVersion]: parsedVersion?.major,
|
||||
[analytics_parameters_1.UserCustomDimension.PackageManager]: packageManagerInfo.name,
|
||||
[analytics_parameters_1.UserCustomDimension.PackageManagerVersion]: packageManagerVersion,
|
||||
[analytics_parameters_1.UserCustomDimension.PackageManagerMajorVersion]: packageManagerVersion
|
||||
? +packageManagerVersion.split('.', 1)[0]
|
||||
: undefined,
|
||||
[analytics_parameters_1.UserCustomDimension.AngularCLIVersion]: version_1.VERSION.full,
|
||||
[analytics_parameters_1.UserCustomDimension.AngularCLIMajorVersion]: version_1.VERSION.major,
|
||||
};
|
||||
}
|
||||
reportWorkspaceInfoEvent(parameters) {
|
||||
this.event('workspace_info', parameters);
|
||||
}
|
||||
reportRebuildRunEvent(parameters) {
|
||||
this.event('run_rebuild', parameters);
|
||||
}
|
||||
reportBuildRunEvent(parameters) {
|
||||
this.event('run_build', parameters);
|
||||
}
|
||||
reportArchitectRunEvent(parameters) {
|
||||
this.event('run_architect', parameters);
|
||||
}
|
||||
reportSchematicRunEvent(parameters) {
|
||||
this.event('run_schematic', parameters);
|
||||
}
|
||||
reportCommandRunEvent(command) {
|
||||
this.event('run_command', { [analytics_parameters_1.EventCustomDimension.Command]: command });
|
||||
}
|
||||
event(eventName, parameters) {
|
||||
this.trackingEventsQueue ??= [];
|
||||
this.trackingEventsQueue.push({
|
||||
...this.userParameters,
|
||||
...parameters,
|
||||
'en': eventName,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Flush on an interval (if the event loop is waiting).
|
||||
*
|
||||
* @returns a method that when called will terminate the periodic
|
||||
* flush and call flush one last time.
|
||||
*/
|
||||
periodFlush() {
|
||||
let analyticsFlushPromise = Promise.resolve();
|
||||
const analyticsFlushInterval = setInterval(() => {
|
||||
if (this.trackingEventsQueue?.length) {
|
||||
analyticsFlushPromise = analyticsFlushPromise.then(() => this.flush());
|
||||
}
|
||||
}, 4000);
|
||||
return () => {
|
||||
clearInterval(analyticsFlushInterval);
|
||||
// Flush one last time.
|
||||
return analyticsFlushPromise.then(() => this.flush());
|
||||
};
|
||||
}
|
||||
async flush() {
|
||||
const pendingTrackingEvents = this.trackingEventsQueue;
|
||||
this.logger.debug(`Analytics flush size. ${pendingTrackingEvents?.length}.`);
|
||||
if (!pendingTrackingEvents?.length) {
|
||||
return;
|
||||
}
|
||||
// The below is needed so that if flush is called multiple times,
|
||||
// we don't report the same event multiple times.
|
||||
this.trackingEventsQueue = undefined;
|
||||
try {
|
||||
await this.send(pendingTrackingEvents);
|
||||
}
|
||||
catch (error) {
|
||||
// Failure to report analytics shouldn't crash the CLI.
|
||||
(0, error_1.assertIsError)(error);
|
||||
this.logger.debug(`Send analytics error. ${error.message}.`);
|
||||
}
|
||||
}
|
||||
async send(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = https.request({
|
||||
host: 'www.google-analytics.com',
|
||||
method: 'POST',
|
||||
path: '/g/collect?' + this.requestParameterStringified,
|
||||
headers: {
|
||||
// The below is needed for tech details to be collected even though we provide our own information from the OS Node.js module
|
||||
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
|
||||
},
|
||||
}, (response) => {
|
||||
// The below is needed as otherwise the response will never close which will cause the CLI not to terminate.
|
||||
response.on('data', () => { });
|
||||
if (response.statusCode !== 200 && response.statusCode !== 204) {
|
||||
reject(new Error(`Analytics reporting failed with status code: ${response.statusCode}.`));
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
request.on('error', reject);
|
||||
const queryParameters = data.map((p) => querystring.stringify(p)).join('\n');
|
||||
request.write(queryParameters);
|
||||
request.end();
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.AnalyticsCollector = AnalyticsCollector;
|
||||
//# sourceMappingURL=analytics-collector.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"analytics-collector.js","sourceRoot":"","sources":["analytics-collector.ts"],"names":[],"mappings":"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"}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
/** Any changes in this file needs to be done in the mts version. */
|
||||
export type PrimitiveTypes = string | number | boolean;
|
||||
/**
|
||||
* GA built-in request parameters
|
||||
* @see https://www.thyngster.com/ga4-measurement-protocol-cheatsheet
|
||||
* @see http://go/depot/google3/analytics/container_tag/templates/common/gold/mpv2_schema.js
|
||||
*/
|
||||
export declare enum RequestParameter {
|
||||
ClientId = "cid",
|
||||
DebugView = "_dbg",
|
||||
GtmVersion = "gtm",
|
||||
Language = "ul",
|
||||
NewToSite = "_nsi",
|
||||
NonInteraction = "ni",
|
||||
PageLocation = "dl",
|
||||
PageTitle = "dt",
|
||||
ProtocolVersion = "v",
|
||||
SessionEngaged = "seg",
|
||||
SessionId = "sid",
|
||||
SessionNumber = "sct",
|
||||
SessionStart = "_ss",
|
||||
TrackingId = "tid",
|
||||
TrafficType = "tt",
|
||||
UserAgentArchitecture = "uaa",
|
||||
UserAgentBitness = "uab",
|
||||
UserAgentFullVersionList = "uafvl",
|
||||
UserAgentMobile = "uamb",
|
||||
UserAgentModel = "uam",
|
||||
UserAgentPlatform = "uap",
|
||||
UserAgentPlatformVersion = "uapv",
|
||||
UserId = "uid"
|
||||
}
|
||||
/**
|
||||
* User scoped custom dimensions.
|
||||
* @remarks
|
||||
* - User custom dimensions limit is 25.
|
||||
* - `up.*` string type.
|
||||
* - `upn.*` number type.
|
||||
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
||||
*/
|
||||
export declare enum UserCustomDimension {
|
||||
UserId = "up.ng_user_id",
|
||||
OsArchitecture = "up.ng_os_architecture",
|
||||
NodeVersion = "up.ng_node_version",
|
||||
NodeMajorVersion = "upn.ng_node_major_version",
|
||||
AngularCLIVersion = "up.ng_cli_version",
|
||||
AngularCLIMajorVersion = "upn.ng_cli_major_version",
|
||||
PackageManager = "up.ng_package_manager",
|
||||
PackageManagerVersion = "up.ng_pkg_manager_version",
|
||||
PackageManagerMajorVersion = "upn.ng_pkg_manager_major_v"
|
||||
}
|
||||
/**
|
||||
* Event scoped custom dimensions.
|
||||
* @remarks
|
||||
* - Event custom dimensions limit is 50.
|
||||
* - `ep.*` string type.
|
||||
* - `epn.*` number type.
|
||||
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
||||
*/
|
||||
export declare enum EventCustomDimension {
|
||||
Command = "ep.ng_command",
|
||||
SchematicCollectionName = "ep.ng_schematic_collection_name",
|
||||
SchematicName = "ep.ng_schematic_name",
|
||||
Standalone = "ep.ng_standalone",
|
||||
SSR = "ep.ng_ssr",
|
||||
Style = "ep.ng_style",
|
||||
Routing = "ep.ng_routing",
|
||||
InlineTemplate = "ep.ng_inline_template",
|
||||
InlineStyle = "ep.ng_inline_style",
|
||||
BuilderTarget = "ep.ng_builder_target",
|
||||
Aot = "ep.ng_aot",
|
||||
Optimization = "ep.ng_optimization"
|
||||
}
|
||||
/**
|
||||
* Event scoped custom mertics.
|
||||
* @remarks
|
||||
* - Event scoped custom mertics limit is 50.
|
||||
* - `ep.*` string type.
|
||||
* - `epn.*` number type.
|
||||
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
||||
*/
|
||||
export declare enum EventCustomMetric {
|
||||
AllChunksCount = "epn.ng_all_chunks_count",
|
||||
LazyChunksCount = "epn.ng_lazy_chunks_count",
|
||||
InitialChunksCount = "epn.ng_initial_chunks_count",
|
||||
ChangedChunksCount = "epn.ng_changed_chunks_count",
|
||||
DurationInMs = "epn.ng_duration_ms",
|
||||
CssSizeInBytes = "epn.ng_css_size_bytes",
|
||||
JsSizeInBytes = "epn.ng_js_size_bytes",
|
||||
NgComponentCount = "epn.ng_component_count",
|
||||
AllProjectsCount = "epn.all_projects_count",
|
||||
LibraryProjectsCount = "epn.libs_projects_count",
|
||||
ApplicationProjectsCount = "epn.apps_projects_count"
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EventCustomMetric = exports.EventCustomDimension = exports.UserCustomDimension = exports.RequestParameter = void 0;
|
||||
/**
|
||||
* GA built-in request parameters
|
||||
* @see https://www.thyngster.com/ga4-measurement-protocol-cheatsheet
|
||||
* @see http://go/depot/google3/analytics/container_tag/templates/common/gold/mpv2_schema.js
|
||||
*/
|
||||
var RequestParameter;
|
||||
(function (RequestParameter) {
|
||||
RequestParameter["ClientId"] = "cid";
|
||||
RequestParameter["DebugView"] = "_dbg";
|
||||
RequestParameter["GtmVersion"] = "gtm";
|
||||
RequestParameter["Language"] = "ul";
|
||||
RequestParameter["NewToSite"] = "_nsi";
|
||||
RequestParameter["NonInteraction"] = "ni";
|
||||
RequestParameter["PageLocation"] = "dl";
|
||||
RequestParameter["PageTitle"] = "dt";
|
||||
RequestParameter["ProtocolVersion"] = "v";
|
||||
RequestParameter["SessionEngaged"] = "seg";
|
||||
RequestParameter["SessionId"] = "sid";
|
||||
RequestParameter["SessionNumber"] = "sct";
|
||||
RequestParameter["SessionStart"] = "_ss";
|
||||
RequestParameter["TrackingId"] = "tid";
|
||||
RequestParameter["TrafficType"] = "tt";
|
||||
RequestParameter["UserAgentArchitecture"] = "uaa";
|
||||
RequestParameter["UserAgentBitness"] = "uab";
|
||||
RequestParameter["UserAgentFullVersionList"] = "uafvl";
|
||||
RequestParameter["UserAgentMobile"] = "uamb";
|
||||
RequestParameter["UserAgentModel"] = "uam";
|
||||
RequestParameter["UserAgentPlatform"] = "uap";
|
||||
RequestParameter["UserAgentPlatformVersion"] = "uapv";
|
||||
RequestParameter["UserId"] = "uid";
|
||||
})(RequestParameter || (exports.RequestParameter = RequestParameter = {}));
|
||||
/**
|
||||
* User scoped custom dimensions.
|
||||
* @remarks
|
||||
* - User custom dimensions limit is 25.
|
||||
* - `up.*` string type.
|
||||
* - `upn.*` number type.
|
||||
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
||||
*/
|
||||
var UserCustomDimension;
|
||||
(function (UserCustomDimension) {
|
||||
UserCustomDimension["UserId"] = "up.ng_user_id";
|
||||
UserCustomDimension["OsArchitecture"] = "up.ng_os_architecture";
|
||||
UserCustomDimension["NodeVersion"] = "up.ng_node_version";
|
||||
UserCustomDimension["NodeMajorVersion"] = "upn.ng_node_major_version";
|
||||
UserCustomDimension["AngularCLIVersion"] = "up.ng_cli_version";
|
||||
UserCustomDimension["AngularCLIMajorVersion"] = "upn.ng_cli_major_version";
|
||||
UserCustomDimension["PackageManager"] = "up.ng_package_manager";
|
||||
UserCustomDimension["PackageManagerVersion"] = "up.ng_pkg_manager_version";
|
||||
UserCustomDimension["PackageManagerMajorVersion"] = "upn.ng_pkg_manager_major_v";
|
||||
})(UserCustomDimension || (exports.UserCustomDimension = UserCustomDimension = {}));
|
||||
/**
|
||||
* Event scoped custom dimensions.
|
||||
* @remarks
|
||||
* - Event custom dimensions limit is 50.
|
||||
* - `ep.*` string type.
|
||||
* - `epn.*` number type.
|
||||
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
||||
*/
|
||||
var EventCustomDimension;
|
||||
(function (EventCustomDimension) {
|
||||
EventCustomDimension["Command"] = "ep.ng_command";
|
||||
EventCustomDimension["SchematicCollectionName"] = "ep.ng_schematic_collection_name";
|
||||
EventCustomDimension["SchematicName"] = "ep.ng_schematic_name";
|
||||
EventCustomDimension["Standalone"] = "ep.ng_standalone";
|
||||
EventCustomDimension["SSR"] = "ep.ng_ssr";
|
||||
EventCustomDimension["Style"] = "ep.ng_style";
|
||||
EventCustomDimension["Routing"] = "ep.ng_routing";
|
||||
EventCustomDimension["InlineTemplate"] = "ep.ng_inline_template";
|
||||
EventCustomDimension["InlineStyle"] = "ep.ng_inline_style";
|
||||
EventCustomDimension["BuilderTarget"] = "ep.ng_builder_target";
|
||||
EventCustomDimension["Aot"] = "ep.ng_aot";
|
||||
EventCustomDimension["Optimization"] = "ep.ng_optimization";
|
||||
})(EventCustomDimension || (exports.EventCustomDimension = EventCustomDimension = {}));
|
||||
/**
|
||||
* Event scoped custom mertics.
|
||||
* @remarks
|
||||
* - Event scoped custom mertics limit is 50.
|
||||
* - `ep.*` string type.
|
||||
* - `epn.*` number type.
|
||||
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
||||
*/
|
||||
var EventCustomMetric;
|
||||
(function (EventCustomMetric) {
|
||||
EventCustomMetric["AllChunksCount"] = "epn.ng_all_chunks_count";
|
||||
EventCustomMetric["LazyChunksCount"] = "epn.ng_lazy_chunks_count";
|
||||
EventCustomMetric["InitialChunksCount"] = "epn.ng_initial_chunks_count";
|
||||
EventCustomMetric["ChangedChunksCount"] = "epn.ng_changed_chunks_count";
|
||||
EventCustomMetric["DurationInMs"] = "epn.ng_duration_ms";
|
||||
EventCustomMetric["CssSizeInBytes"] = "epn.ng_css_size_bytes";
|
||||
EventCustomMetric["JsSizeInBytes"] = "epn.ng_js_size_bytes";
|
||||
EventCustomMetric["NgComponentCount"] = "epn.ng_component_count";
|
||||
EventCustomMetric["AllProjectsCount"] = "epn.all_projects_count";
|
||||
EventCustomMetric["LibraryProjectsCount"] = "epn.libs_projects_count";
|
||||
EventCustomMetric["ApplicationProjectsCount"] = "epn.apps_projects_count";
|
||||
})(EventCustomMetric || (exports.EventCustomMetric = EventCustomMetric = {}));
|
||||
//# sourceMappingURL=analytics-parameters.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"analytics-parameters.js","sourceRoot":"","sources":["analytics-parameters.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAMH;;;;GAIG;AACH,IAAY,gBAwBX;AAxBD,WAAY,gBAAgB;IAC1B,oCAAgB,CAAA;IAChB,sCAAkB,CAAA;IAClB,sCAAkB,CAAA;IAClB,mCAAe,CAAA;IACf,sCAAkB,CAAA;IAClB,yCAAqB,CAAA;IACrB,uCAAmB,CAAA;IACnB,oCAAgB,CAAA;IAChB,yCAAqB,CAAA;IACrB,0CAAsB,CAAA;IACtB,qCAAiB,CAAA;IACjB,yCAAqB,CAAA;IACrB,wCAAoB,CAAA;IACpB,sCAAkB,CAAA;IAClB,sCAAkB,CAAA;IAClB,iDAA6B,CAAA;IAC7B,4CAAwB,CAAA;IACxB,sDAAkC,CAAA;IAClC,4CAAwB,CAAA;IACxB,0CAAsB,CAAA;IACtB,6CAAyB,CAAA;IACzB,qDAAiC,CAAA;IACjC,kCAAc,CAAA;AAChB,CAAC,EAxBW,gBAAgB,gCAAhB,gBAAgB,QAwB3B;AAED;;;;;;;GAOG;AACH,IAAY,mBAUX;AAVD,WAAY,mBAAmB;IAC7B,+CAAwB,CAAA;IACxB,+DAAwC,CAAA;IACxC,yDAAkC,CAAA;IAClC,qEAA8C,CAAA;IAC9C,8DAAuC,CAAA;IACvC,0EAAmD,CAAA;IACnD,+DAAwC,CAAA;IACxC,0EAAmD,CAAA;IACnD,gFAAyD,CAAA;AAC3D,CAAC,EAVW,mBAAmB,mCAAnB,mBAAmB,QAU9B;AAED;;;;;;;GAOG;AACH,IAAY,oBAaX;AAbD,WAAY,oBAAoB;IAC9B,iDAAyB,CAAA;IACzB,mFAA2D,CAAA;IAC3D,8DAAsC,CAAA;IACtC,uDAA+B,CAAA;IAC/B,yCAAiB,CAAA;IACjB,6CAAqB,CAAA;IACrB,iDAAyB,CAAA;IACzB,gEAAwC,CAAA;IACxC,0DAAkC,CAAA;IAClC,8DAAsC,CAAA;IACtC,yCAAiB,CAAA;IACjB,2DAAmC,CAAA;AACrC,CAAC,EAbW,oBAAoB,oCAApB,oBAAoB,QAa/B;AAED;;;;;;;GAOG;AACH,IAAY,iBAYX;AAZD,WAAY,iBAAiB;IAC3B,+DAA0C,CAAA;IAC1C,iEAA4C,CAAA;IAC5C,uEAAkD,CAAA;IAClD,uEAAkD,CAAA;IAClD,wDAAmC,CAAA;IACnC,6DAAwC,CAAA;IACxC,2DAAsC,CAAA;IACtC,gEAA2C,CAAA;IAC3C,gEAA2C,CAAA;IAC3C,qEAAgD,CAAA;IAChD,yEAAoD,CAAA;AACtD,CAAC,EAZW,iBAAiB,iCAAjB,iBAAiB,QAY5B"}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import type { CommandContext } from '../command-builder/definitions';
|
||||
/**
|
||||
* This is the ultimate safelist for checking if a package name is safe to report to analytics.
|
||||
*/
|
||||
export declare const analyticsPackageSafelist: (string | RegExp)[];
|
||||
export declare function isPackageNameSafeForAnalytics(name: string): boolean;
|
||||
/**
|
||||
* Set analytics settings. This does not work if the user is not inside a project.
|
||||
* @param global Which config to use. "global" for user-level, and "local" for project-level.
|
||||
* @param value Either a user ID, true to generate a new User ID, or false to disable analytics.
|
||||
*/
|
||||
export declare function setAnalyticsConfig(global: boolean, value: string | boolean): Promise<void>;
|
||||
/**
|
||||
* Prompt the user for usage gathering permission.
|
||||
* @param force Whether to ask regardless of whether or not the user is using an interactive shell.
|
||||
* @return Whether or not the user was shown a prompt.
|
||||
*/
|
||||
export declare function promptAnalytics(context: CommandContext, global: boolean, force?: boolean): Promise<boolean>;
|
||||
export declare function getAnalyticsUserId(context: CommandContext, skipPrompt?: boolean): Promise<string | undefined>;
|
||||
export declare function getAnalyticsInfoString(context: CommandContext): Promise<string>;
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.analyticsPackageSafelist = void 0;
|
||||
exports.isPackageNameSafeForAnalytics = isPackageNameSafeForAnalytics;
|
||||
exports.setAnalyticsConfig = setAnalyticsConfig;
|
||||
exports.promptAnalytics = promptAnalytics;
|
||||
exports.getAnalyticsUserId = getAnalyticsUserId;
|
||||
exports.getAnalyticsInfoString = getAnalyticsInfoString;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const node_crypto_1 = require("node:crypto");
|
||||
const color_1 = require("../utilities/color");
|
||||
const config_1 = require("../utilities/config");
|
||||
const environment_options_1 = require("../utilities/environment-options");
|
||||
const prompt_1 = require("../utilities/prompt");
|
||||
const tty_1 = require("../utilities/tty");
|
||||
/* eslint-disable no-console */
|
||||
/**
|
||||
* This is the ultimate safelist for checking if a package name is safe to report to analytics.
|
||||
*/
|
||||
exports.analyticsPackageSafelist = [
|
||||
/^@angular\//,
|
||||
/^@angular-devkit\//,
|
||||
/^@nguniversal\//,
|
||||
'@schematics/angular',
|
||||
];
|
||||
function isPackageNameSafeForAnalytics(name) {
|
||||
return exports.analyticsPackageSafelist.some((pattern) => {
|
||||
if (typeof pattern == 'string') {
|
||||
return pattern === name;
|
||||
}
|
||||
else {
|
||||
return pattern.test(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Set analytics settings. This does not work if the user is not inside a project.
|
||||
* @param global Which config to use. "global" for user-level, and "local" for project-level.
|
||||
* @param value Either a user ID, true to generate a new User ID, or false to disable analytics.
|
||||
*/
|
||||
async function setAnalyticsConfig(global, value) {
|
||||
const level = global ? 'global' : 'local';
|
||||
const workspace = await (0, config_1.getWorkspace)(level);
|
||||
if (!workspace) {
|
||||
throw new Error(`Could not find ${level} workspace.`);
|
||||
}
|
||||
const cli = (workspace.extensions['cli'] ??= {});
|
||||
if (!workspace || !core_1.json.isJsonObject(cli)) {
|
||||
throw new Error(`Invalid config found at ${workspace.filePath}. CLI should be an object.`);
|
||||
}
|
||||
cli.analytics = value === true ? (0, node_crypto_1.randomUUID)() : value;
|
||||
await workspace.save();
|
||||
}
|
||||
/**
|
||||
* Prompt the user for usage gathering permission.
|
||||
* @param force Whether to ask regardless of whether or not the user is using an interactive shell.
|
||||
* @return Whether or not the user was shown a prompt.
|
||||
*/
|
||||
async function promptAnalytics(context, global, force = false) {
|
||||
const level = global ? 'global' : 'local';
|
||||
const workspace = await (0, config_1.getWorkspace)(level);
|
||||
if (!workspace) {
|
||||
throw new Error(`Could not find a ${level} workspace. Are you in a project?`);
|
||||
}
|
||||
if (force || (0, tty_1.isTTY)()) {
|
||||
const answer = await (0, prompt_1.askConfirmation)(`
|
||||
Would you like to share pseudonymous usage data about this project with the Angular Team
|
||||
at Google under Google's Privacy Policy at https://policies.google.com/privacy. For more
|
||||
details and how to change this setting, see https://angular.dev/cli/analytics.
|
||||
|
||||
`, false);
|
||||
await setAnalyticsConfig(global, answer);
|
||||
if (answer) {
|
||||
console.log('');
|
||||
console.log(core_1.tags.stripIndent `
|
||||
Thank you for sharing pseudonymous usage data. Should you change your mind, the following
|
||||
command will disable this feature entirely:
|
||||
|
||||
${color_1.colors.yellow(`ng analytics disable${global ? ' --global' : ''}`)}
|
||||
`);
|
||||
console.log('');
|
||||
}
|
||||
process.stderr.write(await getAnalyticsInfoString(context));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Get the analytics user id.
|
||||
*
|
||||
* @returns
|
||||
* - `string` user id.
|
||||
* - `false` when disabled.
|
||||
* - `undefined` when not configured.
|
||||
*/
|
||||
async function getAnalyticsUserIdForLevel(level) {
|
||||
if (environment_options_1.analyticsDisabled) {
|
||||
return false;
|
||||
}
|
||||
const workspace = await (0, config_1.getWorkspace)(level);
|
||||
const analyticsConfig = workspace?.getCli()?.['analytics'];
|
||||
if (analyticsConfig === false) {
|
||||
return false;
|
||||
}
|
||||
else if (analyticsConfig === undefined || analyticsConfig === null) {
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
if (typeof analyticsConfig == 'string') {
|
||||
return analyticsConfig;
|
||||
}
|
||||
else if (typeof analyticsConfig == 'object' && typeof analyticsConfig['uid'] == 'string') {
|
||||
return analyticsConfig['uid'];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
async function getAnalyticsUserId(context, skipPrompt = false) {
|
||||
const { workspace } = context;
|
||||
// Global config takes precedence over local config only for the disabled check.
|
||||
// IE:
|
||||
// global: disabled & local: enabled = disabled
|
||||
// global: id: 123 & local: id: 456 = 456
|
||||
// check global
|
||||
const globalConfig = await getAnalyticsUserIdForLevel('global');
|
||||
if (globalConfig === false) {
|
||||
return undefined;
|
||||
}
|
||||
// Not disabled globally, check locally or not set globally and command is run outside of workspace example: `ng new`
|
||||
if (workspace || globalConfig === undefined) {
|
||||
const level = workspace ? 'local' : 'global';
|
||||
let localOrGlobalConfig = await getAnalyticsUserIdForLevel(level);
|
||||
if (localOrGlobalConfig === undefined) {
|
||||
if (!skipPrompt) {
|
||||
// config is unset, prompt user.
|
||||
// TODO: This should honor the `no-interactive` option.
|
||||
// It is currently not an `ng` option but rather only an option for specific commands.
|
||||
// The concept of `ng`-wide options are needed to cleanly handle this.
|
||||
await promptAnalytics(context, !workspace /** global */);
|
||||
localOrGlobalConfig = await getAnalyticsUserIdForLevel(level);
|
||||
}
|
||||
}
|
||||
if (localOrGlobalConfig === false) {
|
||||
return undefined;
|
||||
}
|
||||
else if (typeof localOrGlobalConfig === 'string') {
|
||||
return localOrGlobalConfig;
|
||||
}
|
||||
}
|
||||
return globalConfig;
|
||||
}
|
||||
function analyticsConfigValueToHumanFormat(value) {
|
||||
if (value === false) {
|
||||
return 'disabled';
|
||||
}
|
||||
else if (typeof value === 'string' || value === true) {
|
||||
return 'enabled';
|
||||
}
|
||||
else {
|
||||
return 'not set';
|
||||
}
|
||||
}
|
||||
async function getAnalyticsInfoString(context) {
|
||||
const analyticsInstance = await getAnalyticsUserId(context, true /** skipPrompt */);
|
||||
const { globalConfiguration, workspace: localWorkspace } = context;
|
||||
const globalSetting = globalConfiguration?.getCli()?.['analytics'];
|
||||
const localSetting = localWorkspace?.getCli()?.['analytics'];
|
||||
return (core_1.tags.stripIndents `
|
||||
Global setting: ${analyticsConfigValueToHumanFormat(globalSetting)}
|
||||
Local setting: ${localWorkspace
|
||||
? analyticsConfigValueToHumanFormat(localSetting)
|
||||
: 'No local workspace configuration file.'}
|
||||
Effective status: ${analyticsInstance ? 'enabled' : 'disabled'}
|
||||
` + '\n');
|
||||
}
|
||||
//# sourceMappingURL=analytics.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["analytics.ts"],"names":[],"mappings":"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"}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Architect, Target } from '@angular-devkit/architect';
|
||||
import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node';
|
||||
import { CommandModule, CommandModuleImplementation, CommandScope, OtherOptions } from './command-module';
|
||||
import { Option } from './utilities/json-schema';
|
||||
export interface MissingTargetChoice {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
export declare abstract class ArchitectBaseCommandModule<T extends object> extends CommandModule<T> implements CommandModuleImplementation<T> {
|
||||
scope: CommandScope;
|
||||
protected readonly missingTargetChoices: MissingTargetChoice[] | undefined;
|
||||
protected runSingleTarget(target: Target, options: OtherOptions): Promise<number>;
|
||||
private builderStatsToAnalyticsParameters;
|
||||
private _architectHost;
|
||||
protected getArchitectHost(): WorkspaceNodeModulesArchitectHost;
|
||||
private _architect;
|
||||
protected getArchitect(skipUndefinedArrayTransform: boolean): Architect;
|
||||
protected getArchitectTargetOptions(target: Target): Promise<Option[]>;
|
||||
private warnOnMissingNodeModules;
|
||||
protected getArchitectTarget(): string;
|
||||
protected onMissingTarget(defaultMessage: string): Promise<1>;
|
||||
private getMissingTargetPackageToInstall;
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ArchitectBaseCommandModule = void 0;
|
||||
const architect_1 = require("@angular-devkit/architect");
|
||||
const node_1 = require("@angular-devkit/architect/node");
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const node_module_1 = require("node:module");
|
||||
const analytics_1 = require("../analytics/analytics");
|
||||
const analytics_parameters_1 = require("../analytics/analytics-parameters");
|
||||
const error_1 = require("../utilities/error");
|
||||
const prompt_1 = require("../utilities/prompt");
|
||||
const tty_1 = require("../utilities/tty");
|
||||
const command_module_1 = require("./command-module");
|
||||
const json_schema_1 = require("./utilities/json-schema");
|
||||
class ArchitectBaseCommandModule extends command_module_1.CommandModule {
|
||||
scope = command_module_1.CommandScope.In;
|
||||
missingTargetChoices;
|
||||
async runSingleTarget(target, options) {
|
||||
const architectHost = this.getArchitectHost();
|
||||
let builderName;
|
||||
try {
|
||||
builderName = await architectHost.getBuilderNameForTarget(target);
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
return this.onMissingTarget(e.message);
|
||||
}
|
||||
const isAngularBuild = builderName.startsWith('@angular/build:');
|
||||
const { logger } = this.context;
|
||||
const run = await this.getArchitect(isAngularBuild).scheduleTarget(target, options, {
|
||||
logger,
|
||||
});
|
||||
const analytics = (0, analytics_1.isPackageNameSafeForAnalytics)(builderName)
|
||||
? await this.getAnalytics()
|
||||
: undefined;
|
||||
let outputSubscription;
|
||||
if (analytics) {
|
||||
analytics.reportArchitectRunEvent({
|
||||
[analytics_parameters_1.EventCustomDimension.BuilderTarget]: builderName,
|
||||
});
|
||||
let firstRun = true;
|
||||
outputSubscription = run.output.subscribe(({ stats }) => {
|
||||
const parameters = this.builderStatsToAnalyticsParameters(stats, builderName);
|
||||
if (!parameters) {
|
||||
return;
|
||||
}
|
||||
if (firstRun) {
|
||||
firstRun = false;
|
||||
analytics.reportBuildRunEvent(parameters);
|
||||
}
|
||||
else {
|
||||
analytics.reportRebuildRunEvent(parameters);
|
||||
}
|
||||
});
|
||||
}
|
||||
try {
|
||||
const { error, success } = await run.lastOutput;
|
||||
if (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
return success ? 0 : 1;
|
||||
}
|
||||
finally {
|
||||
await run.stop();
|
||||
outputSubscription?.unsubscribe();
|
||||
}
|
||||
}
|
||||
builderStatsToAnalyticsParameters(stats, builderName) {
|
||||
if (!stats || typeof stats !== 'object' || !('durationInMs' in stats)) {
|
||||
return undefined;
|
||||
}
|
||||
const { optimization, allChunksCount, aot, lazyChunksCount, initialChunksCount, durationInMs, changedChunksCount, cssSizeInBytes, jsSizeInBytes, ngComponentCount, } = stats;
|
||||
return {
|
||||
[analytics_parameters_1.EventCustomDimension.BuilderTarget]: builderName,
|
||||
[analytics_parameters_1.EventCustomDimension.Aot]: aot,
|
||||
[analytics_parameters_1.EventCustomDimension.Optimization]: optimization,
|
||||
[analytics_parameters_1.EventCustomMetric.AllChunksCount]: allChunksCount,
|
||||
[analytics_parameters_1.EventCustomMetric.LazyChunksCount]: lazyChunksCount,
|
||||
[analytics_parameters_1.EventCustomMetric.InitialChunksCount]: initialChunksCount,
|
||||
[analytics_parameters_1.EventCustomMetric.ChangedChunksCount]: changedChunksCount,
|
||||
[analytics_parameters_1.EventCustomMetric.DurationInMs]: durationInMs,
|
||||
[analytics_parameters_1.EventCustomMetric.JsSizeInBytes]: jsSizeInBytes,
|
||||
[analytics_parameters_1.EventCustomMetric.CssSizeInBytes]: cssSizeInBytes,
|
||||
[analytics_parameters_1.EventCustomMetric.NgComponentCount]: ngComponentCount,
|
||||
};
|
||||
}
|
||||
_architectHost;
|
||||
getArchitectHost() {
|
||||
if (this._architectHost) {
|
||||
return this._architectHost;
|
||||
}
|
||||
const workspace = this.getWorkspaceOrThrow();
|
||||
return (this._architectHost = new node_1.WorkspaceNodeModulesArchitectHost(workspace, workspace.basePath));
|
||||
}
|
||||
_architect;
|
||||
getArchitect(skipUndefinedArrayTransform) {
|
||||
if (this._architect) {
|
||||
return this._architect;
|
||||
}
|
||||
const registry = new core_1.json.schema.CoreSchemaRegistry();
|
||||
if (skipUndefinedArrayTransform) {
|
||||
registry.addPostTransform(core_1.json.schema.transforms.addUndefinedObjectDefaults);
|
||||
}
|
||||
else {
|
||||
registry.addPostTransform(core_1.json.schema.transforms.addUndefinedDefaults);
|
||||
}
|
||||
registry.useXDeprecatedProvider((msg) => this.context.logger.warn(msg));
|
||||
const architectHost = this.getArchitectHost();
|
||||
return (this._architect = new architect_1.Architect(architectHost, registry));
|
||||
}
|
||||
async getArchitectTargetOptions(target) {
|
||||
const architectHost = this.getArchitectHost();
|
||||
let builderConf;
|
||||
try {
|
||||
builderConf = await architectHost.getBuilderNameForTarget(target);
|
||||
}
|
||||
catch {
|
||||
return [];
|
||||
}
|
||||
let builderDesc;
|
||||
try {
|
||||
builderDesc = await architectHost.resolveBuilder(builderConf);
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
if (e.code === 'MODULE_NOT_FOUND') {
|
||||
this.warnOnMissingNodeModules();
|
||||
throw new command_module_1.CommandModuleError(`Could not find the '${builderConf}' builder's node package.`);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return (0, json_schema_1.parseJsonSchemaToOptions)(new core_1.json.schema.CoreSchemaRegistry(), builderDesc.optionSchema, true);
|
||||
}
|
||||
warnOnMissingNodeModules() {
|
||||
const basePath = this.context.workspace?.basePath;
|
||||
if (!basePath) {
|
||||
return;
|
||||
}
|
||||
const workspaceResolve = (0, node_module_1.createRequire)(basePath + '/').resolve;
|
||||
try {
|
||||
workspaceResolve('@angular/core');
|
||||
return;
|
||||
}
|
||||
catch { }
|
||||
this.context.logger.warn(`Node packages may not be installed. Try installing with '${this.context.packageManager.name} install'.`);
|
||||
}
|
||||
getArchitectTarget() {
|
||||
return this.commandName;
|
||||
}
|
||||
async onMissingTarget(defaultMessage) {
|
||||
const { logger } = this.context;
|
||||
const choices = this.missingTargetChoices;
|
||||
if (!choices?.length) {
|
||||
logger.error(defaultMessage);
|
||||
return 1;
|
||||
}
|
||||
const missingTargetMessage = `Cannot find "${this.getArchitectTarget()}" target for the specified project.\n` +
|
||||
`You can add a package that implements these capabilities.\n\n` +
|
||||
`For example:\n` +
|
||||
choices.map(({ name, value }) => ` ${name}: ng add ${value}`).join('\n') +
|
||||
'\n';
|
||||
if ((0, tty_1.isTTY)()) {
|
||||
// Use prompts to ask the user if they'd like to install a package.
|
||||
logger.warn(missingTargetMessage);
|
||||
const packageToInstall = await this.getMissingTargetPackageToInstall(choices);
|
||||
if (packageToInstall) {
|
||||
// Example run: `ng add angular-eslint`.
|
||||
const AddCommandModule = (await Promise.resolve().then(() => __importStar(require('../commands/add/cli')))).default;
|
||||
await new AddCommandModule(this.context).run({
|
||||
interactive: true,
|
||||
force: false,
|
||||
dryRun: false,
|
||||
defaults: false,
|
||||
collection: packageToInstall,
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Non TTY display error message.
|
||||
logger.error(missingTargetMessage);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
async getMissingTargetPackageToInstall(choices) {
|
||||
if (choices.length === 1) {
|
||||
// Single choice
|
||||
const { name, value } = choices[0];
|
||||
if (await (0, prompt_1.askConfirmation)(`Would you like to add ${name} now?`, true, false)) {
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Multiple choice
|
||||
return (0, prompt_1.askQuestion)(`Would you like to add a package with "${this.getArchitectTarget()}" capabilities now?`, [
|
||||
{
|
||||
name: 'No',
|
||||
value: null,
|
||||
},
|
||||
...choices,
|
||||
], 0, null);
|
||||
}
|
||||
}
|
||||
exports.ArchitectBaseCommandModule = ArchitectBaseCommandModule;
|
||||
//# sourceMappingURL=architect-base-command-module.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Target } from '@angular-devkit/architect';
|
||||
import { workspaces } from '@angular-devkit/core';
|
||||
import { Argv } from 'yargs';
|
||||
import { ArchitectBaseCommandModule } from './architect-base-command-module';
|
||||
import { CommandModuleImplementation, Options, OtherOptions } from './command-module';
|
||||
export interface ArchitectCommandArgs {
|
||||
configuration?: string;
|
||||
project?: string;
|
||||
}
|
||||
export declare abstract class ArchitectCommandModule extends ArchitectBaseCommandModule<ArchitectCommandArgs> implements CommandModuleImplementation<ArchitectCommandArgs> {
|
||||
abstract readonly multiTarget: boolean;
|
||||
findDefaultBuilderName?(project: workspaces.ProjectDefinition, target: Target): Promise<string | undefined>;
|
||||
builder(argv: Argv): Promise<Argv<ArchitectCommandArgs>>;
|
||||
run(options: Options<ArchitectCommandArgs> & OtherOptions): Promise<number | void>;
|
||||
private getArchitectProject;
|
||||
private getProjectNamesByTarget;
|
||||
/** @returns a sorted list of project names to be used for auto completion. */
|
||||
private getProjectChoices;
|
||||
/** @returns a sorted list of configuration names to be used for auto completion. */
|
||||
private getConfigurationChoices;
|
||||
}
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
||||
var useValue = arguments.length > 2;
|
||||
for (var i = 0; i < initializers.length; i++) {
|
||||
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
||||
}
|
||||
return useValue ? value : void 0;
|
||||
};
|
||||
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
||||
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
||||
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
||||
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
||||
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
||||
var _, done = false;
|
||||
for (var i = decorators.length - 1; i >= 0; i--) {
|
||||
var context = {};
|
||||
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
||||
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
||||
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
||||
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
||||
if (kind === "accessor") {
|
||||
if (result === void 0) continue;
|
||||
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
||||
if (_ = accept(result.get)) descriptor.get = _;
|
||||
if (_ = accept(result.set)) descriptor.set = _;
|
||||
if (_ = accept(result.init)) initializers.unshift(_);
|
||||
}
|
||||
else if (_ = accept(result)) {
|
||||
if (kind === "field") initializers.unshift(_);
|
||||
else descriptor[key] = _;
|
||||
}
|
||||
}
|
||||
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
||||
done = true;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ArchitectCommandModule = void 0;
|
||||
const config_1 = require("../utilities/config");
|
||||
const memoize_1 = require("../utilities/memoize");
|
||||
const architect_base_command_module_1 = require("./architect-base-command-module");
|
||||
const command_module_1 = require("./command-module");
|
||||
let ArchitectCommandModule = (() => {
|
||||
let _classSuper = architect_base_command_module_1.ArchitectBaseCommandModule;
|
||||
let _instanceExtraInitializers = [];
|
||||
let _getProjectNamesByTarget_decorators;
|
||||
return class ArchitectCommandModule extends _classSuper {
|
||||
static {
|
||||
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
||||
_getProjectNamesByTarget_decorators = [memoize_1.memoize];
|
||||
__esDecorate(this, null, _getProjectNamesByTarget_decorators, { kind: "method", name: "getProjectNamesByTarget", static: false, private: false, access: { has: obj => "getProjectNamesByTarget" in obj, get: obj => obj.getProjectNamesByTarget }, metadata: _metadata }, null, _instanceExtraInitializers);
|
||||
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
||||
}
|
||||
async builder(argv) {
|
||||
const target = this.getArchitectTarget();
|
||||
// Add default builder if target is not in project and a command default is provided
|
||||
if (this.findDefaultBuilderName && this.context.workspace) {
|
||||
for (const [project, projectDefinition] of this.context.workspace.projects) {
|
||||
const targetDefinition = projectDefinition.targets.get(target);
|
||||
if (targetDefinition?.builder) {
|
||||
continue;
|
||||
}
|
||||
const defaultBuilder = await this.findDefaultBuilderName(projectDefinition, {
|
||||
project,
|
||||
target,
|
||||
});
|
||||
if (!defaultBuilder) {
|
||||
continue;
|
||||
}
|
||||
if (targetDefinition) {
|
||||
targetDefinition.builder = defaultBuilder;
|
||||
}
|
||||
else {
|
||||
projectDefinition.targets.set(target, {
|
||||
builder: defaultBuilder,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const project = this.getArchitectProject();
|
||||
const { jsonHelp, getYargsCompletions, help } = this.context.args.options;
|
||||
const localYargs = argv
|
||||
.positional('project', {
|
||||
describe: 'The name of the project to build. Can be an application or a library.',
|
||||
type: 'string',
|
||||
// Hide choices from JSON help so that we don't display them in AIO.
|
||||
choices: jsonHelp ? undefined : this.getProjectChoices(),
|
||||
})
|
||||
.option('configuration', {
|
||||
describe: `One or more named builder configurations as a comma-separated ` +
|
||||
`list as specified in the "configurations" section in angular.json.\n` +
|
||||
`The builder uses the named configurations to run the given target.\n` +
|
||||
`For more information, see https://angular.dev/reference/configs/workspace-config#alternate-build-configurations.`,
|
||||
alias: 'c',
|
||||
type: 'string',
|
||||
// Show only in when using --help and auto completion because otherwise comma seperated configuration values will be invalid.
|
||||
// Also, hide choices from JSON help so that we don't display them in AIO.
|
||||
choices: (getYargsCompletions || help) && !jsonHelp && project
|
||||
? this.getConfigurationChoices(project)
|
||||
: undefined,
|
||||
})
|
||||
.strict();
|
||||
if (!project) {
|
||||
return localYargs;
|
||||
}
|
||||
const schemaOptions = await this.getArchitectTargetOptions({
|
||||
project,
|
||||
target,
|
||||
});
|
||||
return this.addSchemaOptionsToCommand(localYargs, schemaOptions);
|
||||
}
|
||||
async run(options) {
|
||||
const originalProcessTitle = process.title;
|
||||
try {
|
||||
const target = this.getArchitectTarget();
|
||||
const { configuration = '', project, ...architectOptions } = options;
|
||||
if (project) {
|
||||
process.title = `${originalProcessTitle} (${project})`;
|
||||
return await this.runSingleTarget({ configuration, target, project }, architectOptions);
|
||||
}
|
||||
// This runs each target sequentially.
|
||||
// Running them in parallel would jumble the log messages.
|
||||
let result = 0;
|
||||
const projectNames = this.getProjectNamesByTarget(target);
|
||||
if (!projectNames) {
|
||||
return this.onMissingTarget('Cannot determine project or target for command.');
|
||||
}
|
||||
for (const project of projectNames) {
|
||||
process.title = `${originalProcessTitle} (${project})`;
|
||||
result |= await this.runSingleTarget({ configuration, target, project }, architectOptions);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
process.title = originalProcessTitle;
|
||||
}
|
||||
}
|
||||
getArchitectProject() {
|
||||
const { options, positional } = this.context.args;
|
||||
const [, projectName] = positional;
|
||||
if (projectName) {
|
||||
return projectName;
|
||||
}
|
||||
// Yargs allows positional args to be used as flags.
|
||||
if (typeof options['project'] === 'string') {
|
||||
return options['project'];
|
||||
}
|
||||
const target = this.getArchitectTarget();
|
||||
const projectFromTarget = this.getProjectNamesByTarget(target);
|
||||
return projectFromTarget?.length ? projectFromTarget[0] : undefined;
|
||||
}
|
||||
getProjectNamesByTarget(target) {
|
||||
const workspace = this.getWorkspaceOrThrow();
|
||||
const allProjectsForTargetName = [];
|
||||
for (const [name, project] of workspace.projects) {
|
||||
if (project.targets.has(target)) {
|
||||
allProjectsForTargetName.push(name);
|
||||
}
|
||||
}
|
||||
if (allProjectsForTargetName.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (this.multiTarget) {
|
||||
// For multi target commands, we always list all projects that have the target.
|
||||
return allProjectsForTargetName;
|
||||
}
|
||||
else {
|
||||
if (allProjectsForTargetName.length === 1) {
|
||||
return allProjectsForTargetName;
|
||||
}
|
||||
const maybeProject = (0, config_1.getProjectByCwd)(workspace);
|
||||
if (maybeProject) {
|
||||
return allProjectsForTargetName.includes(maybeProject) ? [maybeProject] : undefined;
|
||||
}
|
||||
const { getYargsCompletions, help } = this.context.args.options;
|
||||
if (!getYargsCompletions && !help) {
|
||||
// Only issue the below error when not in help / completion mode.
|
||||
throw new command_module_1.CommandModuleError('Cannot determine project for command.\n' +
|
||||
'This is a multi-project workspace and more than one project supports this command. ' +
|
||||
`Run "ng ${this.command}" to execute the command for a specific project or change the current ` +
|
||||
'working directory to a project directory.\n\n' +
|
||||
`Available projects are:\n${allProjectsForTargetName
|
||||
.sort()
|
||||
.map((p) => `- ${p}`)
|
||||
.join('\n')}`);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/** @returns a sorted list of project names to be used for auto completion. */
|
||||
getProjectChoices() {
|
||||
const { workspace } = this.context;
|
||||
return workspace ? [...workspace.projects.keys()].sort() : undefined;
|
||||
}
|
||||
/** @returns a sorted list of configuration names to be used for auto completion. */
|
||||
getConfigurationChoices(project) {
|
||||
const projectDefinition = this.context.workspace?.projects.get(project);
|
||||
if (!projectDefinition) {
|
||||
return undefined;
|
||||
}
|
||||
const target = this.getArchitectTarget();
|
||||
const configurations = projectDefinition.targets.get(target)?.configurations;
|
||||
return configurations ? Object.keys(configurations).sort() : undefined;
|
||||
}
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
__runInitializers(this, _instanceExtraInitializers);
|
||||
}
|
||||
};
|
||||
})();
|
||||
exports.ArchitectCommandModule = ArchitectCommandModule;
|
||||
//# sourceMappingURL=architect-command-module.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+73
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import type { ArgumentsCamelCase, Argv, CommandModule as YargsCommandModule } from 'yargs';
|
||||
import { AnalyticsCollector } from '../analytics/analytics-collector';
|
||||
import { EventCustomDimension, EventCustomMetric } from '../analytics/analytics-parameters';
|
||||
import { AngularWorkspace } from '../utilities/config';
|
||||
import { CommandContext, CommandScope, Options, OtherOptions } from './definitions';
|
||||
import { Option } from './utilities/json-schema';
|
||||
export { CommandScope };
|
||||
export type { CommandContext, Options, OtherOptions };
|
||||
export interface CommandModuleImplementation<T extends {} = {}> extends Omit<YargsCommandModule<{}, T>, 'builder' | 'handler'> {
|
||||
/** Scope in which the command can be executed in. */
|
||||
scope: CommandScope;
|
||||
/** Path used to load the long description for the command in JSON help text. */
|
||||
longDescriptionPath?: string;
|
||||
/** Object declaring the options the command accepts, or a function accepting and returning a yargs instance. */
|
||||
builder(argv: Argv): Promise<Argv<T>> | Argv<T>;
|
||||
/** A function which will be passed the parsed argv. */
|
||||
run(options: Options<T> & OtherOptions): Promise<number | void> | number | void;
|
||||
}
|
||||
export interface FullDescribe {
|
||||
describe?: string;
|
||||
longDescription?: string;
|
||||
longDescriptionRelativePath?: string;
|
||||
}
|
||||
export declare abstract class CommandModule<T extends {} = {}> implements CommandModuleImplementation<T> {
|
||||
protected readonly context: CommandContext;
|
||||
abstract readonly command: string;
|
||||
abstract readonly describe: string | false;
|
||||
abstract readonly longDescriptionPath?: string;
|
||||
protected readonly shouldReportAnalytics: boolean;
|
||||
readonly scope: CommandScope;
|
||||
private readonly optionsWithAnalytics;
|
||||
constructor(context: CommandContext);
|
||||
/**
|
||||
* Description object which contains the long command descroption.
|
||||
* This is used to generate JSON help wich is used in AIO.
|
||||
*
|
||||
* `false` will result in a hidden command.
|
||||
*/
|
||||
get fullDescribe(): FullDescribe | false;
|
||||
protected get commandName(): string;
|
||||
abstract builder(argv: Argv): Promise<Argv<T>> | Argv<T>;
|
||||
abstract run(options: Options<T> & OtherOptions): Promise<number | void> | number | void;
|
||||
handler(args: ArgumentsCamelCase<T> & OtherOptions): Promise<void>;
|
||||
protected getAnalytics(): Promise<AnalyticsCollector | undefined>;
|
||||
/**
|
||||
* Adds schema options to a command also this keeps track of options that are required for analytics.
|
||||
* **Note:** This method should be called from the command bundler method.
|
||||
*/
|
||||
protected addSchemaOptionsToCommand<T>(localYargs: Argv<T>, options: Option[]): Argv<T>;
|
||||
protected getWorkspaceOrThrow(): AngularWorkspace;
|
||||
/**
|
||||
* Flush on an interval (if the event loop is waiting).
|
||||
*
|
||||
* @returns a method that when called will terminate the periodic
|
||||
* flush and call flush one last time.
|
||||
*/
|
||||
protected getAnalyticsParameters(options: (Options<T> & OtherOptions) | OtherOptions): Partial<Record<EventCustomDimension | EventCustomMetric, string | boolean | number>>;
|
||||
private reportCommandRunAnalytics;
|
||||
private reportWorkspaceInfoAnalytics;
|
||||
}
|
||||
/**
|
||||
* Creates an known command module error.
|
||||
* This is used so during executation we can filter between known validation error and real non handled errors.
|
||||
*/
|
||||
export declare class CommandModuleError extends Error {
|
||||
}
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
||||
var useValue = arguments.length > 2;
|
||||
for (var i = 0; i < initializers.length; i++) {
|
||||
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
||||
}
|
||||
return useValue ? value : void 0;
|
||||
};
|
||||
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
||||
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
||||
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
||||
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
||||
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
||||
var _, done = false;
|
||||
for (var i = decorators.length - 1; i >= 0; i--) {
|
||||
var context = {};
|
||||
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
||||
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
||||
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
||||
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
||||
if (kind === "accessor") {
|
||||
if (result === void 0) continue;
|
||||
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
||||
if (_ = accept(result.get)) descriptor.get = _;
|
||||
if (_ = accept(result.set)) descriptor.set = _;
|
||||
if (_ = accept(result.init)) initializers.unshift(_);
|
||||
}
|
||||
else if (_ = accept(result)) {
|
||||
if (kind === "field") initializers.unshift(_);
|
||||
else descriptor[key] = _;
|
||||
}
|
||||
}
|
||||
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
||||
done = true;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CommandModuleError = exports.CommandModule = exports.CommandScope = void 0;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const node_fs_1 = require("node:fs");
|
||||
const node_path_1 = require("node:path");
|
||||
const helpers_1 = require("yargs/helpers");
|
||||
const analytics_1 = require("../analytics/analytics");
|
||||
const analytics_collector_1 = require("../analytics/analytics-collector");
|
||||
const analytics_parameters_1 = require("../analytics/analytics-parameters");
|
||||
const completion_1 = require("../utilities/completion");
|
||||
const memoize_1 = require("../utilities/memoize");
|
||||
const definitions_1 = require("./definitions");
|
||||
Object.defineProperty(exports, "CommandScope", { enumerable: true, get: function () { return definitions_1.CommandScope; } });
|
||||
const json_schema_1 = require("./utilities/json-schema");
|
||||
let CommandModule = (() => {
|
||||
let _instanceExtraInitializers = [];
|
||||
let _getAnalytics_decorators;
|
||||
return class CommandModule {
|
||||
static {
|
||||
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
||||
_getAnalytics_decorators = [memoize_1.memoize];
|
||||
__esDecorate(this, null, _getAnalytics_decorators, { kind: "method", name: "getAnalytics", static: false, private: false, access: { has: obj => "getAnalytics" in obj, get: obj => obj.getAnalytics }, metadata: _metadata }, null, _instanceExtraInitializers);
|
||||
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
||||
}
|
||||
context = __runInitializers(this, _instanceExtraInitializers);
|
||||
shouldReportAnalytics = true;
|
||||
scope = definitions_1.CommandScope.Both;
|
||||
optionsWithAnalytics = new Map();
|
||||
constructor(context) {
|
||||
this.context = context;
|
||||
}
|
||||
/**
|
||||
* Description object which contains the long command descroption.
|
||||
* This is used to generate JSON help wich is used in AIO.
|
||||
*
|
||||
* `false` will result in a hidden command.
|
||||
*/
|
||||
get fullDescribe() {
|
||||
return this.describe === false
|
||||
? false
|
||||
: {
|
||||
describe: this.describe,
|
||||
...(this.longDescriptionPath
|
||||
? {
|
||||
longDescriptionRelativePath: (0, node_path_1.relative)((0, node_path_1.join)(__dirname, '../../../../'), this.longDescriptionPath).replace(/\\/g, node_path_1.posix.sep),
|
||||
longDescription: (0, node_fs_1.readFileSync)(this.longDescriptionPath, 'utf8').replace(/\r\n/g, '\n'),
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
get commandName() {
|
||||
return this.command.split(' ', 1)[0];
|
||||
}
|
||||
async handler(args) {
|
||||
const { _, $0, ...options } = args;
|
||||
// Camelize options as yargs will return the object in kebab-case when camel casing is disabled.
|
||||
const camelCasedOptions = {};
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
camelCasedOptions[helpers_1.Parser.camelCase(key)] = value;
|
||||
}
|
||||
// Set up autocompletion if appropriate.
|
||||
const autocompletionExitCode = await (0, completion_1.considerSettingUpAutocompletion)(this.commandName, this.context.logger);
|
||||
if (autocompletionExitCode !== undefined) {
|
||||
process.exitCode = autocompletionExitCode;
|
||||
return;
|
||||
}
|
||||
// Gather and report analytics.
|
||||
const analytics = await this.getAnalytics();
|
||||
const stopPeriodicFlushes = analytics && analytics.periodFlush();
|
||||
let exitCode;
|
||||
try {
|
||||
if (analytics) {
|
||||
this.reportCommandRunAnalytics(analytics);
|
||||
this.reportWorkspaceInfoAnalytics(analytics);
|
||||
}
|
||||
exitCode = await this.run(camelCasedOptions);
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof core_1.schema.SchemaValidationException) {
|
||||
this.context.logger.fatal(`Error: ${e.message}`);
|
||||
exitCode = 1;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
await stopPeriodicFlushes?.();
|
||||
if (typeof exitCode === 'number' && exitCode > 0) {
|
||||
process.exitCode = exitCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
async getAnalytics() {
|
||||
if (!this.shouldReportAnalytics) {
|
||||
return undefined;
|
||||
}
|
||||
const userId = await (0, analytics_1.getAnalyticsUserId)(this.context,
|
||||
// Don't prompt on `ng update`, 'ng version' or `ng analytics`.
|
||||
['version', 'update', 'analytics'].includes(this.commandName));
|
||||
return userId
|
||||
? new analytics_collector_1.AnalyticsCollector(this.context.logger, userId, {
|
||||
name: this.context.packageManager.name,
|
||||
version: await this.context.packageManager.getVersion(),
|
||||
})
|
||||
: undefined;
|
||||
}
|
||||
/**
|
||||
* Adds schema options to a command also this keeps track of options that are required for analytics.
|
||||
* **Note:** This method should be called from the command bundler method.
|
||||
*/
|
||||
addSchemaOptionsToCommand(localYargs, options) {
|
||||
const optionsWithAnalytics = (0, json_schema_1.addSchemaOptionsToCommand)(localYargs, options,
|
||||
// This should only be done when `--help` is used otherwise default will override options set in angular.json.
|
||||
/* includeDefaultValues= */ this.context.args.options.help);
|
||||
// Record option of analytics.
|
||||
for (const [name, userAnalytics] of optionsWithAnalytics) {
|
||||
this.optionsWithAnalytics.set(name, userAnalytics);
|
||||
}
|
||||
return localYargs;
|
||||
}
|
||||
getWorkspaceOrThrow() {
|
||||
const { workspace } = this.context;
|
||||
if (!workspace) {
|
||||
throw new CommandModuleError('A workspace is required for this command.');
|
||||
}
|
||||
return workspace;
|
||||
}
|
||||
/**
|
||||
* Flush on an interval (if the event loop is waiting).
|
||||
*
|
||||
* @returns a method that when called will terminate the periodic
|
||||
* flush and call flush one last time.
|
||||
*/
|
||||
getAnalyticsParameters(options) {
|
||||
const parameters = {};
|
||||
const validEventCustomDimensionAndMetrics = new Set([
|
||||
...Object.values(analytics_parameters_1.EventCustomDimension),
|
||||
...Object.values(analytics_parameters_1.EventCustomMetric),
|
||||
]);
|
||||
for (const [name, ua] of this.optionsWithAnalytics) {
|
||||
if (!validEventCustomDimensionAndMetrics.has(ua)) {
|
||||
continue;
|
||||
}
|
||||
const value = options[name];
|
||||
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
||||
parameters[ua] = value;
|
||||
}
|
||||
else if (Array.isArray(value)) {
|
||||
// GA doesn't allow array as values.
|
||||
parameters[ua] = value.sort().join(', ');
|
||||
}
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
reportCommandRunAnalytics(analytics) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const internalMethods = this.context.yargsInstance.getInternalMethods();
|
||||
// $0 generate component [name] -> generate_component
|
||||
// $0 add <collection> -> add
|
||||
const fullCommand = internalMethods.getUsageInstance().getUsage()[0][0]
|
||||
.split(' ')
|
||||
.filter((x) => {
|
||||
const code = x.charCodeAt(0);
|
||||
return code >= 97 && code <= 122;
|
||||
})
|
||||
.join('_');
|
||||
analytics.reportCommandRunEvent(fullCommand);
|
||||
}
|
||||
reportWorkspaceInfoAnalytics(analytics) {
|
||||
const { workspace } = this.context;
|
||||
if (!workspace) {
|
||||
return;
|
||||
}
|
||||
let applicationProjectsCount = 0;
|
||||
let librariesProjectsCount = 0;
|
||||
for (const project of workspace.projects.values()) {
|
||||
switch (project.extensions['projectType']) {
|
||||
case 'application':
|
||||
applicationProjectsCount++;
|
||||
break;
|
||||
case 'library':
|
||||
librariesProjectsCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
analytics.reportWorkspaceInfoEvent({
|
||||
[analytics_parameters_1.EventCustomMetric.AllProjectsCount]: librariesProjectsCount + applicationProjectsCount,
|
||||
[analytics_parameters_1.EventCustomMetric.ApplicationProjectsCount]: applicationProjectsCount,
|
||||
[analytics_parameters_1.EventCustomMetric.LibraryProjectsCount]: librariesProjectsCount,
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
||||
exports.CommandModule = CommandModule;
|
||||
/**
|
||||
* Creates an known command module error.
|
||||
* This is used so during executation we can filter between known validation error and real non handled errors.
|
||||
*/
|
||||
class CommandModuleError extends Error {
|
||||
}
|
||||
exports.CommandModuleError = CommandModuleError;
|
||||
//# sourceMappingURL=command-module.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+9
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { logging } from '@angular-devkit/core';
|
||||
export declare function runCommand(args: string[], logger: logging.Logger): Promise<number>;
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runCommand = runCommand;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const promises_1 = require("node:fs/promises");
|
||||
const node_path_1 = require("node:path");
|
||||
const yargs_1 = __importDefault(require("yargs"));
|
||||
const helpers_1 = require("yargs/helpers");
|
||||
const utilities_1 = require("../commands/cache/utilities");
|
||||
const command_config_1 = require("../commands/command-config");
|
||||
const package_managers_1 = require("../package-managers");
|
||||
const color_1 = require("../utilities/color");
|
||||
const config_1 = require("../utilities/config");
|
||||
const error_1 = require("../utilities/error");
|
||||
const version_1 = require("../utilities/version");
|
||||
const command_module_1 = require("./command-module");
|
||||
const command_1 = require("./utilities/command");
|
||||
const json_help_1 = require("./utilities/json-help");
|
||||
const normalize_options_middleware_1 = require("./utilities/normalize-options-middleware");
|
||||
async function runCommand(args, logger) {
|
||||
const { $0, _, help = false, dryRun = false, jsonHelp = false, getYargsCompletions = false, ...rest } = (0, helpers_1.Parser)(args, {
|
||||
boolean: ['help', 'json-help', 'get-yargs-completions', 'dry-run'],
|
||||
alias: { 'collection': 'c' },
|
||||
});
|
||||
// When `getYargsCompletions` is true the scriptName 'ng' at index 0 is not removed.
|
||||
const positional = getYargsCompletions ? _.slice(1) : _;
|
||||
let workspace;
|
||||
let globalConfiguration;
|
||||
try {
|
||||
[workspace, globalConfiguration] = await Promise.all([
|
||||
(0, config_1.getWorkspace)('local'),
|
||||
(0, config_1.getWorkspace)('global'),
|
||||
]);
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
logger.fatal(e.message);
|
||||
return 1;
|
||||
}
|
||||
const root = workspace?.basePath ?? process.cwd();
|
||||
const cacheConfig = workspace && (0, utilities_1.getCacheConfig)(workspace);
|
||||
const packageManager = await (0, package_managers_1.createPackageManager)({
|
||||
cwd: root,
|
||||
logger,
|
||||
dryRun: dryRun || help || jsonHelp || getYargsCompletions,
|
||||
tempDirectory: cacheConfig?.enabled ? cacheConfig.path : undefined,
|
||||
configuredPackageManager: await getConfiguredPackageManager(root, workspace, globalConfiguration),
|
||||
});
|
||||
const localYargs = (0, yargs_1.default)(args);
|
||||
const context = {
|
||||
globalConfiguration,
|
||||
workspace,
|
||||
logger,
|
||||
currentDirectory: process.cwd(),
|
||||
yargsInstance: localYargs,
|
||||
root,
|
||||
packageManager,
|
||||
args: {
|
||||
positional: positional.map((v) => v.toString()),
|
||||
options: {
|
||||
help,
|
||||
jsonHelp,
|
||||
getYargsCompletions,
|
||||
...rest,
|
||||
},
|
||||
},
|
||||
};
|
||||
for (const CommandModule of await getCommandsToRegister(positional[0])) {
|
||||
(0, command_1.addCommandModuleToYargs)(CommandModule, context);
|
||||
}
|
||||
if (jsonHelp) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const usageInstance = localYargs.getInternalMethods().getUsageInstance();
|
||||
usageInstance.help = () => (0, json_help_1.jsonHelpUsage)(localYargs);
|
||||
}
|
||||
// Add default command to support version option when no subcommand is specified
|
||||
localYargs.command('*', false, (builder) => builder.version('version', 'Show Angular CLI version.', version_1.VERSION.full));
|
||||
await localYargs
|
||||
.scriptName('ng')
|
||||
// https://github.com/yargs/yargs/blob/main/docs/advanced.md#customizing-yargs-parser
|
||||
.parserConfiguration({
|
||||
'populate--': true,
|
||||
'unknown-options-as-args': false,
|
||||
'dot-notation': false,
|
||||
'boolean-negation': true,
|
||||
'strip-aliased': true,
|
||||
'strip-dashed': true,
|
||||
'camel-case-expansion': false,
|
||||
})
|
||||
.option('json-help', {
|
||||
describe: 'Show help in JSON format.',
|
||||
implies: ['help'],
|
||||
hidden: true,
|
||||
type: 'boolean',
|
||||
})
|
||||
.help('help', 'Shows a help message for this command in the console.')
|
||||
// A complete list of strings can be found: https://github.com/yargs/yargs/blob/main/locales/en.json
|
||||
.updateStrings({
|
||||
'Commands:': color_1.colors.cyan('Commands:'),
|
||||
'Options:': color_1.colors.cyan('Options:'),
|
||||
'Positionals:': color_1.colors.cyan('Arguments:'),
|
||||
'deprecated': color_1.colors.yellow('deprecated'),
|
||||
'deprecated: %s': color_1.colors.yellow('deprecated:') + ' %s',
|
||||
'Did you mean %s?': 'Unknown command. Did you mean %s?',
|
||||
})
|
||||
.epilogue('For more information, see https://angular.dev/cli/.\n')
|
||||
.demandCommand(1, command_1.demandCommandFailureMessage)
|
||||
.recommendCommands()
|
||||
.middleware((0, normalize_options_middleware_1.createNormalizeOptionsMiddleware)(localYargs))
|
||||
.version(false)
|
||||
.showHelpOnFail(false)
|
||||
.strict()
|
||||
.fail((msg, err) => {
|
||||
throw msg
|
||||
? // Validation failed example: `Unknown argument:`
|
||||
new command_module_1.CommandModuleError(msg)
|
||||
: // Unknown exception, re-throw.
|
||||
err;
|
||||
})
|
||||
.wrap(localYargs.terminalWidth())
|
||||
.parseAsync();
|
||||
return +(process.exitCode ?? 0);
|
||||
}
|
||||
/**
|
||||
* Get the commands that need to be registered.
|
||||
* @returns One or more command factories that needs to be registered.
|
||||
*/
|
||||
async function getCommandsToRegister(commandName) {
|
||||
const commands = [];
|
||||
if (commandName in command_config_1.RootCommands) {
|
||||
commands.push(command_config_1.RootCommands[commandName]);
|
||||
}
|
||||
else if (commandName in command_config_1.RootCommandsAliases) {
|
||||
commands.push(command_config_1.RootCommandsAliases[commandName]);
|
||||
}
|
||||
else {
|
||||
// Unknown command, register every possible command.
|
||||
Object.values(command_config_1.RootCommands).forEach((c) => commands.push(c));
|
||||
}
|
||||
return Promise.all(commands.map((command) => command.factory().then((m) => m.default)));
|
||||
}
|
||||
/**
|
||||
* Gets the configured package manager by checking package.json, or the local and global angular.json files.
|
||||
*
|
||||
* @param root The root directory of the workspace.
|
||||
* @param localWorkspace The local workspace.
|
||||
* @param globalWorkspace The global workspace.
|
||||
* @returns The package manager name and version.
|
||||
*/
|
||||
async function getConfiguredPackageManager(root, localWorkspace, globalWorkspace) {
|
||||
let result;
|
||||
try {
|
||||
const packageJsonPath = (0, node_path_1.join)(root, 'package.json');
|
||||
const pkgJson = JSON.parse(await (0, promises_1.readFile)(packageJsonPath, 'utf-8'));
|
||||
result = getPackageManager(pkgJson);
|
||||
}
|
||||
catch { }
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
if (localWorkspace) {
|
||||
const project = (0, config_1.getProjectByCwd)(localWorkspace);
|
||||
if (project) {
|
||||
result = getPackageManager(localWorkspace.projects.get(project)?.extensions['cli']);
|
||||
}
|
||||
result ??= getPackageManager(localWorkspace.extensions['cli']);
|
||||
}
|
||||
result ??= getPackageManager(globalWorkspace.extensions['cli']);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Get the package manager name from a JSON value.
|
||||
* @param source The JSON value to get the package manager name from.
|
||||
* @returns The package manager name and version.
|
||||
*/
|
||||
function getPackageManager(source) {
|
||||
if (source && (0, core_1.isJsonObject)(source)) {
|
||||
const value = source['packageManager'];
|
||||
if (typeof value === 'string') {
|
||||
return value.split('@', 2);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
//# sourceMappingURL=command-runner.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { logging } from '@angular-devkit/core';
|
||||
import type { Argv, CamelCaseKey } from 'yargs';
|
||||
import type { PackageManager } from '../package-managers/package-manager';
|
||||
import { AngularWorkspace } from '../utilities/config';
|
||||
export declare enum CommandScope {
|
||||
/** Command can only run inside an Angular workspace. */
|
||||
In = 0,
|
||||
/** Command can only run outside an Angular workspace. */
|
||||
Out = 1,
|
||||
/** Command can run inside and outside an Angular workspace. */
|
||||
Both = 2
|
||||
}
|
||||
export interface CommandContext {
|
||||
currentDirectory: string;
|
||||
root: string;
|
||||
workspace?: AngularWorkspace;
|
||||
globalConfiguration: AngularWorkspace;
|
||||
logger: logging.Logger;
|
||||
packageManager: PackageManager;
|
||||
yargsInstance: Argv<{}>;
|
||||
/** Arguments parsed in free-from without parser configuration. */
|
||||
args: {
|
||||
positional: string[];
|
||||
options: {
|
||||
help: boolean;
|
||||
jsonHelp: boolean;
|
||||
getYargsCompletions: boolean;
|
||||
} & Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
export type Options<T> = {
|
||||
[key in keyof T as CamelCaseKey<key>]: T[key];
|
||||
};
|
||||
export type OtherOptions = Record<string, unknown>;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CommandScope = void 0;
|
||||
var CommandScope;
|
||||
(function (CommandScope) {
|
||||
/** Command can only run inside an Angular workspace. */
|
||||
CommandScope[CommandScope["In"] = 0] = "In";
|
||||
/** Command can only run outside an Angular workspace. */
|
||||
CommandScope[CommandScope["Out"] = 1] = "Out";
|
||||
/** Command can run inside and outside an Angular workspace. */
|
||||
CommandScope[CommandScope["Both"] = 2] = "Both";
|
||||
})(CommandScope || (exports.CommandScope = CommandScope = {}));
|
||||
//# sourceMappingURL=definitions.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["definitions.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAOH,IAAY,YASX;AATD,WAAY,YAAY;IACtB,wDAAwD;IACxD,2CAAE,CAAA;IAEF,yDAAyD;IACzD,6CAAG,CAAA;IAEH,+DAA+D;IAC/D,+CAAI,CAAA;AACN,CAAC,EATW,YAAY,4BAAZ,YAAY,QASvB"}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Collection } from '@angular-devkit/schematics';
|
||||
import { FileSystemCollectionDescription, FileSystemSchematicDescription, NodeWorkflow } from '@angular-devkit/schematics/tools';
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, CommandScope, Options, OtherOptions } from './command-module';
|
||||
import { Option } from './utilities/json-schema';
|
||||
export declare const DEFAULT_SCHEMATICS_COLLECTION = "@schematics/angular";
|
||||
export interface SchematicsCommandArgs {
|
||||
interactive: boolean;
|
||||
force: boolean;
|
||||
'dry-run': boolean;
|
||||
defaults: boolean;
|
||||
}
|
||||
export interface SchematicsExecutionOptions extends Options<SchematicsCommandArgs> {
|
||||
packageRegistry?: string;
|
||||
}
|
||||
export declare abstract class SchematicsCommandModule extends CommandModule<SchematicsCommandArgs> implements CommandModuleImplementation<SchematicsCommandArgs> {
|
||||
scope: CommandScope;
|
||||
protected readonly allowPrivateSchematics: boolean;
|
||||
builder(argv: Argv): Promise<Argv<SchematicsCommandArgs>>;
|
||||
/** Get schematic schema options.*/
|
||||
protected getSchematicOptions(collection: Collection<FileSystemCollectionDescription, FileSystemSchematicDescription>, schematicName: string, workflow: NodeWorkflow): Promise<Option[]>;
|
||||
protected getOrCreateWorkflowForBuilder(collectionName: string): NodeWorkflow;
|
||||
protected getOrCreateWorkflowForExecution(collectionName: string, options: SchematicsExecutionOptions): Promise<NodeWorkflow>;
|
||||
protected getSchematicCollections(): Promise<Set<string>>;
|
||||
protected parseSchematicInfo(schematic: string | undefined): [collectionName: string | undefined, schematicName: string | undefined];
|
||||
protected runSchematic(options: {
|
||||
executionOptions: SchematicsExecutionOptions;
|
||||
schematicOptions: OtherOptions;
|
||||
collectionName: string;
|
||||
schematicName: string;
|
||||
}): Promise<number>;
|
||||
private getProjectName;
|
||||
private getResolvePaths;
|
||||
}
|
||||
+408
@@ -0,0 +1,408 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
||||
var useValue = arguments.length > 2;
|
||||
for (var i = 0; i < initializers.length; i++) {
|
||||
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
||||
}
|
||||
return useValue ? value : void 0;
|
||||
};
|
||||
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
||||
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
||||
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
||||
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
||||
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
||||
var _, done = false;
|
||||
for (var i = decorators.length - 1; i >= 0; i--) {
|
||||
var context = {};
|
||||
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
||||
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
||||
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
||||
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
||||
if (kind === "accessor") {
|
||||
if (result === void 0) continue;
|
||||
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
||||
if (_ = accept(result.get)) descriptor.get = _;
|
||||
if (_ = accept(result.set)) descriptor.set = _;
|
||||
if (_ = accept(result.init)) initializers.unshift(_);
|
||||
}
|
||||
else if (_ = accept(result)) {
|
||||
if (kind === "field") initializers.unshift(_);
|
||||
else descriptor[key] = _;
|
||||
}
|
||||
}
|
||||
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
||||
done = true;
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SchematicsCommandModule = exports.DEFAULT_SCHEMATICS_COLLECTION = void 0;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const schematics_1 = require("@angular-devkit/schematics");
|
||||
const tools_1 = require("@angular-devkit/schematics/tools");
|
||||
const node_path_1 = require("node:path");
|
||||
const analytics_1 = require("../analytics/analytics");
|
||||
const analytics_parameters_1 = require("../analytics/analytics-parameters");
|
||||
const config_1 = require("../utilities/config");
|
||||
const error_1 = require("../utilities/error");
|
||||
const memoize_1 = require("../utilities/memoize");
|
||||
const prettier_1 = require("../utilities/prettier");
|
||||
const tty_1 = require("../utilities/tty");
|
||||
const command_module_1 = require("./command-module");
|
||||
const json_schema_1 = require("./utilities/json-schema");
|
||||
const schematic_engine_host_1 = require("./utilities/schematic-engine-host");
|
||||
const schematic_workflow_1 = require("./utilities/schematic-workflow");
|
||||
exports.DEFAULT_SCHEMATICS_COLLECTION = '@schematics/angular';
|
||||
let SchematicsCommandModule = (() => {
|
||||
let _classSuper = command_module_1.CommandModule;
|
||||
let _instanceExtraInitializers = [];
|
||||
let _getOrCreateWorkflowForBuilder_decorators;
|
||||
let _getOrCreateWorkflowForExecution_decorators;
|
||||
let _getSchematicCollections_decorators;
|
||||
return class SchematicsCommandModule extends _classSuper {
|
||||
static {
|
||||
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
||||
_getOrCreateWorkflowForBuilder_decorators = [memoize_1.memoize];
|
||||
_getOrCreateWorkflowForExecution_decorators = [memoize_1.memoize];
|
||||
_getSchematicCollections_decorators = [memoize_1.memoize];
|
||||
__esDecorate(this, null, _getOrCreateWorkflowForBuilder_decorators, { kind: "method", name: "getOrCreateWorkflowForBuilder", static: false, private: false, access: { has: obj => "getOrCreateWorkflowForBuilder" in obj, get: obj => obj.getOrCreateWorkflowForBuilder }, metadata: _metadata }, null, _instanceExtraInitializers);
|
||||
__esDecorate(this, null, _getOrCreateWorkflowForExecution_decorators, { kind: "method", name: "getOrCreateWorkflowForExecution", static: false, private: false, access: { has: obj => "getOrCreateWorkflowForExecution" in obj, get: obj => obj.getOrCreateWorkflowForExecution }, metadata: _metadata }, null, _instanceExtraInitializers);
|
||||
__esDecorate(this, null, _getSchematicCollections_decorators, { kind: "method", name: "getSchematicCollections", static: false, private: false, access: { has: obj => "getSchematicCollections" in obj, get: obj => obj.getSchematicCollections }, metadata: _metadata }, null, _instanceExtraInitializers);
|
||||
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
||||
}
|
||||
scope = (__runInitializers(this, _instanceExtraInitializers), command_module_1.CommandScope.In);
|
||||
allowPrivateSchematics = false;
|
||||
async builder(argv) {
|
||||
return argv
|
||||
.option('interactive', {
|
||||
describe: 'Enable interactive input prompts.',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
})
|
||||
.option('dry-run', {
|
||||
describe: 'Run through and reports activity without writing out results.',
|
||||
type: 'boolean',
|
||||
alias: ['d'],
|
||||
default: false,
|
||||
})
|
||||
.option('defaults', {
|
||||
describe: 'Disable interactive input prompts for options with a default.',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.option('force', {
|
||||
describe: 'Force overwriting of existing files.',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.strict();
|
||||
}
|
||||
/** Get schematic schema options.*/
|
||||
async getSchematicOptions(collection, schematicName, workflow) {
|
||||
const schematic = collection.createSchematic(schematicName, true);
|
||||
const { schemaJson } = schematic.description;
|
||||
if (!schemaJson) {
|
||||
return [];
|
||||
}
|
||||
return (0, json_schema_1.parseJsonSchemaToOptions)(workflow.registry, schemaJson);
|
||||
}
|
||||
getOrCreateWorkflowForBuilder(collectionName) {
|
||||
return new tools_1.NodeWorkflow(this.context.root, {
|
||||
resolvePaths: this.getResolvePaths(collectionName),
|
||||
engineHostCreator: (options) => new schematic_engine_host_1.SchematicEngineHost(options.resolvePaths),
|
||||
});
|
||||
}
|
||||
async getOrCreateWorkflowForExecution(collectionName, options) {
|
||||
const { logger, root, packageManager } = this.context;
|
||||
const { force, dryRun, packageRegistry } = options;
|
||||
const workflow = new tools_1.NodeWorkflow(root, {
|
||||
force,
|
||||
dryRun,
|
||||
packageManager: packageManager.name,
|
||||
// A schema registry is required to allow customizing addUndefinedDefaults
|
||||
registry: new core_1.schema.CoreSchemaRegistry(schematics_1.formats.standardFormats),
|
||||
packageRegistry,
|
||||
resolvePaths: this.getResolvePaths(collectionName),
|
||||
schemaValidation: true,
|
||||
optionTransforms: [
|
||||
// Add configuration file defaults
|
||||
async (schematic, current) => {
|
||||
const projectName = typeof current?.project === 'string' ? current.project : this.getProjectName();
|
||||
return {
|
||||
...(await (0, config_1.getSchematicDefaults)(schematic.collection.name, schematic.name, projectName)),
|
||||
...current,
|
||||
};
|
||||
},
|
||||
],
|
||||
engineHostCreator: (options) => new schematic_engine_host_1.SchematicEngineHost(options.resolvePaths),
|
||||
});
|
||||
workflow.registry.addPostTransform(core_1.schema.transforms.addUndefinedDefaults);
|
||||
workflow.registry.useXDeprecatedProvider((msg) => logger.warn(msg));
|
||||
workflow.registry.addSmartDefaultProvider('projectName', () => this.getProjectName());
|
||||
const workingDir = (0, core_1.normalize)((0, node_path_1.relative)(this.context.root, process.cwd()));
|
||||
workflow.registry.addSmartDefaultProvider('workingDirectory', () => workingDir === '' ? undefined : workingDir);
|
||||
workflow.engineHost.registerOptionsTransform(async (schematic, options) => {
|
||||
const { collection: { name: collectionName }, name: schematicName, } = schematic;
|
||||
const analytics = (0, analytics_1.isPackageNameSafeForAnalytics)(collectionName)
|
||||
? await this.getAnalytics()
|
||||
: undefined;
|
||||
analytics?.reportSchematicRunEvent({
|
||||
[analytics_parameters_1.EventCustomDimension.SchematicCollectionName]: collectionName,
|
||||
[analytics_parameters_1.EventCustomDimension.SchematicName]: schematicName,
|
||||
...this.getAnalyticsParameters(options),
|
||||
});
|
||||
return options;
|
||||
});
|
||||
if (options.interactive !== false && (0, tty_1.isTTY)()) {
|
||||
workflow.registry.usePromptProvider(async (definitions) => {
|
||||
let prompts;
|
||||
const answers = {};
|
||||
for (const definition of definitions) {
|
||||
if (options.defaults && definition.default !== undefined) {
|
||||
continue;
|
||||
}
|
||||
// Only load prompt package if needed
|
||||
prompts ??= await Promise.resolve().then(() => __importStar(require('@inquirer/prompts')));
|
||||
switch (definition.type) {
|
||||
case 'confirmation':
|
||||
answers[definition.id] = await prompts.confirm({
|
||||
message: definition.message,
|
||||
default: definition.default,
|
||||
});
|
||||
break;
|
||||
case 'list':
|
||||
if (!definition.items?.length) {
|
||||
continue;
|
||||
}
|
||||
answers[definition.id] = await (definition.multiselect ? prompts.checkbox : prompts.select)({
|
||||
message: definition.message,
|
||||
validate: (values) => {
|
||||
if (!definition.validator) {
|
||||
return true;
|
||||
}
|
||||
return definition.validator(Object.values(values).map(({ value }) => value));
|
||||
},
|
||||
default: definition.multiselect ? undefined : definition.default,
|
||||
choices: definition.items?.map((item) => typeof item == 'string'
|
||||
? {
|
||||
name: item,
|
||||
value: item,
|
||||
checked: definition.multiselect && Array.isArray(definition.default)
|
||||
? definition.default?.includes(item)
|
||||
: item === definition.default,
|
||||
}
|
||||
: {
|
||||
...item,
|
||||
name: item.label,
|
||||
value: item.value,
|
||||
checked: definition.multiselect && Array.isArray(definition.default)
|
||||
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
definition.default?.includes(item.value)
|
||||
: item.value === definition.default,
|
||||
}),
|
||||
});
|
||||
break;
|
||||
case 'input': {
|
||||
let finalValue;
|
||||
answers[definition.id] = await prompts.input({
|
||||
message: definition.message,
|
||||
default: definition.default,
|
||||
async validate(value) {
|
||||
if (definition.validator === undefined) {
|
||||
return true;
|
||||
}
|
||||
let lastValidation = false;
|
||||
for (const type of definition.propertyTypes) {
|
||||
let potential;
|
||||
switch (type) {
|
||||
case 'string':
|
||||
potential = String(value);
|
||||
break;
|
||||
case 'integer':
|
||||
case 'number':
|
||||
potential = Number(value);
|
||||
break;
|
||||
default:
|
||||
potential = value;
|
||||
break;
|
||||
}
|
||||
lastValidation = await definition.validator(potential);
|
||||
// Can be a string if validation fails
|
||||
if (lastValidation === true) {
|
||||
finalValue = potential;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return lastValidation;
|
||||
},
|
||||
});
|
||||
// Use validated value if present.
|
||||
// This ensures the correct type is inserted into the final schema options.
|
||||
if (finalValue !== undefined) {
|
||||
answers[definition.id] = finalValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return answers;
|
||||
});
|
||||
}
|
||||
return workflow;
|
||||
}
|
||||
async getSchematicCollections() {
|
||||
const getSchematicCollections = (configSection) => {
|
||||
if (!configSection) {
|
||||
return undefined;
|
||||
}
|
||||
const { schematicCollections } = configSection;
|
||||
if (Array.isArray(schematicCollections)) {
|
||||
return new Set(schematicCollections);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
const { workspace, globalConfiguration } = this.context;
|
||||
if (workspace) {
|
||||
const project = (0, config_1.getProjectByCwd)(workspace);
|
||||
if (project) {
|
||||
const value = getSchematicCollections(workspace.getProjectCli(project));
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
const value = getSchematicCollections(workspace?.getCli()) ??
|
||||
getSchematicCollections(globalConfiguration.getCli());
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
return new Set([exports.DEFAULT_SCHEMATICS_COLLECTION]);
|
||||
}
|
||||
parseSchematicInfo(schematic) {
|
||||
if (schematic?.includes(':')) {
|
||||
const [collectionName, schematicName] = schematic.split(':', 2);
|
||||
return [collectionName, schematicName];
|
||||
}
|
||||
return [undefined, schematic];
|
||||
}
|
||||
async runSchematic(options) {
|
||||
const { logger } = this.context;
|
||||
const { schematicOptions, executionOptions, collectionName, schematicName } = options;
|
||||
const workflow = await this.getOrCreateWorkflowForExecution(collectionName, executionOptions);
|
||||
if (!schematicName) {
|
||||
throw new Error('schematicName cannot be undefined.');
|
||||
}
|
||||
const { unsubscribe, files } = (0, schematic_workflow_1.subscribeToWorkflow)(workflow, logger);
|
||||
try {
|
||||
await workflow
|
||||
.execute({
|
||||
collection: collectionName,
|
||||
schematic: schematicName,
|
||||
options: schematicOptions,
|
||||
logger,
|
||||
allowPrivate: this.allowPrivateSchematics,
|
||||
})
|
||||
.toPromise();
|
||||
if (!files.size) {
|
||||
logger.info('Nothing to be done.');
|
||||
}
|
||||
if (executionOptions.dryRun) {
|
||||
logger.warn(`\nNOTE: The "--dry-run" option means no changes were made.`);
|
||||
return 0;
|
||||
}
|
||||
if (files.size) {
|
||||
// Note: we could use a task executor to format the files but this is simpler.
|
||||
try {
|
||||
await (0, prettier_1.formatFiles)(this.context.root, files);
|
||||
}
|
||||
catch (error) {
|
||||
(0, error_1.assertIsError)(error);
|
||||
logger.warn(`WARNING: Formatting of files failed with the following error: ${error.message}`);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (err) {
|
||||
// In case the workflow was not successful, show an appropriate error message.
|
||||
if (err instanceof schematics_1.UnsuccessfulWorkflowExecution) {
|
||||
// "See above" because we already printed the error.
|
||||
logger.fatal('The Schematic workflow failed. See above.');
|
||||
}
|
||||
else {
|
||||
(0, error_1.assertIsError)(err);
|
||||
logger.fatal(err.message);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
finally {
|
||||
unsubscribe();
|
||||
}
|
||||
}
|
||||
getProjectName() {
|
||||
const { workspace } = this.context;
|
||||
if (!workspace) {
|
||||
return undefined;
|
||||
}
|
||||
const projectName = (0, config_1.getProjectByCwd)(workspace);
|
||||
if (projectName) {
|
||||
return projectName;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
getResolvePaths(collectionName) {
|
||||
const { workspace, root } = this.context;
|
||||
if (collectionName[0] === '.') {
|
||||
// Resolve relative collections from the location of `angular.json`
|
||||
return [root];
|
||||
}
|
||||
return workspace
|
||||
? // Workspace
|
||||
collectionName === exports.DEFAULT_SCHEMATICS_COLLECTION
|
||||
? // Favor __dirname for @schematics/angular to use the build-in version
|
||||
[__dirname, process.cwd(), root]
|
||||
: [process.cwd(), root, __dirname]
|
||||
: // Global
|
||||
[__dirname, process.cwd()];
|
||||
}
|
||||
};
|
||||
})();
|
||||
exports.SchematicsCommandModule = SchematicsCommandModule;
|
||||
//# sourceMappingURL=schematics-command-module.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+13
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { CommandContext, CommandModule, CommandModuleImplementation } from '../command-module';
|
||||
export declare const demandCommandFailureMessage = "You need to specify a command before moving on. Use '--help' to view the available commands.";
|
||||
export type CommandModuleConstructor = Partial<CommandModuleImplementation> & {
|
||||
new (context: CommandContext): Partial<CommandModuleImplementation> & CommandModule;
|
||||
};
|
||||
export declare function addCommandModuleToYargs<U extends CommandModuleConstructor>(commandModule: U, context: CommandContext): void;
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.demandCommandFailureMessage = void 0;
|
||||
exports.addCommandModuleToYargs = addCommandModuleToYargs;
|
||||
const command_module_1 = require("../command-module");
|
||||
exports.demandCommandFailureMessage = `You need to specify a command before moving on. Use '--help' to view the available commands.`;
|
||||
function addCommandModuleToYargs(commandModule, context) {
|
||||
const cmd = new commandModule(context);
|
||||
const { args: { options: { jsonHelp }, }, workspace, } = context;
|
||||
const describe = jsonHelp ? cmd.fullDescribe : cmd.describe;
|
||||
context.yargsInstance.command({
|
||||
command: cmd.command,
|
||||
aliases: cmd.aliases,
|
||||
describe:
|
||||
// We cannot add custom fields in help, such as long command description which is used in AIO.
|
||||
// Therefore, we get around this by adding a complex object as a string which we later parse when generating the help files.
|
||||
typeof describe === 'object' ? JSON.stringify(describe) : describe,
|
||||
deprecated: cmd.deprecated,
|
||||
builder: (argv) => {
|
||||
// Skip scope validation when running with '--json-help' since it's easier to generate the output for all commands this way.
|
||||
const isInvalidScope = !jsonHelp &&
|
||||
((cmd.scope === command_module_1.CommandScope.In && !workspace) ||
|
||||
(cmd.scope === command_module_1.CommandScope.Out && workspace));
|
||||
if (isInvalidScope) {
|
||||
throw new command_module_1.CommandModuleError(`This command is not available when running the Angular CLI ${workspace ? 'inside' : 'outside'} a workspace.`);
|
||||
}
|
||||
return cmd.builder(argv);
|
||||
},
|
||||
handler: (args) => cmd.handler(args),
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=command.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"command.js","sourceRoot":"","sources":["command.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAgBH,0DAyCC;AAtDD,sDAM2B;AAEd,QAAA,2BAA2B,GAAG,8FAA8F,CAAC;AAK1I,SAAgB,uBAAuB,CACrC,aAAgB,EAChB,OAAuB;IAEvB,MAAM,GAAG,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,EACJ,IAAI,EAAE,EACJ,OAAO,EAAE,EAAE,QAAQ,EAAE,GACtB,EACD,SAAS,GACV,GAAG,OAAO,CAAC;IAEZ,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;IAE5D,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC;QAC5B,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,QAAQ;QACN,8FAA8F;QAC9F,4HAA4H;QAC5H,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ;QACpE,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAChB,4HAA4H;YAC5H,MAAM,cAAc,GAClB,CAAC,QAAQ;gBACT,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,6BAAY,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;oBAC5C,CAAC,GAAG,CAAC,KAAK,KAAK,6BAAY,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC;YAEnD,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,IAAI,mCAAkB,CAC1B,8DACE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SACzB,eAAe,CAChB,CAAC;YACJ,CAAC;YAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAS,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;KACrC,CAAC,CAAC;AACL,CAAC"}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
interface JsonHelpOption {
|
||||
name: string;
|
||||
type?: string;
|
||||
deprecated: boolean | string;
|
||||
aliases?: string[];
|
||||
default?: string;
|
||||
required?: boolean;
|
||||
positional?: number;
|
||||
enum?: string[];
|
||||
description?: string;
|
||||
}
|
||||
interface JsonHelpDescription {
|
||||
shortDescription?: string;
|
||||
longDescription?: string;
|
||||
longDescriptionRelativePath?: string;
|
||||
}
|
||||
interface JsonHelpSubcommand extends JsonHelpDescription {
|
||||
name: string;
|
||||
aliases: string[];
|
||||
deprecated: string | boolean;
|
||||
}
|
||||
export interface JsonHelp extends JsonHelpDescription {
|
||||
name: string;
|
||||
command: string;
|
||||
options: JsonHelpOption[];
|
||||
subcommands?: JsonHelpSubcommand[];
|
||||
}
|
||||
export declare function jsonHelpUsage(localYargs: Argv): string;
|
||||
export {};
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.jsonHelpUsage = jsonHelpUsage;
|
||||
const yargsDefaultCommandRegExp = /^\$0|\*/;
|
||||
function jsonHelpUsage(localYargs) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const localYargsInstance = localYargs;
|
||||
const { deprecatedOptions, alias: aliases, array, string, boolean, number, choices, demandedOptions, default: defaultVal, hiddenOptions = [], } = localYargsInstance.getOptions();
|
||||
const internalMethods = localYargsInstance.getInternalMethods();
|
||||
const usageInstance = internalMethods.getUsageInstance();
|
||||
const context = internalMethods.getContext();
|
||||
const descriptions = usageInstance.getDescriptions();
|
||||
const groups = localYargsInstance.getGroups();
|
||||
const positional = groups[usageInstance.getPositionalGroupName()];
|
||||
const seen = new Set();
|
||||
const hidden = new Set(hiddenOptions);
|
||||
const normalizeOptions = [];
|
||||
const allAliases = new Set([...Object.values(aliases).flat()]);
|
||||
// Reverted order of https://github.com/yargs/yargs/blob/971e351705f0fbc5566c6ed1dfd707fa65e11c0d/lib/usage.ts#L419-L424
|
||||
for (const [names, type] of [
|
||||
[number, 'number'],
|
||||
[array, 'array'],
|
||||
[string, 'string'],
|
||||
[boolean, 'boolean'],
|
||||
]) {
|
||||
for (const name of names) {
|
||||
if (allAliases.has(name) || hidden.has(name) || seen.has(name)) {
|
||||
// Ignore hidden, aliases and already visited option.
|
||||
continue;
|
||||
}
|
||||
seen.add(name);
|
||||
const positionalIndex = positional?.indexOf(name) ?? -1;
|
||||
const alias = aliases[name];
|
||||
normalizeOptions.push({
|
||||
name,
|
||||
type,
|
||||
deprecated: deprecatedOptions[name],
|
||||
aliases: alias?.length > 0 ? alias : undefined,
|
||||
default: defaultVal[name],
|
||||
required: demandedOptions[name],
|
||||
enum: choices[name],
|
||||
description: descriptions[name]?.replace('__yargsString__:', ''),
|
||||
positional: positionalIndex >= 0 ? positionalIndex : undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
// https://github.com/yargs/yargs/blob/00e4ebbe3acd438e73fdb101e75b4f879eb6d345/lib/usage.ts#L124
|
||||
const subcommands = usageInstance.getCommands()
|
||||
.map(([name, rawDescription, isDefault, aliases, deprecated]) => ({
|
||||
name: name.split(' ', 1)[0].replace(yargsDefaultCommandRegExp, ''),
|
||||
command: name.replace(yargsDefaultCommandRegExp, ''),
|
||||
default: isDefault || undefined,
|
||||
...parseDescription(rawDescription),
|
||||
aliases,
|
||||
deprecated,
|
||||
}))
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
const [command, rawDescription] = usageInstance.getUsage()[0] ?? [];
|
||||
const defaultSubCommand = subcommands.find((x) => x.default)?.command ?? '';
|
||||
const otherSubcommands = subcommands.filter((s) => !s.default);
|
||||
const output = {
|
||||
name: [...context.commands].pop(),
|
||||
command: `${command?.replace(yargsDefaultCommandRegExp, localYargsInstance['$0'])}${defaultSubCommand}`,
|
||||
...parseDescription(rawDescription),
|
||||
options: normalizeOptions.sort((a, b) => a.name.localeCompare(b.name)),
|
||||
subcommands: otherSubcommands.length ? otherSubcommands : undefined,
|
||||
};
|
||||
return JSON.stringify(output, undefined, 2);
|
||||
}
|
||||
function parseDescription(rawDescription) {
|
||||
try {
|
||||
const { longDescription, describe: shortDescription, longDescriptionRelativePath, } = JSON.parse(rawDescription);
|
||||
return {
|
||||
shortDescription,
|
||||
longDescriptionRelativePath,
|
||||
longDescription,
|
||||
};
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
shortDescription: rawDescription,
|
||||
};
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=json-help.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"json-help.js","sourceRoot":"","sources":["json-help.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAsCH,sCA2FC;AA7FD,MAAM,yBAAyB,GAAG,SAAS,CAAC;AAE5C,SAAgB,aAAa,CAAC,UAAgB;IAC5C,8DAA8D;IAC9D,MAAM,kBAAkB,GAAG,UAAiB,CAAC;IAC7C,MAAM,EACJ,iBAAiB,EACjB,KAAK,EAAE,OAAO,EACd,KAAK,EACL,MAAM,EACN,OAAO,EACP,MAAM,EACN,OAAO,EACP,eAAe,EACf,OAAO,EAAE,UAAU,EACnB,aAAa,GAAG,EAAE,GACnB,GAAG,kBAAkB,CAAC,UAAU,EAAE,CAAC;IAEpC,MAAM,eAAe,GAAG,kBAAkB,CAAC,kBAAkB,EAAE,CAAC;IAChE,MAAM,aAAa,GAAG,eAAe,CAAC,gBAAgB,EAAE,CAAC;IACzD,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAG,aAAa,CAAC,eAAe,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,sBAAsB,EAAE,CAAyB,CAAC;IAC1F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACtC,MAAM,gBAAgB,GAAqB,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAW,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEzE,wHAAwH;IACxH,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI;QAC1B,CAAC,MAAM,EAAE,QAAQ,CAAC;QAClB,CAAC,KAAK,EAAE,OAAO,CAAC;QAChB,CAAC,MAAM,EAAE,QAAQ,CAAC;QAClB,CAAC,OAAO,EAAE,SAAS,CAAC;KACrB,EAAE,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/D,qDAAqD;gBACrD,SAAS;YACX,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,MAAM,eAAe,GAAG,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACxD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAE5B,gBAAgB,CAAC,IAAI,CAAC;gBACpB,IAAI;gBACJ,IAAI;gBACJ,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC;gBACnC,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;gBAC9C,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC;gBACzB,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC;gBAC/B,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;gBACnB,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;gBAChE,UAAU,EAAE,eAAe,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;aAC/D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iGAAiG;IACjG,MAAM,WAAW,GACf,aAAa,CAAC,WAAW,EAO1B;SACE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;QAChE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC;QAClE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC;QACpD,OAAO,EAAE,SAAS,IAAI,SAAS;QAC/B,GAAG,gBAAgB,CAAC,cAAc,CAAC;QACnC,OAAO;QACP,UAAU;KACX,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhD,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,MAAM,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC;IAC5E,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAE/D,MAAM,MAAM,GAAa;QACvB,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE;QACjC,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,CAAC,yBAAyB,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC,GAAG,iBAAiB,EAAE;QACvG,GAAG,gBAAgB,CAAC,cAAc,CAAC;QACnC,OAAO,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtE,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;KACpE,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,gBAAgB,CAAC,cAAsB;IAC9C,IAAI,CAAC;QACH,MAAM,EACJ,eAAe,EACf,QAAQ,EAAE,gBAAgB,EAC1B,2BAA2B,GAC5B,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAiB,CAAC;QAE/C,OAAO;YACL,gBAAgB;YAChB,2BAA2B;YAC3B,eAAe;SAChB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,gBAAgB,EAAE,cAAc;SACjC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { json } from '@angular-devkit/core';
|
||||
import type { Argv, Options as YargsOptions } from 'yargs';
|
||||
import { EventCustomDimension } from '../../analytics/analytics-parameters';
|
||||
/**
|
||||
* An option description that can be used by yargs to create a command.
|
||||
* See: https://github.com/yargs/yargs/blob/main/docs/options.mjs
|
||||
*/
|
||||
export interface Option extends YargsOptions {
|
||||
/**
|
||||
* The name of the option.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Whether this option is required or not.
|
||||
*/
|
||||
required?: boolean;
|
||||
/**
|
||||
* Format field of this option.
|
||||
*/
|
||||
format?: string;
|
||||
/**
|
||||
* Whether this option should be hidden from the help output. It will still show up in JSON help.
|
||||
*/
|
||||
hidden?: boolean;
|
||||
/**
|
||||
* If this option can be used as an argument, the position of the argument. Otherwise omitted.
|
||||
*/
|
||||
positional?: number;
|
||||
/**
|
||||
* Whether or not to report this option to the Angular Team, and which custom field to use.
|
||||
* If this is falsey, do not report this option.
|
||||
*/
|
||||
userAnalytics?: string;
|
||||
/**
|
||||
* Type of the values in a key/value pair field.
|
||||
*/
|
||||
itemValueType?: 'string';
|
||||
}
|
||||
/**
|
||||
* Parses a JSON schema to a list of options that can be used by yargs.
|
||||
*
|
||||
* @param registry A schema registry to use for flattening the schema.
|
||||
* @param schema The JSON schema to parse.
|
||||
* @param interactive Whether to prompt the user for missing options.
|
||||
* @returns A list of options.
|
||||
*
|
||||
* @note The schema definition are not resolved at this stage. This means that `$ref` will not be resolved,
|
||||
* and custom keywords like `x-prompt` will not be processed.
|
||||
*/
|
||||
export declare function parseJsonSchemaToOptions(registry: json.schema.SchemaRegistry, schema: json.JsonObject, interactive?: boolean): Promise<Option[]>;
|
||||
/**
|
||||
* Adds schema options to a command also this keeps track of options that are required for analytics.
|
||||
* **Note:** This method should be called from the command bundler method.
|
||||
*
|
||||
* @returns A map from option name to analytics configuration.
|
||||
*/
|
||||
export declare function addSchemaOptionsToCommand<T>(localYargs: Argv<T>, options: Option[], includeDefaultValues: boolean): Map<string, EventCustomDimension>;
|
||||
+349
@@ -0,0 +1,349 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseJsonSchemaToOptions = parseJsonSchemaToOptions;
|
||||
exports.addSchemaOptionsToCommand = addSchemaOptionsToCommand;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
/**
|
||||
* A Yargs check function that validates that the given options are in the form of `key=value`.
|
||||
* @param keyValuePairOptions A set of options that should be in the form of `key=value`.
|
||||
* @param args The parsed arguments.
|
||||
* @returns `true` if the options are valid, otherwise an error is thrown.
|
||||
*/
|
||||
function checkStringMap(keyValuePairOptions, args) {
|
||||
for (const key of keyValuePairOptions) {
|
||||
const value = args[key];
|
||||
if (!Array.isArray(value)) {
|
||||
// Value has been parsed.
|
||||
continue;
|
||||
}
|
||||
for (const pair of value) {
|
||||
if (pair === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (!pair.includes('=')) {
|
||||
throw new Error(`Invalid value for argument: ${key}, Given: '${pair}', Expected key=value pair`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* A Yargs coerce function that converts an array of `key=value` strings to an object.
|
||||
* @param value An array of `key=value` strings.
|
||||
* @returns An object with the keys and values from the input array.
|
||||
*/
|
||||
function coerceToStringMap(value) {
|
||||
const stringMap = {};
|
||||
for (const pair of value) {
|
||||
// This happens when the flag isn't passed at all.
|
||||
if (pair === undefined) {
|
||||
continue;
|
||||
}
|
||||
const eqIdx = pair.indexOf('=');
|
||||
if (eqIdx === -1) {
|
||||
// In the case it is not valid skip processing this option and handle the error in `checkStringMap`
|
||||
return value;
|
||||
}
|
||||
const key = pair.slice(0, eqIdx);
|
||||
stringMap[key] = pair.slice(eqIdx + 1);
|
||||
}
|
||||
return stringMap;
|
||||
}
|
||||
/**
|
||||
* Checks if a JSON schema node represents a string map.
|
||||
* A string map is an object with `additionalProperties` of type `string`.
|
||||
* @param node The JSON schema node to check.
|
||||
* @returns `true` if the node represents a string map, otherwise `false`.
|
||||
*/
|
||||
function isStringMap(node) {
|
||||
// Exclude fields with more specific kinds of properties.
|
||||
if (node.properties || node.patternProperties) {
|
||||
return false;
|
||||
}
|
||||
// Restrict to additionalProperties with string values.
|
||||
return (core_1.json.isJsonObject(node.additionalProperties) &&
|
||||
!node.additionalProperties.enum &&
|
||||
node.additionalProperties.type === 'string');
|
||||
}
|
||||
const SUPPORTED_PRIMITIVE_TYPES = new Set(['boolean', 'number', 'string']);
|
||||
/**
|
||||
* Checks if a string is a supported primitive type.
|
||||
* @param value The string to check.
|
||||
* @returns `true` if the string is a supported primitive type, otherwise `false`.
|
||||
*/
|
||||
function isSupportedPrimitiveType(value) {
|
||||
return SUPPORTED_PRIMITIVE_TYPES.has(value);
|
||||
}
|
||||
/**
|
||||
* Recursively checks if a JSON schema for an array's items is a supported primitive type.
|
||||
* It supports `oneOf` and `anyOf` keywords.
|
||||
* @param schema The JSON schema for the array's items.
|
||||
* @returns `true` if the schema is a supported primitive type, otherwise `false`.
|
||||
*/
|
||||
function isSupportedArrayItemSchema(schema) {
|
||||
if (typeof schema.type === 'string' && isSupportedPrimitiveType(schema.type)) {
|
||||
return true;
|
||||
}
|
||||
if (core_1.json.isJsonArray(schema.enum)) {
|
||||
return true;
|
||||
}
|
||||
if (core_1.json.isJsonArray(schema.items)) {
|
||||
return schema.items.some((item) => (0, core_1.isJsonObject)(item) && isSupportedArrayItemSchema(item));
|
||||
}
|
||||
if (core_1.json.isJsonArray(schema.oneOf) &&
|
||||
schema.oneOf.some((item) => (0, core_1.isJsonObject)(item) && isSupportedArrayItemSchema(item))) {
|
||||
return true;
|
||||
}
|
||||
if (core_1.json.isJsonArray(schema.anyOf) &&
|
||||
schema.anyOf.some((item) => (0, core_1.isJsonObject)(item) && isSupportedArrayItemSchema(item))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Gets the supported types for a JSON schema node.
|
||||
* @param current The JSON schema node to get the supported types for.
|
||||
* @returns An array of supported types.
|
||||
*/
|
||||
function getSupportedTypes(current) {
|
||||
const typeSet = core_1.json.schema.getTypesOfSchema(current);
|
||||
if (typeSet.size === 0) {
|
||||
return [];
|
||||
}
|
||||
return [...typeSet].filter((type) => {
|
||||
switch (type) {
|
||||
case 'boolean':
|
||||
case 'number':
|
||||
case 'string':
|
||||
return true;
|
||||
case 'array':
|
||||
return (0, core_1.isJsonObject)(current.items) && isSupportedArrayItemSchema(current.items);
|
||||
case 'object':
|
||||
return isStringMap(current);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Gets the enum values for a JSON schema node.
|
||||
* @param current The JSON schema node to get the enum values for.
|
||||
* @returns An array of enum values.
|
||||
*/
|
||||
function getEnumValues(current) {
|
||||
if (core_1.json.isJsonArray(current.enum)) {
|
||||
return current.enum.sort();
|
||||
}
|
||||
if ((0, core_1.isJsonObject)(current.items)) {
|
||||
const enumValues = getEnumValues(current.items);
|
||||
if (enumValues?.length) {
|
||||
return enumValues;
|
||||
}
|
||||
}
|
||||
if (typeof current.type === 'string' && isSupportedPrimitiveType(current.type)) {
|
||||
return [];
|
||||
}
|
||||
const subSchemas = (core_1.json.isJsonArray(current.oneOf) && current.oneOf) ||
|
||||
(core_1.json.isJsonArray(current.anyOf) && current.anyOf);
|
||||
if (subSchemas) {
|
||||
// Find the first enum.
|
||||
for (const subSchema of subSchemas) {
|
||||
if ((0, core_1.isJsonObject)(subSchema)) {
|
||||
const enumValues = getEnumValues(subSchema);
|
||||
if (enumValues) {
|
||||
return enumValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
/**
|
||||
* Gets the default value for a JSON schema node.
|
||||
* @param current The JSON schema node to get the default value for.
|
||||
* @param type The type of the JSON schema node.
|
||||
* @returns The default value, or `undefined` if there is no default value.
|
||||
*/
|
||||
function getDefaultValue(current, type) {
|
||||
const defaultValue = current.default;
|
||||
if (defaultValue === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (type === 'array') {
|
||||
return Array.isArray(defaultValue) && defaultValue.length > 0 ? defaultValue : undefined;
|
||||
}
|
||||
if (typeof defaultValue === type) {
|
||||
return defaultValue;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/**
|
||||
* Gets the aliases for a JSON schema node.
|
||||
* @param current The JSON schema node to get the aliases for.
|
||||
* @returns An array of aliases.
|
||||
*/
|
||||
function getAliases(current) {
|
||||
if (core_1.json.isJsonArray(current.aliases)) {
|
||||
return [...current.aliases].map(String);
|
||||
}
|
||||
if (current.alias) {
|
||||
return [String(current.alias)];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
/**
|
||||
* Parses a JSON schema to a list of options that can be used by yargs.
|
||||
*
|
||||
* @param registry A schema registry to use for flattening the schema.
|
||||
* @param schema The JSON schema to parse.
|
||||
* @param interactive Whether to prompt the user for missing options.
|
||||
* @returns A list of options.
|
||||
*
|
||||
* @note The schema definition are not resolved at this stage. This means that `$ref` will not be resolved,
|
||||
* and custom keywords like `x-prompt` will not be processed.
|
||||
*/
|
||||
async function parseJsonSchemaToOptions(registry, schema, interactive = true) {
|
||||
const options = [];
|
||||
function visitor(current, pointer, parentSchema) {
|
||||
if (!parentSchema ||
|
||||
core_1.json.isJsonArray(current) ||
|
||||
pointer.split(/\/(?:properties|items|definitions)\//g).length > 2) {
|
||||
// Ignore root, arrays, and subitems.
|
||||
return;
|
||||
}
|
||||
if (pointer.includes('/not/')) {
|
||||
// We don't support anyOf/not.
|
||||
throw new Error('The "not" keyword is not supported in JSON Schema.');
|
||||
}
|
||||
const ptr = core_1.json.schema.parseJsonPointer(pointer);
|
||||
if (ptr[ptr.length - 2] !== 'properties') {
|
||||
// Skip any non-property items.
|
||||
return;
|
||||
}
|
||||
const name = ptr.at(-1);
|
||||
const types = getSupportedTypes(current);
|
||||
if (types.length === 0) {
|
||||
// This means it's not usable on the command line. e.g. an Object.
|
||||
return;
|
||||
}
|
||||
const [type] = types;
|
||||
const $default = current.$default;
|
||||
const $defaultIndex = (0, core_1.isJsonObject)($default) && $default['$source'] === 'argv' ? $default['index'] : undefined;
|
||||
const positional = typeof $defaultIndex === 'number' ? $defaultIndex : undefined;
|
||||
let required = core_1.json.isJsonArray(schema.required) && schema.required.includes(name);
|
||||
if (required && interactive && current['x-prompt']) {
|
||||
required = false;
|
||||
}
|
||||
const visible = current.visible !== false;
|
||||
const xDeprecated = current['x-deprecated'];
|
||||
const enumValues = getEnumValues(current);
|
||||
const option = {
|
||||
name,
|
||||
description: String(current.description ?? ''),
|
||||
default: getDefaultValue(current, type),
|
||||
choices: enumValues?.length ? enumValues : undefined,
|
||||
required,
|
||||
alias: getAliases(current),
|
||||
format: typeof current.format === 'string' ? current.format : undefined,
|
||||
hidden: !!current.hidden || !visible,
|
||||
userAnalytics: typeof current['x-user-analytics'] === 'string' ? current['x-user-analytics'] : undefined,
|
||||
deprecated: xDeprecated === true || typeof xDeprecated === 'string' ? xDeprecated : undefined,
|
||||
positional,
|
||||
...(type === 'object'
|
||||
? {
|
||||
type: 'array',
|
||||
itemValueType: 'string',
|
||||
}
|
||||
: {
|
||||
type,
|
||||
}),
|
||||
};
|
||||
options.push(option);
|
||||
}
|
||||
const flattenedSchema = await registry.ɵflatten(schema);
|
||||
core_1.json.schema.visitJsonSchema(flattenedSchema, visitor);
|
||||
// Sort by positional and name.
|
||||
return options.sort((a, b) => {
|
||||
if (a.positional) {
|
||||
return b.positional ? a.positional - b.positional : a.name.localeCompare(b.name);
|
||||
}
|
||||
else if (b.positional) {
|
||||
return -1;
|
||||
}
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Adds schema options to a command also this keeps track of options that are required for analytics.
|
||||
* **Note:** This method should be called from the command bundler method.
|
||||
*
|
||||
* @returns A map from option name to analytics configuration.
|
||||
*/
|
||||
function addSchemaOptionsToCommand(localYargs, options, includeDefaultValues) {
|
||||
const booleanOptionsWithNoPrefix = new Set();
|
||||
const keyValuePairOptions = new Set();
|
||||
const optionsWithAnalytics = new Map();
|
||||
for (const option of options) {
|
||||
const { default: defaultVal, positional, deprecated, description, alias, userAnalytics, type, itemValueType, hidden, name, choices, } = option;
|
||||
let dashedName = core_1.strings.dasherize(name);
|
||||
// Handle options which have been defined in the schema with `no` prefix.
|
||||
if (type === 'boolean' && dashedName.startsWith('no-')) {
|
||||
dashedName = dashedName.slice(3);
|
||||
booleanOptionsWithNoPrefix.add(dashedName);
|
||||
}
|
||||
if (itemValueType) {
|
||||
keyValuePairOptions.add(dashedName);
|
||||
}
|
||||
const sharedOptions = {
|
||||
alias,
|
||||
hidden,
|
||||
description,
|
||||
deprecated,
|
||||
choices,
|
||||
coerce: itemValueType ? coerceToStringMap : undefined,
|
||||
// This should only be done when `--help` is used otherwise default will override options set in angular.json.
|
||||
...(includeDefaultValues ? { default: defaultVal } : {}),
|
||||
};
|
||||
if (positional === undefined) {
|
||||
localYargs = localYargs.option(dashedName, {
|
||||
array: itemValueType ? true : undefined,
|
||||
type: itemValueType ?? type,
|
||||
...sharedOptions,
|
||||
});
|
||||
}
|
||||
else {
|
||||
localYargs = localYargs.positional(dashedName, {
|
||||
type: type === 'array' || type === 'count' ? 'string' : type,
|
||||
...sharedOptions,
|
||||
});
|
||||
}
|
||||
// Record option of analytics.
|
||||
if (userAnalytics !== undefined) {
|
||||
optionsWithAnalytics.set(name, userAnalytics);
|
||||
}
|
||||
}
|
||||
// Valid key/value options
|
||||
if (keyValuePairOptions.size) {
|
||||
localYargs.check(checkStringMap.bind(null, keyValuePairOptions), false);
|
||||
}
|
||||
// Handle options which have been defined in the schema with `no` prefix.
|
||||
if (booleanOptionsWithNoPrefix.size) {
|
||||
localYargs.middleware((options) => {
|
||||
for (const key of booleanOptionsWithNoPrefix) {
|
||||
if (key in options) {
|
||||
options[`no-${key}`] = !options[key];
|
||||
delete options[key];
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
return optionsWithAnalytics;
|
||||
}
|
||||
//# sourceMappingURL=json-schema.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import type { Arguments, Argv } from 'yargs';
|
||||
/**
|
||||
* A Yargs middleware that normalizes non Array options when the argument has been provided multiple times.
|
||||
*
|
||||
* By default, when an option is non array and it is provided multiple times in the command line, yargs
|
||||
* will not override it's value but instead it will be changed to an array unless `duplicate-arguments-array` is disabled.
|
||||
* But this option also have an effect on real array options which isn't desired.
|
||||
*
|
||||
* See: https://github.com/yargs/yargs-parser/pull/163#issuecomment-516566614
|
||||
*/
|
||||
export declare function createNormalizeOptionsMiddleware(localeYargs: Argv): (args: Arguments) => void;
|
||||
Generated
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createNormalizeOptionsMiddleware = createNormalizeOptionsMiddleware;
|
||||
/**
|
||||
* A Yargs middleware that normalizes non Array options when the argument has been provided multiple times.
|
||||
*
|
||||
* By default, when an option is non array and it is provided multiple times in the command line, yargs
|
||||
* will not override it's value but instead it will be changed to an array unless `duplicate-arguments-array` is disabled.
|
||||
* But this option also have an effect on real array options which isn't desired.
|
||||
*
|
||||
* See: https://github.com/yargs/yargs-parser/pull/163#issuecomment-516566614
|
||||
*/
|
||||
function createNormalizeOptionsMiddleware(localeYargs) {
|
||||
return (args) => {
|
||||
// `getOptions` is not included in the types even though it's public API.
|
||||
// https://github.com/yargs/yargs/issues/2098
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const { array } = localeYargs.getOptions();
|
||||
const arrayOptions = new Set(array);
|
||||
for (const [key, value] of Object.entries(args)) {
|
||||
if (key !== '_' && Array.isArray(value) && !arrayOptions.has(key)) {
|
||||
const newValue = value.pop();
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Option '${key}' has been specified multiple times. The value '${newValue}' will be used.`);
|
||||
args[key] = newValue;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=normalize-options-middleware.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"normalize-options-middleware.js","sourceRoot":"","sources":["normalize-options-middleware.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAaH,4EAmBC;AA5BD;;;;;;;;GAQG;AACH,SAAgB,gCAAgC,CAAC,WAAiB;IAChE,OAAO,CAAC,IAAe,EAAE,EAAE;QACzB,yEAAyE;QACzE,6CAA6C;QAC7C,8DAA8D;QAC9D,MAAM,EAAE,KAAK,EAAE,GAAI,WAAmB,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAEpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClE,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;gBAC7B,sCAAsC;gBACtC,OAAO,CAAC,IAAI,CACV,WAAW,GAAG,mDAAmD,QAAQ,iBAAiB,CAC3F,CAAC;gBACF,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
||||
Generated
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { RuleFactory } from '@angular-devkit/schematics';
|
||||
import { FileSystemCollectionDesc, NodeModulesEngineHost } from '@angular-devkit/schematics/tools';
|
||||
export declare class SchematicEngineHost extends NodeModulesEngineHost {
|
||||
protected _resolveReferenceString(refString: string, parentPath: string, collectionDescription?: FileSystemCollectionDesc): {
|
||||
ref: RuleFactory<{}>;
|
||||
path: string;
|
||||
} | null;
|
||||
}
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SchematicEngineHost = void 0;
|
||||
const schematics_1 = require("@angular-devkit/schematics");
|
||||
const tools_1 = require("@angular-devkit/schematics/tools");
|
||||
const jsonc_parser_1 = require("jsonc-parser");
|
||||
const node_fs_1 = require("node:fs");
|
||||
const node_module_1 = require("node:module");
|
||||
const node_path_1 = require("node:path");
|
||||
const node_vm_1 = require("node:vm");
|
||||
const error_1 = require("../../utilities/error");
|
||||
/**
|
||||
* Environment variable to control schematic package redirection
|
||||
*/
|
||||
const schematicRedirectVariable = process.env['NG_SCHEMATIC_REDIRECT']?.toLowerCase();
|
||||
function shouldWrapSchematic(schematicFile, schematicEncapsulation) {
|
||||
// Check environment variable if present
|
||||
switch (schematicRedirectVariable) {
|
||||
case '0':
|
||||
case 'false':
|
||||
case 'off':
|
||||
case 'none':
|
||||
return false;
|
||||
case 'all':
|
||||
return true;
|
||||
}
|
||||
const normalizedSchematicFile = schematicFile.replace(/\\/g, '/');
|
||||
// Never wrap the internal update schematic when executed directly
|
||||
// It communicates with the update command via `global`
|
||||
// But we still want to redirect schematics located in `@angular/cli/node_modules`.
|
||||
if (normalizedSchematicFile.includes('node_modules/@angular/cli/') &&
|
||||
!normalizedSchematicFile.includes('node_modules/@angular/cli/node_modules/')) {
|
||||
return false;
|
||||
}
|
||||
// @angular/pwa uses dynamic imports which causes `[1] 2468039 segmentation fault` when wrapped.
|
||||
// We should remove this when make `importModuleDynamically` work.
|
||||
// See: https://nodejs.org/docs/latest-v14.x/api/vm.html
|
||||
if (normalizedSchematicFile.includes('@angular/pwa')) {
|
||||
return false;
|
||||
}
|
||||
// Check for first-party Angular schematic packages
|
||||
// Angular schematics are safe to use in the wrapped VM context
|
||||
const isFirstParty = /\/node_modules\/@(?:angular|schematics|nguniversal)\//.test(normalizedSchematicFile);
|
||||
// Use value of defined option if present, otherwise default to first-party usage.
|
||||
return schematicEncapsulation ?? isFirstParty;
|
||||
}
|
||||
class SchematicEngineHost extends tools_1.NodeModulesEngineHost {
|
||||
_resolveReferenceString(refString, parentPath, collectionDescription) {
|
||||
const [path, name] = refString.split('#', 2);
|
||||
// Mimic behavior of ExportStringRef class used in default behavior
|
||||
const fullPath = path[0] === '.' ? (0, node_path_1.resolve)(parentPath ?? process.cwd(), path) : path;
|
||||
const referenceRequire = (0, node_module_1.createRequire)(__filename);
|
||||
const schematicFile = referenceRequire.resolve(fullPath, { paths: [parentPath] });
|
||||
if (shouldWrapSchematic(schematicFile, collectionDescription?.encapsulation)) {
|
||||
const schematicPath = (0, node_path_1.dirname)(schematicFile);
|
||||
const moduleCache = new Map();
|
||||
const factoryInitializer = wrap(schematicFile, schematicPath, moduleCache, name || 'default');
|
||||
const factory = factoryInitializer();
|
||||
if (!factory || typeof factory !== 'function') {
|
||||
return null;
|
||||
}
|
||||
return { ref: factory, path: schematicPath };
|
||||
}
|
||||
// All other schematics use default behavior
|
||||
return super._resolveReferenceString(refString, parentPath, collectionDescription);
|
||||
}
|
||||
}
|
||||
exports.SchematicEngineHost = SchematicEngineHost;
|
||||
/**
|
||||
* Minimal shim modules for legacy deep imports of `@schematics/angular`
|
||||
*/
|
||||
const legacyModules = {
|
||||
'@schematics/angular/utility/config': {
|
||||
getWorkspace(host) {
|
||||
const path = '/.angular.json';
|
||||
const data = host.read(path);
|
||||
if (!data) {
|
||||
throw new schematics_1.SchematicsException(`Could not find (${path})`);
|
||||
}
|
||||
return (0, jsonc_parser_1.parse)(data.toString(), [], { allowTrailingComma: true });
|
||||
},
|
||||
},
|
||||
'@schematics/angular/utility/project': {
|
||||
buildDefaultPath(project) {
|
||||
const root = project.sourceRoot ? `/${project.sourceRoot}/` : `/${project.root}/src/`;
|
||||
return `${root}${project.projectType === 'application' ? 'app' : 'lib'}`;
|
||||
},
|
||||
},
|
||||
};
|
||||
/**
|
||||
* Wrap a JavaScript file in a VM context to allow specific Angular dependencies to be redirected.
|
||||
* This VM setup is ONLY intended to redirect dependencies.
|
||||
*
|
||||
* @param schematicFile A JavaScript schematic file path that should be wrapped.
|
||||
* @param schematicDirectory A directory that will be used as the location of the JavaScript file.
|
||||
* @param moduleCache A map to use for caching repeat module usage and proper `instanceof` support.
|
||||
* @param exportName An optional name of a specific export to return. Otherwise, return all exports.
|
||||
*/
|
||||
function wrap(schematicFile, schematicDirectory, moduleCache, exportName) {
|
||||
const hostRequire = (0, node_module_1.createRequire)(__filename);
|
||||
const schematicRequire = (0, node_module_1.createRequire)(schematicFile);
|
||||
const customRequire = function (id) {
|
||||
if (legacyModules[id]) {
|
||||
// Provide compatibility modules for older versions of @angular/cdk
|
||||
return legacyModules[id];
|
||||
}
|
||||
else if (id.startsWith('schematics:')) {
|
||||
// Schematics built-in modules use the `schematics` scheme (similar to the Node.js `node` scheme)
|
||||
const builtinId = id.slice(11);
|
||||
const builtinModule = loadBuiltinModule(builtinId);
|
||||
if (!builtinModule) {
|
||||
throw new Error(`Unknown schematics built-in module '${id}' requested from schematic '${schematicFile}'`);
|
||||
}
|
||||
return builtinModule;
|
||||
}
|
||||
else if (id.startsWith('@angular-devkit/') || id.startsWith('@schematics/')) {
|
||||
// Files should not redirect `@angular/core` and instead use the direct
|
||||
// dependency if available. This allows old major version migrations to continue to function
|
||||
// even though the latest major version may have breaking changes in `@angular/core`.
|
||||
if (id.startsWith('@angular-devkit/core')) {
|
||||
try {
|
||||
return schematicRequire(id);
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
if (e.code !== 'MODULE_NOT_FOUND') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Resolve from inside the `@angular/cli` project
|
||||
return hostRequire(id);
|
||||
}
|
||||
else if (id.startsWith('.') || id.startsWith('@angular/cdk')) {
|
||||
// Wrap relative files inside the schematic collection
|
||||
// Also wrap `@angular/cdk`, it contains helper utilities that import core schematic packages
|
||||
// Resolve from the original file
|
||||
const modulePath = schematicRequire.resolve(id);
|
||||
// Use cached module if available
|
||||
const cachedModule = moduleCache.get(modulePath);
|
||||
if (cachedModule) {
|
||||
return cachedModule;
|
||||
}
|
||||
// Do not wrap vendored third-party packages or JSON files
|
||||
if (!/[/\\]node_modules[/\\]@schematics[/\\]angular[/\\]third_party[/\\]/.test(modulePath) &&
|
||||
!modulePath.endsWith('.json')) {
|
||||
// Wrap module and save in cache
|
||||
const wrappedModule = wrap(modulePath, (0, node_path_1.dirname)(modulePath), moduleCache)();
|
||||
moduleCache.set(modulePath, wrappedModule);
|
||||
return wrappedModule;
|
||||
}
|
||||
}
|
||||
// All others are required directly from the original file
|
||||
return schematicRequire(id);
|
||||
};
|
||||
// Setup a wrapper function to capture the module's exports
|
||||
const schematicCode = (0, node_fs_1.readFileSync)(schematicFile, 'utf8');
|
||||
const script = new node_vm_1.Script(node_module_1.Module.wrap(schematicCode), {
|
||||
filename: schematicFile,
|
||||
lineOffset: 1,
|
||||
});
|
||||
const schematicModule = new node_module_1.Module(schematicFile);
|
||||
const moduleFactory = script.runInThisContext();
|
||||
return () => {
|
||||
moduleFactory(schematicModule.exports, customRequire, schematicModule, schematicFile, schematicDirectory);
|
||||
return exportName ? schematicModule.exports[exportName] : schematicModule.exports;
|
||||
};
|
||||
}
|
||||
function loadBuiltinModule(id) {
|
||||
return undefined;
|
||||
}
|
||||
//# sourceMappingURL=schematic-engine-host.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { logging } from '@angular-devkit/core';
|
||||
import { NodeWorkflow } from '@angular-devkit/schematics/tools';
|
||||
export declare function subscribeToWorkflow(workflow: NodeWorkflow, logger: logging.LoggerApi): {
|
||||
files: Set<string>;
|
||||
error: boolean;
|
||||
unsubscribe: () => void;
|
||||
};
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.subscribeToWorkflow = subscribeToWorkflow;
|
||||
const color_1 = require("../../utilities/color");
|
||||
function removeLeadingSlash(value) {
|
||||
return value[0] === '/' ? value.slice(1) : value;
|
||||
}
|
||||
function subscribeToWorkflow(workflow, logger) {
|
||||
const files = new Set();
|
||||
let error = false;
|
||||
let logs = [];
|
||||
const reporterSubscription = workflow.reporter.subscribe((event) => {
|
||||
// Strip leading slash to prevent confusion.
|
||||
const eventPath = removeLeadingSlash(event.path);
|
||||
switch (event.kind) {
|
||||
case 'error':
|
||||
error = true;
|
||||
logger.error(`ERROR! ${eventPath} ${event.description == 'alreadyExist' ? 'already exists' : 'does not exist'}.`);
|
||||
break;
|
||||
case 'update':
|
||||
logs.push(
|
||||
// TODO: `as unknown` was necessary during TS 5.9 update. Figure out a long-term solution.
|
||||
`${color_1.colors.cyan('UPDATE')} ${eventPath} (${event.content.length} bytes)`);
|
||||
files.add(eventPath);
|
||||
break;
|
||||
case 'create':
|
||||
logs.push(
|
||||
// TODO: `as unknown` was necessary during TS 5.9 update. Figure out a long-term solution.
|
||||
`${color_1.colors.green('CREATE')} ${eventPath} (${event.content.length} bytes)`);
|
||||
files.add(eventPath);
|
||||
break;
|
||||
case 'delete':
|
||||
logs.push(`${color_1.colors.yellow('DELETE')} ${eventPath}`);
|
||||
files.add(eventPath);
|
||||
break;
|
||||
case 'rename': {
|
||||
const newFilename = removeLeadingSlash(event.to);
|
||||
logs.push(`${color_1.colors.blue('RENAME')} ${eventPath} => ${newFilename}`);
|
||||
files.add(newFilename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
const lifecycleSubscription = workflow.lifeCycle.subscribe((event) => {
|
||||
if (event.kind == 'end' || event.kind == 'post-tasks-start') {
|
||||
if (!error) {
|
||||
// Output the logging queue, no error happened.
|
||||
logs.forEach((log) => logger.info(log));
|
||||
}
|
||||
logs = [];
|
||||
error = false;
|
||||
}
|
||||
});
|
||||
return {
|
||||
files,
|
||||
error,
|
||||
unsubscribe: () => {
|
||||
reporterSubscription.unsubscribe();
|
||||
lifecycleSubscription.unsubscribe();
|
||||
},
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=schematic-workflow.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"schematic-workflow.js","sourceRoot":"","sources":["schematic-workflow.ts"],"names":[],"mappings":"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"}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModuleImplementation, Options, OtherOptions } from '../../command-builder/command-module';
|
||||
import { SchematicsCommandArgs, SchematicsCommandModule } from '../../command-builder/schematics-command-module';
|
||||
interface AddCommandArgs extends SchematicsCommandArgs {
|
||||
collection: string;
|
||||
verbose?: boolean;
|
||||
registry?: string;
|
||||
'skip-confirmation'?: boolean;
|
||||
}
|
||||
export default class AddCommandModule extends SchematicsCommandModule implements CommandModuleImplementation<AddCommandArgs> {
|
||||
#private;
|
||||
command: string;
|
||||
describe: string;
|
||||
longDescriptionPath: string;
|
||||
protected allowPrivateSchematics: boolean;
|
||||
private readonly schematicName;
|
||||
private rootRequire;
|
||||
builder(argv: Argv): Promise<Argv<AddCommandArgs>>;
|
||||
run(options: Options<AddCommandArgs> & OtherOptions): Promise<number | void>;
|
||||
private findCompatiblePackageVersionTask;
|
||||
private loadPackageInfoTask;
|
||||
private confirmInstallationTask;
|
||||
private installPackageTask;
|
||||
private isProjectVersionValid;
|
||||
private getCollectionName;
|
||||
private isPackageInstalled;
|
||||
private executeSchematic;
|
||||
private findProjectVersion;
|
||||
private getPeerDependencyConflicts;
|
||||
}
|
||||
export {};
|
||||
+623
@@ -0,0 +1,623 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const listr2_1 = require("listr2");
|
||||
const node_assert_1 = __importDefault(require("node:assert"));
|
||||
const promises_1 = __importDefault(require("node:fs/promises"));
|
||||
const node_module_1 = require("node:module");
|
||||
const node_path_1 = require("node:path");
|
||||
const npm_package_arg_1 = __importDefault(require("npm-package-arg"));
|
||||
const semver_1 = __importStar(require("semver"));
|
||||
const schematics_command_module_1 = require("../../command-builder/schematics-command-module");
|
||||
const package_managers_1 = require("../../package-managers");
|
||||
const error_1 = require("../../utilities/error");
|
||||
const tty_1 = require("../../utilities/tty");
|
||||
const version_1 = require("../../utilities/version");
|
||||
class CommandError extends Error {
|
||||
}
|
||||
/**
|
||||
* The set of packages that should have certain versions excluded from consideration
|
||||
* when attempting to find a compatible version for a package.
|
||||
* The key is a package name and the value is a SemVer range of versions to exclude.
|
||||
*/
|
||||
const packageVersionExclusions = {
|
||||
// @angular/localize@9.x and earlier versions as well as @angular/localize@10.0 prereleases do not have peer dependencies setup.
|
||||
'@angular/localize': '<10.0.0',
|
||||
// @angular/material@7.x versions have unbounded peer dependency ranges (>=7.0.0).
|
||||
'@angular/material': '7.x',
|
||||
};
|
||||
const DEFAULT_CONFLICT_DISPLAY_LIMIT = 5;
|
||||
/**
|
||||
* A map of packages to built-in schematics.
|
||||
* This is used for packages that do not have a native `ng-add` schematic.
|
||||
*/
|
||||
const BUILT_IN_SCHEMATICS = {
|
||||
tailwindcss: {
|
||||
collection: '@schematics/angular',
|
||||
name: 'tailwind',
|
||||
},
|
||||
'@vitest/browser-playwright': {
|
||||
collection: '@schematics/angular',
|
||||
name: 'vitest-browser',
|
||||
},
|
||||
'@vitest/browser-webdriverio': {
|
||||
collection: '@schematics/angular',
|
||||
name: 'vitest-browser',
|
||||
},
|
||||
'@vitest/browser-preview': {
|
||||
collection: '@schematics/angular',
|
||||
name: 'vitest-browser',
|
||||
},
|
||||
};
|
||||
class AddCommandModule extends schematics_command_module_1.SchematicsCommandModule {
|
||||
command = 'add <collection>';
|
||||
describe = 'Adds support for an external library to your project.';
|
||||
longDescriptionPath = (0, node_path_1.join)(__dirname, 'long-description.md');
|
||||
allowPrivateSchematics = true;
|
||||
schematicName = 'ng-add';
|
||||
rootRequire = (0, node_module_1.createRequire)(this.context.root + '/');
|
||||
#projectVersionCache = new Map();
|
||||
async builder(argv) {
|
||||
const localYargs = (await super.builder(argv))
|
||||
.positional('collection', {
|
||||
description: 'The package to be added.',
|
||||
type: 'string',
|
||||
demandOption: true,
|
||||
})
|
||||
.option('registry', { description: 'The NPM registry to use.', type: 'string' })
|
||||
.option('verbose', {
|
||||
description: 'Display additional details about internal operations during execution.',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.option('skip-confirmation', {
|
||||
description: 'Skip asking a confirmation prompt before installing and executing the package. ' +
|
||||
'Ensure package name is correct prior to using this option.',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
// Prior to downloading we don't know the full schema and therefore we cannot be strict on the options.
|
||||
// Possibly in the future update the logic to use the following syntax:
|
||||
// `ng add @angular/localize -- --package-options`.
|
||||
.strict(false);
|
||||
const collectionName = this.getCollectionName();
|
||||
if (!collectionName) {
|
||||
return localYargs;
|
||||
}
|
||||
const workflow = this.getOrCreateWorkflowForBuilder(collectionName);
|
||||
try {
|
||||
const collection = workflow.engine.createCollection(collectionName);
|
||||
const options = await this.getSchematicOptions(collection, this.schematicName, workflow);
|
||||
return this.addSchemaOptionsToCommand(localYargs, options);
|
||||
}
|
||||
catch (error) {
|
||||
// During `ng add` prior to the downloading of the package
|
||||
// we are not able to resolve and create a collection.
|
||||
// Or when the collection value is a path to a tarball.
|
||||
}
|
||||
return localYargs;
|
||||
}
|
||||
async run(options) {
|
||||
this.#projectVersionCache.clear();
|
||||
const { logger } = this.context;
|
||||
const { collection, skipConfirmation } = options;
|
||||
let packageIdentifier;
|
||||
try {
|
||||
packageIdentifier = (0, npm_package_arg_1.default)(collection);
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
logger.error(e.message);
|
||||
return 1;
|
||||
}
|
||||
if (packageIdentifier.name &&
|
||||
packageIdentifier.registry &&
|
||||
this.isPackageInstalled(packageIdentifier.name)) {
|
||||
const validVersion = await this.isProjectVersionValid(packageIdentifier);
|
||||
if (validVersion) {
|
||||
// Already installed so just run schematic
|
||||
logger.info('Skipping installation: Package already installed');
|
||||
return this.executeSchematic({ ...options, collection: packageIdentifier.name });
|
||||
}
|
||||
}
|
||||
const taskContext = {
|
||||
packageIdentifier,
|
||||
executeSchematic: this.executeSchematic.bind(this),
|
||||
getPeerDependencyConflicts: this.getPeerDependencyConflicts.bind(this),
|
||||
dryRun: options.dryRun,
|
||||
};
|
||||
const tasks = new listr2_1.Listr([
|
||||
{
|
||||
title: 'Determining Package Manager',
|
||||
task: (_context, task) => (task.output = `Using package manager: ${listr2_1.color.dim(this.context.packageManager.name)}`),
|
||||
rendererOptions: { persistentOutput: true },
|
||||
},
|
||||
{
|
||||
title: 'Searching for compatible package version',
|
||||
enabled: packageIdentifier.type === 'range' && packageIdentifier.rawSpec === '*',
|
||||
task: (context, task) => this.findCompatiblePackageVersionTask(context, task, options),
|
||||
rendererOptions: { persistentOutput: true },
|
||||
},
|
||||
{
|
||||
title: 'Loading package information',
|
||||
task: (context, task) => this.loadPackageInfoTask(context, task, options),
|
||||
rendererOptions: { persistentOutput: true },
|
||||
},
|
||||
{
|
||||
title: 'Confirming installation',
|
||||
enabled: !skipConfirmation && !options.dryRun,
|
||||
task: (context, task) => this.confirmInstallationTask(context, task),
|
||||
rendererOptions: { persistentOutput: true },
|
||||
},
|
||||
{
|
||||
title: 'Installing package',
|
||||
skip: (context) => {
|
||||
if (context.dryRun) {
|
||||
return `Skipping package installation. Would install package ${listr2_1.color.blue(context.packageIdentifier.toString())}.`;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
task: (context, task) => this.installPackageTask(context, task, options),
|
||||
rendererOptions: { bottomBar: Infinity },
|
||||
},
|
||||
// TODO: Rework schematic execution as a task and insert here
|
||||
], {
|
||||
/* options */
|
||||
});
|
||||
try {
|
||||
const result = await tasks.run(taskContext);
|
||||
(0, node_assert_1.default)(result.collectionName, 'Collection name should always be available');
|
||||
// Check if the installed package has actual add actions and not just schematic support
|
||||
if (result.hasSchematics && !options.dryRun) {
|
||||
const workflow = this.getOrCreateWorkflowForBuilder(result.collectionName);
|
||||
const collection = workflow.engine.createCollection(result.collectionName);
|
||||
// listSchematicNames cannot be used here since it does not list private schematics.
|
||||
// Most `ng-add` schematics are marked as private.
|
||||
// TODO: Consider adding a `hasSchematic` helper to the schematic collection object.
|
||||
try {
|
||||
collection.createSchematic(this.schematicName, true);
|
||||
}
|
||||
catch {
|
||||
result.hasSchematics = false;
|
||||
}
|
||||
}
|
||||
if (!result.hasSchematics) {
|
||||
// Fallback to a built-in schematic if the package does not have an `ng-add` schematic
|
||||
const packageName = result.packageIdentifier.name;
|
||||
if (packageName) {
|
||||
const builtInSchematic = BUILT_IN_SCHEMATICS[packageName];
|
||||
if (builtInSchematic) {
|
||||
logger.info(`The ${listr2_1.color.blue(packageName)} package does not provide \`ng add\` actions.`);
|
||||
logger.info('The Angular CLI will use built-in actions to add it to your project.');
|
||||
return this.executeSchematic({
|
||||
...options,
|
||||
collection: builtInSchematic.collection,
|
||||
schematicName: builtInSchematic.name,
|
||||
package: packageName,
|
||||
});
|
||||
}
|
||||
}
|
||||
let message = options.dryRun
|
||||
? 'The package does not provide any `ng add` actions, so no further actions would be taken.'
|
||||
: 'Package installed successfully. The package does not provide any `ng add` actions, so no further actions were taken.';
|
||||
if (result.homepage) {
|
||||
message += `\nFor more information about this package, visit its homepage at ${result.homepage}`;
|
||||
}
|
||||
logger.info(message);
|
||||
return;
|
||||
}
|
||||
if (options.dryRun) {
|
||||
logger.info("The package's `ng add` actions would be executed next.");
|
||||
return;
|
||||
}
|
||||
return this.executeSchematic({ ...options, collection: result.collectionName });
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof CommandError) {
|
||||
logger.error(e.message);
|
||||
return 1;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
async findCompatiblePackageVersionTask(context, task, options) {
|
||||
const { registry, verbose } = options;
|
||||
const { packageIdentifier } = context;
|
||||
const { packageManager } = this.context;
|
||||
const packageName = packageIdentifier.name;
|
||||
(0, node_assert_1.default)(packageName, 'Registry package identifiers should always have a name.');
|
||||
const rejectionReasons = [];
|
||||
// Attempt to use the 'latest' tag from the registry.
|
||||
try {
|
||||
const latestManifest = await packageManager.getManifest(`${packageName}@latest`, {
|
||||
registry,
|
||||
});
|
||||
if (latestManifest) {
|
||||
const conflicts = await this.getPeerDependencyConflicts(latestManifest);
|
||||
if (!conflicts) {
|
||||
context.packageIdentifier = npm_package_arg_1.default.resolve(latestManifest.name, latestManifest.version);
|
||||
task.output = `Found compatible package version: ${listr2_1.color.blue(latestManifest.version)}.`;
|
||||
return;
|
||||
}
|
||||
rejectionReasons.push(...conflicts);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
throw new CommandError(`Unable to load package information from registry: ${e.message}`);
|
||||
}
|
||||
// 'latest' is invalid or not found, search for most recent matching package.
|
||||
task.output =
|
||||
'Could not find a compatible version with `latest`. Searching for a compatible version.';
|
||||
let packageMetadata;
|
||||
try {
|
||||
packageMetadata = await packageManager.getRegistryMetadata(packageName, {
|
||||
registry,
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
throw new CommandError(`Unable to load package information from registry: ${e.message}`);
|
||||
}
|
||||
if (!packageMetadata) {
|
||||
throw new CommandError('Unable to load package information from registry.');
|
||||
}
|
||||
// Allow prelease versions if the CLI itself is a prerelease or locally built.
|
||||
const allowPrereleases = !!(0, semver_1.prerelease)(version_1.VERSION.full) || version_1.VERSION.full === '0.0.0';
|
||||
const potentialVersions = this.#getPotentialVersions(packageMetadata, allowPrereleases);
|
||||
// Heuristic-based search: Check the latest release of each major version first.
|
||||
const majorVersions = this.#getMajorVersions(potentialVersions);
|
||||
let found = await this.#findCompatibleVersion(context, majorVersions, {
|
||||
registry,
|
||||
verbose,
|
||||
rejectionReasons,
|
||||
});
|
||||
// Exhaustive search: If no compatible major version is found, fall back to checking all versions.
|
||||
if (!found) {
|
||||
const checkedVersions = new Set(majorVersions);
|
||||
const remainingVersions = potentialVersions.filter((v) => !checkedVersions.has(v));
|
||||
found = await this.#findCompatibleVersion(context, remainingVersions, {
|
||||
registry,
|
||||
verbose,
|
||||
rejectionReasons,
|
||||
});
|
||||
}
|
||||
if (!found) {
|
||||
let message = `Unable to find compatible package.`;
|
||||
if (rejectionReasons.length > 0) {
|
||||
message +=
|
||||
'\nThis is often because of incompatible peer dependencies.\n' +
|
||||
'These versions were rejected due to the following conflicts:\n' +
|
||||
rejectionReasons
|
||||
.slice(0, verbose ? undefined : DEFAULT_CONFLICT_DISPLAY_LIMIT)
|
||||
.map((r) => ` - ${r}`)
|
||||
.join('\n');
|
||||
}
|
||||
task.output = message;
|
||||
}
|
||||
else {
|
||||
task.output = `Found compatible package version: ${listr2_1.color.blue(context.packageIdentifier.toString())}.`;
|
||||
}
|
||||
}
|
||||
async #findCompatibleVersion(context, versions, options) {
|
||||
const { packageIdentifier } = context;
|
||||
const { packageManager } = this.context;
|
||||
const { registry, verbose, rejectionReasons } = options;
|
||||
const packageName = packageIdentifier.name;
|
||||
(0, node_assert_1.default)(packageName, 'Package name must be defined.');
|
||||
for (const version of versions) {
|
||||
const manifest = await packageManager.getManifest(`${packageName}@${version}`, {
|
||||
registry,
|
||||
});
|
||||
if (!manifest) {
|
||||
continue;
|
||||
}
|
||||
const conflicts = await this.getPeerDependencyConflicts(manifest);
|
||||
if (conflicts) {
|
||||
if (verbose || rejectionReasons.length < DEFAULT_CONFLICT_DISPLAY_LIMIT) {
|
||||
rejectionReasons.push(...conflicts);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
context.packageIdentifier = npm_package_arg_1.default.resolve(manifest.name, manifest.version);
|
||||
return manifest;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#getPotentialVersions(packageMetadata, allowPrereleases) {
|
||||
const versionExclusions = packageVersionExclusions[packageMetadata.name];
|
||||
const latestVersion = packageMetadata['dist-tags']['latest'];
|
||||
const versions = Object.values(packageMetadata.versions).filter((version) => {
|
||||
// Latest tag has already been checked
|
||||
if (latestVersion && version === latestVersion) {
|
||||
return false;
|
||||
}
|
||||
// Prerelease versions are not stable and should not be considered by default
|
||||
if (!allowPrereleases && (0, semver_1.prerelease)(version)) {
|
||||
return false;
|
||||
}
|
||||
// Excluded package versions should not be considered
|
||||
if (versionExclusions && (0, semver_1.satisfies)(version, versionExclusions, { includePrerelease: true })) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// Sort in reverse SemVer order so that the newest compatible version is chosen
|
||||
return versions.sort((a, b) => (0, semver_1.compare)(b, a, true));
|
||||
}
|
||||
#getMajorVersions(versions) {
|
||||
const majorVersions = new Map();
|
||||
for (const version of versions) {
|
||||
const major = semver_1.default.major(version);
|
||||
const existing = majorVersions.get(major);
|
||||
if (!existing || semver_1.default.gt(version, existing)) {
|
||||
majorVersions.set(major, version);
|
||||
}
|
||||
}
|
||||
return [...majorVersions.values()].sort((a, b) => (0, semver_1.compare)(b, a, true));
|
||||
}
|
||||
async loadPackageInfoTask(context, task, options) {
|
||||
const { registry } = options;
|
||||
let manifest;
|
||||
try {
|
||||
manifest = await this.context.packageManager.getManifest(context.packageIdentifier.toString(), {
|
||||
registry,
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
throw new CommandError(`Unable to fetch package information for '${context.packageIdentifier}': ${e.message}`);
|
||||
}
|
||||
if (!manifest) {
|
||||
throw new CommandError(`Unable to fetch package information for '${context.packageIdentifier}'.`);
|
||||
}
|
||||
context.hasSchematics = !!manifest.schematics;
|
||||
context.savePackage = manifest['ng-add']?.save;
|
||||
context.collectionName = manifest.name;
|
||||
context.homepage = manifest.homepage;
|
||||
if (await this.getPeerDependencyConflicts(manifest)) {
|
||||
task.output = listr2_1.color.yellow(listr2_1.figures.warning +
|
||||
' Package has unmet peer dependencies. Adding the package may not succeed.');
|
||||
}
|
||||
}
|
||||
async confirmInstallationTask(context, task) {
|
||||
if (!(0, tty_1.isTTY)()) {
|
||||
task.output =
|
||||
`'--skip-confirmation' can be used to bypass installation confirmation. ` +
|
||||
`Ensure package name is correct prior to '--skip-confirmation' option usage.`;
|
||||
throw new CommandError('No terminal detected');
|
||||
}
|
||||
const { ListrInquirerPromptAdapter } = await Promise.resolve().then(() => __importStar(require('@listr2/prompt-adapter-inquirer')));
|
||||
const { confirm } = await Promise.resolve().then(() => __importStar(require('@inquirer/prompts')));
|
||||
const shouldProceed = await task.prompt(ListrInquirerPromptAdapter).run(confirm, {
|
||||
message: `The package ${listr2_1.color.blue(context.packageIdentifier.toString())} will be installed and executed.\n` +
|
||||
'Would you like to proceed?',
|
||||
default: true,
|
||||
theme: { prefix: '' },
|
||||
});
|
||||
if (!shouldProceed) {
|
||||
throw new CommandError('Command aborted');
|
||||
}
|
||||
}
|
||||
async installPackageTask(context, task, options) {
|
||||
const { registry } = options;
|
||||
const { packageIdentifier, savePackage } = context;
|
||||
const { packageManager } = this.context;
|
||||
// Only show if installation will actually occur
|
||||
task.title = 'Installing package';
|
||||
try {
|
||||
if (context.savePackage === false) {
|
||||
task.title += ' in temporary location';
|
||||
// Temporary packages are located in a different directory
|
||||
// Hence we need to resolve them using the temp path
|
||||
const { workingDirectory } = await packageManager.acquireTempPackage(packageIdentifier.toString(), {
|
||||
registry,
|
||||
});
|
||||
const tempRequire = (0, node_module_1.createRequire)(workingDirectory + '/');
|
||||
(0, node_assert_1.default)(context.collectionName, 'Collection name should always be available');
|
||||
const resolvedCollectionPath = tempRequire.resolve((0, node_path_1.join)(context.collectionName, 'package.json'));
|
||||
context.collectionName = (0, node_path_1.dirname)(resolvedCollectionPath);
|
||||
}
|
||||
else {
|
||||
await packageManager.add(packageIdentifier.toString(), 'none', savePackage === 'devDependencies', false, true, {
|
||||
registry,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof package_managers_1.PackageManagerError) {
|
||||
const output = e.stderr || e.stdout;
|
||||
if (output) {
|
||||
throw new CommandError(`Package installation failed: ${e.message}\nOutput: ${output}`);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
async isProjectVersionValid(packageIdentifier) {
|
||||
if (!packageIdentifier.name) {
|
||||
return false;
|
||||
}
|
||||
const installedVersion = await this.findProjectVersion(packageIdentifier.name);
|
||||
if (!installedVersion) {
|
||||
return false;
|
||||
}
|
||||
if (packageIdentifier.rawSpec === '*') {
|
||||
return true;
|
||||
}
|
||||
if (packageIdentifier.type === 'range' &&
|
||||
packageIdentifier.fetchSpec &&
|
||||
packageIdentifier.fetchSpec !== '*') {
|
||||
return (0, semver_1.satisfies)(installedVersion, packageIdentifier.fetchSpec);
|
||||
}
|
||||
if (packageIdentifier.type === 'version') {
|
||||
const v1 = (0, semver_1.valid)(packageIdentifier.fetchSpec);
|
||||
const v2 = (0, semver_1.valid)(installedVersion);
|
||||
return v1 !== null && v1 === v2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getCollectionName() {
|
||||
const [, collectionName] = this.context.args.positional;
|
||||
if (!collectionName) {
|
||||
return undefined;
|
||||
}
|
||||
// The CLI argument may specify also a version, like `ng add @my/lib@13.0.0`,
|
||||
// but here we need only the name of the package, like `@my/lib`.
|
||||
try {
|
||||
const packageName = (0, npm_package_arg_1.default)(collectionName).name;
|
||||
if (packageName) {
|
||||
return packageName;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
this.context.logger.error(e.message);
|
||||
}
|
||||
return collectionName;
|
||||
}
|
||||
isPackageInstalled(name) {
|
||||
try {
|
||||
this.rootRequire.resolve((0, node_path_1.join)(name, 'package.json'));
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
(0, error_1.assertIsError)(e);
|
||||
if (e.code !== 'MODULE_NOT_FOUND') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
executeSchematic(options) {
|
||||
const { verbose, skipConfirmation, interactive, force, dryRun, registry, defaults, collection: collectionName, schematicName, ...schematicOptions } = options;
|
||||
return this.runSchematic({
|
||||
schematicOptions,
|
||||
schematicName: schematicName ?? this.schematicName,
|
||||
collectionName,
|
||||
executionOptions: {
|
||||
interactive,
|
||||
force,
|
||||
dryRun,
|
||||
defaults,
|
||||
packageRegistry: registry,
|
||||
},
|
||||
});
|
||||
}
|
||||
async findProjectVersion(name) {
|
||||
const cachedVersion = this.#projectVersionCache.get(name);
|
||||
if (cachedVersion !== undefined) {
|
||||
return cachedVersion;
|
||||
}
|
||||
const { root } = this.context;
|
||||
let installedPackagePath;
|
||||
try {
|
||||
installedPackagePath = this.rootRequire.resolve((0, node_path_1.join)(name, 'package.json'));
|
||||
}
|
||||
catch { }
|
||||
if (installedPackagePath) {
|
||||
try {
|
||||
const installedPackage = JSON.parse(await promises_1.default.readFile(installedPackagePath, 'utf-8'));
|
||||
this.#projectVersionCache.set(name, installedPackage.version);
|
||||
return installedPackage.version;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
let projectManifest;
|
||||
try {
|
||||
projectManifest = JSON.parse(await promises_1.default.readFile((0, node_path_1.join)(root, 'package.json'), 'utf-8'));
|
||||
}
|
||||
catch { }
|
||||
if (projectManifest) {
|
||||
const version = projectManifest.dependencies?.[name] || projectManifest.devDependencies?.[name];
|
||||
if (version) {
|
||||
this.#projectVersionCache.set(name, version);
|
||||
return version;
|
||||
}
|
||||
}
|
||||
this.#projectVersionCache.set(name, null);
|
||||
return null;
|
||||
}
|
||||
async getPeerDependencyConflicts(manifest) {
|
||||
if (!manifest.peerDependencies) {
|
||||
return false;
|
||||
}
|
||||
const checks = Object.entries(manifest.peerDependencies).map(async ([peer, range]) => {
|
||||
let peerIdentifier;
|
||||
try {
|
||||
peerIdentifier = npm_package_arg_1.default.resolve(peer, range);
|
||||
}
|
||||
catch {
|
||||
this.context.logger.warn(`Invalid peer dependency ${peer} found in package.`);
|
||||
return null;
|
||||
}
|
||||
if (peerIdentifier.type !== 'version' && peerIdentifier.type !== 'range') {
|
||||
// type === 'tag' | 'file' | 'directory' | 'remote' | 'git'
|
||||
// Cannot accurately compare these as the tag/location may have changed since install.
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const version = await this.findProjectVersion(peer);
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
const options = { includePrerelease: true };
|
||||
if (!(0, semver_1.intersects)(version, peerIdentifier.rawSpec, options) &&
|
||||
!(0, semver_1.satisfies)(version, peerIdentifier.rawSpec, options)) {
|
||||
return (`Package "${manifest.name}@${manifest.version}" has an incompatible peer dependency to "` +
|
||||
`${peer}@${peerIdentifier.rawSpec}" (requires "${version}" in project).`);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Not found or invalid so ignore
|
||||
}
|
||||
return null;
|
||||
});
|
||||
const conflicts = (await Promise.all(checks)).filter((result) => !!result);
|
||||
return conflicts.length > 0 && conflicts;
|
||||
}
|
||||
}
|
||||
exports.default = AddCommandModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+7
@@ -0,0 +1,7 @@
|
||||
Adds the npm package for a published library to your workspace, and configures
|
||||
the project in the current working directory to use that library, as specified by the library's schematic.
|
||||
For example, adding `@angular/pwa` configures your project for PWA support:
|
||||
|
||||
```bash
|
||||
ng add @angular/pwa
|
||||
```
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, Options } from '../../command-builder/command-module';
|
||||
export default class AnalyticsCommandModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
describe: string;
|
||||
longDescriptionPath: string;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(_options: Options<{}>): void;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const node_path_1 = require("node:path");
|
||||
const command_module_1 = require("../../command-builder/command-module");
|
||||
const command_1 = require("../../command-builder/utilities/command");
|
||||
const cli_1 = require("./info/cli");
|
||||
const cli_2 = require("./settings/cli");
|
||||
class AnalyticsCommandModule extends command_module_1.CommandModule {
|
||||
command = 'analytics';
|
||||
describe = 'Configures the gathering of Angular CLI usage metrics.';
|
||||
longDescriptionPath = (0, node_path_1.join)(__dirname, 'long-description.md');
|
||||
builder(localYargs) {
|
||||
const subcommands = [
|
||||
cli_1.AnalyticsInfoCommandModule,
|
||||
cli_2.AnalyticsDisableModule,
|
||||
cli_2.AnalyticsEnableModule,
|
||||
cli_2.AnalyticsPromptModule,
|
||||
].sort(); // sort by class name.
|
||||
for (const module of subcommands) {
|
||||
(0, command_1.addCommandModuleToYargs)(module, this.context);
|
||||
}
|
||||
return localYargs.demandCommand(1, command_1.demandCommandFailureMessage).strict();
|
||||
}
|
||||
run(_options) { }
|
||||
}
|
||||
exports.default = AnalyticsCommandModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,yCAAiC;AAEjC,yEAI8C;AAC9C,qEAGiD;AACjD,oCAAwD;AACxD,wCAIwB;AAExB,MAAqB,sBACnB,SAAQ,8BAAa;IAGrB,OAAO,GAAG,WAAW,CAAC;IACtB,QAAQ,GAAG,wDAAwD,CAAC;IACpE,mBAAmB,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAE7D,OAAO,CAAC,UAAgB;QACtB,MAAM,WAAW,GAAG;YAClB,gCAA0B;YAC1B,4BAAsB;YACtB,2BAAqB;YACrB,2BAAqB;SACtB,CAAC,IAAI,EAAE,CAAC,CAAC,sBAAsB;QAEhC,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,IAAA,iCAAuB,EAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,qCAA2B,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3E,CAAC;IAED,GAAG,CAAC,QAAqB,IAAS,CAAC;CACpC;AAxBD,yCAwBC"}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, Options } from '../../../command-builder/command-module';
|
||||
export declare class AnalyticsInfoCommandModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
describe: string;
|
||||
longDescriptionPath?: string;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(_options: Options<{}>): Promise<void>;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AnalyticsInfoCommandModule = void 0;
|
||||
const analytics_1 = require("../../../analytics/analytics");
|
||||
const command_module_1 = require("../../../command-builder/command-module");
|
||||
class AnalyticsInfoCommandModule extends command_module_1.CommandModule {
|
||||
command = 'info';
|
||||
describe = 'Prints analytics gathering and reporting configuration in the console.';
|
||||
longDescriptionPath;
|
||||
builder(localYargs) {
|
||||
return localYargs.strict();
|
||||
}
|
||||
async run(_options) {
|
||||
this.context.logger.info(await (0, analytics_1.getAnalyticsInfoString)(this.context));
|
||||
}
|
||||
}
|
||||
exports.AnalyticsInfoCommandModule = AnalyticsInfoCommandModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAGH,4DAAsE;AACtE,4EAIiD;AAEjD,MAAa,0BACX,SAAQ,8BAAa;IAGrB,OAAO,GAAG,MAAM,CAAC;IACjB,QAAQ,GAAG,wEAAwE,CAAC;IACpF,mBAAmB,CAAU;IAE7B,OAAO,CAAC,UAAgB;QACtB,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,QAAqB;QAC7B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,IAAA,kCAAsB,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,CAAC;CACF;AAfD,gEAeC"}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
You can help the Angular Team to prioritize features and improvements by permitting the Angular team to send command-line command usage statistics to Google.
|
||||
The Angular Team does not collect usage statistics unless you explicitly opt in. When installing the Angular CLI you are prompted to allow global collection of usage statistics.
|
||||
If you say no or skip the prompt, no data is collected.
|
||||
|
||||
### What is collected?
|
||||
|
||||
Usage analytics include the commands and selected flags for each execution.
|
||||
Usage analytics may include the following information:
|
||||
|
||||
- Your operating system \(macOS, Linux distribution, Windows\) and its version.
|
||||
- Package manager name and version \(local version only\).
|
||||
- Node.js version \(local version only\).
|
||||
- Angular CLI version \(local version only\).
|
||||
- Command name that was run.
|
||||
- Workspace information, the number of application and library projects.
|
||||
- For schematics commands \(add, generate and new\), the schematic collection and name and a list of selected flags.
|
||||
- For build commands \(build, serve\), the builder name, the number and size of bundles \(initial and lazy\), compilation units, the time it took to build and rebuild, and basic Angular-specific API usage.
|
||||
|
||||
Only Angular owned and developed schematics and builders are reported.
|
||||
Third-party schematics and builders do not send data to the Angular Team.
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, Options } from '../../../command-builder/command-module';
|
||||
interface AnalyticsCommandArgs {
|
||||
global: boolean;
|
||||
}
|
||||
declare abstract class AnalyticsSettingModule extends CommandModule<AnalyticsCommandArgs> implements CommandModuleImplementation<AnalyticsCommandArgs> {
|
||||
longDescriptionPath?: string;
|
||||
builder(localYargs: Argv): Argv<AnalyticsCommandArgs>;
|
||||
abstract run({ global }: Options<AnalyticsCommandArgs>): Promise<void>;
|
||||
}
|
||||
export declare class AnalyticsDisableModule extends AnalyticsSettingModule implements CommandModuleImplementation<AnalyticsCommandArgs> {
|
||||
command: string;
|
||||
aliases: string;
|
||||
describe: string;
|
||||
run({ global }: Options<AnalyticsCommandArgs>): Promise<void>;
|
||||
}
|
||||
export declare class AnalyticsEnableModule extends AnalyticsSettingModule implements CommandModuleImplementation<AnalyticsCommandArgs> {
|
||||
command: string;
|
||||
aliases: string;
|
||||
describe: string;
|
||||
run({ global }: Options<AnalyticsCommandArgs>): Promise<void>;
|
||||
}
|
||||
export declare class AnalyticsPromptModule extends AnalyticsSettingModule implements CommandModuleImplementation<AnalyticsCommandArgs> {
|
||||
command: string;
|
||||
describe: string;
|
||||
run({ global }: Options<AnalyticsCommandArgs>): Promise<void>;
|
||||
}
|
||||
export {};
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AnalyticsPromptModule = exports.AnalyticsEnableModule = exports.AnalyticsDisableModule = void 0;
|
||||
const analytics_1 = require("../../../analytics/analytics");
|
||||
const command_module_1 = require("../../../command-builder/command-module");
|
||||
class AnalyticsSettingModule extends command_module_1.CommandModule {
|
||||
longDescriptionPath;
|
||||
builder(localYargs) {
|
||||
return localYargs
|
||||
.option('global', {
|
||||
description: `Configure analytics gathering and reporting globally in the caller's home directory.`,
|
||||
alias: ['g'],
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.strict();
|
||||
}
|
||||
}
|
||||
class AnalyticsDisableModule extends AnalyticsSettingModule {
|
||||
command = 'disable';
|
||||
aliases = 'off';
|
||||
describe = 'Disables analytics gathering and reporting for the user.';
|
||||
async run({ global }) {
|
||||
await (0, analytics_1.setAnalyticsConfig)(global, false);
|
||||
process.stderr.write(await (0, analytics_1.getAnalyticsInfoString)(this.context));
|
||||
}
|
||||
}
|
||||
exports.AnalyticsDisableModule = AnalyticsDisableModule;
|
||||
class AnalyticsEnableModule extends AnalyticsSettingModule {
|
||||
command = 'enable';
|
||||
aliases = 'on';
|
||||
describe = 'Enables analytics gathering and reporting for the user.';
|
||||
async run({ global }) {
|
||||
await (0, analytics_1.setAnalyticsConfig)(global, true);
|
||||
process.stderr.write(await (0, analytics_1.getAnalyticsInfoString)(this.context));
|
||||
}
|
||||
}
|
||||
exports.AnalyticsEnableModule = AnalyticsEnableModule;
|
||||
class AnalyticsPromptModule extends AnalyticsSettingModule {
|
||||
command = 'prompt';
|
||||
describe = 'Prompts the user to set the analytics gathering status interactively.';
|
||||
async run({ global }) {
|
||||
await (0, analytics_1.promptAnalytics)(this.context, global, true);
|
||||
}
|
||||
}
|
||||
exports.AnalyticsPromptModule = AnalyticsPromptModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAGH,4DAIsC;AACtC,4EAIiD;AAMjD,MAAe,sBACb,SAAQ,8BAAmC;IAG3C,mBAAmB,CAAU;IAE7B,OAAO,CAAC,UAAgB;QACtB,OAAO,UAAU;aACd,MAAM,CAAC,QAAQ,EAAE;YAChB,WAAW,EAAE,sFAAsF;YACnG,KAAK,EAAE,CAAC,GAAG,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;SACf,CAAC;aACD,MAAM,EAAE,CAAC;IACd,CAAC;CAGF;AAED,MAAa,sBACX,SAAQ,sBAAsB;IAG9B,OAAO,GAAG,SAAS,CAAC;IACpB,OAAO,GAAG,KAAK,CAAC;IAChB,QAAQ,GAAG,0DAA0D,CAAC;IAEtE,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAiC;QACjD,MAAM,IAAA,8BAAkB,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAA,kCAAsB,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,CAAC;CACF;AAZD,wDAYC;AAED,MAAa,qBACX,SAAQ,sBAAsB;IAG9B,OAAO,GAAG,QAAQ,CAAC;IACnB,OAAO,GAAG,IAAI,CAAC;IACf,QAAQ,GAAG,yDAAyD,CAAC;IACrE,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAiC;QACjD,MAAM,IAAA,8BAAkB,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAA,kCAAsB,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,CAAC;CACF;AAXD,sDAWC;AAED,MAAa,qBACX,SAAQ,sBAAsB;IAG9B,OAAO,GAAG,QAAQ,CAAC;IACnB,QAAQ,GAAG,uEAAuE,CAAC;IAEnF,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAiC;QACjD,MAAM,IAAA,2BAAe,EAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;CACF;AAVD,sDAUC"}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { ArchitectCommandModule } from '../../command-builder/architect-command-module';
|
||||
import { CommandModuleImplementation } from '../../command-builder/command-module';
|
||||
export default class BuildCommandModule extends ArchitectCommandModule implements CommandModuleImplementation {
|
||||
multiTarget: boolean;
|
||||
command: string;
|
||||
aliases: string[] | undefined;
|
||||
describe: string;
|
||||
longDescriptionPath: string;
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const node_path_1 = require("node:path");
|
||||
const architect_command_module_1 = require("../../command-builder/architect-command-module");
|
||||
const command_config_1 = require("../command-config");
|
||||
class BuildCommandModule extends architect_command_module_1.ArchitectCommandModule {
|
||||
multiTarget = false;
|
||||
command = 'build [project]';
|
||||
aliases = command_config_1.RootCommands['build'].aliases;
|
||||
describe = 'Compiles an Angular application or library into an output directory named dist/ at the given output path.';
|
||||
longDescriptionPath = (0, node_path_1.join)(__dirname, 'long-description.md');
|
||||
}
|
||||
exports.default = BuildCommandModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,yCAAiC;AACjC,6FAAwF;AAExF,sDAAiD;AAEjD,MAAqB,kBACnB,SAAQ,iDAAsB;IAG9B,WAAW,GAAG,KAAK,CAAC;IACpB,OAAO,GAAG,iBAAiB,CAAC;IAC5B,OAAO,GAAG,6BAAY,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;IACxC,QAAQ,GACN,2GAA2G,CAAC;IAC9G,mBAAmB,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;CAC9D;AAVD,qCAUC"}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
The command can be used to build a project of type "application" or "library".
|
||||
When used to build a library, a different builder is invoked, and only the `ts-config`, `configuration`, `poll` and `watch` options are applied.
|
||||
All other options apply only to building applications.
|
||||
|
||||
The application builder uses the [esbuild](https://esbuild.github.io/) build tool, with default configuration options specified in the workspace configuration file (`angular.json`) or with a named alternative configuration.
|
||||
A "development" configuration is created by default when you use the CLI to create the project, and you can use that configuration by specifying the `--configuration development`.
|
||||
|
||||
The configuration options generally correspond to the command options.
|
||||
You can override individual configuration defaults by specifying the corresponding options on the command line.
|
||||
The command can accept option names given in dash-case.
|
||||
Note that in the configuration file, you must specify names in camelCase.
|
||||
|
||||
Some additional options can only be set through the configuration file,
|
||||
either by direct editing or with the `ng config` command.
|
||||
These include `assets`, `styles`, and `scripts` objects that provide runtime-global resources to include in the project.
|
||||
Resources in CSS, such as images and fonts, are automatically written and fingerprinted at the root of the output folder.
|
||||
|
||||
For further details, see [Workspace Configuration](reference/configs/workspace-config).
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, CommandScope } from '../../../command-builder/command-module';
|
||||
export declare class CacheCleanModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
describe: string;
|
||||
longDescriptionPath: string | undefined;
|
||||
scope: CommandScope;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(): Promise<void>;
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CacheCleanModule = void 0;
|
||||
const promises_1 = require("node:fs/promises");
|
||||
const command_module_1 = require("../../../command-builder/command-module");
|
||||
const utilities_1 = require("../utilities");
|
||||
class CacheCleanModule extends command_module_1.CommandModule {
|
||||
command = 'clean';
|
||||
describe = 'Deletes persistent disk cache from disk.';
|
||||
longDescriptionPath;
|
||||
scope = command_module_1.CommandScope.In;
|
||||
builder(localYargs) {
|
||||
return localYargs.strict();
|
||||
}
|
||||
run() {
|
||||
const { path } = (0, utilities_1.getCacheConfig)(this.context.workspace);
|
||||
return (0, promises_1.rm)(path, {
|
||||
force: true,
|
||||
recursive: true,
|
||||
maxRetries: 3,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.CacheCleanModule = CacheCleanModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,+CAAsC;AAEtC,4EAIiD;AACjD,4CAA8C;AAE9C,MAAa,gBAAiB,SAAQ,8BAAa;IACjD,OAAO,GAAG,OAAO,CAAC;IAClB,QAAQ,GAAG,0CAA0C,CAAC;IACtD,mBAAmB,CAAqB;IAC/B,KAAK,GAAG,6BAAY,CAAC,EAAE,CAAC;IAEjC,OAAO,CAAC,UAAgB;QACtB,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,GAAG;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,0BAAc,EAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAExD,OAAO,IAAA,aAAE,EAAC,IAAI,EAAE;YACd,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,CAAC;SACd,CAAC,CAAC;IACL,CAAC;CACF;AAnBD,4CAmBC"}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, CommandScope, Options } from '../../command-builder/command-module';
|
||||
export default class CacheCommandModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
describe: string;
|
||||
longDescriptionPath: string;
|
||||
scope: CommandScope;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(_options: Options<{}>): void;
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const node_path_1 = require("node:path");
|
||||
const command_module_1 = require("../../command-builder/command-module");
|
||||
const command_1 = require("../../command-builder/utilities/command");
|
||||
const cli_1 = require("./clean/cli");
|
||||
const cli_2 = require("./info/cli");
|
||||
const cli_3 = require("./settings/cli");
|
||||
class CacheCommandModule extends command_module_1.CommandModule {
|
||||
command = 'cache';
|
||||
describe = 'Configure persistent disk cache and retrieve cache statistics.';
|
||||
longDescriptionPath = (0, node_path_1.join)(__dirname, 'long-description.md');
|
||||
scope = command_module_1.CommandScope.In;
|
||||
builder(localYargs) {
|
||||
const subcommands = [
|
||||
cli_3.CacheEnableModule,
|
||||
cli_3.CacheDisableModule,
|
||||
cli_1.CacheCleanModule,
|
||||
cli_2.CacheInfoCommandModule,
|
||||
].sort();
|
||||
for (const module of subcommands) {
|
||||
(0, command_1.addCommandModuleToYargs)(module, this.context);
|
||||
}
|
||||
return localYargs.demandCommand(1, command_1.demandCommandFailureMessage).strict();
|
||||
}
|
||||
run(_options) { }
|
||||
}
|
||||
exports.default = CacheCommandModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,yCAAiC;AAEjC,yEAK8C;AAC9C,qEAGiD;AACjD,qCAA+C;AAC/C,oCAAoD;AACpD,wCAAuE;AAEvE,MAAqB,kBACnB,SAAQ,8BAAa;IAGrB,OAAO,GAAG,OAAO,CAAC;IAClB,QAAQ,GAAG,gEAAgE,CAAC;IAC5E,mBAAmB,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;IACpD,KAAK,GAAG,6BAAY,CAAC,EAAE,CAAC;IAEjC,OAAO,CAAC,UAAgB;QACtB,MAAM,WAAW,GAAG;YAClB,uBAAiB;YACjB,wBAAkB;YAClB,sBAAgB;YAChB,4BAAsB;SACvB,CAAC,IAAI,EAAE,CAAC;QAET,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,IAAA,iCAAuB,EAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,qCAA2B,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3E,CAAC;IAED,GAAG,CAAC,QAAqB,IAAS,CAAC;CACpC;AAzBD,qCAyBC"}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, CommandScope } from '../../../command-builder/command-module';
|
||||
export declare class CacheInfoCommandModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
describe: string;
|
||||
longDescriptionPath?: string | undefined;
|
||||
scope: CommandScope;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(): Promise<void>;
|
||||
private getSizeOfDirectory;
|
||||
private formatSize;
|
||||
private effectiveEnabledStatus;
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CacheInfoCommandModule = void 0;
|
||||
const fs = __importStar(require("node:fs/promises"));
|
||||
const node_path_1 = require("node:path");
|
||||
const command_module_1 = require("../../../command-builder/command-module");
|
||||
const color_1 = require("../../../utilities/color");
|
||||
const environment_options_1 = require("../../../utilities/environment-options");
|
||||
const utilities_1 = require("../utilities");
|
||||
class CacheInfoCommandModule extends command_module_1.CommandModule {
|
||||
command = 'info';
|
||||
describe = 'Prints persistent disk cache configuration and statistics in the console.';
|
||||
longDescriptionPath;
|
||||
scope = command_module_1.CommandScope.In;
|
||||
builder(localYargs) {
|
||||
return localYargs.strict();
|
||||
}
|
||||
async run() {
|
||||
const cacheConfig = (0, utilities_1.getCacheConfig)(this.context.workspace);
|
||||
const { path, environment, enabled } = cacheConfig;
|
||||
const effectiveStatus = this.effectiveEnabledStatus(cacheConfig);
|
||||
const sizeOnDisk = await this.getSizeOfDirectory(path);
|
||||
const info = [
|
||||
{
|
||||
label: 'Enabled',
|
||||
value: enabled ? color_1.colors.green('Yes') : color_1.colors.red('No'),
|
||||
},
|
||||
{
|
||||
label: 'Environment',
|
||||
value: color_1.colors.cyan(environment),
|
||||
},
|
||||
{
|
||||
label: 'Path',
|
||||
value: color_1.colors.cyan(path),
|
||||
},
|
||||
{
|
||||
label: 'Size on disk',
|
||||
value: color_1.colors.cyan(sizeOnDisk),
|
||||
},
|
||||
{
|
||||
label: 'Effective Status',
|
||||
value: (effectiveStatus ? color_1.colors.green('Enabled') : color_1.colors.red('Disabled')) +
|
||||
' (current machine)',
|
||||
},
|
||||
];
|
||||
const maxLabelLength = Math.max(...info.map((l) => l.label.length));
|
||||
const output = info
|
||||
.map(({ label, value }) => color_1.colors.bold(label.padEnd(maxLabelLength + 2)) + `: ${value}`)
|
||||
.join('\n');
|
||||
this.context.logger.info(`\n${color_1.colors.bold('Cache Information')}\n\n${output}\n`);
|
||||
}
|
||||
async getSizeOfDirectory(path) {
|
||||
const directoriesStack = [path];
|
||||
let size = 0;
|
||||
while (directoriesStack.length) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const dirPath = directoriesStack.pop();
|
||||
let entries = [];
|
||||
try {
|
||||
entries = await fs.readdir(dirPath);
|
||||
}
|
||||
catch { }
|
||||
for (const entry of entries) {
|
||||
const entryPath = (0, node_path_1.join)(dirPath, entry);
|
||||
const stats = await fs.stat(entryPath);
|
||||
if (stats.isDirectory()) {
|
||||
directoriesStack.push(entryPath);
|
||||
}
|
||||
size += stats.size;
|
||||
}
|
||||
}
|
||||
return this.formatSize(size);
|
||||
}
|
||||
formatSize(size) {
|
||||
if (size <= 0) {
|
||||
return '0 bytes';
|
||||
}
|
||||
const abbreviations = ['bytes', 'kB', 'MB', 'GB'];
|
||||
const index = Math.floor(Math.log(size) / Math.log(1024));
|
||||
const roundedSize = size / Math.pow(1024, index);
|
||||
// bytes don't have a fraction
|
||||
const fractionDigits = index === 0 ? 0 : 2;
|
||||
return `${roundedSize.toFixed(fractionDigits)} ${abbreviations[index]}`;
|
||||
}
|
||||
effectiveEnabledStatus(cacheConfig) {
|
||||
const { enabled, environment } = cacheConfig;
|
||||
if (enabled) {
|
||||
switch (environment) {
|
||||
case 'ci':
|
||||
return environment_options_1.isCI;
|
||||
case 'local':
|
||||
return !environment_options_1.isCI;
|
||||
}
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
exports.CacheInfoCommandModule = CacheInfoCommandModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,qDAAuC;AACvC,yCAAiC;AAEjC,4EAIiD;AACjD,oDAAkD;AAClD,gFAA8D;AAC9D,4CAA8C;AAE9C,MAAa,sBAAuB,SAAQ,8BAAa;IACvD,OAAO,GAAG,MAAM,CAAC;IACjB,QAAQ,GAAG,2EAA2E,CAAC;IACvF,mBAAmB,CAAsB;IAChC,KAAK,GAAG,6BAAY,CAAC,EAAE,CAAC;IAEjC,OAAO,CAAC,UAAgB;QACtB,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,WAAW,GAAG,IAAA,0BAAc,EAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3D,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC;QAEnD,MAAM,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAuC;YAC/C;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,cAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,cAAM,CAAC,GAAG,CAAC,IAAI,CAAC;aACxD;YACD;gBACE,KAAK,EAAE,aAAa;gBACpB,KAAK,EAAE,cAAM,CAAC,IAAI,CAAC,WAAW,CAAC;aAChC;YACD;gBACE,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,cAAM,CAAC,IAAI,CAAC,IAAI,CAAC;aACzB;YACD;gBACE,KAAK,EAAE,cAAc;gBACrB,KAAK,EAAE,cAAM,CAAC,IAAI,CAAC,UAAU,CAAC;aAC/B;YACD;gBACE,KAAK,EAAE,kBAAkB;gBACzB,KAAK,EACH,CAAC,eAAe,CAAC,CAAC,CAAC,cAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,cAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBACpE,oBAAoB;aACvB;SACF,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,IAAI;aAChB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,cAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;aACvF,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,cAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,MAAM,IAAI,CAAC,CAAC;IACnF,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,IAAY;QAC3C,MAAM,gBAAgB,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,IAAI,GAAG,CAAC,CAAC;QAEb,OAAO,gBAAgB,CAAC,MAAM,EAAE,CAAC;YAC/B,oEAAoE;YACpE,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,EAAG,CAAC;YACxC,IAAI,OAAO,GAAa,EAAE,CAAC;YAE3B,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAEV,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBACvC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACnC,CAAC;gBAED,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAEO,UAAU,CAAC,IAAY;QAC7B,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACd,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjD,8BAA8B;QAC9B,MAAM,cAAc,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3C,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;IAC1E,CAAC;IAEO,sBAAsB,CAAC,WAAsD;QACnF,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;QAE7C,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,WAAW,EAAE,CAAC;gBACpB,KAAK,IAAI;oBACP,OAAO,0BAAI,CAAC;gBACd,KAAK,OAAO;oBACV,OAAO,CAAC,0BAAI,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA3GD,wDA2GC"}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
Angular CLI saves a number of cachable operations on disk by default.
|
||||
|
||||
When you re-run the same build, the build system restores the state of the previous build and re-uses previously performed operations, which decreases the time taken to build and test your applications and libraries.
|
||||
|
||||
To amend the default cache settings, add the `cli.cache` object to your [Workspace Configuration](reference/configs/workspace-config).
|
||||
The object goes under `cli.cache` at the top level of the file, outside the `projects` sections.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"cli": {
|
||||
"cache": {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
"projects": {},
|
||||
}
|
||||
```
|
||||
|
||||
For more information, see [cache options](reference/configs/workspace-config#cache-options).
|
||||
|
||||
### Cache environments
|
||||
|
||||
By default, disk cache is only enabled for local environments. The value of environment can be one of the following:
|
||||
|
||||
- `all` - allows disk cache on all machines.
|
||||
- `local` - allows disk cache only on development machines.
|
||||
- `ci` - allows disk cache only on continuous integration (CI) systems.
|
||||
|
||||
To change the environment setting to `all`, run the following command:
|
||||
|
||||
```bash
|
||||
ng config cli.cache.environment all
|
||||
```
|
||||
|
||||
For more information, see `environment` in [cache options](reference/configs/workspace-config#cache-options).
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The Angular CLI checks for the presence and value of the `CI` environment variable to determine in which environment it is running.
|
||||
|
||||
</div>
|
||||
|
||||
### Cache path
|
||||
|
||||
By default, `.angular/cache` is used as a base directory to store cache results.
|
||||
|
||||
To change this path to `.cache/ng`, run the following command:
|
||||
|
||||
```bash
|
||||
ng config cli.cache.path ".cache/ng"
|
||||
```
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation, CommandScope } from '../../../command-builder/command-module';
|
||||
export declare class CacheDisableModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
aliases: string;
|
||||
describe: string;
|
||||
longDescriptionPath: string | undefined;
|
||||
scope: CommandScope;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(): Promise<void>;
|
||||
}
|
||||
export declare class CacheEnableModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
aliases: string;
|
||||
describe: string;
|
||||
longDescriptionPath: string | undefined;
|
||||
scope: CommandScope;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(): Promise<void>;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CacheEnableModule = exports.CacheDisableModule = void 0;
|
||||
const command_module_1 = require("../../../command-builder/command-module");
|
||||
const utilities_1 = require("../utilities");
|
||||
class CacheDisableModule extends command_module_1.CommandModule {
|
||||
command = 'disable';
|
||||
aliases = 'off';
|
||||
describe = 'Disables persistent disk cache for all projects in the workspace.';
|
||||
longDescriptionPath;
|
||||
scope = command_module_1.CommandScope.In;
|
||||
builder(localYargs) {
|
||||
return localYargs;
|
||||
}
|
||||
run() {
|
||||
return (0, utilities_1.updateCacheConfig)(this.getWorkspaceOrThrow(), 'enabled', false);
|
||||
}
|
||||
}
|
||||
exports.CacheDisableModule = CacheDisableModule;
|
||||
class CacheEnableModule extends command_module_1.CommandModule {
|
||||
command = 'enable';
|
||||
aliases = 'on';
|
||||
describe = 'Enables disk cache for all projects in the workspace.';
|
||||
longDescriptionPath;
|
||||
scope = command_module_1.CommandScope.In;
|
||||
builder(localYargs) {
|
||||
return localYargs;
|
||||
}
|
||||
run() {
|
||||
return (0, utilities_1.updateCacheConfig)(this.getWorkspaceOrThrow(), 'enabled', true);
|
||||
}
|
||||
}
|
||||
exports.CacheEnableModule = CacheEnableModule;
|
||||
//# sourceMappingURL=cli.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cli.js","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAGH,4EAIiD;AACjD,4CAAiD;AAEjD,MAAa,kBAAmB,SAAQ,8BAAa;IACnD,OAAO,GAAG,SAAS,CAAC;IACpB,OAAO,GAAG,KAAK,CAAC;IAChB,QAAQ,GAAG,mEAAmE,CAAC;IAC/E,mBAAmB,CAAqB;IAC/B,KAAK,GAAG,6BAAY,CAAC,EAAE,CAAC;IAEjC,OAAO,CAAC,UAAgB;QACtB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,GAAG;QACD,OAAO,IAAA,6BAAiB,EAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACzE,CAAC;CACF;AAdD,gDAcC;AAED,MAAa,iBAAkB,SAAQ,8BAAa;IAClD,OAAO,GAAG,QAAQ,CAAC;IACnB,OAAO,GAAG,IAAI,CAAC;IACf,QAAQ,GAAG,uDAAuD,CAAC;IACnE,mBAAmB,CAAqB;IAC/B,KAAK,GAAG,6BAAY,CAAC,EAAE,CAAC;IAEjC,OAAO,CAAC,UAAgB;QACtB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,GAAG;QACD,OAAO,IAAA,6BAAiB,EAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACxE,CAAC;CACF;AAdD,8CAcC"}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Cache } from '../../../lib/config/workspace-schema';
|
||||
import { AngularWorkspace } from '../../utilities/config';
|
||||
export declare function updateCacheConfig<K extends keyof Cache>(workspace: AngularWorkspace, key: K, value: Cache[K]): Promise<void>;
|
||||
export declare function getCacheConfig(workspace: AngularWorkspace | undefined): Required<Cache>;
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.updateCacheConfig = updateCacheConfig;
|
||||
exports.getCacheConfig = getCacheConfig;
|
||||
const core_1 = require("@angular-devkit/core");
|
||||
const node_path_1 = require("node:path");
|
||||
const workspace_schema_1 = require("../../../lib/config/workspace-schema");
|
||||
function updateCacheConfig(workspace, key, value) {
|
||||
const cli = (workspace.extensions['cli'] ??= {});
|
||||
const cache = (cli['cache'] ??= {});
|
||||
cache[key] = value;
|
||||
return workspace.save();
|
||||
}
|
||||
function getCacheConfig(workspace) {
|
||||
if (!workspace) {
|
||||
throw new Error(`Cannot retrieve cache configuration as workspace is not defined.`);
|
||||
}
|
||||
const defaultSettings = {
|
||||
path: (0, node_path_1.resolve)(workspace.basePath, '.angular/cache'),
|
||||
environment: workspace_schema_1.Environment.Local,
|
||||
enabled: true,
|
||||
};
|
||||
const cliSetting = workspace.extensions['cli'];
|
||||
if (!cliSetting || !(0, core_1.isJsonObject)(cliSetting)) {
|
||||
return defaultSettings;
|
||||
}
|
||||
const cacheSettings = cliSetting['cache'];
|
||||
if (!(0, core_1.isJsonObject)(cacheSettings)) {
|
||||
return defaultSettings;
|
||||
}
|
||||
const { path = defaultSettings.path, environment = defaultSettings.environment, enabled = defaultSettings.enabled,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} = cacheSettings;
|
||||
return {
|
||||
path: (0, node_path_1.resolve)(workspace.basePath, path),
|
||||
environment,
|
||||
enabled,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=utilities.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utilities.js","sourceRoot":"","sources":["utilities.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAOH,8CAUC;AAED,wCAiCC;AAlDD,+CAAoD;AACpD,yCAAoC;AACpC,2EAA0E;AAG1E,SAAgB,iBAAiB,CAC/B,SAA2B,EAC3B,GAAM,EACN,KAAe;IAEf,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,CAA4C,CAAC;IAC5F,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACpC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAEnB,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,SAAgB,cAAc,CAAC,SAAuC;IACpE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,eAAe,GAAoB;QACvC,IAAI,EAAE,IAAA,mBAAO,EAAC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC;QACnD,WAAW,EAAE,8BAAW,CAAC,KAAK;QAC9B,OAAO,EAAE,IAAI;KACd,CAAC;IAEF,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,IAAI,CAAC,IAAA,mBAAY,EAAC,UAAU,CAAC,EAAE,CAAC;QAC7C,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAA,mBAAY,EAAC,aAAa,CAAC,EAAE,CAAC;QACjC,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,EACJ,IAAI,GAAG,eAAe,CAAC,IAAI,EAC3B,WAAW,GAAG,eAAe,CAAC,WAAW,EACzC,OAAO,GAAG,eAAe,CAAC,OAAO;IACjC,8DAA8D;MAC/D,GAAG,aAAoC,CAAC;IAEzC,OAAO;QACL,IAAI,EAAE,IAAA,mBAAO,EAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;QACvC,WAAW;QACX,OAAO;KACR,CAAC;AACJ,CAAC"}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { CommandModuleConstructor } from '../command-builder/utilities/command';
|
||||
export type CommandNames = 'add' | 'analytics' | 'build' | 'cache' | 'completion' | 'config' | 'deploy' | 'e2e' | 'extract-i18n' | 'generate' | 'lint' | 'make-this-awesome' | 'mcp' | 'new' | 'run' | 'serve' | 'test' | 'update' | 'version';
|
||||
export interface CommandConfig {
|
||||
aliases?: string[];
|
||||
factory: () => Promise<{
|
||||
default: CommandModuleConstructor;
|
||||
}>;
|
||||
}
|
||||
export declare const RootCommands: Record<CommandNames & string, CommandConfig>;
|
||||
export declare const RootCommandsAliases: Record<string, CommandConfig>;
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RootCommandsAliases = exports.RootCommands = void 0;
|
||||
exports.RootCommands = {
|
||||
'add': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./add/cli'))),
|
||||
},
|
||||
'analytics': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./analytics/cli'))),
|
||||
},
|
||||
'build': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./build/cli'))),
|
||||
aliases: ['b'],
|
||||
},
|
||||
'cache': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./cache/cli'))),
|
||||
},
|
||||
'completion': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./completion/cli'))),
|
||||
},
|
||||
'config': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./config/cli'))),
|
||||
},
|
||||
'deploy': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./deploy/cli'))),
|
||||
},
|
||||
'e2e': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./e2e/cli'))),
|
||||
aliases: ['e'],
|
||||
},
|
||||
'extract-i18n': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./extract-i18n/cli'))),
|
||||
},
|
||||
'generate': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./generate/cli'))),
|
||||
aliases: ['g'],
|
||||
},
|
||||
'lint': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./lint/cli'))),
|
||||
},
|
||||
'make-this-awesome': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./make-this-awesome/cli'))),
|
||||
},
|
||||
'mcp': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./mcp/cli'))),
|
||||
},
|
||||
'new': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./new/cli'))),
|
||||
aliases: ['n'],
|
||||
},
|
||||
'run': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./run/cli'))),
|
||||
},
|
||||
'serve': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./serve/cli'))),
|
||||
aliases: ['dev', 's'],
|
||||
},
|
||||
'test': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./test/cli'))),
|
||||
aliases: ['t'],
|
||||
},
|
||||
'update': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./update/cli'))),
|
||||
},
|
||||
'version': {
|
||||
factory: () => Promise.resolve().then(() => __importStar(require('./version/cli'))),
|
||||
aliases: ['v'],
|
||||
},
|
||||
};
|
||||
exports.RootCommandsAliases = Object.values(exports.RootCommands).reduce((prev, current) => {
|
||||
current.aliases?.forEach((alias) => {
|
||||
prev[alias] = current;
|
||||
});
|
||||
return prev;
|
||||
}, {});
|
||||
//# sourceMappingURL=command-config.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"command-config.js","sourceRoot":"","sources":["command-config.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BU,QAAA,YAAY,GAGrB;IACF,KAAK,EAAE;QACL,OAAO,EAAE,GAAG,EAAE,mDAAQ,WAAW,GAAC;KACnC;IACD,WAAW,EAAE;QACX,OAAO,EAAE,GAAG,EAAE,mDAAQ,iBAAiB,GAAC;KACzC;IACD,OAAO,EAAE;QACP,OAAO,EAAE,GAAG,EAAE,mDAAQ,aAAa,GAAC;QACpC,OAAO,EAAE,CAAC,GAAG,CAAC;KACf;IACD,OAAO,EAAE;QACP,OAAO,EAAE,GAAG,EAAE,mDAAQ,aAAa,GAAC;KACrC;IACD,YAAY,EAAE;QACZ,OAAO,EAAE,GAAG,EAAE,mDAAQ,kBAAkB,GAAC;KAC1C;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,GAAG,EAAE,mDAAQ,cAAc,GAAC;KACtC;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,GAAG,EAAE,mDAAQ,cAAc,GAAC;KACtC;IAED,KAAK,EAAE;QACL,OAAO,EAAE,GAAG,EAAE,mDAAQ,WAAW,GAAC;QAClC,OAAO,EAAE,CAAC,GAAG,CAAC;KACf;IACD,cAAc,EAAE;QACd,OAAO,EAAE,GAAG,EAAE,mDAAQ,oBAAoB,GAAC;KAC5C;IACD,UAAU,EAAE;QACV,OAAO,EAAE,GAAG,EAAE,mDAAQ,gBAAgB,GAAC;QACvC,OAAO,EAAE,CAAC,GAAG,CAAC;KACf;IACD,MAAM,EAAE;QACN,OAAO,EAAE,GAAG,EAAE,mDAAQ,YAAY,GAAC;KACpC;IACD,mBAAmB,EAAE;QACnB,OAAO,EAAE,GAAG,EAAE,mDAAQ,yBAAyB,GAAC;KACjD;IACD,KAAK,EAAE;QACL,OAAO,EAAE,GAAG,EAAE,mDAAQ,WAAW,GAAC;KACnC;IACD,KAAK,EAAE;QACL,OAAO,EAAE,GAAG,EAAE,mDAAQ,WAAW,GAAC;QAClC,OAAO,EAAE,CAAC,GAAG,CAAC;KACf;IACD,KAAK,EAAE;QACL,OAAO,EAAE,GAAG,EAAE,mDAAQ,WAAW,GAAC;KACnC;IACD,OAAO,EAAE;QACP,OAAO,EAAE,GAAG,EAAE,mDAAQ,aAAa,GAAC;QACpC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC;KACtB;IACD,MAAM,EAAE;QACN,OAAO,EAAE,GAAG,EAAE,mDAAQ,YAAY,GAAC;QACnC,OAAO,EAAE,CAAC,GAAG,CAAC;KACf;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,GAAG,EAAE,mDAAQ,cAAc,GAAC;KACtC;IACD,SAAS,EAAE;QACT,OAAO,EAAE,GAAG,EAAE,mDAAQ,eAAe,GAAC;QACtC,OAAO,EAAE,CAAC,GAAG,CAAC;KACf;CACF,CAAC;AAEW,QAAA,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,oBAAY,CAAC,CAAC,MAAM,CACnE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;IAChB,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AACd,CAAC,EACD,EAAmC,CACpC,CAAC"}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import { Argv } from 'yargs';
|
||||
import { CommandModule, CommandModuleImplementation } from '../../command-builder/command-module';
|
||||
export default class CompletionCommandModule extends CommandModule implements CommandModuleImplementation {
|
||||
command: string;
|
||||
describe: string;
|
||||
longDescriptionPath: string;
|
||||
builder(localYargs: Argv): Argv;
|
||||
run(): Promise<number>;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user