diff --git a/.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx b/.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx deleted file mode 100755 index 8b087d6572fd..000000000000 --- a/.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx +++ /dev/null @@ -1,8 +0,0 @@ -# @generated -# Input hashes for repository rule npm_translate_lock(name = "npm2", pnpm_lock = "@//:pnpm-lock.yaml"). -# This file should be checked into version control along with the pnpm-lock.yaml file. -.npmrc=-1406867100 -package.json=-443660789 -pnpm-lock.yaml=-1265630020 -pnpm-workspace.yaml=1711114604 -yarn.lock=-38145536 diff --git a/.bazelignore b/.bazelignore index 15acb77b79de..af73bfcff7c4 100644 --- a/.bazelignore +++ b/.bazelignore @@ -4,7 +4,7 @@ # https://github.com/bazelbuild/bazel/issues/8106 .git node_modules -dist +dist/ # All integration test node_modules folders integration/animations/node_modules @@ -24,6 +24,7 @@ integration/ng_elements/node_modules integration/ng_update/node_modules integration/ng_update_migrations/node_modules integration/ng-add-localize/node_modules +integration/no_ts_linker/node_modules integration/nodenext_resolution/node_modules integration/platform-server/node_modules integration/platform-server-zoneless/node_modules @@ -34,5 +35,43 @@ integration/standalone-bootstrap/node_modules integration/terser/node_modules integration/trusted-types/node_modules integration/typings_test_rxjs7/node_modules -integration/typings_test_ts58/node_modules +integration/legacy-animations/node_modules +integration/legacy-animations-async/node_modules +integration/typings_test_ts59/node_modules modules/ssr-benchmarks/node_modules +vscode-ng-language-service/integration/project/dist/ + +# For rules_js +adev/node_modules +adev/shared-docs/node_modules +adev/shared-docs/pipeline/api-gen/node_modules +dev-app/node_modules +modules/node_modules +integration/node_modules +packages/animations/node_modules +packages/common/node_modules +packages/localize/node_modules +packages/compiler-cli/node_modules +packages/compiler-cli/linker/babel/test/node_modules +packages/compiler/node_modules +packages/core/node_modules +packages/core/test/bundling/node_modules +packages/elements/node_modules +packages/forms/node_modules +packages/language-service/node_modules +packages/platform-browser/node_modules +packages/platform-server/node_modules +packages/platform-browser-dynamic/node_modules +packages/router/node_modules +packages/zone.js/node_modules +packages/zone.js/test/typings/node_modules +packages/upgrade/node_modules +packages/benchpress/node_modules +packages/service-worker/node_modules +packages/zone.js/test/typings/node_modules +packages/zone.js/node_modules +tools/bazel/rules_angular_store/node_modules +vscode-ng-language-service/node_modules +vscode-ng-language-service/server/node_modules +vscode-ng-language-service/integration/pre_standalone_project/node_modules +vscode-ng-language-service/integration/project/node_modules diff --git a/.bazelrc b/.bazelrc index a847d902c90d..033be894fe4c 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,5 +1,5 @@ # Enable debugging tests with --config=debug -test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results --spawn_strategy=local +test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results --strategy=TestRunner=standalone # Do not attempt to de-flake locally. # On CI we might set this to `3` to run with deflaking. @@ -9,6 +9,12 @@ test --flaky_test_attempts=1 common --@aspect_rules_ts//ts:skipLibCheck=always common --@aspect_rules_ts//ts:default_to_tsc_transpiler +# Needed as otherwise `env` of TS actions would be ignored. +common --incompatible_merge_fixed_and_default_shell_env + +# Frozen lockfile +common --lockfile_mode=error + ############################### # Filesystem interactions # ############################### @@ -35,7 +41,7 @@ test --nolegacy_external_runfiles # in Bazel 0.21.0 but turned off again in 0.22.0. Follow # https://github.com/bazelbuild/bazel/issues/7026 for more details. # This flag is needed to so that the bazel cache is not invalidated -# when running bazel via `yarn bazel`. +# when running bazel via `pnpm bazel`. # See https://github.com/angular/angular/issues/27514. build --incompatible_strict_action_env run --incompatible_strict_action_env @@ -57,12 +63,15 @@ build --enable_runfiles # Releases should always be stamped with version control info # This command assumes node on the path and is a workaround for # https://github.com/bazelbuild/bazel/issues/4802 -build:release --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=release" +build:release --workspace_status_command="pnpm --silent ng-dev release build-env-stamp --mode=release" build:release --stamp # Snapshots should also be stamped with version control information. -build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot" +build:snapshot-build --workspace_status_command="pnpm --silent ng-dev release build-env-stamp --mode=snapshot" build:snapshot-build --stamp +# @angular/language-server package depends directly on other Angular framework packages. +# This flag ensures that the language server uses the snapshot-built framework packages from the repository. +build:snapshot-build --//:enable_language_server_snapshot_repo_deps # Angular DevTools for Firefox releases *cannot* be stamped and `--config snapshot-build-firefox` is a no-op. # This is because Mozilla requires add-on source code to be uploaded and then they manually reproduce the build. @@ -106,9 +115,9 @@ build:remote --cpu=k8 build:remote --host_cpu=k8 # Toolchain and platform related flags -build:remote --extra_execution_platforms=@npm//@angular/build-tooling/bazel/remote-execution:platform -build:remote --host_platform=@npm//@angular/build-tooling/bazel/remote-execution:platform -build:remote --platforms=@npm//@angular/build-tooling/bazel/remote-execution:platform +build:remote --extra_execution_platforms=@devinfra//bazel/remote-execution:platform_with_network +build:remote --host_platform=@devinfra//bazel/remote-execution:platform_with_network +build:remote --platforms=@devinfra//bazel/remote-execution:platform_with_network # Remote instance and caching build:remote --remote_instance_name=projects/internal-200822/instances/primary_instance @@ -139,7 +148,7 @@ common --experimental_allow_tags_propagation # Disable network access in the sandbox by default. To enable network access # for a particular target, use: # -# load("@npm//@angular/build-tooling/bazel/remote-execution:index.bzl", "ENABLE_NETWORK") +# load("@devinfra//bazel/remote-execution:index.bzl", "ENABLE_NETWORK") # my_target( # ..., # exec_properties = ENABLE_NETWORK, # Enables network in remote exec @@ -163,8 +172,6 @@ test:saucelabs --flaky_test_attempts=1 # --ng_perf will ask the Ivy compiler to produce performance results for each build. build --flag_alias=ng_perf=//packages/compiler-cli:ng_perf -# --full_build_adev will run adev build/serve in a full mode, performing prerendering and DCE. -build --flag_alias=full_build_adev=//adev:full_build_adev #################################################### # User bazel configuration diff --git a/.bazelversion b/.bazelversion index f22d756da39d..5942a0d3a0e7 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -6.5.0 +7.7.1 diff --git a/.devcontainer/recommended-devcontainer.json b/.devcontainer/recommended-devcontainer.json index 32513341983a..03a2e3b5d790 100644 --- a/.devcontainer/recommended-devcontainer.json +++ b/.devcontainer/recommended-devcontainer.json @@ -3,7 +3,7 @@ "name": "Angular dev container", "dockerFile": "Dockerfile", "appPort": [4000, 4200, 4433, 5000, 8080, 9876], - "postCreateCommand": "yarn install", + "postCreateCommand": "pnpm install", "extensions": [ "devondcarew.bazel-code", "ms-vscode.vscode-typescript-tslint-plugin" diff --git a/.gemini/config.yaml b/.gemini/config.yaml new file mode 100644 index 000000000000..28eab0db4d88 --- /dev/null +++ b/.gemini/config.yaml @@ -0,0 +1,10 @@ +have_fun: false +code_review: + disable: false + comment_severity_threshold: MEDIUM + max_review_comments: -1 + pull_request_opened: + help: false + summary: false + code_review: false +ignore_patterns: [] diff --git a/.github/actions/deploy-docs-site/BUILD.bazel b/.github/actions/deploy-docs-site/BUILD.bazel index 2606a1bc3145..2c87772b1f38 100644 --- a/.github/actions/deploy-docs-site/BUILD.bazel +++ b/.github/actions/deploy-docs-site/BUILD.bazel @@ -1,6 +1,4 @@ -load("@aspect_rules_ts//ts:defs.bzl", rules_js_tsconfig = "ts_config") -load("//tools:defaults.bzl", "esbuild_checked_in") -load("//tools:defaults2.bzl", "ts_project") +load("//tools:defaults.bzl", "esbuild_checked_in", "ts_config", "ts_project") package(default_visibility = ["//.github/actions/deploy-docs-site:__subpackages__"]) @@ -10,10 +8,13 @@ exports_files([ esbuild_checked_in( name = "main", + config = "esbuild.conf.js", entry_point = ":lib/main.mts", external = [ "undici", + "pnpapi", ], + metafile = False, platform = "node", target = "node20", deps = [ @@ -21,7 +22,7 @@ esbuild_checked_in( ], ) -rules_js_tsconfig( +ts_config( name = "tsconfig", src = "tsconfig.json", ) diff --git a/.github/actions/deploy-docs-site/esbuild.conf.js b/.github/actions/deploy-docs-site/esbuild.conf.js new file mode 100644 index 000000000000..da6fa8ad9172 --- /dev/null +++ b/.github/actions/deploy-docs-site/esbuild.conf.js @@ -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 + */ + +module.exports = { + resolveExtensions: ['.mjs', '.js'], + format: 'esm', + banner: { + // Workaround for: https://github.com/evanw/esbuild/issues/946 + js: `import {createRequire as __cjsCompatRequire} from 'module'; +const require = __cjsCompatRequire(import.meta.url);`, + }, +}; diff --git a/.github/actions/deploy-docs-site/lib/deploy.mts b/.github/actions/deploy-docs-site/lib/deploy.mts index afe44097913f..2c7b50975b4c 100644 --- a/.github/actions/deploy-docs-site/lib/deploy.mts +++ b/.github/actions/deploy-docs-site/lib/deploy.mts @@ -1,4 +1,4 @@ -import {cp, mkdtemp, readFile, rm, writeFile} from 'node:fs/promises'; +import {mkdtemp, readFile, rm, writeFile} from 'node:fs/promises'; import {Deployment} from './deployments.mjs'; import {join} from 'node:path'; @@ -9,7 +9,7 @@ import {getCredentialFilePath} from './credential.mjs'; export async function deployToFirebase( deployment: Deployment, configPath: string, - distDirPath: string, + stagingDir: string, ) { if (deployment.destination == undefined) { console.log(`No deployment necessary for docs created from: ${deployment.branch}`); @@ -18,37 +18,33 @@ export async function deployToFirebase( console.log('Preparing for deployment to firebase...'); - const tmpDeployDir = await mkdtemp(join(tmpdir(), 'deploy-directory')); - const deployConfigPath = join(tmpDeployDir, 'firebase.json'); + const deployConfigPath = join(stagingDir, 'firebase.json'); const config = JSON.parse(await readFile(configPath, {encoding: 'utf-8'})) as { hosting: {public: string}; }; - config['hosting']['public'] = './dist'; + config['hosting']['public'] = './browser'; await writeFile(deployConfigPath, JSON.stringify(config, null, 2)); - await cp(distDirPath, join(tmpDeployDir, 'dist'), {recursive: true}); - spawnSync(`chmod 777 -R ${tmpDeployDir}`, {encoding: 'utf-8', shell: true}); - firebase( `target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`, - tmpDeployDir, + stagingDir, ); firebase( `target:apply --config ${deployConfigPath} --project angular-dev-site hosting angular-docs ${deployment.destination}`, - tmpDeployDir, + stagingDir, ); firebase( `deploy --config ${deployConfigPath} --project angular-dev-site --only hosting --non-interactive`, - tmpDeployDir, + stagingDir, ); firebase( `target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`, - tmpDeployDir, + stagingDir, ); - await rm(tmpDeployDir, {recursive: true}); + await rm(stagingDir, {recursive: true}); } export async function setupRedirect(deployment: Deployment) { @@ -103,7 +99,7 @@ export async function setupRedirect(deployment: Deployment) { } function firebase(cmd: string, cwd?: string) { - spawnSync('npx', `-y firebase-tools@13.15.1 ${cmd}`.split(' '), { + const {status} = spawnSync('npx', `-y firebase-tools@13.15.1 ${cmd}`.split(' '), { cwd, encoding: 'utf-8', shell: true, @@ -113,4 +109,8 @@ function firebase(cmd: string, cwd?: string) { GOOGLE_APPLICATION_CREDENTIALS: getCredentialFilePath(), }, }); + if (status !== 0) { + console.error('Firebase command failed, see log above for details.'); + process.exit(status); + } } diff --git a/.github/actions/deploy-docs-site/lib/deployments.mts b/.github/actions/deploy-docs-site/lib/deployments.mts index 2690ca34726a..f1c974ab8926 100644 --- a/.github/actions/deploy-docs-site/lib/deployments.mts +++ b/.github/actions/deploy-docs-site/lib/deployments.mts @@ -9,6 +9,7 @@ export interface Deployment { to: string; }; destination?: string; + servingUrl: string; } export type Deployments = Map; @@ -31,6 +32,7 @@ export async function getDeployments(): Promise { docSites.set(branch.name, { branch: branch.name, destination: `v${branch.version.major}-angular-dev`, + servingUrl: `https://v${branch.version.major}.angular.dev/`, }); }); @@ -40,12 +42,14 @@ export async function getDeployments(): Promise { from: `v${releaseTrains.latest.version.major}-angular-dev`, to: 'https://angular.dev', }, + servingUrl: 'https://angular.dev/', destination: 'angular-dev-site', }); if (releaseTrains.releaseCandidate) { docSites.set(releaseTrains.next.branchName, { branch: releaseTrains.next.branchName, + servingUrl: 'https://next.angular.dev/', }); docSites.set(releaseTrains.releaseCandidate.branchName, { @@ -55,11 +59,13 @@ export async function getDeployments(): Promise { from: `v${releaseTrains.releaseCandidate.version.major}-angular-dev`, to: 'https://next.angular.dev', }, + servingUrl: 'https://next.angular.dev/', }); } else { docSites.set(releaseTrains.next.branchName, { branch: releaseTrains.next.branchName, destination: 'next-angular-dev', + servingUrl: 'https://next.angular.dev/', }); } diff --git a/.github/actions/deploy-docs-site/lib/main.mts b/.github/actions/deploy-docs-site/lib/main.mts index 45a7a070c77d..a8677de254bd 100644 --- a/.github/actions/deploy-docs-site/lib/main.mts +++ b/.github/actions/deploy-docs-site/lib/main.mts @@ -2,8 +2,13 @@ import {getInput, setFailed} from '@actions/core'; import {context} from '@actions/github'; import {deployToFirebase, setupRedirect} from './deploy.mjs'; import {getDeployments} from './deployments.mjs'; +import {generateSitemap} from './sitemap.mjs'; import {AuthenticatedGitClient, GithubConfig, setConfig} from '@angular/ng-dev'; import {githubReleaseTrainReadToken} from './credential.mjs'; +import {spawnSync} from 'child_process'; +import {cp, mkdtemp} from 'fs/promises'; +import {tmpdir} from 'os'; +import {join} from 'path'; const refMatcher = /refs\/heads\/(.*)/; @@ -28,7 +33,11 @@ async function deployDocs() { const currentBranch = matchedRef[1]; const configPath = getInput('configPath'); - const distDir = getInput('distDir'); + const stagingDir = await mkdtemp(join(tmpdir(), 'deploy-directory')); + + // Copy all files from the distDir into stagingDir and modify the permissions for editing + await cp(getInput('distDir'), stagingDir, {recursive: true}); + spawnSync(`chmod 777 -R ${stagingDir}`, {encoding: 'utf-8', shell: true}); const deployment = (await getDeployments()).get(currentBranch); if (deployment === undefined) { @@ -57,7 +66,8 @@ async function deployDocs() { console.log(` To: ${deployment.redirect.to}`); } - await deployToFirebase(deployment, configPath, distDir); + await generateSitemap(deployment, stagingDir); + await deployToFirebase(deployment, configPath, stagingDir); await setupRedirect(deployment); } diff --git a/.github/actions/deploy-docs-site/lib/sitemap.mts b/.github/actions/deploy-docs-site/lib/sitemap.mts new file mode 100644 index 000000000000..19bec71e4e1e --- /dev/null +++ b/.github/actions/deploy-docs-site/lib/sitemap.mts @@ -0,0 +1,33 @@ +import {Deployment} from './deployments.mjs'; +import {join} from 'path'; +import {readFileSync, writeFileSync} from 'fs'; + +export async function generateSitemap(deployment: Deployment, distDir: string) { + const servingUrlWithoutEndingSlash = deployment.servingUrl.endsWith('/') + ? deployment.servingUrl.slice(0, -1) + : deployment.servingUrl; + + /** Timestamp string used to of the last file update. */ + const lastModifiedTimestamp = new Date().toISOString(); + /** An object containing all of the routes available within the application. */ + const routes = JSON.parse(readFileSync(join(distDir, 'prerendered-routes.json'), 'utf-8')); + /** The generated sitemap string. */ + const sitemap = ` + + ${Object.keys(routes.routes) + .map((route) => { + const routeWithoutLeadingSlash = route.startsWith('/') ? route.slice(1) : route; + return ` + + ${servingUrlWithoutEndingSlash}/${routeWithoutLeadingSlash} + ${lastModifiedTimestamp} + daily + 1.0 + + `; + }) + .join('')} + `; + writeFileSync(join(distDir, 'browser', 'sitemap.xml'), sitemap, 'utf-8'); + console.log(`Generated sitemap with ${Object.keys(routes.routes).length} entries.`); +} diff --git a/.github/actions/deploy-docs-site/main.js b/.github/actions/deploy-docs-site/main.js index 835255aef017..b86bdb0a23e3 100644 --- a/.github/actions/deploy-docs-site/main.js +++ b/.github/actions/deploy-docs-site/main.js @@ -1,20 +1,17 @@ - import {createRequire as __cjsCompatRequire} from 'module'; const require = __cjsCompatRequire(import.meta.url); - var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); - throw new Error('Dynamic require of "' + x + '" is not supported'); + throw Error('Dynamic require of "' + x + '" is not supported'); }); var __commonJS = (cb, mod) => function __require2() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; @@ -28,13 +25,13 @@ var __copyProps = (to, from, except, desc) => { return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); -var __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); - return value; -}; // var require_utils = __commonJS({ @@ -106,11 +103,11 @@ var require_command = __commonJS({ }; Object.defineProperty(exports, "__esModule", { value: true }); exports.issue = exports.issueCommand = void 0; - var os3 = __importStar(__require("os")); + var os2 = __importStar(__require("os")); var utils_1 = require_utils(); - function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os3.EOL); + function issueCommand(command2, properties, message) { + const cmd = new Command(command2, properties, message); + process.stdout.write(cmd.toString() + os2.EOL); } exports.issueCommand = issueCommand; function issue(name, message = "") { @@ -119,11 +116,11 @@ var require_command = __commonJS({ exports.issue = issue; var CMD_STRING = "::"; var Command = class { - constructor(command, properties, message) { - if (!command) { - command = "missing.command"; + constructor(command2, properties, message) { + if (!command2) { + command2 = "missing.command"; } - this.command = command; + this.command = command2; this.properties = properties; this.message = message; } @@ -199,17 +196,17 @@ var require_file_command = __commonJS({ exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; var crypto = __importStar(__require("crypto")); var fs = __importStar(__require("fs")); - var os3 = __importStar(__require("os")); + var os2 = __importStar(__require("os")); var utils_1 = require_utils(); - function issueFileCommand(command, message) { - const filePath = process.env[`GITHUB_${command}`]; + function issueFileCommand(command2, message) { + const filePath = process.env[`GITHUB_${command2}`]; if (!filePath) { - throw new Error(`Unable to find environment variable for file command ${command}`); + throw new Error(`Unable to find environment variable for file command ${command2}`); } if (!fs.existsSync(filePath)) { throw new Error(`Missing file at path: ${filePath}`); } - fs.appendFileSync(filePath, `${(0, utils_1.toCommandValue)(message)}${os3.EOL}`, { + fs.appendFileSync(filePath, `${(0, utils_1.toCommandValue)(message)}${os2.EOL}`, { encoding: "utf8" }); } @@ -223,7 +220,7 @@ var require_file_command = __commonJS({ if (convertedValue.includes(delimiter)) { throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); } - return `${key}<<${delimiter}${os3.EOL}${convertedValue}${os3.EOL}${delimiter}`; + return `${key}<<${delimiter}${os2.EOL}${convertedValue}${os2.EOL}${delimiter}`; } exports.prepareKeyValueMessage = prepareKeyValueMessage; } @@ -250,7 +247,7 @@ var require_proxy = __commonJS({ if (proxyVar) { try { return new DecodedURL(proxyVar); - } catch (_a) { + } catch (_a2) { if (!proxyVar.startsWith("http://") && !proxyVar.startsWith("https://")) return new DecodedURL(`http://${proxyVar}`); } @@ -586,11 +583,11 @@ var require_lib = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -606,7 +603,7 @@ var require_lib = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -677,12 +674,12 @@ var require_lib = __commonJS({ var RetryableHttpVerbs = ["OPTIONS", "GET", "DELETE", "HEAD"]; var ExponentialBackoffCeiling = 10; var ExponentialBackoffTimeSlice = 5; - var HttpClientError = class extends Error { + var HttpClientError = class _HttpClientError extends Error { constructor(message, statusCode) { super(message); this.name = "HttpClientError"; this.statusCode = statusCode; - Object.setPrototypeOf(this, HttpClientError.prototype); + Object.setPrototypeOf(this, _HttpClientError.prototype); } }; exports.HttpClientError = HttpClientError; @@ -692,26 +689,26 @@ var require_lib = __commonJS({ } readBody() { return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve5) => __awaiter(this, void 0, void 0, function* () { let output = Buffer.alloc(0); this.message.on("data", (chunk) => { output = Buffer.concat([output, chunk]); }); this.message.on("end", () => { - resolve(output.toString()); + resolve5(output.toString()); }); })); }); } readBodyBuffer() { return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve5) => __awaiter(this, void 0, void 0, function* () { const chunks = []; this.message.on("data", (chunk) => { chunks.push(chunk); }); this.message.on("end", () => { - resolve(Buffer.concat(chunks)); + resolve5(Buffer.concat(chunks)); }); })); }); @@ -724,7 +721,7 @@ var require_lib = __commonJS({ } exports.isHttps = isHttps; var HttpClient = class { - constructor(userAgent3, handlers, requestOptions) { + constructor(userAgent2, handlers, requestOptions) { this._ignoreSslError = false; this._allowRedirects = true; this._allowRedirectDowngrade = false; @@ -733,7 +730,7 @@ var require_lib = __commonJS({ this._maxRetries = 1; this._keepAlive = false; this._disposed = false; - this.userAgent = userAgent3; + this.userAgent = userAgent2; this.handlers = handlers || []; this.requestOptions = requestOptions; if (requestOptions) { @@ -801,6 +798,10 @@ var require_lib = __commonJS({ return this.request(verb, requestUrl, stream, additionalHeaders); }); } + /** + * Gets a typed object from an endpoint + * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise + */ getJson(requestUrl, additionalHeaders = {}) { return __awaiter(this, void 0, void 0, function* () { additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); @@ -835,6 +836,11 @@ var require_lib = __commonJS({ return this._processResponse(res, this.requestOptions); }); } + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ request(verb, requestUrl, data, headers) { return __awaiter(this, void 0, void 0, function* () { if (this._disposed) { @@ -895,28 +901,42 @@ var require_lib = __commonJS({ return response; }); } + /** + * Needs to be called if keepAlive is set to true in request options. + */ dispose() { if (this._agent) { this._agent.destroy(); } this._disposed = true; } + /** + * Raw request. + * @param info + * @param data + */ requestRaw(info, data) { return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => { + return new Promise((resolve5, reject) => { function callbackForResult(err, res) { if (err) { reject(err); } else if (!res) { reject(new Error("Unknown error")); } else { - resolve(res); + resolve5(res); } } this.requestRawWithCallback(info, data, callbackForResult); }); }); } + /** + * Raw request with callback. + * @param info + * @param data + * @param onResult + */ requestRawWithCallback(info, data, onResult) { if (typeof data === "string") { if (!info.options.headers) { @@ -960,6 +980,11 @@ var require_lib = __commonJS({ req.end(); } } + /** + * Gets an http agent. This function is useful when you need an http agent that handles + * routing through a proxy server - depending upon the url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ getAgent(serverUrl) { const parsedUrl = new URL(serverUrl); return this._getAgent(parsedUrl); @@ -998,14 +1023,14 @@ var require_lib = __commonJS({ } _mergeHeaders(headers) { if (this.requestOptions && this.requestOptions.headers) { - return Object.assign({}, lowercaseKeys3(this.requestOptions.headers), lowercaseKeys3(headers || {})); + return Object.assign({}, lowercaseKeys2(this.requestOptions.headers), lowercaseKeys2(headers || {})); } - return lowercaseKeys3(headers || {}); + return lowercaseKeys2(headers || {}); } _getExistingOrDefaultHeader(additionalHeaders, header, _default) { let clientHeader; if (this.requestOptions && this.requestOptions.headers) { - clientHeader = lowercaseKeys3(this.requestOptions.headers)[header]; + clientHeader = lowercaseKeys2(this.requestOptions.headers)[header]; } return additionalHeaders[header] || clientHeader || _default; } @@ -1081,12 +1106,12 @@ var require_lib = __commonJS({ return __awaiter(this, void 0, void 0, function* () { retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); - return new Promise((resolve) => setTimeout(() => resolve(), ms)); + return new Promise((resolve5) => setTimeout(() => resolve5(), ms)); }); } _processResponse(res, options) { return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve5, reject) => __awaiter(this, void 0, void 0, function* () { const statusCode = res.message.statusCode || 0; const response = { statusCode, @@ -1094,7 +1119,7 @@ var require_lib = __commonJS({ headers: {} }; if (statusCode === HttpCodes.NotFound) { - resolve(response); + resolve5(response); } function dateTimeDeserializer(key, value) { if (typeof value === "string") { @@ -1133,14 +1158,14 @@ var require_lib = __commonJS({ err.result = response.result; reject(err); } else { - resolve(response); + resolve5(response); } })); }); } }; exports.HttpClient = HttpClient; - var lowercaseKeys3 = (obj) => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); + var lowercaseKeys2 = (obj) => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); } }); @@ -1150,11 +1175,11 @@ var require_auth = __commonJS({ "use strict"; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -1170,7 +1195,7 @@ var require_auth = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -1188,6 +1213,7 @@ var require_auth = __commonJS({ } options.headers["Authorization"] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString("base64")}`; } + // This handler cannot handle 401 canHandleAuthentication() { return false; } @@ -1202,12 +1228,15 @@ var require_auth = __commonJS({ constructor(token) { this.token = token; } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 prepareRequest(options) { if (!options.headers) { throw Error("The request has no headers"); } options.headers["Authorization"] = `Bearer ${this.token}`; } + // This handler cannot handle 401 canHandleAuthentication() { return false; } @@ -1222,12 +1251,15 @@ var require_auth = __commonJS({ constructor(token) { this.token = token; } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 prepareRequest(options) { if (!options.headers) { throw Error("The request has no headers"); } options.headers["Authorization"] = `Basic ${Buffer.from(`PAT:${this.token}`).toString("base64")}`; } + // This handler cannot handle 401 canHandleAuthentication() { return false; } @@ -1247,11 +1279,11 @@ var require_oidc_utils = __commonJS({ "use strict"; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -1267,7 +1299,7 @@ var require_oidc_utils = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -1277,13 +1309,13 @@ var require_oidc_utils = __commonJS({ var http_client_1 = require_lib(); var auth_1 = require_auth(); var core_1 = require_core(); - var OidcClient = class { + var OidcClient = class _OidcClient { static createHttpClient(allowRetry = true, maxRetry = 10) { const requestOptions = { allowRetries: allowRetry, maxRetries: maxRetry }; - return new http_client_1.HttpClient("actions/oidc-client", [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + return new http_client_1.HttpClient("actions/oidc-client", [new auth_1.BearerCredentialHandler(_OidcClient.getRequestToken())], requestOptions); } static getRequestToken() { const token = process.env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"]; @@ -1300,9 +1332,9 @@ var require_oidc_utils = __commonJS({ return runtimeUrl; } static getCall(id_token_url) { - var _a; + var _a2; return __awaiter(this, void 0, void 0, function* () { - const httpclient = OidcClient.createHttpClient(); + const httpclient = _OidcClient.createHttpClient(); const res = yield httpclient.getJson(id_token_url).catch((error) => { throw new Error(`Failed to get ID Token. @@ -1310,7 +1342,7 @@ var require_oidc_utils = __commonJS({ Error Message: ${error.message}`); }); - const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + const id_token = (_a2 = res.result) === null || _a2 === void 0 ? void 0 : _a2.value; if (!id_token) { throw new Error("Response json body do not have ID Token field"); } @@ -1320,13 +1352,13 @@ var require_oidc_utils = __commonJS({ static getIDToken(audience) { return __awaiter(this, void 0, void 0, function* () { try { - let id_token_url = OidcClient.getIDTokenUrl(); + let id_token_url = _OidcClient.getIDTokenUrl(); if (audience) { const encodedAudience = encodeURIComponent(audience); id_token_url = `${id_token_url}&audience=${encodedAudience}`; } (0, core_1.debug)(`ID token url is ${id_token_url}`); - const id_token = yield OidcClient.getCall(id_token_url); + const id_token = yield _OidcClient.getCall(id_token_url); (0, core_1.setSecret)(id_token); return id_token; } catch (error) { @@ -1345,11 +1377,11 @@ var require_summary = __commonJS({ "use strict"; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -1365,7 +1397,7 @@ var require_summary = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -1374,13 +1406,19 @@ var require_summary = __commonJS({ exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; var os_1 = __require("os"); var fs_1 = __require("fs"); - var { access, appendFile: appendFile2, writeFile: writeFile2 } = fs_1.promises; + var { access, appendFile, writeFile: writeFile3 } = fs_1.promises; exports.SUMMARY_ENV_VAR = "GITHUB_STEP_SUMMARY"; exports.SUMMARY_DOCS_URL = "https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary"; var Summary = class { constructor() { this._buffer = ""; } + /** + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path + */ filePath() { return __awaiter(this, void 0, void 0, function* () { if (this._filePath) { @@ -1392,13 +1430,22 @@ var require_summary = __commonJS({ } try { yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); - } catch (_a) { + } catch (_a2) { throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); } this._filePath = pathFromEnv; return this._filePath; }); } + /** + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element + */ wrap(tag, content, attrs = {}) { const htmlAttrs = Object.entries(attrs).map(([key, value]) => ` ${key}="${value}"`).join(""); if (!content) { @@ -1406,48 +1453,111 @@ var require_summary = __commonJS({ } return `<${tag}${htmlAttrs}>${content}`; } + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ write(options) { return __awaiter(this, void 0, void 0, function* () { const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); const filePath = yield this.filePath(); - const writeFunc = overwrite ? writeFile2 : appendFile2; + const writeFunc = overwrite ? writeFile3 : appendFile; yield writeFunc(filePath, this._buffer, { encoding: "utf8" }); return this.emptyBuffer(); }); } + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ clear() { return __awaiter(this, void 0, void 0, function* () { return this.emptyBuffer().write({ overwrite: true }); }); } + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ stringify() { return this._buffer; } + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ isEmptyBuffer() { return this._buffer.length === 0; } + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ emptyBuffer() { this._buffer = ""; return this; } + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ addRaw(text, addEOL = false) { this._buffer += text; return addEOL ? this.addEOL() : this; } + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ addEOL() { return this.addRaw(os_1.EOL); } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ addCodeBlock(code, lang) { const attrs = Object.assign({}, lang && { lang }); const element = this.wrap("pre", this.wrap("code", code), attrs); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ addList(items, ordered = false) { const tag = ordered ? "ol" : "ul"; const listItems = items.map((item) => this.wrap("li", item)).join(""); const element = this.wrap(tag, listItems); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ addTable(rows) { const tableBody = rows.map((row) => { const cells = row.map((cell) => { @@ -1464,35 +1574,86 @@ var require_summary = __commonJS({ const element = this.wrap("table", tableBody); return this.addRaw(element).addEOL(); } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ addDetails(label, content) { const element = this.wrap("details", this.wrap("summary", label) + content); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ addImage(src, alt, options) { const { width, height } = options || {}; const attrs = Object.assign(Object.assign({}, width && { width }), height && { height }); const element = this.wrap("img", null, Object.assign({ src, alt }, attrs)); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ addHeading(text, level) { const tag = `h${level}`; const allowedTag = ["h1", "h2", "h3", "h4", "h5", "h6"].includes(tag) ? tag : "h1"; const element = this.wrap(allowedTag, text); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ addSeparator() { const element = this.wrap("hr", null); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ addBreak() { const element = this.wrap("br", null); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ addQuote(text, cite) { const attrs = Object.assign({}, cite && { cite }); const element = this.wrap("blockquote", text, attrs); return this.addRaw(element).addEOL(); } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ addLink(text, href) { const element = this.wrap("a", text, { href }); return this.addRaw(element).addEOL(); @@ -1592,11 +1753,11 @@ var require_io_util = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -1612,17 +1773,17 @@ var require_io_util = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; - var _a; + var _a2; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0; var fs = __importStar(__require("fs")); var path = __importStar(__require("path")); - _a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; + _a2 = fs.promises, exports.chmod = _a2.chmod, exports.copyFile = _a2.copyFile, exports.lstat = _a2.lstat, exports.mkdir = _a2.mkdir, exports.open = _a2.open, exports.readdir = _a2.readdir, exports.readlink = _a2.readlink, exports.rename = _a2.rename, exports.rm = _a2.rm, exports.rmdir = _a2.rmdir, exports.stat = _a2.stat, exports.symlink = _a2.symlink, exports.unlink = _a2.unlink; exports.IS_WINDOWS = process.platform === "win32"; exports.UV_FS_O_EXLOCK = 268435456; exports.READONLY = fs.constants.O_RDONLY; @@ -1729,8 +1890,8 @@ var require_io_util = __commonJS({ return (stats.mode & 1) > 0 || (stats.mode & 8) > 0 && stats.gid === process.getgid() || (stats.mode & 64) > 0 && stats.uid === process.getuid(); } function getCmdPath() { - var _a2; - return (_a2 = process.env["COMSPEC"]) !== null && _a2 !== void 0 ? _a2 : `cmd.exe`; + var _a3; + return (_a3 = process.env["COMSPEC"]) !== null && _a3 !== void 0 ? _a3 : `cmd.exe`; } exports.getCmdPath = getCmdPath; } @@ -1770,11 +1931,11 @@ var require_io = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -1790,7 +1951,7 @@ var require_io = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -2023,11 +2184,11 @@ var require_toolrunner = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -2043,14 +2204,14 @@ var require_toolrunner = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.argStringToArray = exports.ToolRunner = void 0; - var os3 = __importStar(__require("os")); + var os2 = __importStar(__require("os")); var events = __importStar(__require("events")); var child = __importStar(__require("child_process")); var path = __importStar(__require("path")); @@ -2105,12 +2266,12 @@ var require_toolrunner = __commonJS({ _processLineBuffer(data, strBuffer, onLine) { try { let s = strBuffer + data.toString(); - let n = s.indexOf(os3.EOL); + let n = s.indexOf(os2.EOL); while (n > -1) { const line = s.substring(0, n); onLine(line); - s = s.substring(n + os3.EOL.length); - n = s.indexOf(os3.EOL); + s = s.substring(n + os2.EOL.length); + n = s.indexOf(os2.EOL); } return s; } catch (err) { @@ -2256,13 +2417,22 @@ var require_toolrunner = __commonJS({ } return result; } + /** + * Exec a tool. + * Output will be streamed to the live console. + * Returns promise with return code + * + * @param tool path to tool to exec + * @param options optional exec options. See ExecOptions + * @returns number + */ exec() { return __awaiter(this, void 0, void 0, function* () { if (!ioUtil.isRooted(this.toolPath) && (this.toolPath.includes("/") || IS_WINDOWS && this.toolPath.includes("\\"))) { this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); } this.toolPath = yield io.which(this.toolPath, true); - return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve5, reject) => __awaiter(this, void 0, void 0, function* () { this._debug(`exec tool: ${this.toolPath}`); this._debug("arguments:"); for (const arg of this.args) { @@ -2270,7 +2440,7 @@ var require_toolrunner = __commonJS({ } const optionsNonNull = this._cloneExecOptions(this.options); if (!optionsNonNull.silent && optionsNonNull.outStream) { - optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os3.EOL); + optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os2.EOL); } const state = new ExecState(optionsNonNull, this.toolPath); state.on("debug", (message) => { @@ -2345,7 +2515,7 @@ var require_toolrunner = __commonJS({ if (error) { reject(error); } else { - resolve(exitCode); + resolve5(exitCode); } }); if (this.options.input) { @@ -2404,7 +2574,7 @@ var require_toolrunner = __commonJS({ return args; } exports.argStringToArray = argStringToArray; - var ExecState = class extends events.EventEmitter { + var ExecState = class _ExecState extends events.EventEmitter { constructor(options, toolPath) { super(); this.processClosed = false; @@ -2431,7 +2601,7 @@ var require_toolrunner = __commonJS({ if (this.processClosed) { this._setResult(); } else if (this.processExited) { - this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this); + this.timeout = timers_1.setTimeout(_ExecState.HandleTimeout, this.delay, this); } } _debug(message) { @@ -2503,11 +2673,11 @@ var require_exec = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -2523,7 +2693,7 @@ var require_exec = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -2532,7 +2702,7 @@ var require_exec = __commonJS({ exports.getExecOutput = exports.exec = void 0; var string_decoder_1 = __require("string_decoder"); var tr = __importStar(require_toolrunner()); - function exec(commandLine, args, options) { + function exec2(commandLine, args, options) { return __awaiter(this, void 0, void 0, function* () { const commandArgs = tr.argStringToArray(commandLine); if (commandArgs.length === 0) { @@ -2544,16 +2714,16 @@ var require_exec = __commonJS({ return runner.exec(); }); } - exports.exec = exec; + exports.exec = exec2; function getExecOutput(commandLine, args, options) { - var _a, _b; + var _a2, _b2; return __awaiter(this, void 0, void 0, function* () { let stdout = ""; let stderr = ""; const stdoutDecoder = new string_decoder_1.StringDecoder("utf8"); const stderrDecoder = new string_decoder_1.StringDecoder("utf8"); - const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout; - const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr; + const originalStdoutListener = (_a2 = options === null || options === void 0 ? void 0 : options.listeners) === null || _a2 === void 0 ? void 0 : _a2.stdout; + const originalStdErrListener = (_b2 = options === null || options === void 0 ? void 0 : options.listeners) === null || _b2 === void 0 ? void 0 : _b2.stderr; const stdErrListener = (data) => { stderr += stderrDecoder.write(data); if (originalStdErrListener) { @@ -2567,7 +2737,7 @@ var require_exec = __commonJS({ } }; const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener }); - const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners })); + const exitCode = yield exec2(commandLine, args, Object.assign(Object.assign({}, options), { listeners })); stdout += stdoutDecoder.end(); stderr += stderrDecoder.end(); return { @@ -2619,11 +2789,11 @@ var require_platform = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -2639,7 +2809,7 @@ var require_platform = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -2650,12 +2820,12 @@ var require_platform = __commonJS({ Object.defineProperty(exports, "__esModule", { value: true }); exports.getDetails = exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0; var os_1 = __importDefault(__require("os")); - var exec = __importStar(require_exec()); + var exec2 = __importStar(require_exec()); var getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () { - const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', void 0, { + const { stdout: version } = yield exec2.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', void 0, { silent: true }); - const { stdout: name } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"', void 0, { + const { stdout: name } = yield exec2.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"', void 0, { silent: true }); return { @@ -2664,19 +2834,19 @@ var require_platform = __commonJS({ }; }); var getMacOsInfo = () => __awaiter(void 0, void 0, void 0, function* () { - var _a, _b, _c, _d; - const { stdout } = yield exec.getExecOutput("sw_vers", void 0, { + var _a2, _b2, _c2, _d; + const { stdout } = yield exec2.getExecOutput("sw_vers", void 0, { silent: true }); - const version = (_b = (_a = stdout.match(/ProductVersion:\s*(.+)/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : ""; - const name = (_d = (_c = stdout.match(/ProductName:\s*(.+)/)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : ""; + const version = (_b2 = (_a2 = stdout.match(/ProductVersion:\s*(.+)/)) === null || _a2 === void 0 ? void 0 : _a2[1]) !== null && _b2 !== void 0 ? _b2 : ""; + const name = (_d = (_c2 = stdout.match(/ProductName:\s*(.+)/)) === null || _c2 === void 0 ? void 0 : _c2[1]) !== null && _d !== void 0 ? _d : ""; return { name, version }; }); var getLinuxInfo = () => __awaiter(void 0, void 0, void 0, function* () { - const { stdout } = yield exec.getExecOutput("lsb_release", ["-i", "-r", "-s"], { + const { stdout } = yield exec2.getExecOutput("lsb_release", ["-i", "-r", "-s"], { silent: true }); const [name, version] = stdout.trim().split("\n"); @@ -2743,11 +2913,11 @@ var require_core = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -2763,7 +2933,7 @@ var require_core = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -2773,7 +2943,7 @@ var require_core = __commonJS({ var command_1 = require_command(); var file_command_1 = require_file_command(); var utils_1 = require_utils(); - var os3 = __importStar(__require("os")); + var os2 = __importStar(__require("os")); var path = __importStar(__require("path")); var oidc_utils_1 = require_oidc_utils(); var ExitCode; @@ -2841,7 +3011,7 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); if (filePath) { return (0, file_command_1.issueFileCommand)("OUTPUT", (0, file_command_1.prepareKeyValueMessage)(name, value)); } - process.stdout.write(os3.EOL); + process.stdout.write(os2.EOL); (0, command_1.issueCommand)("set-output", { name }, (0, utils_1.toCommandValue)(value)); } exports.setOutput = setOutput; @@ -2875,7 +3045,7 @@ Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); } exports.notice = notice; function info(message) { - process.stdout.write(message + os3.EOL); + process.stdout.write(message + os2.EOL); } exports.info = info; function startGroup(name) { @@ -2948,8 +3118,11 @@ var require_context = __commonJS({ var fs_1 = __require("fs"); var os_1 = __require("os"); var Context = class { + /** + * Hydrate the context from the environment + */ constructor() { - var _a, _b, _c; + var _a2, _b2, _c2; this.payload = {}; if (process.env.GITHUB_EVENT_PATH) { if ((0, fs_1.existsSync)(process.env.GITHUB_EVENT_PATH)) { @@ -2969,9 +3142,9 @@ var require_context = __commonJS({ this.runAttempt = parseInt(process.env.GITHUB_RUN_ATTEMPT, 10); this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); - this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; - this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; - this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; + this.apiUrl = (_a2 = process.env.GITHUB_API_URL) !== null && _a2 !== void 0 ? _a2 : `https://api.github.com`; + this.serverUrl = (_b2 = process.env.GITHUB_SERVER_URL) !== null && _b2 !== void 0 ? _b2 : `https://github.com`; + this.graphqlUrl = (_c2 = process.env.GITHUB_GRAPHQL_URL) !== null && _c2 !== void 0 ? _c2 : `https://api.github.com/graphql`; } get issue() { const payload = this.payload; @@ -3033,11 +3206,11 @@ var require_utils2 = __commonJS({ }; var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); + return value instanceof P ? value : new P(function(resolve5) { + resolve5(value); }); } - return new (P || (P = Promise))(function(resolve, reject) { + return new (P || (P = Promise))(function(resolve5, reject) { function fulfilled(value) { try { step(generator.next(value)); @@ -3053,7 +3226,7 @@ var require_utils2 = __commonJS({ } } function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + result.done ? resolve5(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); @@ -3101,7 +3274,7 @@ var require_dist_node = __commonJS({ ""(exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); - function getUserAgent3() { + function getUserAgent2() { if (typeof navigator === "object" && "userAgent" in navigator) { return navigator.userAgent; } @@ -3110,7 +3283,7 @@ var require_dist_node = __commonJS({ } return ""; } - exports.getUserAgent = getUserAgent3; + exports.getUserAgent = getUserAgent2; } }); @@ -3280,24 +3453,24 @@ var require_dist_node2 = __commonJS({ var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export(dist_src_exports, { - endpoint: () => endpoint3 + endpoint: () => endpoint2 }); module.exports = __toCommonJS(dist_src_exports); - var import_universal_user_agent7 = require_dist_node(); - var VERSION11 = "9.0.6"; - var userAgent3 = `octokit-endpoint.js/${VERSION11} ${(0, import_universal_user_agent7.getUserAgent)()}`; - var DEFAULTS3 = { + var import_universal_user_agent5 = require_dist_node(); + var VERSION9 = "9.0.6"; + var userAgent2 = `octokit-endpoint.js/${VERSION9} ${(0, import_universal_user_agent5.getUserAgent)()}`; + var DEFAULTS2 = { method: "GET", baseUrl: "https://api.github.com", headers: { accept: "application/vnd.github.v3+json", - "user-agent": userAgent3 + "user-agent": userAgent2 }, mediaType: { format: "" } }; - function lowercaseKeys3(object) { + function lowercaseKeys2(object) { if (!object) { return {}; } @@ -3306,21 +3479,21 @@ var require_dist_node2 = __commonJS({ return newObj; }, {}); } - function isPlainObject5(value) { + function isPlainObject3(value) { if (typeof value !== "object" || value === null) return false; if (Object.prototype.toString.call(value) !== "[object Object]") return false; - const proto2 = Object.getPrototypeOf(value); - if (proto2 === null) + const proto = Object.getPrototypeOf(value); + if (proto === null) return true; - const Ctor = Object.prototype.hasOwnProperty.call(proto2, "constructor") && proto2.constructor; + const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor; return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value); } function mergeDeep3(defaults, options) { const result = Object.assign({}, defaults); Object.keys(options).forEach((key) => { - if (isPlainObject5(options[key])) { + if (isPlainObject3(options[key])) { if (!(key in defaults)) Object.assign(result, { [key]: options[key] }); else @@ -3331,7 +3504,7 @@ var require_dist_node2 = __commonJS({ }); return result; } - function removeUndefinedProperties3(obj) { + function removeUndefinedProperties2(obj) { for (const key in obj) { if (obj[key] === void 0) { delete obj[key]; @@ -3339,16 +3512,16 @@ var require_dist_node2 = __commonJS({ } return obj; } - function merge3(defaults, route, options) { + function merge2(defaults, route, options) { if (typeof route === "string") { let [method, url] = route.split(" "); options = Object.assign(url ? { method, url } : { url: method }, options); } else { options = Object.assign({}, route); } - options.headers = lowercaseKeys3(options.headers); - removeUndefinedProperties3(options); - removeUndefinedProperties3(options.headers); + options.headers = lowercaseKeys2(options.headers); + removeUndefinedProperties2(options); + removeUndefinedProperties2(options.headers); const mergedOptions = mergeDeep3(defaults || {}, options); if (options.url === "/graphql") { if (defaults && defaults.mediaType.previews?.length) { @@ -3360,7 +3533,7 @@ var require_dist_node2 = __commonJS({ } return mergedOptions; } - function addQueryParameters3(url, parameters) { + function addQueryParameters2(url, parameters) { const separator = /\?/.test(url) ? "&" : "?"; const names = Object.keys(parameters); if (names.length === 0) { @@ -3373,18 +3546,18 @@ var require_dist_node2 = __commonJS({ return `${name}=${encodeURIComponent(parameters[name])}`; }).join("&"); } - var urlVariableRegex3 = /\{[^{}}]+\}/g; - function removeNonChars3(variableName) { + var urlVariableRegex2 = /\{[^{}}]+\}/g; + function removeNonChars2(variableName) { return variableName.replace(/(?:^\W+)|(?:(? a.concat(b), []); + return matches.map(removeNonChars2).reduce((a, b) => a.concat(b), []); } - function omit3(object, keysToOmit) { + function omit2(object, keysToOmit) { const result = { __proto__: null }; for (const key of Object.keys(object)) { if (keysToOmit.indexOf(key) === -1) { @@ -3393,7 +3566,7 @@ var require_dist_node2 = __commonJS({ } return result; } - function encodeReserved3(str) { + function encodeReserved2(str) { return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) { if (!/%[0-9A-Fa-f]/.test(part)) { part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); @@ -3401,67 +3574,67 @@ var require_dist_node2 = __commonJS({ return part; }).join(""); } - function encodeUnreserved3(str) { + function encodeUnreserved2(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return "%" + c.charCodeAt(0).toString(16).toUpperCase(); }); } - function encodeValue3(operator, value, key) { - value = operator === "+" || operator === "#" ? encodeReserved3(value) : encodeUnreserved3(value); + function encodeValue2(operator, value, key) { + value = operator === "+" || operator === "#" ? encodeReserved2(value) : encodeUnreserved2(value); if (key) { - return encodeUnreserved3(key) + "=" + value; + return encodeUnreserved2(key) + "=" + value; } else { return value; } } - function isDefined3(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } - function isKeyOperator3(operator) { + function isKeyOperator2(operator) { return operator === ";" || operator === "&" || operator === "?"; } - function getValues3(context2, operator, key, modifier) { + function getValues2(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined3(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { value = value.substring(0, parseInt(modifier, 10)); } result.push( - encodeValue3(operator, value, isKeyOperator3(operator) ? key : "") + encodeValue2(operator, value, isKeyOperator2(operator) ? key : "") ); } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined3).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( - encodeValue3(operator, value2, isKeyOperator3(operator) ? key : "") + encodeValue2(operator, value2, isKeyOperator2(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined3(value[k])) { - result.push(encodeValue3(operator, value[k], k)); + if (isDefined2(value[k])) { + result.push(encodeValue2(operator, value[k], k)); } }); } } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined3).forEach(function(value2) { - tmp.push(encodeValue3(operator, value2)); + value.filter(isDefined2).forEach(function(value2) { + tmp.push(encodeValue2(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined3(value[k])) { - tmp.push(encodeUnreserved3(k)); - tmp.push(encodeValue3(operator, value[k].toString())); + if (isDefined2(value[k])) { + tmp.push(encodeUnreserved2(k)); + tmp.push(encodeValue2(operator, value[k].toString())); } }); } - if (isKeyOperator3(operator)) { - result.push(encodeUnreserved3(key) + "=" + tmp.join(",")); + if (isKeyOperator2(operator)) { + result.push(encodeUnreserved2(key) + "=" + tmp.join(",")); } else if (tmp.length !== 0) { result.push(tmp.join(",")); } @@ -3469,23 +3642,23 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined3(value)) { - result.push(encodeUnreserved3(key)); + if (isDefined2(value)) { + result.push(encodeUnreserved2(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { - result.push(encodeUnreserved3(key) + "="); + result.push(encodeUnreserved2(key) + "="); } else if (value === "") { result.push(""); } } return result; } - function parseUrl3(template) { + function parseUrl2(template) { return { - expand: expand3.bind(null, template) + expand: expand2.bind(null, template) }; } - function expand3(template, context2) { + function expand2(template, context2) { var operators = ["+", "#", ".", "/", ";", "?", "&"]; template = template.replace( /\{([^\{\}]+)\}|([^\{\}]+)/g, @@ -3499,7 +3672,7 @@ var require_dist_node2 = __commonJS({ } expression.split(/,/g).forEach(function(variable) { var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); - values.push(getValues3(context2, operator, tmp[1], tmp[2] || tmp[3])); + values.push(getValues2(context2, operator, tmp[1], tmp[2] || tmp[3])); }); if (operator && operator !== "+") { var separator = ","; @@ -3513,7 +3686,7 @@ var require_dist_node2 = __commonJS({ return values.join(","); } } else { - return encodeReserved3(literal); + return encodeReserved2(literal); } } ); @@ -3523,12 +3696,12 @@ var require_dist_node2 = __commonJS({ return template.replace(/\/$/, ""); } } - function parse3(options) { + function parse2(options) { let method = options.method.toUpperCase(); let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); let headers = Object.assign({}, options.headers); let body; - let parameters = omit3(options, [ + let parameters = omit2(options, [ "method", "baseUrl", "url", @@ -3536,18 +3709,18 @@ var require_dist_node2 = __commonJS({ "request", "mediaType" ]); - const urlVariableNames = extractUrlVariableNames3(url); - url = parseUrl3(url).expand(parameters); + const urlVariableNames = extractUrlVariableNames2(url); + url = parseUrl2(url).expand(parameters); if (!/^http/.test(url)) { url = options.baseUrl + url; } const omittedParameters = Object.keys(options).filter((option) => urlVariableNames.includes(option)).concat("baseUrl"); - const remainingParameters = omit3(parameters, omittedParameters); + const remainingParameters = omit2(parameters, omittedParameters); const isBinaryRequest = /application\/octet-stream/i.test(headers.accept); if (!isBinaryRequest) { if (options.mediaType.format) { headers.accept = headers.accept.split(/,/).map( - (format) => format.replace( + (format3) => format3.replace( /application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}` ) @@ -3557,14 +3730,14 @@ var require_dist_node2 = __commonJS({ if (options.mediaType.previews?.length) { const previewsFromAcceptHeader = headers.accept.match(/(? { - const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; - return `application/vnd.github.${preview}-preview${format}`; + const format3 = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; + return `application/vnd.github.${preview}-preview${format3}`; }).join(","); } } } if (["GET", "HEAD"].includes(method)) { - url = addQueryParameters3(url, remainingParameters); + url = addQueryParameters2(url, remainingParameters); } else { if ("data" in remainingParameters) { body = remainingParameters.data; @@ -3586,20 +3759,20 @@ var require_dist_node2 = __commonJS({ options.request ? { request: options.request } : null ); } - function endpointWithDefaults3(defaults, route, options) { - return parse3(merge3(defaults, route, options)); + function endpointWithDefaults2(defaults, route, options) { + return parse2(merge2(defaults, route, options)); } - function withDefaults6(oldDefaults, newDefaults) { - const DEFAULTS22 = merge3(oldDefaults, newDefaults); - const endpoint22 = endpointWithDefaults3.bind(null, DEFAULTS22); + function withDefaults4(oldDefaults, newDefaults) { + const DEFAULTS22 = merge2(oldDefaults, newDefaults); + const endpoint22 = endpointWithDefaults2.bind(null, DEFAULTS22); return Object.assign(endpoint22, { DEFAULTS: DEFAULTS22, - defaults: withDefaults6.bind(null, DEFAULTS22), - merge: merge3.bind(null, DEFAULTS22), - parse: parse3 + defaults: withDefaults4.bind(null, DEFAULTS22), + merge: merge2.bind(null, DEFAULTS22), + parse: parse2 }); } - var endpoint3 = withDefaults6(null, DEFAULTS3); + var endpoint2 = withDefaults4(null, DEFAULTS2); } }); @@ -3720,20 +3893,24 @@ var require_dist_node4 = __commonJS({ return to; }; var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export(dist_src_exports, { - RequestError: () => RequestError3 + RequestError: () => RequestError2 }); module.exports = __toCommonJS(dist_src_exports); var import_deprecation = require_dist_node3(); var import_once = __toESM2(require_once()); var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation)); var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation)); - var RequestError3 = class extends Error { + var RequestError2 = class extends Error { constructor(message, statusCode, options) { super(message); if (Error.captureStackTrace) { @@ -3808,39 +3985,39 @@ var require_dist_node5 = __commonJS({ var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var dist_src_exports = {}; __export(dist_src_exports, { - request: () => request3 + request: () => request2 }); module.exports = __toCommonJS(dist_src_exports); - var import_endpoint3 = require_dist_node2(); - var import_universal_user_agent7 = require_dist_node(); - var VERSION11 = "8.4.1"; - function isPlainObject5(value) { + var import_endpoint2 = require_dist_node2(); + var import_universal_user_agent5 = require_dist_node(); + var VERSION9 = "8.4.1"; + function isPlainObject3(value) { if (typeof value !== "object" || value === null) return false; if (Object.prototype.toString.call(value) !== "[object Object]") return false; - const proto2 = Object.getPrototypeOf(value); - if (proto2 === null) + const proto = Object.getPrototypeOf(value); + if (proto === null) return true; - const Ctor = Object.prototype.hasOwnProperty.call(proto2, "constructor") && proto2.constructor; + const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor; return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value); } - var import_request_error3 = require_dist_node4(); + var import_request_error2 = require_dist_node4(); function getBufferResponse(response) { return response.arrayBuffer(); } - function fetchWrapper3(requestOptions) { - var _a, _b, _c, _d; + function fetchWrapper2(requestOptions) { + var _a2, _b2, _c2, _d; const log = requestOptions.request && requestOptions.request.log ? requestOptions.request.log : console; - const parseSuccessResponseBody = ((_a = requestOptions.request) == null ? void 0 : _a.parseSuccessResponseBody) !== false; - if (isPlainObject5(requestOptions.body) || Array.isArray(requestOptions.body)) { + const parseSuccessResponseBody = ((_a2 = requestOptions.request) == null ? void 0 : _a2.parseSuccessResponseBody) !== false; + if (isPlainObject3(requestOptions.body) || Array.isArray(requestOptions.body)) { requestOptions.body = JSON.stringify(requestOptions.body); } let headers = {}; let status; let url; let { fetch: fetch2 } = globalThis; - if ((_b = requestOptions.request) == null ? void 0 : _b.fetch) { + if ((_b2 = requestOptions.request) == null ? void 0 : _b2.fetch) { fetch2 = requestOptions.request.fetch; } if (!fetch2) { @@ -3851,9 +4028,11 @@ var require_dist_node5 = __commonJS({ return fetch2(requestOptions.url, { method: requestOptions.method, body: requestOptions.body, - redirect: (_c = requestOptions.request) == null ? void 0 : _c.redirect, + redirect: (_c2 = requestOptions.request) == null ? void 0 : _c2.redirect, headers: requestOptions.headers, signal: (_d = requestOptions.request) == null ? void 0 : _d.signal, + // duplex must be set if request.body is ReadableStream or Async Iterables. + // See https://fetch.spec.whatwg.org/#dom-requestinit-duplex. ...requestOptions.body && { duplex: "half" } }).then(async (response) => { url = response.url; @@ -3875,7 +4054,7 @@ var require_dist_node5 = __commonJS({ if (status < 400) { return; } - throw new import_request_error3.RequestError(response.statusText, status, { + throw new import_request_error2.RequestError(response.statusText, status, { response: { url, status, @@ -3886,19 +4065,19 @@ var require_dist_node5 = __commonJS({ }); } if (status === 304) { - throw new import_request_error3.RequestError("Not modified", status, { + throw new import_request_error2.RequestError("Not modified", status, { response: { url, status, headers, - data: await getResponseData3(response) + data: await getResponseData2(response) }, request: requestOptions }); } if (status >= 400) { - const data = await getResponseData3(response); - const error = new import_request_error3.RequestError(toErrorMessage3(data), status, { + const data = await getResponseData2(response); + const error = new import_request_error2.RequestError(toErrorMessage2(data), status, { response: { url, status, @@ -3909,7 +4088,7 @@ var require_dist_node5 = __commonJS({ }); throw error; } - return parseSuccessResponseBody ? await getResponseData3(response) : response.body; + return parseSuccessResponseBody ? await getResponseData2(response) : response.body; }).then((data) => { return { status, @@ -3918,7 +4097,7 @@ var require_dist_node5 = __commonJS({ data }; }).catch((error) => { - if (error instanceof import_request_error3.RequestError) + if (error instanceof import_request_error2.RequestError) throw error; else if (error.name === "AbortError") throw error; @@ -3930,12 +4109,12 @@ var require_dist_node5 = __commonJS({ message = error.cause; } } - throw new import_request_error3.RequestError(message, 500, { + throw new import_request_error2.RequestError(message, 500, { request: requestOptions }); }); } - async function getResponseData3(response) { + async function getResponseData2(response) { const contentType = response.headers.get("content-type"); if (/application\/json/.test(contentType)) { return response.json().catch(() => response.text()).catch(() => ""); @@ -3945,7 +4124,7 @@ var require_dist_node5 = __commonJS({ } return getBufferResponse(response); } - function toErrorMessage3(data) { + function toErrorMessage2(data) { if (typeof data === "string") return data; let suffix; @@ -3962,32 +4141,32 @@ var require_dist_node5 = __commonJS({ } return `Unknown error: ${JSON.stringify(data)}`; } - function withDefaults6(oldEndpoint, newDefaults) { - const endpoint22 = oldEndpoint.defaults(newDefaults); + function withDefaults4(oldEndpoint, newDefaults) { + const endpoint2 = oldEndpoint.defaults(newDefaults); const newApi = function(route, parameters) { - const endpointOptions = endpoint22.merge(route, parameters); + const endpointOptions = endpoint2.merge(route, parameters); if (!endpointOptions.request || !endpointOptions.request.hook) { - return fetchWrapper3(endpoint22.parse(endpointOptions)); + return fetchWrapper2(endpoint2.parse(endpointOptions)); } const request22 = (route2, parameters2) => { - return fetchWrapper3( - endpoint22.parse(endpoint22.merge(route2, parameters2)) + return fetchWrapper2( + endpoint2.parse(endpoint2.merge(route2, parameters2)) ); }; Object.assign(request22, { - endpoint: endpoint22, - defaults: withDefaults6.bind(null, endpoint22) + endpoint: endpoint2, + defaults: withDefaults4.bind(null, endpoint2) }); return endpointOptions.request.hook(request22, endpointOptions); }; return Object.assign(newApi, { - endpoint: endpoint22, - defaults: withDefaults6.bind(null, endpoint22) + endpoint: endpoint2, + defaults: withDefaults4.bind(null, endpoint2) }); } - var request3 = withDefaults6(import_endpoint3.endpoint, { + var request2 = withDefaults4(import_endpoint2.endpoint, { headers: { - "user-agent": `octokit-request.js/${VERSION11} ${(0, import_universal_user_agent7.getUserAgent)()}` + "user-agent": `octokit-request.js/${VERSION9} ${(0, import_universal_user_agent5.getUserAgent)()}` } }); } @@ -4021,19 +4200,19 @@ var require_dist_node6 = __commonJS({ withCustomRequest: () => withCustomRequest2 }); module.exports = __toCommonJS(index_exports); - var import_request3 = require_dist_node5(); - var import_universal_user_agent7 = require_dist_node(); - var VERSION11 = "7.1.1"; + var import_request32 = require_dist_node5(); + var import_universal_user_agent5 = require_dist_node(); + var VERSION9 = "7.1.1"; var import_request22 = require_dist_node5(); - var import_request4 = require_dist_node5(); + var import_request5 = require_dist_node5(); function _buildMessageForResponseErrors2(data) { return `Request failed due to following response errors: ` + data.errors.map((e) => ` - ${e.message}`).join("\n"); } var GraphqlResponseError2 = class extends Error { - constructor(request22, headers, response) { + constructor(request2, headers, response) { super(_buildMessageForResponseErrors2(response)); - this.request = request22; + this.request = request2; this.headers = headers; this.response = response; this.name = "GraphqlResponseError"; @@ -4055,7 +4234,7 @@ var require_dist_node6 = __commonJS({ ]; var FORBIDDEN_VARIABLE_OPTIONS2 = ["query", "method", "url"]; var GHES_V3_SUFFIX_REGEX2 = /\/api\/v3\/?$/; - function graphql3(request22, query2, options) { + function graphql3(request2, query2, options) { if (options) { if (typeof query2 === "string" && "query" in options) { return Promise.reject( @@ -4086,11 +4265,11 @@ var require_dist_node6 = __commonJS({ result.variables[key] = parsedOptions[key]; return result; }, {}); - const baseUrl = parsedOptions.baseUrl || request22.endpoint.DEFAULTS.baseUrl; + const baseUrl = parsedOptions.baseUrl || request2.endpoint.DEFAULTS.baseUrl; if (GHES_V3_SUFFIX_REGEX2.test(baseUrl)) { requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX2, "/api/graphql"); } - return request22(requestOptions).then((response) => { + return request2(requestOptions).then((response) => { if (response.data.errors) { const headers = {}; for (const key of Object.keys(response.headers)) { @@ -4105,25 +4284,25 @@ var require_dist_node6 = __commonJS({ return response.data.data; }); } - function withDefaults6(request22, newDefaults) { - const newRequest = request22.defaults(newDefaults); + function withDefaults4(request2, newDefaults) { + const newRequest = request2.defaults(newDefaults); const newApi = (query2, options) => { return graphql3(newRequest, query2, options); }; return Object.assign(newApi, { - defaults: withDefaults6.bind(null, newRequest), + defaults: withDefaults4.bind(null, newRequest), endpoint: newRequest.endpoint }); } - var graphql22 = withDefaults6(import_request3.request, { + var graphql22 = withDefaults4(import_request32.request, { headers: { - "user-agent": `octokit-graphql.js/${VERSION11} ${(0, import_universal_user_agent7.getUserAgent)()}` + "user-agent": `octokit-graphql.js/${VERSION9} ${(0, import_universal_user_agent5.getUserAgent)()}` }, method: "POST", url: "/graphql" }); function withCustomRequest2(customRequest) { - return withDefaults6(customRequest, { + return withDefaults4(customRequest, { method: "POST", url: "/graphql" }); @@ -4177,13 +4356,13 @@ var require_dist_node7 = __commonJS({ } return `token ${token}`; } - async function hook2(token, request3, route, parameters) { - const endpoint3 = request3.endpoint.merge( + async function hook2(token, request2, route, parameters) { + const endpoint2 = request2.endpoint.merge( route, parameters ); - endpoint3.headers.authorization = withAuthorizationPrefix2(token); - return request3(endpoint3); + endpoint2.headers.authorization = withAuthorizationPrefix2(token); + return request2(endpoint2); } var createTokenAuth3 = function createTokenAuth22(token) { if (!token) { @@ -4228,20 +4407,35 @@ var require_dist_node8 = __commonJS({ Octokit: () => Octokit3 }); module.exports = __toCommonJS(index_exports); - var import_universal_user_agent7 = require_dist_node(); + var import_universal_user_agent5 = require_dist_node(); var import_before_after_hook2 = require_before_after_hook(); - var import_request3 = require_dist_node5(); + var import_request5 = require_dist_node5(); var import_graphql2 = require_dist_node6(); var import_auth_token2 = require_dist_node7(); - var VERSION11 = "5.2.1"; - var noop2 = () => { + var VERSION9 = "5.2.2"; + var noop3 = () => { }; var consoleWarn2 = console.warn.bind(console); var consoleError2 = console.error.bind(console); - var userAgentTrail2 = `octokit-core.js/${VERSION11} ${(0, import_universal_user_agent7.getUserAgent)()}`; + function createLogger2(logger = {}) { + if (typeof logger.debug !== "function") { + logger.debug = noop3; + } + if (typeof logger.info !== "function") { + logger.info = noop3; + } + if (typeof logger.warn !== "function") { + logger.warn = consoleWarn2; + } + if (typeof logger.error !== "function") { + logger.error = consoleError2; + } + return logger; + } + var userAgentTrail2 = `octokit-core.js/${VERSION9} ${(0, import_universal_user_agent5.getUserAgent)()}`; var Octokit3 = class { static { - this.VERSION = VERSION11; + this.VERSION = VERSION9; } static defaults(defaults) { const OctokitWithDefaults = class extends this { @@ -4268,6 +4462,12 @@ var require_dist_node8 = __commonJS({ static { this.plugins = []; } + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ static plugin(...newPlugins) { const currentPlugins = this.plugins; const NewOctokit = class extends this { @@ -4282,9 +4482,10 @@ var require_dist_node8 = __commonJS({ constructor(options = {}) { const hook2 = new import_before_after_hook2.Collection(); const requestDefaults = { - baseUrl: import_request3.request.endpoint.DEFAULTS.baseUrl, + baseUrl: import_request5.request.endpoint.DEFAULTS.baseUrl, headers: {}, request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type hook: hook2.bind(null, "request") }), mediaType: { @@ -4302,17 +4503,9 @@ var require_dist_node8 = __commonJS({ if (options.timeZone) { requestDefaults.headers["time-zone"] = options.timeZone; } - this.request = import_request3.request.defaults(requestDefaults); + this.request = import_request5.request.defaults(requestDefaults); this.graphql = (0, import_graphql2.withCustomRequest)(this.request).defaults(requestDefaults); - this.log = Object.assign( - { - debug: noop2, - info: noop2, - warn: consoleWarn2, - error: consoleError2 - }, - options.log - ); + this.log = createLogger2(options.log); this.hook = hook2; if (!options.authStrategy) { if (!options.auth) { @@ -4331,6 +4524,11 @@ var require_dist_node8 = __commonJS({ { request: this.request, log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. octokit: this, octokitOptions: otherOptions }, @@ -4376,7 +4574,7 @@ var require_dist_node9 = __commonJS({ restEndpointMethods: () => restEndpointMethods2 }); module.exports = __toCommonJS(dist_src_exports); - var VERSION11 = "10.4.1"; + var VERSION9 = "10.4.1"; var Endpoints2 = { actions: { addCustomLabelsToSelfHostedRunnerForOrg: [ @@ -6368,8 +6566,8 @@ var require_dist_node9 = __commonJS({ var endpoints_default2 = Endpoints2; var endpointMethodsMap2 = /* @__PURE__ */ new Map(); for (const [scope, endpoints] of Object.entries(endpoints_default2)) { - for (const [methodName, endpoint3] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint3; + for (const [methodName, endpoint2] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint2; const [method, url] = route.split(/ /); const endpointDefaults = Object.assign( { @@ -6396,6 +6594,7 @@ var require_dist_node9 = __commonJS({ getOwnPropertyDescriptor(target, methodName) { return { value: this.get(target, methodName), + // ensures method is in the cache configurable: true, writable: true, enumerable: true @@ -6492,7 +6691,7 @@ var require_dist_node9 = __commonJS({ rest: api }; } - restEndpointMethods2.VERSION = VERSION11; + restEndpointMethods2.VERSION = VERSION9; function legacyRestEndpointMethods2(octokit) { const api = endpointsToMethods2(octokit); return { @@ -6500,7 +6699,7 @@ var require_dist_node9 = __commonJS({ rest: api }; } - legacyRestEndpointMethods2.VERSION = VERSION11; + legacyRestEndpointMethods2.VERSION = VERSION9; } }); @@ -6533,7 +6732,7 @@ var require_dist_node10 = __commonJS({ paginatingEndpoints: () => paginatingEndpoints }); module.exports = __toCommonJS(dist_src_exports); - var VERSION11 = "9.2.2"; + var VERSION9 = "9.2.2"; function normalizePaginatedListResponse2(response) { if (!response.data) { return { @@ -6879,7 +7078,7 @@ var require_dist_node10 = __commonJS({ }) }; } - paginateRest2.VERSION = VERSION11; + paginateRest2.VERSION = VERSION9; } }); @@ -7001,17 +7200,17 @@ var require_github = __commonJS({ var require_tmp = __commonJS({ ""(exports, module) { var fs = __require("fs"); - var os3 = __require("os"); + var os2 = __require("os"); var path = __require("path"); var crypto = __require("crypto"); - var _c = { fs: fs.constants, os: os3.constants }; + var _c2 = { fs: fs.constants, os: os2.constants }; var RANDOM_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; var TEMPLATE_PATTERN = /XXXXXX/; var DEFAULT_TRIES = 3; - var CREATE_FLAGS = (_c.O_CREAT || _c.fs.O_CREAT) | (_c.O_EXCL || _c.fs.O_EXCL) | (_c.O_RDWR || _c.fs.O_RDWR); - var IS_WIN32 = os3.platform() === "win32"; - var EBADF = _c.EBADF || _c.os.errno.EBADF; - var ENOENT = _c.ENOENT || _c.os.errno.ENOENT; + var CREATE_FLAGS = (_c2.O_CREAT || _c2.fs.O_CREAT) | (_c2.O_EXCL || _c2.fs.O_EXCL) | (_c2.O_RDWR || _c2.fs.O_RDWR); + var IS_WIN32 = os2.platform() === "win32"; + var EBADF = _c2.EBADF || _c2.os.errno.EBADF; + var ENOENT = _c2.ENOENT || _c2.os.errno.ENOENT; var DIR_MODE = 448; var FILE_MODE = 384; var EXIT = "exit"; @@ -7026,34 +7225,33 @@ var require_tmp = __commonJS({ } function tmpName(options, callback) { const args = _parseArguments(options, callback), opts = args[0], cb = args[1]; - try { - _assertAndSanitizeOptions(opts); - } catch (err) { - return cb(err); - } - let tries = opts.tries; - (function _getUniqueName() { - try { - const name = _generateTmpName(opts); - fs.stat(name, function(err) { - if (!err) { - if (tries-- > 0) - return _getUniqueName(); - return cb(new Error("Could not get a unique tmp filename, max tries reached " + name)); - } - cb(null, name); - }); - } catch (err) { - cb(err); - } - })(); + _assertAndSanitizeOptions(opts, function(err, sanitizedOptions) { + if (err) + return cb(err); + let tries = sanitizedOptions.tries; + (function _getUniqueName() { + try { + const name = _generateTmpName(sanitizedOptions); + fs.stat(name, function(err2) { + if (!err2) { + if (tries-- > 0) + return _getUniqueName(); + return cb(new Error("Could not get a unique tmp filename, max tries reached " + name)); + } + cb(null, name); + }); + } catch (err2) { + cb(err2); + } + })(); + }); } function tmpNameSync(options) { const args = _parseArguments(options), opts = args[0]; - _assertAndSanitizeOptions(opts); - let tries = opts.tries; + const sanitizedOptions = _assertAndSanitizeOptionsSync(opts); + let tries = sanitizedOptions.tries; do { - const name = _generateTmpName(opts); + const name = _generateTmpName(sanitizedOptions); try { fs.statSync(name); } catch (e) { @@ -7085,7 +7283,7 @@ var require_tmp = __commonJS({ const args = _parseArguments(options), opts = args[0]; const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor; const name = tmpNameSync(opts); - var fd = fs.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE); + let fd = fs.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE); if (opts.discardDescriptor) { fs.closeSync(fd); fd = void 0; @@ -7202,14 +7400,11 @@ var require_tmp = __commonJS({ } catch (e) { rnd = crypto.pseudoRandomBytes(howMany); } - for (var i = 0; i < howMany; i++) { + for (let i = 0; i < howMany; i++) { value.push(RANDOM_CHARS[rnd[i] % RANDOM_CHARS.length]); } return value.join(""); } - function _isBlank(s) { - return s === null || _isUndefined(s) || !s.trim(); - } function _isUndefined(obj) { return typeof obj === "undefined"; } @@ -7226,12 +7421,38 @@ var require_tmp = __commonJS({ } return [actualOptions, callback]; } + function _resolvePath(name, tmpDir, cb) { + const pathToResolve = path.isAbsolute(name) ? name : path.join(tmpDir, name); + fs.stat(pathToResolve, function(err) { + if (err) { + fs.realpath(path.dirname(pathToResolve), function(err2, parentDir) { + if (err2) + return cb(err2); + cb(null, path.join(parentDir, path.basename(pathToResolve))); + }); + } else { + fs.realpath(pathToResolve, cb); + } + }); + } + function _resolvePathSync(name, tmpDir) { + const pathToResolve = path.isAbsolute(name) ? name : path.join(tmpDir, name); + try { + fs.statSync(pathToResolve); + return fs.realpathSync(pathToResolve); + } catch (_err) { + const parentDir = fs.realpathSync(path.dirname(pathToResolve)); + return path.join(parentDir, path.basename(pathToResolve)); + } + } function _generateTmpName(opts) { const tmpDir = opts.tmpdir; - if (!_isUndefined(opts.name)) + if (!_isUndefined(opts.name)) { return path.join(tmpDir, opts.dir, opts.name); - if (!_isUndefined(opts.template)) + } + if (!_isUndefined(opts.template)) { return path.join(tmpDir, opts.dir, opts.template).replace(TEMPLATE_PATTERN, _randomChars(6)); + } const name = [ opts.prefix ? opts.prefix : "tmp", "-", @@ -7242,54 +7463,82 @@ var require_tmp = __commonJS({ ].join(""); return path.join(tmpDir, opts.dir, name); } - function _assertAndSanitizeOptions(options) { - options.tmpdir = _getTmpDir(options); - const tmpDir = options.tmpdir; - if (!_isUndefined(options.name)) - _assertIsRelative(options.name, "name", tmpDir); - if (!_isUndefined(options.dir)) - _assertIsRelative(options.dir, "dir", tmpDir); - if (!_isUndefined(options.template)) { - _assertIsRelative(options.template, "template", tmpDir); - if (!options.template.match(TEMPLATE_PATTERN)) - throw new Error(`Invalid template, found "${options.template}".`); - } - if (!_isUndefined(options.tries) && isNaN(options.tries) || options.tries < 0) + function _assertOptionsBase(options) { + if (!_isUndefined(options.name)) { + const name = options.name; + if (path.isAbsolute(name)) + throw new Error(`name option must not contain an absolute path, found "${name}".`); + const basename2 = path.basename(name); + if (basename2 === ".." || basename2 === "." || basename2 !== name) + throw new Error(`name option must not contain a path, found "${name}".`); + } + if (!_isUndefined(options.template) && !options.template.match(TEMPLATE_PATTERN)) { + throw new Error(`Invalid template, found "${options.template}".`); + } + if (!_isUndefined(options.tries) && isNaN(options.tries) || options.tries < 0) { throw new Error(`Invalid tries, found "${options.tries}".`); + } options.tries = _isUndefined(options.name) ? options.tries || DEFAULT_TRIES : 1; options.keep = !!options.keep; options.detachDescriptor = !!options.detachDescriptor; options.discardDescriptor = !!options.discardDescriptor; options.unsafeCleanup = !!options.unsafeCleanup; - options.dir = _isUndefined(options.dir) ? "" : path.relative(tmpDir, _resolvePath(options.dir, tmpDir)); - options.template = _isUndefined(options.template) ? void 0 : path.relative(tmpDir, _resolvePath(options.template, tmpDir)); - options.template = _isBlank(options.template) ? void 0 : path.relative(options.dir, options.template); - options.name = _isUndefined(options.name) ? void 0 : options.name; options.prefix = _isUndefined(options.prefix) ? "" : options.prefix; options.postfix = _isUndefined(options.postfix) ? "" : options.postfix; } - function _resolvePath(name, tmpDir) { - if (name.startsWith(tmpDir)) { - return path.resolve(name); - } else { - return path.resolve(path.join(tmpDir, name)); + function _getRelativePath(option, name, tmpDir, cb) { + if (_isUndefined(name)) + return cb(null); + _resolvePath(name, tmpDir, function(err, resolvedPath) { + if (err) + return cb(err); + const relativePath = path.relative(tmpDir, resolvedPath); + if (!resolvedPath.startsWith(tmpDir)) { + return cb(new Error(`${option} option must be relative to "${tmpDir}", found "${relativePath}".`)); + } + cb(null, relativePath); + }); + } + function _getRelativePathSync(option, name, tmpDir) { + if (_isUndefined(name)) + return; + const resolvedPath = _resolvePathSync(name, tmpDir); + const relativePath = path.relative(tmpDir, resolvedPath); + if (!resolvedPath.startsWith(tmpDir)) { + throw new Error(`${option} option must be relative to "${tmpDir}", found "${relativePath}".`); } + return relativePath; } - function _assertIsRelative(name, option, tmpDir) { - if (option === "name") { - if (path.isAbsolute(name)) - throw new Error(`${option} option must not contain an absolute path, found "${name}".`); - let basename = path.basename(name); - if (basename === ".." || basename === "." || basename !== name) - throw new Error(`${option} option must not contain a path, found "${name}".`); - } else { - if (path.isAbsolute(name) && !name.startsWith(tmpDir)) { - throw new Error(`${option} option must be relative to "${tmpDir}", found "${name}".`); + function _assertAndSanitizeOptions(options, cb) { + _getTmpDir(options, function(err, tmpDir) { + if (err) + return cb(err); + options.tmpdir = tmpDir; + try { + _assertOptionsBase(options, tmpDir); + } catch (err2) { + return cb(err2); } - let resolvedPath = _resolvePath(name, tmpDir); - if (!resolvedPath.startsWith(tmpDir)) - throw new Error(`${option} option must be relative to "${tmpDir}", found "${resolvedPath}".`); - } + _getRelativePath("dir", options.dir, tmpDir, function(err2, dir2) { + if (err2) + return cb(err2); + options.dir = _isUndefined(dir2) ? "" : dir2; + _getRelativePath("template", options.template, tmpDir, function(err3, template) { + if (err3) + return cb(err3); + options.template = template; + cb(null, options); + }); + }); + }); + } + function _assertAndSanitizeOptionsSync(options) { + const tmpDir = options.tmpdir = _getTmpDirSync(options); + _assertOptionsBase(options, tmpDir); + const dir2 = _getRelativePathSync("dir", options.dir, tmpDir); + options.dir = _isUndefined(dir2) ? "" : dir2; + options.template = _getRelativePathSync("template", options.template, tmpDir); + return options; } function _isEBADF(error) { return _isExpectedError(error, -EBADF, "EBADF"); @@ -7303,15 +7552,18 @@ var require_tmp = __commonJS({ function setGracefulCleanup() { _gracefulCleanup = true; } - function _getTmpDir(options) { - return path.resolve(options && options.tmpdir || os3.tmpdir()); + function _getTmpDir(options, cb) { + return fs.realpath(options && options.tmpdir || os2.tmpdir(), cb); + } + function _getTmpDirSync(options) { + return fs.realpathSync(options && options.tmpdir || os2.tmpdir()); } process.addListener(EXIT, _garbageCollector); Object.defineProperty(module.exports, "tmpdir", { enumerable: true, configurable: false, get: function() { - return _getTmpDir(); + return _getTmpDirSync(); } }); module.exports.dir = dir; @@ -7324,13 +7576,47 @@ var require_tmp = __commonJS({ } }); +// +var require_emoji_regex = __commonJS({ + ""(exports, module) { + module.exports = () => { + return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g; + }; + } +}); + +// +var require_get_caller_file = __commonJS({ + ""(exports, module) { + "use strict"; + module.exports = function getCallerFile2(position) { + if (position === void 0) { + position = 2; + } + if (position >= Error.stackTraceLimit) { + throw new TypeError("getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: `" + position + "` and Error.stackTraceLimit was: `" + Error.stackTraceLimit + "`"); + } + var oldPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = function(_, stack2) { + return stack2; + }; + var stack = new Error().stack; + Error.prepareStackTrace = oldPrepareStackTrace; + if (stack !== null && typeof stack === "object") { + return stack[position] ? stack[position].getFileName() : void 0; + } + }; + } +}); + // var require_constants = __commonJS({ ""(exports, module) { "use strict"; var SEMVER_SPEC_VERSION = "2.0.0"; var MAX_LENGTH = 256; - var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */ + 9007199254740991; var MAX_SAFE_COMPONENT_LENGTH = 16; var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6; var RELEASE_TYPES = [ @@ -7478,6 +7764,9 @@ var require_identifiers = __commonJS({ "use strict"; var numeric = /^[0-9]+$/; var compareIdentifiers = (a, b) => { + if (typeof a === "number" && typeof b === "number") { + return a === b ? 0 : a < b ? -1 : 1; + } const anum = numeric.test(a); const bnum = numeric.test(b); if (anum && bnum) { @@ -7503,10 +7792,10 @@ var require_semver = __commonJS({ var { safeRe: re, t } = require_re(); var parseOptions = require_parse_options(); var { compareIdentifiers } = require_identifiers(); - var SemVer = class { + var SemVer = class _SemVer { constructor(version, options) { options = parseOptions(options); - if (version instanceof SemVer) { + if (version instanceof _SemVer) { if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) { return version; } else { @@ -7569,11 +7858,11 @@ var require_semver = __commonJS({ } compare(other) { debug("SemVer.compare", this.version, this.options, other); - if (!(other instanceof SemVer)) { + if (!(other instanceof _SemVer)) { if (typeof other === "string" && other === this.version) { return 0; } - other = new SemVer(other, this.options); + other = new _SemVer(other, this.options); } if (other.version === this.version) { return 0; @@ -7581,14 +7870,32 @@ var require_semver = __commonJS({ return this.compareMain(other) || this.comparePre(other); } compareMain(other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); + if (!(other instanceof _SemVer)) { + other = new _SemVer(other, this.options); + } + if (this.major < other.major) { + return -1; + } + if (this.major > other.major) { + return 1; + } + if (this.minor < other.minor) { + return -1; + } + if (this.minor > other.minor) { + return 1; + } + if (this.patch < other.patch) { + return -1; + } + if (this.patch > other.patch) { + return 1; } - return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch); + return 0; } comparePre(other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); + if (!(other instanceof _SemVer)) { + other = new _SemVer(other, this.options); } if (this.prerelease.length && !other.prerelease.length) { return -1; @@ -7616,8 +7923,8 @@ var require_semver = __commonJS({ } while (++i); } compareBuild(other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); + if (!(other instanceof _SemVer)) { + other = new _SemVer(other, this.options); } let i = 0; do { @@ -7637,6 +7944,8 @@ var require_semver = __commonJS({ } } while (++i); } + // preminor will bump the version up to the next minor release, and immediately + // down to pre-release. premajor and prepatch work the same way. inc(release, identifier, identifierBase) { if (release.startsWith("pre")) { if (!identifier && identifierBase === false) { @@ -7754,7 +8063,7 @@ var require_parse = __commonJS({ ""(exports, module) { "use strict"; var SemVer = require_semver(); - var parse3 = (version, options, throwErrors = false) => { + var parse2 = (version, options, throwErrors = false) => { if (version instanceof SemVer) { return version; } @@ -7767,7 +8076,7 @@ var require_parse = __commonJS({ throw er; } }; - module.exports = parse3; + module.exports = parse2; } }); @@ -7775,9 +8084,9 @@ var require_parse = __commonJS({ var require_valid = __commonJS({ ""(exports, module) { "use strict"; - var parse3 = require_parse(); + var parse2 = require_parse(); var valid = (version, options) => { - const v = parse3(version, options); + const v = parse2(version, options); return v ? v.version : null; }; module.exports = valid; @@ -7788,9 +8097,9 @@ var require_valid = __commonJS({ var require_clean = __commonJS({ ""(exports, module) { "use strict"; - var parse3 = require_parse(); + var parse2 = require_parse(); var clean = (version, options) => { - const s = parse3(version.trim().replace(/^[=v]+/, ""), options); + const s = parse2(version.trim().replace(/^[=v]+/, ""), options); return s ? s.version : null; }; module.exports = clean; @@ -7825,10 +8134,10 @@ var require_inc = __commonJS({ var require_diff = __commonJS({ ""(exports, module) { "use strict"; - var parse3 = require_parse(); + var parse2 = require_parse(); var diff = (version1, version2) => { - const v1 = parse3(version1, null, true); - const v2 = parse3(version2, null, true); + const v1 = parse2(version1, null, true); + const v2 = parse2(version2, null, true); const comparison = v1.compare(v2); if (comparison === 0) { return null; @@ -7899,9 +8208,9 @@ var require_patch = __commonJS({ var require_prerelease = __commonJS({ ""(exports, module) { "use strict"; - var parse3 = require_parse(); + var parse2 = require_parse(); var prerelease = (version, options) => { - const parsed = parse3(version, options); + const parsed = parse2(version, options); return parsed && parsed.prerelease.length ? parsed.prerelease : null; }; module.exports = prerelease; @@ -8087,7 +8396,7 @@ var require_coerce = __commonJS({ ""(exports, module) { "use strict"; var SemVer = require_semver(); - var parse3 = require_parse(); + var parse2 = require_parse(); var { safeRe: re, t } = require_re(); var coerce = (version, options) => { if (version instanceof SemVer) { @@ -8122,7 +8431,7 @@ var require_coerce = __commonJS({ const patch = match[4] || "0"; const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ""; const build = options.includePrerelease && match[6] ? `+${match[6]}` : ""; - return parse3(`${major}.${minor}.${patch}${prerelease}${build}`, options); + return parse2(`${major}.${minor}.${patch}${prerelease}${build}`, options); }; module.exports = coerce; } @@ -8171,14 +8480,14 @@ var require_range = __commonJS({ ""(exports, module) { "use strict"; var SPACE_CHARACTERS = /\s+/g; - var Range = class { + var Range = class _Range { constructor(range, options) { options = parseOptions(options); - if (range instanceof Range) { + if (range instanceof _Range) { if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) { return range; } else { - return new Range(range.raw, options); + return new _Range(range.raw, options); } } if (range instanceof Comparator) { @@ -8276,7 +8585,7 @@ var require_range = __commonJS({ return result; } intersects(range, options) { - if (!(range instanceof Range)) { + if (!(range instanceof _Range)) { throw new TypeError("a Range is required"); } return this.set.some((thisComparators) => { @@ -8289,6 +8598,7 @@ var require_range = __commonJS({ }); }); } + // if ANY of the sets match ALL of its comparators, then pass test(version) { if (!version) { return false; @@ -8338,6 +8648,7 @@ var require_range = __commonJS({ return result; }; var parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], ""); debug("comp", comp, options); comp = replaceCarets(comp, options); debug("caret", comp); @@ -8546,13 +8857,13 @@ var require_comparator = __commonJS({ ""(exports, module) { "use strict"; var ANY = Symbol("SemVer ANY"); - var Comparator = class { + var Comparator = class _Comparator { static get ANY() { return ANY; } constructor(comp, options) { options = parseOptions(options); - if (comp instanceof Comparator) { + if (comp instanceof _Comparator) { if (comp.loose === !!options.loose) { return comp; } else { @@ -8605,7 +8916,7 @@ var require_comparator = __commonJS({ return cmp(version, this.operator, this.semver, this.options); } intersects(comp, options) { - if (!(comp instanceof Comparator)) { + if (!(comp instanceof _Comparator)) { throw new TypeError("a Comparator is required"); } if (this.operator === "") { @@ -9136,7 +9447,7 @@ var require_semver2 = __commonJS({ var constants = require_constants(); var SemVer = require_semver(); var identifiers = require_identifiers(); - var parse3 = require_parse(); + var parse2 = require_parse(); var valid = require_valid(); var clean = require_clean(); var inc = require_inc(); @@ -9174,7 +9485,7 @@ var require_semver2 = __commonJS({ var simplifyRange = require_simplify(); var subset = require_subset(); module.exports = { - parse: parse3, + parse: parse2, valid, clean, inc, @@ -9259,8 +9570,8 @@ var require_dist = __commonJS({ return ""; } var builder = []; - for (var _i = 0, _a = Object.entries(params3); _i < _a.length; _i++) { - var _b = _a[_i], key = _b[0], value = _b[1]; + for (var _i = 0, _a2 = Object.entries(params3); _i < _a2.length; _i++) { + var _b2 = _a2[_i], key = _b2[0], value = _b2[1]; var params_1 = void 0; if (value === null) { params_1 = "null"; @@ -9322,12 +9633,12 @@ var require_dist = __commonJS({ } function renderObject(name, obj, context2) { var fields = []; - for (var _i = 0, _a = Object.entries(obj); _i < _a.length; _i++) { - var _b = _a[_i], key = _b[0], value = _b[1]; + for (var _i = 0, _a2 = Object.entries(obj); _i < _a2.length; _i++) { + var _b2 = _a2[_i], key = _b2[0], value = _b2[1]; fields.push(renderType(key, value, context2)); } - for (var _c = 0, _d = Object.getOwnPropertySymbols(obj); _c < _d.length; _c++) { - var sym = _d[_c]; + for (var _c2 = 0, _d = Object.getOwnPropertySymbols(obj); _c2 < _d.length; _c2++) { + var sym = _d[_c2]; var value = obj[sym]; if (isInlineFragmentObject(value)) { fields.push(renderInlineFragment(value, context2)); @@ -9349,17 +9660,19 @@ var require_dist = __commonJS({ var rendered = /* @__PURE__ */ new Map(); var executingContext = context2; var currentContext = { + // The current context for execution. fragments: /* @__PURE__ */ new Map() }; while (executingContext.fragments.size > 0) { - for (var _i = 0, _a = Array.from(executingContext.fragments.entries()); _i < _a.length; _i++) { - var _b = _a[_i], sym = _b[0], fragment2 = _b[1]; + for (var _i = 0, _a2 = Array.from(executingContext.fragments.entries()); _i < _a2.length; _i++) { + var _b2 = _a2[_i], sym = _b2[0], fragment2 = _b2[1]; if (!rendered.has(sym)) { rendered.set(sym, renderFragment(fragment2, currentContext)); } } executingContext = currentContext; currentContext = { + // Reset current context. fragments: /* @__PURE__ */ new Map() }; } @@ -9371,11 +9684,12 @@ var require_dist = __commonJS({ }; renderObject(void 0, value, context2); var currentContext = { + // The current context for execution. fragments: /* @__PURE__ */ new Map() }; var output = ""; - for (var _i = 0, _a = Array.from(context2.fragments.entries()); _i < _a.length; _i++) { - var _b = _a[_i], fragment2 = _b[1]; + for (var _i = 0, _a2 = Array.from(context2.fragments.entries()); _i < _a2.length; _i++) { + var _b2 = _a2[_i], fragment2 = _b2[1]; output = output + renderFragment(fragment2, currentContext); } return output; @@ -9417,9 +9731,9 @@ var require_dist = __commonJS({ return "".concat(alias2, ":").concat(target); } function fragment(name, typeName, input) { - var _a, _b; - var fragment2 = (_a = {}, _a[typeSymbol] = exports.GraphQLType.FRAGMENT, _a.name = name, _a.typeName = typeName, _a.internal = input, _a); - return _b = {}, _b[Symbol("Fragment(".concat(name, " on ").concat(typeName, ")"))] = fragment2, _b; + var _a2, _b2; + var fragment2 = (_a2 = {}, _a2[typeSymbol] = exports.GraphQLType.FRAGMENT, _a2.name = name, _a2.typeName = typeName, _a2.internal = input, _a2); + return _b2 = {}, _b2[Symbol("Fragment(".concat(name, " on ").concat(typeName, ")"))] = fragment2, _b2; } function rawString(input) { return JSON.stringify(input); @@ -9440,59 +9754,62 @@ var require_dist = __commonJS({ return obj; } function on(typeName, internal) { - var _a, _b; - var fragment2 = (_a = {}, _a[typeSymbol] = exports.GraphQLType.INLINE_FRAGMENT, _a.typeName = typeName, _a.internal = internal, _a); - return _b = {}, _b[Symbol("InlineFragment(".concat(typeName, ")"))] = fragment2, _b; + var _a2, _b2; + var fragment2 = (_a2 = {}, _a2[typeSymbol] = exports.GraphQLType.INLINE_FRAGMENT, _a2.typeName = typeName, _a2.internal = internal, _a2); + return _b2 = {}, _b2[Symbol("InlineFragment(".concat(typeName, ")"))] = fragment2, _b2; } function onUnion(types3) { var fragments = {}; - for (var _i = 0, _a = Object.entries(types3); _i < _a.length; _i++) { - var _b = _a[_i], typeName = _b[0], internal = _b[1]; + for (var _i = 0, _a2 = Object.entries(types3); _i < _a2.length; _i++) { + var _b2 = _a2[_i], typeName = _b2[0], internal = _b2[1]; fragments = __assign(__assign({}, fragments), on(typeName, internal)); } return fragments; } function scalarType() { - var _a; - var scalar = (_a = {}, _a[typeSymbol] = exports.GraphQLType.SCALAR, _a); + var _a2; + var scalar = (_a2 = {}, _a2[typeSymbol] = exports.GraphQLType.SCALAR, _a2); return scalar; } - var types2 = function() { - function types3() { - } - Object.defineProperty(types3, "number", { - get: function() { + var types2 = ( + /** @class */ + function() { + function types3() { + } + Object.defineProperty(types3, "number", { + get: function() { + return scalarType(); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(types3, "string", { + get: function() { + return scalarType(); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(types3, "boolean", { + get: function() { + return scalarType(); + }, + enumerable: false, + configurable: true + }); + types3.constant = function(_c2) { return scalarType(); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(types3, "string", { - get: function() { + }; + types3.oneOf = function(_e) { return scalarType(); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(types3, "boolean", { - get: function() { + }; + types3.custom = function() { return scalarType(); - }, - enumerable: false, - configurable: true - }); - types3.constant = function(_c) { - return scalarType(); - }; - types3.oneOf = function(_e) { - return scalarType(); - }; - types3.custom = function() { - return scalarType(); - }; - types3.optional = types3; - return types3; - }(); + }; + types3.optional = types3; + return types3; + }() + ); exports.alias = alias; exports.fragment = fragment; exports.fragmentToString = fragmentToString; @@ -9524,7 +9841,7 @@ var require_fast_content_type_parse = __commonJS({ var defaultContentType = { type: "", parameters: new NullObject() }; Object.freeze(defaultContentType.parameters); Object.freeze(defaultContentType); - function parse3(header) { + function parse2(header) { if (typeof header !== "string") { throw new TypeError("argument header is required and must be a string"); } @@ -9562,7 +9879,7 @@ var require_fast_content_type_parse = __commonJS({ } return result; } - function safeParse3(header) { + function safeParse2(header) { if (typeof header !== "string") { return defaultContentType; } @@ -9600,9 +9917,9 @@ var require_fast_content_type_parse = __commonJS({ } return result; } - module.exports.default = { parse: parse3, safeParse: safeParse3 }; - module.exports.parse = parse3; - module.exports.safeParse = safeParse3; + module.exports.default = { parse: parse2, safeParse: safeParse2 }; + module.exports.parse = parse2; + module.exports.safeParse = safeParse2; module.exports.defaultContentType = defaultContentType; } }); @@ -9778,7 +10095,7 @@ var require_cjs = __commonJS({ var require_lib2 = __commonJS({ ""(exports, module) { var { isexe, sync: isexeSync } = require_cjs(); - var { join: join3, delimiter, sep: sep2, posix } = __require("path"); + var { join: join6, delimiter, sep: sep2, posix } = __require("path"); var isWindows = process.platform === "win32"; var rSlash = new RegExp(`[${posix.sep}${sep2 === posix.sep ? "" : sep2}]`.replace(/(\\)/g, "\\$1")); var rRel = new RegExp(`^\\.${rSlash.source}`); @@ -9789,8 +10106,10 @@ var require_lib2 = __commonJS({ delimiter: optDelimiter = delimiter }) => { const pathEnv = cmd.match(rSlash) ? [""] : [ + // windows always checks the cwd first ...isWindows ? [process.cwd()] : [], - ...(optPath || "").split(optDelimiter) + ...(optPath || /* istanbul ignore next: very unusual */ + "").split(optDelimiter) ]; if (isWindows) { const pathExtExe = optPathExt || [".EXE", ".CMD", ".BAT", ".COM"].join(optDelimiter); @@ -9805,7 +10124,7 @@ var require_lib2 = __commonJS({ var getPathPart = (raw, cmd) => { const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw; const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : ""; - return prefix + join3(pathPart, cmd); + return prefix + join6(pathPart, cmd); }; var which2 = async (cmd, opt = {}) => { const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); @@ -9863,16 +10182,21 @@ var require_lib2 = __commonJS({ // var require_lockfile = __commonJS({ ""(exports, module) { - module.exports = function(modules) { + module.exports = /******/ + function(modules) { var installedModules = {}; function __webpack_require__(moduleId) { if (installedModules[moduleId]) { return installedModules[moduleId].exports; } var module2 = installedModules[moduleId] = { + /******/ i: moduleId, + /******/ l: false, + /******/ exports: {} + /******/ }; modules[moduleId].call(module2.exports, module2, module2.exports, __webpack_require__); module2.l = true; @@ -9886,18 +10210,28 @@ var require_lockfile = __commonJS({ __webpack_require__.d = function(exports2, name, getter) { if (!__webpack_require__.o(exports2, name)) { Object.defineProperty(exports2, name, { + /******/ configurable: false, + /******/ enumerable: true, + /******/ get: getter + /******/ }); } }; __webpack_require__.n = function(module2) { - var getter = module2 && module2.__esModule ? function getDefault() { - return module2["default"]; - } : function getModuleExports() { - return module2; - }; + var getter = module2 && module2.__esModule ? ( + /******/ + function getDefault() { + return module2["default"]; + } + ) : ( + /******/ + function getModuleExports() { + return module2; + } + ); __webpack_require__.d(getter, "a", getter); return getter; }; @@ -9907,9 +10241,13 @@ var require_lockfile = __commonJS({ __webpack_require__.p = ""; return __webpack_require__(__webpack_require__.s = 14); }([ + /* 0 */ + /***/ function(module2, exports2) { module2.exports = __require("path"); }, + /* 1 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; exports2.__esModule = true; @@ -9921,7 +10259,7 @@ var require_lockfile = __commonJS({ exports2.default = function(fn) { return function() { var gen = fn.apply(this, arguments); - return new _promise2.default(function(resolve, reject) { + return new _promise2.default(function(resolve5, reject) { function step(key, arg) { try { var info = gen[key](arg); @@ -9931,7 +10269,7 @@ var require_lockfile = __commonJS({ return; } if (info.done) { - resolve(value); + resolve5(value); } else { return _promise2.default.resolve(value).then(function(value2) { step("next", value2); @@ -9945,12 +10283,18 @@ var require_lockfile = __commonJS({ }; }; }, + /* 2 */ + /***/ function(module2, exports2) { module2.exports = __require("util"); }, + /* 3 */ + /***/ function(module2, exports2) { module2.exports = __require("fs"); }, + /* 4 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -9964,9 +10308,9 @@ var require_lockfile = __commonJS({ } exports2.MessageError = MessageError; class ProcessSpawnError extends MessageError { - constructor(msg, code, process4) { + constructor(msg, code, process3) { super(msg, code); - this.process = process4; + this.process = process3; } } exports2.ProcessSpawnError = ProcessSpawnError; @@ -9984,6 +10328,8 @@ var require_lockfile = __commonJS({ } exports2.ResponseError = ResponseError; }, + /* 5 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -9999,8 +10345,8 @@ var require_lockfile = __commonJS({ let build = (() => { var _ref5 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { const src = data.src, dest = data.dest, type = data.type; - const onFresh = data.onFresh || noop2; - const onDone = data.onDone || noop2; + const onFresh = data.onFresh || noop3; + const onDone = data.onDone || noop3; if (files.has(dest.toLowerCase())) { reporter.verbose(`The case-insensitive file ${dest} shouldn't be copied twice in one bulk copy`); } else { @@ -10250,8 +10596,8 @@ var require_lockfile = __commonJS({ let build = (() => { var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { const src = data.src, dest = data.dest; - const onFresh = data.onFresh || noop2; - const onDone = data.onDone || noop2; + const onFresh = data.onFresh || noop3; + const onDone = data.onDone || noop3; if (files.has(dest.toLowerCase())) { onDone(); return; @@ -10420,7 +10766,7 @@ var require_lockfile = __commonJS({ _ref10 = _i7.value; } const item = _ref10; - const onDone = item.onDone || noop2; + const onDone = item.onDone || noop3; item.onDone = function() { events.onProgress(item.dest); onDone(); @@ -10480,8 +10826,8 @@ var require_lockfile = __commonJS({ let copyBulk = exports2.copyBulk = (() => { var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { const events = { - onStart: _events && _events.onStart || noop2, - onProgress: _events && _events.onProgress || noop2, + onStart: _events && _events.onStart || noop3, + onProgress: _events && _events.onProgress || noop3, possibleExtraneous: _events ? _events.possibleExtraneous : /* @__PURE__ */ new Set(), ignoreBasenames: _events && _events.ignoreBasenames || [], artifactFiles: _events && _events.artifactFiles || [] @@ -10522,8 +10868,8 @@ var require_lockfile = __commonJS({ let hardlinkBulk = exports2.hardlinkBulk = (() => { var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { const events = { - onStart: _events && _events.onStart || noop2, - onProgress: _events && _events.onProgress || noop2, + onStart: _events && _events.onStart || noop3, + onProgress: _events && _events.onProgress || noop3, possibleExtraneous: _events ? _events.possibleExtraneous : /* @__PURE__ */ new Set(), artifactFiles: _events && _events.artifactFiles || [], ignoreBasenames: [] @@ -10640,16 +10986,16 @@ var require_lockfile = __commonJS({ if (process.platform === "win32") { yield fsSymlink(src, dest, "junction"); } else { - let relative; + let relative2; try { - relative = (_path || _load_path()).default.relative((_fs || _load_fs()).default.realpathSync((_path || _load_path()).default.dirname(dest)), (_fs || _load_fs()).default.realpathSync(src)); + relative2 = (_path || _load_path()).default.relative((_fs || _load_fs()).default.realpathSync((_path || _load_path()).default.dirname(dest)), (_fs || _load_fs()).default.realpathSync(src)); } catch (err) { if (err.code !== "ENOENT") { throw err; } - relative = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(dest), src); + relative2 = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(dest), src); } - yield fsSymlink(relative || ".", dest); + yield fsSymlink(relative2 || ".", dest); } }); return function symlink2(_x24, _x25) { @@ -10678,17 +11024,17 @@ var require_lockfile = __commonJS({ _ref28 = _i14.value; } const name = _ref28; - const relative = relativeDir ? (_path || _load_path()).default.join(relativeDir, name) : name; + const relative2 = relativeDir ? (_path || _load_path()).default.join(relativeDir, name) : name; const loc = (_path || _load_path()).default.join(dir, name); const stat2 = yield lstat(loc); files.push({ - relative, + relative: relative2, basename: name, absolute: loc, mtime: +stat2.mtime }); if (stat2.isDirectory()) { - files = files.concat(yield walk(loc, relative, ignoreBasenames)); + files = files.concat(yield walk(loc, relative2, ignoreBasenames)); } } return files; @@ -10733,7 +11079,7 @@ var require_lockfile = __commonJS({ if (eol !== "\n") { data = data.replace(/\n/g, eol); } - yield writeFile2(path, data); + yield writeFile3(path, data); }); return function writeFilePreservingEol2(_x30, _x31) { return _ref31.apply(this, arguments); @@ -10745,7 +11091,7 @@ var require_lockfile = __commonJS({ const file = (_path || _load_path()).default.join(dir, filename); const fileLink = (_path || _load_path()).default.join(dir, filename + "-link"); try { - yield writeFile2(file, "test"); + yield writeFile3(file, "test"); yield link(file, fileLink); } catch (err) { return false; @@ -10900,7 +11246,7 @@ var require_lockfile = __commonJS({ const lockQueue = exports2.lockQueue = new (_blockingQueue || _load_blockingQueue()).default("fs lock"); const readFileBuffer = exports2.readFileBuffer = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readFile); const open = exports2.open = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.open); - const writeFile2 = exports2.writeFile = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.writeFile); + const writeFile3 = exports2.writeFile = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.writeFile); const readlink = exports2.readlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readlink); const realpath = exports2.realpath = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.realpath); const readdir = exports2.readdir = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readdir); @@ -10918,18 +11264,18 @@ var require_lockfile = __commonJS({ const fsSymlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.symlink); const invariant = __webpack_require__(7); const stripBOM = __webpack_require__(122); - const noop2 = () => { + const noop3 = () => { }; function copy(src, dest, reporter) { return copyBulk([{ src, dest }], reporter); } function _readFile(loc, encoding) { - return new Promise((resolve, reject) => { + return new Promise((resolve5, reject) => { (_fs || _load_fs()).default.readFile(loc, encoding, function(err, content) { if (err) { reject(err); } else { - resolve(content); + resolve5(content); } }); }); @@ -10946,13 +11292,15 @@ var require_lockfile = __commonJS({ const cr = "\r".charCodeAt(0); const lf = "\n".charCodeAt(0); }, + /* 6 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getPathKey = getPathKey; - const os3 = __webpack_require__(36); + const os2 = __webpack_require__(36); const path = __webpack_require__(0); const userHome = __webpack_require__(45).default; var _require = __webpack_require__(171); @@ -10976,9 +11324,9 @@ var require_lockfile = __commonJS({ function getPreferredCacheDirectories() { const preferredCacheDirectories = [getCacheDir()]; if (process.getuid) { - preferredCacheDirectories.push(path.join(os3.tmpdir(), `.yarn-cache-${process.getuid()}`)); + preferredCacheDirectories.push(path.join(os2.tmpdir(), `.yarn-cache-${process.getuid()}`)); } - preferredCacheDirectories.push(path.join(os3.tmpdir(), `.yarn-cache`)); + preferredCacheDirectories.push(path.join(os2.tmpdir(), `.yarn-cache`)); return preferredCacheDirectories; } const PREFERRED_MODULE_CACHE_DIRECTORIES = exports2.PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories(); @@ -11035,18 +11383,20 @@ var require_lockfile = __commonJS({ unknown: "red" }; }, + /* 7 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var NODE_ENV = process.env.NODE_ENV; - var invariant = function(condition, format, a, b, c, d, e, f) { + var invariant = function(condition, format3, a, b, c, d, e, f) { if (NODE_ENV !== "production") { - if (format === void 0) { + if (format3 === void 0) { throw new Error("invariant requires an error message argument"); } } if (!condition) { var error; - if (format === void 0) { + if (format3 === void 0) { error = new Error( "Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings." ); @@ -11054,7 +11404,7 @@ var require_lockfile = __commonJS({ var args = [a, b, c, d, e, f]; var argIndex = 0; error = new Error( - format.replace(/%s/g, function() { + format3.replace(/%s/g, function() { return args[argIndex++]; }) ); @@ -11067,15 +11417,21 @@ var require_lockfile = __commonJS({ module2.exports = invariant; }, , + /* 9 */ + /***/ function(module2, exports2) { module2.exports = __require("crypto"); }, , + /* 11 */ + /***/ function(module2, exports2) { var global = module2.exports = typeof window != "undefined" && window.Math == Math ? window : typeof self != "undefined" && self.Math == Math ? self : Function("return this")(); if (typeof __g == "number") __g = global; }, + /* 12 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -11087,7 +11443,7 @@ var require_lockfile = __commonJS({ exports2.removeSuffix = removeSuffix; exports2.addSuffix = addSuffix; exports2.hyphenate = hyphenate; - exports2.camelCase = camelCase; + exports2.camelCase = camelCase2; exports2.compareSortedArrays = compareSortedArrays; exports2.sleep = sleep; const _camelCase = __webpack_require__(176); @@ -11134,7 +11490,7 @@ var require_lockfile = __commonJS({ return "-" + match.charAt(0).toLowerCase(); }); } - function camelCase(str) { + function camelCase2(str) { if (/[A-Z]/.test(str)) { return null; } else { @@ -11153,11 +11509,13 @@ var require_lockfile = __commonJS({ return true; } function sleep(ms) { - return new Promise((resolve) => { - setTimeout(resolve, ms); + return new Promise((resolve5) => { + setTimeout(resolve5, ms); }); } }, + /* 13 */ + /***/ function(module2, exports2, __webpack_require__) { var store = __webpack_require__(107)("wks"); var uid = __webpack_require__(111); @@ -11168,6 +11526,8 @@ var require_lockfile = __commonJS({ }; $exports.store = store; }, + /* 14 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -11291,6 +11651,8 @@ var require_lockfile = __commonJS({ this.cache = cache; this.parseResultType = parseResultType; } + // source string if the `cache` was parsed + // if true, we're parsing an old yarn file and need to update integrity fields hasEntriesExistWithoutIntegrity() { if (!this.cache) { return false; @@ -11401,11 +11763,15 @@ var require_lockfile = __commonJS({ }, , , + /* 17 */ + /***/ function(module2, exports2) { module2.exports = __require("stream"); }, , , + /* 20 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -11441,9 +11807,13 @@ var require_lockfile = __commonJS({ } }, , + /* 22 */ + /***/ function(module2, exports2) { module2.exports = __require("assert"); }, + /* 23 */ + /***/ function(module2, exports2) { var core = module2.exports = { version: "2.5.7" }; if (typeof __e == "number") @@ -11452,6 +11822,8 @@ var require_lockfile = __commonJS({ , , , + /* 27 */ + /***/ function(module2, exports2, __webpack_require__) { var isObject = __webpack_require__(34); module2.exports = function(it) { @@ -11461,6 +11833,8 @@ var require_lockfile = __commonJS({ }; }, , + /* 29 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -11493,6 +11867,8 @@ var require_lockfile = __commonJS({ } }, , + /* 31 */ + /***/ function(module2, exports2, __webpack_require__) { var dP = __webpack_require__(50); var createDesc = __webpack_require__(106); @@ -11503,6 +11879,8 @@ var require_lockfile = __commonJS({ return object; }; }, + /* 32 */ + /***/ function(module2, exports2, __webpack_require__) { var buffer = __webpack_require__(63); var Buffer2 = buffer.Buffer; @@ -11556,6 +11934,8 @@ var require_lockfile = __commonJS({ return buffer.SlowBuffer(size); }; }, + /* 33 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = !__webpack_require__(85)(function() { return Object.defineProperty({}, "a", { get: function() { @@ -11563,20 +11943,28 @@ var require_lockfile = __commonJS({ } }).a != 7; }); }, + /* 34 */ + /***/ function(module2, exports2) { module2.exports = function(it) { return typeof it === "object" ? it !== null : typeof it === "function"; }; }, + /* 35 */ + /***/ function(module2, exports2) { module2.exports = {}; }, + /* 36 */ + /***/ function(module2, exports2) { module2.exports = __require("os"); }, , , , + /* 40 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -11586,13 +11974,13 @@ var require_lockfile = __commonJS({ exports2.promisify = promisify; exports2.queue = queue; function wait(delay) { - return new Promise((resolve) => { - setTimeout(resolve, delay); + return new Promise((resolve5) => { + setTimeout(resolve5, delay); }); } function promisify(fn, firstData) { return function(...args) { - return new Promise(function(resolve, reject) { + return new Promise(function(resolve5, reject) { args.push(function(err, ...result) { let res = result; if (result.length <= 1) { @@ -11605,7 +11993,7 @@ var require_lockfile = __commonJS({ if (err) { reject(err); } else { - resolve(res); + resolve5(res); } }); fn.apply(null, args); @@ -11620,7 +12008,7 @@ var require_lockfile = __commonJS({ if (!total) { return Promise.resolve(results); } - return new Promise((resolve, reject) => { + return new Promise((resolve5, reject) => { for (let i = 0; i < concurrency; i++) { next(); } @@ -11631,7 +12019,7 @@ var require_lockfile = __commonJS({ results.push(result); total--; if (total === 0) { - resolve(results); + resolve5(results); } else { if (arr.length) { next(); @@ -11642,6 +12030,8 @@ var require_lockfile = __commonJS({ }); } }, + /* 41 */ + /***/ function(module2, exports2, __webpack_require__) { var global = __webpack_require__(11); var core = __webpack_require__(23); @@ -11702,6 +12092,8 @@ var require_lockfile = __commonJS({ $export.R = 128; module2.exports = $export; }, + /* 42 */ + /***/ function(module2, exports2, __webpack_require__) { try { var util = __webpack_require__(2); @@ -11714,6 +12106,8 @@ var require_lockfile = __commonJS({ }, , , + /* 45 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -11732,6 +12126,8 @@ var require_lockfile = __commonJS({ const userHomeDir = (_rootUser || _load_rootUser()).default ? path.resolve("/usr/local/share") : home; exports2.default = userHomeDir; }, + /* 46 */ + /***/ function(module2, exports2) { module2.exports = function(it) { if (typeof it != "function") @@ -11739,12 +12135,16 @@ var require_lockfile = __commonJS({ return it; }; }, + /* 47 */ + /***/ function(module2, exports2) { var toString = {}.toString; module2.exports = function(it) { return toString.call(it).slice(8, -1); }; }, + /* 48 */ + /***/ function(module2, exports2, __webpack_require__) { var aFunction = __webpack_require__(46); module2.exports = function(fn, that, length) { @@ -11770,12 +12170,16 @@ var require_lockfile = __commonJS({ }; }; }, + /* 49 */ + /***/ function(module2, exports2) { var hasOwnProperty = {}.hasOwnProperty; module2.exports = function(it, key) { return hasOwnProperty.call(it, key); }; }, + /* 50 */ + /***/ function(module2, exports2, __webpack_require__) { var anObject = __webpack_require__(27); var IE8_DOM_DEFINE = __webpack_require__(184); @@ -11800,9 +12204,13 @@ var require_lockfile = __commonJS({ , , , + /* 54 */ + /***/ function(module2, exports2) { module2.exports = __require("events"); }, + /* 55 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; const Buffer2 = __webpack_require__(32).Buffer; @@ -11842,7 +12250,16 @@ var require_lockfile = __commonJS({ } toString(opts) { if (opts && opts.strict) { - if (!(SPEC_ALGORITHMS.some((x) => x === this.algorithm) && this.digest.match(BASE64_REGEX) && (this.options || []).every((opt) => opt.match(VCHAR_REGEX)))) { + if (!// The spec has very restricted productions for algorithms. + // https://www.w3.org/TR/CSP2/#source-list-syntax + (SPEC_ALGORITHMS.some((x) => x === this.algorithm) && // Usually, if someone insists on using a "different" base64, we + // leave it as-is, since there's multiple standards, and the + // specified is not a URL-safe variant. + // https://www.w3.org/TR/CSP2/#base64_value + this.digest.match(BASE64_REGEX) && // Option syntax is strictly visual chars. + // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-option-expression + // https://tools.ietf.org/html/rfc5234#appendix-B.1 + (this.options || []).every((opt) => opt.match(VCHAR_REGEX)))) { return ""; } } @@ -11871,13 +12288,13 @@ var require_lockfile = __commonJS({ } concat(integrity, opts) { const other = typeof integrity === "string" ? integrity : stringify(integrity, opts); - return parse3(`${this.toString(opts)} ${other}`, opts); + return parse2(`${this.toString(opts)} ${other}`, opts); } hexDigest() { - return parse3(this, { single: true }).hexDigest(); + return parse2(this, { single: true }).hexDigest(); } match(integrity, opts) { - const other = parse3(integrity, opts); + const other = parse2(integrity, opts); const algo = other.pickAlgorithm(opts); return this[algo] && other[algo] && this[algo].find( (hash) => other[algo].find( @@ -11896,8 +12313,8 @@ var require_lockfile = __commonJS({ }); } } - module2.exports.parse = parse3; - function parse3(sri, opts) { + module2.exports.parse = parse2; + function parse2(sri, opts) { opts = opts || {}; if (typeof sri === "string") { return _parse(sri, opts); @@ -11930,7 +12347,7 @@ var require_lockfile = __commonJS({ if (obj.algorithm && obj.digest) { return Hash.prototype.toString.call(obj, opts); } else if (typeof obj === "string") { - return stringify(parse3(obj, opts), opts); + return stringify(parse2(obj, opts), opts); } else { return Integrity.prototype.toString.call(obj, opts); } @@ -11938,7 +12355,7 @@ var require_lockfile = __commonJS({ module2.exports.fromHex = fromHex; function fromHex(hexDigest, algorithm, opts) { const optString = opts && opts.options && opts.options.length ? `?${opts.options.join("?")}` : ""; - return parse3( + return parse2( `${algorithm}-${Buffer2.from(hexDigest, "hex").toString("base64")}${optString}`, opts ); @@ -11969,7 +12386,7 @@ var require_lockfile = __commonJS({ opts = opts || {}; const P = opts.Promise || Promise; const istream = integrityStream(opts); - return new P((resolve, reject) => { + return new P((resolve5, reject) => { stream.pipe(istream); stream.on("error", reject); istream.on("error", reject); @@ -11977,7 +12394,7 @@ var require_lockfile = __commonJS({ istream.on("integrity", (s) => { sri = s; }); - istream.on("end", () => resolve(sri)); + istream.on("end", () => resolve5(sri)); istream.on("data", () => { }); }); @@ -11985,7 +12402,7 @@ var require_lockfile = __commonJS({ module2.exports.checkData = checkData; function checkData(data, sri, opts) { opts = opts || {}; - sri = parse3(sri, opts); + sri = parse2(sri, opts); if (!Object.keys(sri).length) { if (opts.error) { throw Object.assign( @@ -12000,7 +12417,7 @@ var require_lockfile = __commonJS({ } const algorithm = sri.pickAlgorithm(opts); const digest = crypto.createHash(algorithm).update(data).digest("base64"); - const newSri = parse3({ algorithm, digest }); + const newSri = parse2({ algorithm, digest }); const match = newSri.match(sri, opts); if (match || !opts.error) { return match; @@ -12030,7 +12447,7 @@ var require_lockfile = __commonJS({ const checker = integrityStream(Object.assign({}, opts, { integrity: sri })); - return new P((resolve, reject) => { + return new P((resolve5, reject) => { stream.pipe(checker); stream.on("error", reject); checker.on("error", reject); @@ -12038,7 +12455,7 @@ var require_lockfile = __commonJS({ checker.on("verified", (s) => { sri2 = s; }); - checker.on("end", () => resolve(sri2)); + checker.on("end", () => resolve5(sri2)); checker.on("data", () => { }); }); @@ -12046,7 +12463,7 @@ var require_lockfile = __commonJS({ module2.exports.integrityStream = integrityStream; function integrityStream(opts) { opts = opts || {}; - const sri = opts.integrity && parse3(opts.integrity, opts); + const sri = opts.integrity && parse2(opts.integrity, opts); const goodSri = sri && Object.keys(sri).length; const algorithm = goodSri && sri.pickAlgorithm(opts); const digests = goodSri && sri[algorithm]; @@ -12065,7 +12482,7 @@ var require_lockfile = __commonJS({ } }).on("end", () => { const optString = opts.options && opts.options.length ? `?${opts.options.join("?")}` : ""; - const newSri = parse3(hashes.map((h, i) => { + const newSri = parse2(hashes.map((h, i) => { return `${algorithms[i]}-${h.digest("base64")}${optString}`; }).join(" "), opts); const match = goodSri && newSri.match(sri, opts); @@ -12134,6 +12551,8 @@ var require_lockfile = __commonJS({ "sha256", "sha384", "sha512", + // TODO - it's unclear _which_ of these Node will actually use as its name + // for the algorithm, so we guesswork it based on the OpenSSL names. "sha3", "sha3-256", "sha3-384", @@ -12150,6 +12569,8 @@ var require_lockfile = __commonJS({ , , , + /* 60 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = minimatch; minimatch.Minimatch = Minimatch; @@ -12159,7 +12580,7 @@ var require_lockfile = __commonJS({ } catch (er) { } var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; - var expand3 = __webpack_require__(175); + var expand2 = __webpack_require__(175); var plTypes = { "!": { open: "(?:(?!(?:", close: "))[^/]*?)" }, "?": { open: "(?:", close: ")?" }, @@ -12320,11 +12741,11 @@ var require_lockfile = __commonJS({ if (options.nobrace || !pattern.match(/\{.*\}/)) { return [pattern]; } - return expand3(pattern); + return expand2(pattern); } - Minimatch.prototype.parse = parse3; + Minimatch.prototype.parse = parse2; var SUBPARSE = {}; - function parse3(pattern, isSub) { + function parse2(pattern, isSub) { if (pattern.length > 1024 * 64) { throw new TypeError("pattern is too long"); } @@ -12717,6 +13138,8 @@ var require_lockfile = __commonJS({ return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); } }, + /* 61 */ + /***/ function(module2, exports2, __webpack_require__) { var wrappy = __webpack_require__(123); module2.exports = wrappy(once); @@ -12759,12 +13182,16 @@ var require_lockfile = __commonJS({ } }, , + /* 63 */ + /***/ function(module2, exports2) { module2.exports = __require("buffer"); }, , , , + /* 67 */ + /***/ function(module2, exports2) { module2.exports = function(it) { if (it == void 0) @@ -12772,6 +13199,8 @@ var require_lockfile = __commonJS({ return it; }; }, + /* 68 */ + /***/ function(module2, exports2, __webpack_require__) { var isObject = __webpack_require__(34); var document2 = __webpack_require__(11).document; @@ -12780,27 +13209,33 @@ var require_lockfile = __commonJS({ return is ? document2.createElement(it) : {}; }; }, + /* 69 */ + /***/ function(module2, exports2) { module2.exports = true; }, + /* 70 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var aFunction = __webpack_require__(46); function PromiseCapability(C) { - var resolve, reject; + var resolve5, reject; this.promise = new C(function($$resolve, $$reject) { - if (resolve !== void 0 || reject !== void 0) + if (resolve5 !== void 0 || reject !== void 0) throw TypeError("Bad Promise constructor"); - resolve = $$resolve; + resolve5 = $$resolve; reject = $$reject; }); - this.resolve = aFunction(resolve); + this.resolve = aFunction(resolve5); this.reject = aFunction(reject); } module2.exports.f = function(C) { return new PromiseCapability(C); }; }, + /* 71 */ + /***/ function(module2, exports2, __webpack_require__) { var def = __webpack_require__(50).f; var has = __webpack_require__(49); @@ -12810,6 +13245,8 @@ var require_lockfile = __commonJS({ def(it, TAG, { configurable: true, value: tag }); }; }, + /* 72 */ + /***/ function(module2, exports2, __webpack_require__) { var shared = __webpack_require__(107)("keys"); var uid = __webpack_require__(111); @@ -12817,6 +13254,8 @@ var require_lockfile = __commonJS({ return shared[key] || (shared[key] = uid(key)); }; }, + /* 73 */ + /***/ function(module2, exports2) { var ceil = Math.ceil; var floor = Math.floor; @@ -12824,6 +13263,8 @@ var require_lockfile = __commonJS({ return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); }; }, + /* 74 */ + /***/ function(module2, exports2, __webpack_require__) { var IObject = __webpack_require__(131); var defined = __webpack_require__(67); @@ -12831,6 +13272,8 @@ var require_lockfile = __commonJS({ return IObject(defined(it)); }; }, + /* 75 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = glob; var fs = __webpack_require__(3); @@ -13383,6 +13826,8 @@ var require_lockfile = __commonJS({ return cb(null, c, stat); }; }, + /* 76 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; function posix(path) { @@ -13401,10 +13846,14 @@ var require_lockfile = __commonJS({ }, , , + /* 79 */ + /***/ function(module2, exports2) { module2.exports = __require("tty"); }, , + /* 81 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -13412,7 +13861,7 @@ var require_lockfile = __commonJS({ }); exports2.default = function(str, fileLoc = "lockfile") { str = (0, (_stripBom || _load_stripBom()).default)(str); - return hasMergeConflicts(str) ? parseWithConflict(str, fileLoc) : { type: "success", object: parse3(str, fileLoc) }; + return hasMergeConflicts(str) ? parseWithConflict(str, fileLoc) : { type: "success", object: parse2(str, fileLoc) }; }; var _util; function _load_util() { @@ -13564,7 +14013,7 @@ var require_lockfile = __commonJS({ } yield buildToken(TOKEN_TYPES.eof); } - class Parser { + class Parser2 { constructor(input, fileLoc = "lockfile") { this.comments = []; this.tokens = tokenise(input); @@ -13745,15 +14194,15 @@ var require_lockfile = __commonJS({ function hasMergeConflicts(str) { return str.includes(MERGE_CONFLICT_START) && str.includes(MERGE_CONFLICT_SEP) && str.includes(MERGE_CONFLICT_END); } - function parse3(str, fileLoc) { - const parser = new Parser(str, fileLoc); - parser.next(); - return parser.parse(); + function parse2(str, fileLoc) { + const parser2 = new Parser2(str, fileLoc); + parser2.next(); + return parser2.parse(); } function parseWithConflict(str, fileLoc) { const variants = extractConflictVariants(str); try { - return { type: "merge", object: Object.assign({}, parse3(variants[0], fileLoc), parse3(variants[1], fileLoc)) }; + return { type: "merge", object: Object.assign({}, parse2(variants[0], fileLoc), parse2(variants[1], fileLoc)) }; } catch (err) { if (err instanceof SyntaxError) { return { type: "conflict", object: {} }; @@ -13765,6 +14214,8 @@ var require_lockfile = __commonJS({ }, , , + /* 84 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -13809,9 +14260,9 @@ var require_lockfile = __commonJS({ } else { this.stillActive(); } - return new Promise((resolve, reject) => { + return new Promise((resolve5, reject) => { const queue = this.queue[key] = this.queue[key] || []; - queue.push({ factory, resolve, reject }); + queue.push({ factory, resolve: resolve5, reject }); if (!this.running[key]) { this.shift(key); } @@ -13835,7 +14286,7 @@ var require_lockfile = __commonJS({ return; } var _queue$shift = queue.shift(); - const resolve = _queue$shift.resolve, reject = _queue$shift.reject, factory = _queue$shift.factory; + const resolve5 = _queue$shift.resolve, reject = _queue$shift.reject, factory = _queue$shift.factory; if (!queue.length) { delete this.queue[key]; } @@ -13847,7 +14298,7 @@ var require_lockfile = __commonJS({ this.running[key] = true; this.runningCount++; factory().then(function(val) { - resolve(val); + resolve5(val); next(); return null; }).catch(function(err) { @@ -13875,10 +14326,12 @@ var require_lockfile = __commonJS({ } exports2.default = BlockingQueue; }, + /* 85 */ + /***/ function(module2, exports2) { - module2.exports = function(exec) { + module2.exports = function(exec2) { try { - return !!exec(); + return !!exec2(); } catch (e) { return true; } @@ -13898,10 +14351,12 @@ var require_lockfile = __commonJS({ , , , + /* 100 */ + /***/ function(module2, exports2, __webpack_require__) { var cof = __webpack_require__(47); var TAG = __webpack_require__(13)("toStringTag"); - var ARG = cof(function() { + var ARG = cof(/* @__PURE__ */ function() { return arguments; }()) == "Arguments"; var tryGet = function(it, key) { @@ -13915,13 +14370,19 @@ var require_lockfile = __commonJS({ return it === void 0 ? "Undefined" : it === null ? "Null" : typeof (T = tryGet(O = Object(it), TAG)) == "string" ? T : ARG ? cof(O) : (B = cof(O)) == "Object" && typeof O.callee == "function" ? "Arguments" : B; }; }, + /* 101 */ + /***/ function(module2, exports2) { module2.exports = "constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","); }, + /* 102 */ + /***/ function(module2, exports2, __webpack_require__) { var document2 = __webpack_require__(11).document; module2.exports = document2 && document2.documentElement; }, + /* 103 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var LIBRARY = __webpack_require__(69); @@ -13943,8 +14404,8 @@ var require_lockfile = __commonJS({ module2.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { $iterCreate(Constructor, NAME, next); var getMethod = function(kind) { - if (!BUGGY && kind in proto2) - return proto2[kind]; + if (!BUGGY && kind in proto) + return proto[kind]; switch (kind) { case KEYS: return function keys() { @@ -13962,11 +14423,11 @@ var require_lockfile = __commonJS({ var TAG = NAME + " Iterator"; var DEF_VALUES = DEFAULT == VALUES; var VALUES_BUG = false; - var proto2 = Base.prototype; - var $native = proto2[ITERATOR] || proto2[FF_ITERATOR] || DEFAULT && proto2[DEFAULT]; + var proto = Base.prototype; + var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; var $default = $native || getMethod(DEFAULT); var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod("entries") : void 0; - var $anyNative = NAME == "Array" ? proto2.entries || $native : $native; + var $anyNative = NAME == "Array" ? proto.entries || $native : $native; var methods, key, IteratorPrototype; if ($anyNative) { IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); @@ -13982,8 +14443,8 @@ var require_lockfile = __commonJS({ return $native.call(this); }; } - if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto2[ITERATOR])) { - hide(proto2, ITERATOR, $default); + if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { + hide(proto, ITERATOR, $default); } Iterators[NAME] = $default; Iterators[TAG] = returnThis; @@ -13995,8 +14456,8 @@ var require_lockfile = __commonJS({ }; if (FORCED) for (key in methods) { - if (!(key in proto2)) - redefine(proto2, key, methods[key]); + if (!(key in proto)) + redefine(proto, key, methods[key]); } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); @@ -14004,15 +14465,19 @@ var require_lockfile = __commonJS({ return methods; }; }, + /* 104 */ + /***/ function(module2, exports2) { - module2.exports = function(exec) { + module2.exports = function(exec2) { try { - return { e: false, v: exec() }; + return { e: false, v: exec2() }; } catch (e) { return { e: true, v: e }; } }; }, + /* 105 */ + /***/ function(module2, exports2, __webpack_require__) { var anObject = __webpack_require__(27); var isObject = __webpack_require__(34); @@ -14022,11 +14487,13 @@ var require_lockfile = __commonJS({ if (isObject(x) && x.constructor === C) return x; var promiseCapability = newPromiseCapability.f(C); - var resolve = promiseCapability.resolve; - resolve(x); + var resolve5 = promiseCapability.resolve; + resolve5(x); return promiseCapability.promise; }; }, + /* 106 */ + /***/ function(module2, exports2) { module2.exports = function(bitmap, value) { return { @@ -14037,6 +14504,8 @@ var require_lockfile = __commonJS({ }; }; }, + /* 107 */ + /***/ function(module2, exports2, __webpack_require__) { var core = __webpack_require__(23); var global = __webpack_require__(11); @@ -14050,6 +14519,8 @@ var require_lockfile = __commonJS({ copyright: "\xA9 2018 Denis Pushkarev (zloirock.ru)" }); }, + /* 108 */ + /***/ function(module2, exports2, __webpack_require__) { var anObject = __webpack_require__(27); var aFunction = __webpack_require__(46); @@ -14060,13 +14531,15 @@ var require_lockfile = __commonJS({ return C === void 0 || (S = anObject(C)[SPECIES]) == void 0 ? D : aFunction(S); }; }, + /* 109 */ + /***/ function(module2, exports2, __webpack_require__) { var ctx = __webpack_require__(48); var invoke = __webpack_require__(185); var html = __webpack_require__(102); var cel = __webpack_require__(68); var global = __webpack_require__(11); - var process4 = global.process; + var process3 = global.process; var setTask = global.setImmediate; var clearTask = global.clearImmediate; var MessageChannel = global.MessageChannel; @@ -14101,9 +14574,9 @@ var require_lockfile = __commonJS({ clearTask = function clearImmediate(id) { delete queue[id]; }; - if (__webpack_require__(47)(process4) == "process") { + if (__webpack_require__(47)(process3) == "process") { defer = function(id) { - process4.nextTick(ctx(run, id, 1)); + process3.nextTick(ctx(run, id, 1)); }; } else if (Dispatch && Dispatch.now) { defer = function(id) { @@ -14137,6 +14610,8 @@ var require_lockfile = __commonJS({ clear: clearTask }; }, + /* 110 */ + /***/ function(module2, exports2, __webpack_require__) { var toInteger = __webpack_require__(73); var min = Math.min; @@ -14144,6 +14619,8 @@ var require_lockfile = __commonJS({ return it > 0 ? min(toInteger(it), 9007199254740991) : 0; }; }, + /* 111 */ + /***/ function(module2, exports2) { var id = 0; var px = Math.random(); @@ -14151,6 +14628,8 @@ var require_lockfile = __commonJS({ return "Symbol(".concat(key === void 0 ? "" : key, ")_", (++id + px).toString(36)); }; }, + /* 112 */ + /***/ function(module2, exports2, __webpack_require__) { exports2 = module2.exports = createDebug.debug = createDebug["default"] = createDebug; exports2.coerce = coerce; @@ -14176,7 +14655,7 @@ var require_lockfile = __commonJS({ if (!debug.enabled) return; var self2 = debug; - var curr = +new Date(); + var curr = +/* @__PURE__ */ new Date(); var ms = curr - (prevTime || curr); self2.diff = ms; self2.prev = prevTime; @@ -14191,11 +14670,11 @@ var require_lockfile = __commonJS({ args.unshift("%O"); } var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format3) { if (match === "%%") return match; index++; - var formatter = exports2.formatters[format]; + var formatter = exports2.formatters[format3]; if ("function" === typeof formatter) { var val = args[index]; match = formatter.call(self2, val); @@ -14277,6 +14756,8 @@ var require_lockfile = __commonJS({ } }, , + /* 114 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = realpath; realpath.realpath = realpath; @@ -14332,6 +14813,8 @@ var require_lockfile = __commonJS({ fs.realpathSync = origRealpathSync; } }, + /* 115 */ + /***/ function(module2, exports2, __webpack_require__) { exports2.alphasort = alphasort; exports2.alphasorti = alphasorti; @@ -14524,6 +15007,8 @@ var require_lockfile = __commonJS({ }); } }, + /* 116 */ + /***/ function(module2, exports2, __webpack_require__) { var path = __webpack_require__(0); var fs = __webpack_require__(3); @@ -14612,6 +15097,8 @@ var require_lockfile = __commonJS({ , , , + /* 122 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; module2.exports = (x) => { @@ -14624,6 +15111,8 @@ var require_lockfile = __commonJS({ return x; }; }, + /* 123 */ + /***/ function(module2, exports2) { module2.exports = wrappy; function wrappy(fn, cb) { @@ -14658,12 +15147,16 @@ var require_lockfile = __commonJS({ , , , + /* 131 */ + /***/ function(module2, exports2, __webpack_require__) { var cof = __webpack_require__(47); module2.exports = Object("z").propertyIsEnumerable(0) ? Object : function(it) { return cof(it) == "String" ? it.split("") : Object(it); }; }, + /* 132 */ + /***/ function(module2, exports2, __webpack_require__) { var $keys = __webpack_require__(195); var enumBugKeys = __webpack_require__(101); @@ -14671,6 +15164,8 @@ var require_lockfile = __commonJS({ return $keys(O, enumBugKeys); }; }, + /* 133 */ + /***/ function(module2, exports2, __webpack_require__) { var defined = __webpack_require__(67); module2.exports = function(it) { @@ -14688,6 +15183,8 @@ var require_lockfile = __commonJS({ , , , + /* 145 */ + /***/ function(module2, exports2) { module2.exports = { "name": "yarn", "installationMethod": "unknown", "version": "1.10.0-0", "license": "BSD-2-Clause", "preferGlobal": true, "description": "\u{1F4E6}\u{1F408} Fast, reliable, and secure dependency management.", "dependencies": { "@zkochan/cmd-shim": "^2.2.4", "babel-runtime": "^6.26.0", "bytes": "^3.0.0", "camelcase": "^4.0.0", "chalk": "^2.1.0", "commander": "^2.9.0", "death": "^1.0.0", "debug": "^3.0.0", "deep-equal": "^1.0.1", "detect-indent": "^5.0.0", "dnscache": "^1.0.1", "glob": "^7.1.1", "gunzip-maybe": "^1.4.0", "hash-for-dep": "^1.2.3", "imports-loader": "^0.8.0", "ini": "^1.3.4", "inquirer": "^3.0.1", "invariant": "^2.2.0", "is-builtin-module": "^2.0.0", "is-ci": "^1.0.10", "is-webpack-bundle": "^1.0.0", "leven": "^2.0.0", "loud-rejection": "^1.2.0", "micromatch": "^2.3.11", "mkdirp": "^0.5.1", "node-emoji": "^1.6.1", "normalize-url": "^2.0.0", "npm-logical-tree": "^1.2.1", "object-path": "^0.11.2", "proper-lockfile": "^2.0.0", "puka": "^1.0.0", "read": "^1.0.7", "request": "^2.87.0", "request-capture-har": "^1.2.2", "rimraf": "^2.5.0", "semver": "^5.1.0", "ssri": "^5.3.0", "strip-ansi": "^4.0.0", "strip-bom": "^3.0.0", "tar-fs": "^1.16.0", "tar-stream": "^1.6.1", "uuid": "^3.0.1", "v8-compile-cache": "^2.0.0", "validate-npm-package-license": "^3.0.3", "yn": "^2.0.0" }, "devDependencies": { "babel-core": "^6.26.0", "babel-eslint": "^7.2.3", "babel-loader": "^6.2.5", "babel-plugin-array-includes": "^2.0.3", "babel-plugin-transform-builtin-extend": "^1.1.2", "babel-plugin-transform-inline-imports-commonjs": "^1.0.0", "babel-plugin-transform-runtime": "^6.4.3", "babel-preset-env": "^1.6.0", "babel-preset-flow": "^6.23.0", "babel-preset-stage-0": "^6.0.0", "babylon": "^6.5.0", "commitizen": "^2.9.6", "cz-conventional-changelog": "^2.0.0", "eslint": "^4.3.0", "eslint-config-fb-strict": "^22.0.0", "eslint-plugin-babel": "^5.0.0", "eslint-plugin-flowtype": "^2.35.0", "eslint-plugin-jasmine": "^2.6.2", "eslint-plugin-jest": "^21.0.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-prefer-object-spread": "^1.2.1", "eslint-plugin-prettier": "^2.1.2", "eslint-plugin-react": "^7.1.0", "eslint-plugin-relay": "^0.0.24", "eslint-plugin-yarn-internal": "file:scripts/eslint-rules", "execa": "^0.10.0", "flow-bin": "^0.66.0", "git-release-notes": "^3.0.0", "gulp": "^3.9.0", "gulp-babel": "^7.0.0", "gulp-if": "^2.0.1", "gulp-newer": "^1.0.0", "gulp-plumber": "^1.0.1", "gulp-sourcemaps": "^2.2.0", "gulp-util": "^3.0.7", "gulp-watch": "^5.0.0", "jest": "^22.4.4", "jsinspect": "^0.12.6", "minimatch": "^3.0.4", "mock-stdin": "^0.3.0", "prettier": "^1.5.2", "temp": "^0.8.3", "webpack": "^2.1.0-beta.25", "yargs": "^6.3.0" }, "resolutions": { "sshpk": "^1.14.2" }, "engines": { "node": ">=4.0.0" }, "repository": "yarnpkg/yarn", "bin": { "yarn": "./bin/yarn.js", "yarnpkg": "./bin/yarn.js" }, "scripts": { "build": "gulp build", "build-bundle": "node ./scripts/build-webpack.js", "build-chocolatey": "powershell ./scripts/build-chocolatey.ps1", "build-deb": "./scripts/build-deb.sh", "build-dist": "bash ./scripts/build-dist.sh", "build-win-installer": "scripts\\build-windows-installer.bat", "changelog": "git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md", "dupe-check": "yarn jsinspect ./src", "lint": "eslint . && flow check", "pkg-tests": "yarn --cwd packages/pkg-tests jest yarn.test.js", "prettier": "eslint src __tests__ --fix", "release-branch": "./scripts/release-branch.sh", "test": "yarn lint && yarn test-only", "test-only": "node --max_old_space_size=4096 ", "test-only-debug": "node --inspect-brk --max_old_space_size=4096 ", "test-coverage": "node --max_old_space_size=4096 ", "watch": "gulp watch", "commit": "git-cz" }, "jest": { "collectCoverageFrom": ["src/**/*.js"], "testEnvironment": "node", "modulePathIgnorePatterns": ["__tests__/fixtures/", "packages/pkg-tests/pkg-tests-fixtures", "dist/"], "testPathIgnorePatterns": ["__tests__/(fixtures|__mocks__)/", "updates/", "_(temp|mock|install|init|helpers).js$", "packages/pkg-tests"] }, "config": { "commitizen": { "path": "./" } } }; }, @@ -14695,6 +15192,8 @@ var require_lockfile = __commonJS({ , , , + /* 150 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -14810,6 +15309,8 @@ ${indent}`); , , , + /* 164 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -14893,11 +15394,11 @@ ${indent}`); })(); const copyFilePoly = (src, dest, flags, data) => { if ((_fs || _load_fs()).default.copyFile) { - return new Promise((resolve, reject) => (_fs || _load_fs()).default.copyFile(src, dest, flags, (err) => { + return new Promise((resolve5, reject) => (_fs || _load_fs()).default.copyFile(src, dest, flags, (err) => { if (err) { reject(err); } else { - fixTimes(void 0, dest, data).then(() => resolve()).catch((ex) => reject(ex)); + fixTimes(void 0, dest, data).then(() => resolve5()).catch((ex) => reject(ex)); } })); } else { @@ -14940,6 +15441,8 @@ ${indent}`); , , , + /* 169 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -14962,6 +15465,8 @@ ${indent}`); } }, , + /* 171 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; Object.defineProperty(exports2, "__esModule", { @@ -15010,9 +15515,13 @@ ${indent}`); } }, , + /* 173 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = { "default": __webpack_require__(179), __esModule: true }; }, + /* 174 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; module2.exports = balanced; @@ -15036,13 +15545,13 @@ ${indent}`); } balanced.range = range; function range(a, b, str) { - var begs, beg, left, right, result; + var begs, beg, left2, right2, result; var ai = str.indexOf(a); var bi = str.indexOf(b, ai + 1); var i = ai; if (ai >= 0 && bi > 0) { begs = []; - left = str.length; + left2 = str.length; while (i >= 0 && !result) { if (i == ai) { begs.push(i); @@ -15051,21 +15560,23 @@ ${indent}`); result = [begs.pop(), bi]; } else { beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; + if (beg < left2) { + left2 = beg; + right2 = bi; } bi = str.indexOf(b, i + 1); } i = ai < bi && ai >= 0 ? ai : bi; } if (begs.length) { - result = [left, right]; + result = [left2, right2]; } } return result; } }, + /* 175 */ + /***/ function(module2, exports2, __webpack_require__) { var concatMap = __webpack_require__(178); var balanced = __webpack_require__(174); @@ -15110,7 +15621,7 @@ ${indent}`); if (str.substr(0, 2) === "{}") { str = "\\{\\}" + str.substr(2); } - return expand3(escapeBraces(str), true).map(unescapeBraces); + return expand2(escapeBraces(str), true).map(unescapeBraces); } function identity(e) { return e; @@ -15127,7 +15638,7 @@ ${indent}`); function gte(i, y) { return i >= y; } - function expand3(str, isTop) { + function expand2(str, isTop) { var expansions = []; var m = balanced("{", "}", str); if (!m || /\$$/.test(m.pre)) @@ -15139,7 +15650,7 @@ ${indent}`); if (!isSequence && !isOptions) { if (m.post.match(/,.*\}/)) { str = m.pre + "{" + m.body + escClose + m.post; - return expand3(str); + return expand2(str); } return [str]; } @@ -15149,9 +15660,9 @@ ${indent}`); } else { n = parseCommaParts(m.body); if (n.length === 1) { - n = expand3(n[0], false).map(embrace); + n = expand2(n[0], false).map(embrace); if (n.length === 1) { - var post = m.post.length ? expand3(m.post, false) : [""]; + var post = m.post.length ? expand2(m.post, false) : [""]; return post.map(function(p) { return m.pre + n[0] + p; }); @@ -15159,7 +15670,7 @@ ${indent}`); } } var pre = m.pre; - var post = m.post.length ? expand3(m.post, false) : [""]; + var post = m.post.length ? expand2(m.post, false) : [""]; var N; if (isSequence) { var x = numeric(n[0]); @@ -15197,7 +15708,7 @@ ${indent}`); } } else { N = concatMap(n, function(el) { - return expand3(el, false); + return expand2(el, false); }); } for (var j = 0; j < N.length; j++) { @@ -15210,6 +15721,8 @@ ${indent}`); return expansions; } }, + /* 176 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; function preserveCamelCase(str) { @@ -15260,6 +15773,8 @@ ${indent}`); }; }, , + /* 178 */ + /***/ function(module2, exports2) { module2.exports = function(xs, fn) { var res = []; @@ -15276,6 +15791,8 @@ ${indent}`); return Object.prototype.toString.call(xs) === "[object Array]"; }; }, + /* 179 */ + /***/ function(module2, exports2, __webpack_require__) { __webpack_require__(205); __webpack_require__(207); @@ -15285,10 +15802,14 @@ ${indent}`); __webpack_require__(209); module2.exports = __webpack_require__(23).Promise; }, + /* 180 */ + /***/ function(module2, exports2) { module2.exports = function() { }; }, + /* 181 */ + /***/ function(module2, exports2) { module2.exports = function(it, Constructor, name, forbiddenField) { if (!(it instanceof Constructor) || forbiddenField !== void 0 && forbiddenField in it) { @@ -15297,6 +15818,8 @@ ${indent}`); return it; }; }, + /* 182 */ + /***/ function(module2, exports2, __webpack_require__) { var toIObject = __webpack_require__(74); var toLength = __webpack_require__(110); @@ -15323,6 +15846,8 @@ ${indent}`); }; }; }, + /* 183 */ + /***/ function(module2, exports2, __webpack_require__) { var ctx = __webpack_require__(48); var call = __webpack_require__(187); @@ -15357,6 +15882,8 @@ ${indent}`); exports2.BREAK = BREAK; exports2.RETURN = RETURN; }, + /* 184 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = !__webpack_require__(33) && !__webpack_require__(85)(function() { return Object.defineProperty(__webpack_require__(68)("div"), "a", { get: function() { @@ -15364,6 +15891,8 @@ ${indent}`); } }).a != 7; }); }, + /* 185 */ + /***/ function(module2, exports2) { module2.exports = function(fn, args, that) { var un = that === void 0; @@ -15382,6 +15911,8 @@ ${indent}`); return fn.apply(that, args); }; }, + /* 186 */ + /***/ function(module2, exports2, __webpack_require__) { var Iterators = __webpack_require__(35); var ITERATOR = __webpack_require__(13)("iterator"); @@ -15390,6 +15921,8 @@ ${indent}`); return it !== void 0 && (Iterators.Array === it || ArrayProto[ITERATOR] === it); }; }, + /* 187 */ + /***/ function(module2, exports2, __webpack_require__) { var anObject = __webpack_require__(27); module2.exports = function(iterator2, fn, value, entries) { @@ -15403,6 +15936,8 @@ ${indent}`); } }; }, + /* 188 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var create = __webpack_require__(192); @@ -15417,6 +15952,8 @@ ${indent}`); setToStringTag(Constructor, NAME + " Iterator"); }; }, + /* 189 */ + /***/ function(module2, exports2, __webpack_require__) { var ITERATOR = __webpack_require__(13)("iterator"); var SAFE_CLOSING = false; @@ -15430,7 +15967,7 @@ ${indent}`); }); } catch (e) { } - module2.exports = function(exec, skipClosing) { + module2.exports = function(exec2, skipClosing) { if (!skipClosing && !SAFE_CLOSING) return false; var safe = false; @@ -15443,29 +15980,33 @@ ${indent}`); arr[ITERATOR] = function() { return iter; }; - exec(arr); + exec2(arr); } catch (e) { } return safe; }; }, + /* 190 */ + /***/ function(module2, exports2) { module2.exports = function(done, value) { return { value, done: !!done }; }; }, + /* 191 */ + /***/ function(module2, exports2, __webpack_require__) { var global = __webpack_require__(11); var macrotask = __webpack_require__(109).set; var Observer = global.MutationObserver || global.WebKitMutationObserver; - var process4 = global.process; + var process3 = global.process; var Promise2 = global.Promise; - var isNode = __webpack_require__(47)(process4) == "process"; + var isNode = __webpack_require__(47)(process3) == "process"; module2.exports = function() { var head, last, notify; var flush = function() { var parent, fn; - if (isNode && (parent = process4.domain)) + if (isNode && (parent = process3.domain)) parent.exit(); while (head) { fn = head.fn; @@ -15486,7 +16027,7 @@ ${indent}`); }; if (isNode) { notify = function() { - process4.nextTick(flush); + process3.nextTick(flush); }; } else if (Observer && !(global.navigator && global.navigator.standalone)) { var toggle = true; @@ -15517,6 +16058,8 @@ ${indent}`); }; }; }, + /* 192 */ + /***/ function(module2, exports2, __webpack_require__) { var anObject = __webpack_require__(27); var dPs = __webpack_require__(193); @@ -15555,6 +16098,8 @@ ${indent}`); return Properties === void 0 ? result : dPs(result, Properties); }; }, + /* 193 */ + /***/ function(module2, exports2, __webpack_require__) { var dP = __webpack_require__(50); var anObject = __webpack_require__(27); @@ -15570,6 +16115,8 @@ ${indent}`); return O; }; }, + /* 194 */ + /***/ function(module2, exports2, __webpack_require__) { var has = __webpack_require__(49); var toObject = __webpack_require__(133); @@ -15585,6 +16132,8 @@ ${indent}`); return O instanceof Object ? ObjectProto : null; }; }, + /* 195 */ + /***/ function(module2, exports2, __webpack_require__) { var has = __webpack_require__(49); var toIObject = __webpack_require__(74); @@ -15605,6 +16154,8 @@ ${indent}`); return result; }; }, + /* 196 */ + /***/ function(module2, exports2, __webpack_require__) { var hide = __webpack_require__(31); module2.exports = function(target, src, safe) { @@ -15617,9 +16168,13 @@ ${indent}`); return target; }; }, + /* 197 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = __webpack_require__(31); }, + /* 198 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var global = __webpack_require__(11); @@ -15638,6 +16193,8 @@ ${indent}`); }); }; }, + /* 199 */ + /***/ function(module2, exports2, __webpack_require__) { var toInteger = __webpack_require__(73); var defined = __webpack_require__(67); @@ -15654,6 +16211,8 @@ ${indent}`); }; }; }, + /* 200 */ + /***/ function(module2, exports2, __webpack_require__) { var toInteger = __webpack_require__(73); var max = Math.max; @@ -15663,6 +16222,8 @@ ${indent}`); return index < 0 ? max(index + length, 0) : min(index, length); }; }, + /* 201 */ + /***/ function(module2, exports2, __webpack_require__) { var isObject = __webpack_require__(34); module2.exports = function(it, S) { @@ -15678,11 +16239,15 @@ ${indent}`); throw TypeError("Can't convert object to primitive value"); }; }, + /* 202 */ + /***/ function(module2, exports2, __webpack_require__) { var global = __webpack_require__(11); var navigator2 = global.navigator; module2.exports = navigator2 && navigator2.userAgent || ""; }, + /* 203 */ + /***/ function(module2, exports2, __webpack_require__) { var classof = __webpack_require__(100); var ITERATOR = __webpack_require__(13)("iterator"); @@ -15692,6 +16257,8 @@ ${indent}`); return it[ITERATOR] || it["@@iterator"] || Iterators[classof(it)]; }; }, + /* 204 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var addToUnscopables = __webpack_require__(180); @@ -15721,8 +16288,12 @@ ${indent}`); addToUnscopables("values"); addToUnscopables("entries"); }, + /* 205 */ + /***/ function(module2, exports2) { }, + /* 206 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var LIBRARY = __webpack_require__(69); @@ -15739,15 +16310,15 @@ ${indent}`); var microtask = __webpack_require__(191)(); var newPromiseCapabilityModule = __webpack_require__(70); var perform = __webpack_require__(104); - var userAgent3 = __webpack_require__(202); + var userAgent2 = __webpack_require__(202); var promiseResolve = __webpack_require__(105); var PROMISE = "Promise"; var TypeError2 = global.TypeError; - var process4 = global.process; - var versions = process4 && process4.versions; + var process3 = global.process; + var versions = process3 && process3.versions; var v8 = versions && versions.v8 || ""; var $Promise = global[PROMISE]; - var isNode = classof(process4) == "process"; + var isNode = classof(process3) == "process"; var empty = function() { }; var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; @@ -15755,10 +16326,10 @@ ${indent}`); var USE_NATIVE = !!function() { try { var promise = $Promise.resolve(1); - var FakePromise = (promise.constructor = {})[__webpack_require__(13)("species")] = function(exec) { - exec(empty, empty); + var FakePromise = (promise.constructor = {})[__webpack_require__(13)("species")] = function(exec2) { + exec2(empty, empty); }; - return (isNode || typeof PromiseRejectionEvent == "function") && promise.then(empty) instanceof FakePromise && v8.indexOf("6.6") !== 0 && userAgent3.indexOf("Chrome/66") === -1; + return (isNode || typeof PromiseRejectionEvent == "function") && promise.then(empty) instanceof FakePromise && v8.indexOf("6.6") !== 0 && userAgent2.indexOf("Chrome/66") === -1; } catch (e) { } }(); @@ -15777,7 +16348,7 @@ ${indent}`); var i = 0; var run = function(reaction) { var handler2 = ok ? reaction.ok : reaction.fail; - var resolve = reaction.resolve; + var resolve5 = reaction.resolve; var reject = reaction.reject; var domain = reaction.domain; var result, then, exited; @@ -15802,9 +16373,9 @@ ${indent}`); if (result === reaction.promise) { reject(TypeError2("Promise-chain cycle")); } else if (then = isThenable(result)) { - then.call(result, resolve, reject); + then.call(result, resolve5, reject); } else - resolve(result); + resolve5(result); } else reject(value); } catch (e) { @@ -15829,7 +16400,7 @@ ${indent}`); if (unhandled) { result = perform(function() { if (isNode) { - process4.emit("unhandledRejection", value, promise); + process3.emit("unhandledRejection", value, promise); } else if (handler2 = global.onunhandledrejection) { handler2({ promise, reason: value }); } else if ((console2 = global.console) && console2.error) { @@ -15850,7 +16421,7 @@ ${indent}`); task.call(global, function() { var handler2; if (isNode) { - process4.emit("rejectionHandled", promise); + process3.emit("rejectionHandled", promise); } else if (handler2 = global.onrejectionhandled) { handler2({ promise, reason: promise._v }); } @@ -15917,11 +16488,12 @@ ${indent}`); this._n = false; }; Internal.prototype = __webpack_require__(196)($Promise.prototype, { + // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) then: function then(onFulfilled, onRejected) { var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); reaction.ok = typeof onFulfilled == "function" ? onFulfilled : true; reaction.fail = typeof onRejected == "function" && onRejected; - reaction.domain = isNode ? process4.domain : void 0; + reaction.domain = isNode ? process3.domain : void 0; this._c.push(reaction); if (this._a) this._a.push(reaction); @@ -15929,6 +16501,7 @@ ${indent}`); notify(this, false); return reaction.promise; }, + // 25.4.5.1 Promise.prototype.catch(onRejected) "catch": function(onRejected) { return this.then(void 0, onRejected); } @@ -15948,6 +16521,7 @@ ${indent}`); __webpack_require__(198)(PROMISE); Wrapper = __webpack_require__(23)[PROMISE]; $export($export.S + $export.F * !USE_NATIVE, PROMISE, { + // 25.4.4.5 Promise.reject(r) reject: function reject(r) { var capability = newPromiseCapability(this); var $$reject = capability.reject; @@ -15956,17 +16530,19 @@ ${indent}`); } }); $export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { - resolve: function resolve(x) { + // 25.4.4.6 Promise.resolve(x) + resolve: function resolve5(x) { return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x); } }); $export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(189)(function(iter) { $Promise.all(iter)["catch"](empty); })), PROMISE, { + // 25.4.4.1 Promise.all(iterable) all: function all(iterable) { var C = this; var capability = newPromiseCapability(C); - var resolve = capability.resolve; + var resolve5 = capability.resolve; var reject = capability.reject; var result = perform(function() { var values = []; @@ -15982,15 +16558,16 @@ ${indent}`); return; alreadyCalled = true; values[$index] = value; - --remaining || resolve(values); + --remaining || resolve5(values); }, reject); }); - --remaining || resolve(values); + --remaining || resolve5(values); }); if (result.e) reject(result.v); return capability.promise; }, + // 25.4.4.4 Promise.race(iterable) race: function race(iterable) { var C = this; var capability = newPromiseCapability(C); @@ -16006,6 +16583,8 @@ ${indent}`); } }); }, + /* 207 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var $at = __webpack_require__(199)(true); @@ -16023,6 +16602,8 @@ ${indent}`); return { value: point, done: false }; }); }, + /* 208 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var $export = __webpack_require__(41); @@ -16032,14 +16613,14 @@ ${indent}`); var promiseResolve = __webpack_require__(105); $export($export.P + $export.R, "Promise", { "finally": function(onFinally) { var C = speciesConstructor(this, core.Promise || global.Promise); - var isFunction = typeof onFinally == "function"; + var isFunction2 = typeof onFinally == "function"; return this.then( - isFunction ? function(x) { + isFunction2 ? function(x) { return promiseResolve(C, onFinally()).then(function() { return x; }); } : onFinally, - isFunction ? function(e) { + isFunction2 ? function(e) { return promiseResolve(C, onFinally()).then(function() { throw e; }); @@ -16047,6 +16628,8 @@ ${indent}`); ); } }); }, + /* 209 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; var $export = __webpack_require__(41); @@ -16059,6 +16642,8 @@ ${indent}`); return promiseCapability.promise; } }); }, + /* 210 */ + /***/ function(module2, exports2, __webpack_require__) { __webpack_require__(204); var global = __webpack_require__(11); @@ -16069,12 +16654,14 @@ ${indent}`); for (var i = 0; i < DOMIterables.length; i++) { var NAME = DOMIterables[i]; var Collection2 = global[NAME]; - var proto2 = Collection2 && Collection2.prototype; - if (proto2 && !proto2[TO_STRING_TAG]) - hide(proto2, TO_STRING_TAG, NAME); + var proto = Collection2 && Collection2.prototype; + if (proto && !proto[TO_STRING_TAG]) + hide(proto, TO_STRING_TAG, NAME); Iterators[NAME] = Iterators.Array; } }, + /* 211 */ + /***/ function(module2, exports2, __webpack_require__) { exports2 = module2.exports = __webpack_require__(112); exports2.log = log; @@ -16168,7 +16755,11 @@ ${indent}`); if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } - return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); } exports2.formatters.j = function(v) { try { @@ -16228,6 +16819,8 @@ ${indent}`); } } }, + /* 212 */ + /***/ function(module2, exports2, __webpack_require__) { if (typeof process === "undefined" || process.type === "renderer") { module2.exports = __webpack_require__(211); @@ -16235,8 +16828,10 @@ ${indent}`); module2.exports = __webpack_require__(213); } }, + /* 213 */ + /***/ function(module2, exports2, __webpack_require__) { - var tty3 = __webpack_require__(79); + var tty2 = __webpack_require__(79); var util = __webpack_require__(2); exports2 = module2.exports = __webpack_require__(112); exports2.init = init; @@ -16247,8 +16842,8 @@ ${indent}`); exports2.useColors = useColors; exports2.colors = [6, 2, 3, 4, 5, 1]; try { - var supportsColor3 = __webpack_require__(239); - if (supportsColor3 && supportsColor3.level >= 2) { + var supportsColor2 = __webpack_require__(239); + if (supportsColor2 && supportsColor2.level >= 2) { exports2.colors = [ 20, 21, @@ -16349,7 +16944,7 @@ ${indent}`); return obj; }, {}); function useColors() { - return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty3.isatty(process.stderr.fd); + return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty2.isatty(process.stderr.fd); } exports2.formatters.o = function(v) { this.inspectOpts.colors = this.useColors; @@ -16378,7 +16973,7 @@ ${indent}`); if (exports2.inspectOpts.hideDate) { return ""; } else { - return new Date().toISOString() + " "; + return (/* @__PURE__ */ new Date()).toISOString() + " "; } } function log() { @@ -16406,6 +17001,8 @@ ${indent}`); , , , + /* 217 */ + /***/ function(module2, exports2, __webpack_require__) { var pathModule = __webpack_require__(0); var isWindows = process.platform === "win32"; @@ -16443,7 +17040,7 @@ ${indent}`); function maybeCallback(cb) { return typeof cb === "function" ? cb : rethrow(); } - var normalize = pathModule.normalize; + var normalize2 = pathModule.normalize; if (isWindows) { var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; } else { @@ -16612,6 +17209,8 @@ ${indent}`); } }; }, + /* 218 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = globSync; globSync.GlobSync = GlobSync; @@ -16963,6 +17562,8 @@ ${indent}`); }, , , + /* 221 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; module2.exports = function(flag, argv) { @@ -16974,6 +17575,8 @@ ${indent}`); }; }, , + /* 223 */ + /***/ function(module2, exports2, __webpack_require__) { var wrappy = __webpack_require__(123); var reqs = /* @__PURE__ */ Object.create(null); @@ -17017,6 +17620,8 @@ ${indent}`); return array; } }, + /* 224 */ + /***/ function(module2, exports2) { if (typeof Object.create === "function") { module2.exports = function inherits(ctor, superCtor) { @@ -17043,10 +17648,14 @@ ${indent}`); }, , , + /* 227 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = typeof __webpack_require__ !== "undefined"; }, , + /* 229 */ + /***/ function(module2, exports2) { var s = 1e3; var m = s * 60; @@ -17057,7 +17666,7 @@ ${indent}`); options = options || {}; var type = typeof val; if (type === "string" && val.length > 0) { - return parse3(val); + return parse2(val); } else if (type === "number" && isNaN(val) === false) { return options.long ? fmtLong(val) : fmtShort(val); } @@ -17065,7 +17674,7 @@ ${indent}`); "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) ); }; - function parse3(str) { + function parse2(str) { str = String(str); if (str.length > 100) { return; @@ -17148,6 +17757,8 @@ ${indent}`); , , , + /* 233 */ + /***/ function(module2, exports2, __webpack_require__) { module2.exports = rimraf; rimraf.sync = rimrafSync; @@ -17436,9 +18047,11 @@ ${indent}`); , , , + /* 239 */ + /***/ function(module2, exports2, __webpack_require__) { "use strict"; - var hasFlag3 = __webpack_require__(221); + var hasFlag2 = __webpack_require__(221); var support = function(level) { if (level === 0) { return false; @@ -17451,16 +18064,16 @@ ${indent}`); }; }; var supportLevel = function() { - if (hasFlag3("no-color") || hasFlag3("no-colors") || hasFlag3("color=false")) { + if (hasFlag2("no-color") || hasFlag2("no-colors") || hasFlag2("color=false")) { return 0; } - if (hasFlag3("color=16m") || hasFlag3("color=full") || hasFlag3("color=truecolor")) { + if (hasFlag2("color=16m") || hasFlag2("color=full") || hasFlag2("color=truecolor")) { return 3; } - if (hasFlag3("color=256")) { + if (hasFlag2("color=256")) { return 2; } - if (hasFlag3("color") || hasFlag3("colors") || hasFlag3("color=true") || hasFlag3("color=always")) { + if (hasFlag2("color") || hasFlag2("colors") || hasFlag2("color=true") || hasFlag2("color=always")) { return 1; } if (process.stdout && !process.stdout.isTTY) { @@ -17497,6 +18110,7 @@ ${indent}`); } module2.exports = process && support(supportLevel); } + /******/ ]); } }); @@ -17731,20 +18345,24 @@ var require_directives = __commonJS({ "}": "%7D" }; var escapeTagName = (tn) => tn.replace(/[!,[\]{}]/g, (ch) => escapeChars[ch]); - var Directives = class { + var Directives = class _Directives { constructor(yaml, tags) { this.docStart = null; this.docEnd = false; - this.yaml = Object.assign({}, Directives.defaultYaml, yaml); - this.tags = Object.assign({}, Directives.defaultTags, tags); + this.yaml = Object.assign({}, _Directives.defaultYaml, yaml); + this.tags = Object.assign({}, _Directives.defaultTags, tags); } clone() { - const copy = new Directives(this.yaml, this.tags); + const copy = new _Directives(this.yaml, this.tags); copy.docStart = this.docStart; return copy; } + /** + * During parsing, get a Directives instance for the current document and + * update the stream state according to the current version's spec. + */ atDocument() { - const res = new Directives(this.yaml, this.tags); + const res = new _Directives(this.yaml, this.tags); switch (this.yaml.version) { case "1.1": this.atNextDocument = true; @@ -17752,18 +18370,22 @@ var require_directives = __commonJS({ case "1.2": this.atNextDocument = false; this.yaml = { - explicit: Directives.defaultYaml.explicit, + explicit: _Directives.defaultYaml.explicit, version: "1.2" }; - this.tags = Object.assign({}, Directives.defaultTags); + this.tags = Object.assign({}, _Directives.defaultTags); break; } return res; } + /** + * @param onError - May be called even if the action was successful + * @returns `true` on success + */ add(line, onError) { if (this.atNextDocument) { - this.yaml = { explicit: Directives.defaultYaml.explicit, version: "1.1" }; - this.tags = Object.assign({}, Directives.defaultTags); + this.yaml = { explicit: _Directives.defaultYaml.explicit, version: "1.1" }; + this.tags = Object.assign({}, _Directives.defaultTags); this.atNextDocument = false; } const parts = line.trim().split(/[ \t]+/); @@ -17800,6 +18422,12 @@ var require_directives = __commonJS({ return false; } } + /** + * Resolves a tag, matching handles to those defined in %TAG directives. + * + * @returns Resolved tag, which may also be the non-specific tag `'!'` or a + * `'!local'` tag, or `null` if unresolvable. + */ tagName(source, onError) { if (source === "!") return "!"; @@ -17834,6 +18462,10 @@ var require_directives = __commonJS({ onError(`Could not resolve tag: ${source}`); return null; } + /** + * Given a fully resolved tag, returns its printable string form, + * taking into account current tag prefixes and defaults. + */ tagString(tag) { for (const [handle, prefix] of Object.entries(this.tags)) { if (tag.startsWith(prefix)) @@ -17907,12 +18539,16 @@ var require_anchors = __commonJS({ return { onAnchor: (source) => { aliasObjects.push(source); - if (!prevAnchors) - prevAnchors = anchorNames(doc); + prevAnchors ?? (prevAnchors = anchorNames(doc)); const anchor = findNewAnchor(prefix, prevAnchors); prevAnchors.add(anchor); return anchor; }, + /** + * With circular references, the source node is only resolved after all + * of its child nodes are. This is why anchors are set only after all of + * the nodes have been created. + */ setAnchors: () => { for (const source of aliasObjects) { const ref = sourceObjects.get(source); @@ -18026,12 +18662,14 @@ var require_Node = __commonJS({ constructor(type) { Object.defineProperty(this, identity.NODE_TYPE, { value: type }); } + /** Create a copy of this node. */ clone() { const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this)); if (this.range) copy.range = this.range.slice(); return copy; } + /** A plain JavaScript representation of this node. */ toJS(doc, { mapAsMap, maxAliasCount, onAnchor, reviver } = {}) { if (!identity.isDocument(doc)) throw new TypeError("A document argument is required"); @@ -18073,23 +18711,39 @@ var require_Alias = __commonJS({ } }); } - resolve(doc) { + /** + * Resolve the value of this alias within `doc`, finding the last + * instance of the `source` anchor before this node. + */ + resolve(doc, ctx) { + let nodes; + if (ctx?.aliasResolveCache) { + nodes = ctx.aliasResolveCache; + } else { + nodes = []; + visit.visit(doc, { + Node: (_key, node) => { + if (identity.isAlias(node) || identity.hasAnchor(node)) + nodes.push(node); + } + }); + if (ctx) + ctx.aliasResolveCache = nodes; + } let found = void 0; - visit.visit(doc, { - Node: (_key, node) => { - if (node === this) - return visit.visit.BREAK; - if (node.anchor === this.source) - found = node; - } - }); + for (const node of nodes) { + if (node === this) + break; + if (node.anchor === this.source) + found = node; + } return found; } toJSON(_arg, ctx) { if (!ctx) return { source: this.source }; const { anchors: anchors2, doc, maxAliasCount } = ctx; - const source = this.resolve(doc); + const source = this.resolve(doc, ctx); if (!source) { const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`; throw new ReferenceError(msg); @@ -18218,8 +18872,7 @@ var require_createNode = __commonJS({ if (aliasDuplicateObjects && value && typeof value === "object") { ref = sourceObjects.get(value); if (ref) { - if (!ref.anchor) - ref.anchor = onAnchor(value); + ref.anchor ?? (ref.anchor = onAnchor(value)); return new Alias.Alias(ref.anchor); } else { ref = { anchor: null, node: null }; @@ -18298,6 +18951,11 @@ var require_Collection = __commonJS({ writable: true }); } + /** + * Create a copy of this collection. + * + * @param schema - If defined, overwrites the original's schema + */ clone(schema) { const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this)); if (schema) @@ -18307,6 +18965,11 @@ var require_Collection = __commonJS({ copy.range = this.range.slice(); return copy; } + /** + * Adds a value to the collection. For `!!map` and `!!omap` the value must + * be a Pair instance or a `{ key, value }` object, which may not have a key + * that already exists in the map. + */ addIn(path, value) { if (isEmptyPath(path)) this.add(value); @@ -18321,6 +18984,10 @@ var require_Collection = __commonJS({ throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); } } + /** + * Removes a value from the collection. + * @returns `true` if the item was found and removed. + */ deleteIn(path) { const [key, ...rest] = path; if (rest.length === 0) @@ -18331,6 +18998,11 @@ var require_Collection = __commonJS({ else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); } + /** + * Returns item at `key`, or `undefined` if not found. By default unwraps + * scalar values from their surrounding node; to disable set `keepScalar` to + * `true` (collections are always returned intact). + */ getIn(path, keepScalar) { const [key, ...rest] = path; const node = this.get(key, true); @@ -18347,6 +19019,9 @@ var require_Collection = __commonJS({ return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag; }); } + /** + * Checks if the collection includes a value with the key `key`. + */ hasIn(path) { const [key, ...rest] = path; if (rest.length === 0) @@ -18354,6 +19029,10 @@ var require_Collection = __commonJS({ const node = this.get(key, true); return identity.isCollection(node) ? node.hasIn(rest) : false; } + /** + * Sets a value in this collection. For `!!set`, `value` needs to be a + * boolean to add/remove the item from the set. + */ setIn(path, value) { const [key, ...rest] = path; if (rest.length === 0) { @@ -18671,7 +19350,7 @@ ${indent}`) + "'"; } function blockString({ comment, type, value }, ctx, onComment, onChompKeep) { const { blockQuote, commentString, lineWidth } = ctx.options; - if (!blockQuote || /\n[\t ]+$/.test(value) || /^\s*$/.test(value)) { + if (!blockQuote || /\n[\t ]+$/.test(value)) { return quotedString(value, ctx); } const indent = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? " " : ""); @@ -18750,7 +19429,7 @@ ${indent}${start}${value}${end}`; if (implicitKey && value.includes("\n") || inFlow && /[[\]{},]/.test(value)) { return quotedString(value, ctx); } - if (!value || /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) { + if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) { return implicitKey || inFlow || !value.includes("\n") ? quotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep); } if (!implicitKey && !inFlow && type !== Scalar.Scalar.PLAIN && value.includes("\n")) { @@ -18882,7 +19561,7 @@ var require_stringify = __commonJS({ tagObj = tags.find((t) => t.nodeClass && obj instanceof t.nodeClass); } if (!tagObj) { - const name = obj?.constructor?.name ?? typeof obj; + const name = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj); throw new Error(`Tag not resolved for ${name} value`); } return tagObj; @@ -18896,7 +19575,7 @@ var require_stringify = __commonJS({ anchors$1.add(anchor); props.push(`&${anchor}`); } - const tag = node.tag ? node.tag : tagObj.default ? null : tagObj.tag; + const tag = node.tag ?? (tagObj.default ? null : tagObj.tag); if (tag) props.push(doc.directives.tagString(tag)); return props.join(" "); @@ -18919,8 +19598,7 @@ var require_stringify = __commonJS({ } let tagObj = void 0; const node = identity.isNode(item) ? item : ctx.doc.createNode(item, { onTagObj: (o) => tagObj = o }); - if (!tagObj) - tagObj = getTagObject(ctx.doc.schema.tags, node); + tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node)); const props = stringifyProps(node, tagObj, ctx); if (props.length > 0) ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1; @@ -19072,7 +19750,7 @@ ${ctx.indent}`; var require_log = __commonJS({ ""(exports) { "use strict"; - var node_process = __require("node:process"); + var node_process = __require("process"); function debug(logLevel, ...messages) { if (logLevel === "debug") console.log(...messages); @@ -19097,7 +19775,7 @@ var require_merge = __commonJS({ var identity = require_identity(); var Scalar = require_Scalar(); var MERGE_KEY = "<<"; - var merge3 = { + var merge2 = { identify: (value) => value === MERGE_KEY || typeof value === "symbol" && value.description === MERGE_KEY, default: "key", tag: "tag:yaml.org,2002:merge", @@ -19107,7 +19785,7 @@ var require_merge = __commonJS({ }), stringify: () => MERGE_KEY }; - var isMergeKey = (ctx, key) => (merge3.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge3.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge3.tag && tag.default); + var isMergeKey = (ctx, key) => (merge2.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge2.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge2.tag && tag.default); function addMergeToJSMap(ctx, map, value) { value = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value; if (identity.isSeq(value)) @@ -19143,7 +19821,7 @@ var require_merge = __commonJS({ } exports.addMergeToJSMap = addMergeToJSMap; exports.isMergeKey = isMergeKey; - exports.merge = merge3; + exports.merge = merge2; } }); @@ -19152,15 +19830,15 @@ var require_addPairToJSMap = __commonJS({ ""(exports) { "use strict"; var log = require_log(); - var merge3 = require_merge(); + var merge2 = require_merge(); var stringify = require_stringify(); var identity = require_identity(); var toJS = require_toJS(); function addPairToJSMap(ctx, map, { key, value }) { if (identity.isNode(key) && key.addToJSMap) key.addToJSMap(ctx, map, value); - else if (merge3.isMergeKey(ctx, key)) - merge3.addMergeToJSMap(ctx, map, value); + else if (merge2.isMergeKey(ctx, key)) + merge2.addMergeToJSMap(ctx, map, value); else { const jsKey = toJS.toJS(key, "", ctx); if (map instanceof Map) { @@ -19224,7 +19902,7 @@ var require_Pair = __commonJS({ const v = createNode.createNode(value, void 0, ctx); return new Pair(k, v); } - var Pair = class { + var Pair = class _Pair { constructor(key, value = null) { Object.defineProperty(this, identity.NODE_TYPE, { value: identity.PAIR }); this.key = key; @@ -19236,7 +19914,7 @@ var require_Pair = __commonJS({ key = key.clone(schema); if (identity.isNode(value)) value = value.clone(schema); - return new Pair(key, value); + return new _Pair(key, value); } toJSON(_, ctx) { const pair = ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {}; @@ -19425,6 +20103,10 @@ var require_YAMLMap = __commonJS({ super(identity.MAP, schema); this.items = []; } + /** + * A generic collection parsing method that can be extended + * to other node classes that inherit from YAMLMap + */ static from(schema, obj, ctx) { const { keepUndefined, replacer } = ctx; const map = new this(schema); @@ -19448,6 +20130,12 @@ var require_YAMLMap = __commonJS({ } return map; } + /** + * Adds a value to the collection. + * + * @param overwrite - If not set `true`, using a key that is already in the + * collection will throw. Otherwise, overwrites the previous value. + */ add(pair, overwrite) { let _pair; if (identity.isPair(pair)) @@ -19493,6 +20181,11 @@ var require_YAMLMap = __commonJS({ set(key, value) { this.add(new Pair.Pair(key, value), true); } + /** + * @param ctx - Conversion context, originally set in Document#toJS() + * @param {Class} Type - If set, forces the returned collection type + * @returns Instance of Type, Map, or Object + */ toJSON(_, ctx, Type) { const map = Type ? new Type() : ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {}; if (ctx?.onCreate) @@ -19567,6 +20260,14 @@ var require_YAMLSeq = __commonJS({ add(value) { this.items.push(value); } + /** + * Removes a value from the collection. + * + * `key` must contain a representation of an integer for this to succeed. + * It may be wrapped in a `Scalar`. + * + * @returns `true` if the item was found and removed. + */ delete(key) { const idx = asItemIndex(key); if (typeof idx !== "number") @@ -19581,10 +20282,23 @@ var require_YAMLSeq = __commonJS({ const it = this.items[idx]; return !keepScalar && identity.isScalar(it) ? it.value : it; } + /** + * Checks if the collection includes a value with the key `key`. + * + * `key` must contain a representation of an integer for this to succeed. + * It may be wrapped in a `Scalar`. + */ has(key) { const idx = asItemIndex(key); return typeof idx === "number" && idx < this.items.length; } + /** + * Sets a value in this collection. For `!!set`, `value` needs to be a + * boolean to add/remove the item from the set. + * + * If `key` does not contain a representation of an integer, this will throw. + * It may be wrapped in a `Scalar`. + */ set(key, value) { const idx = asItemIndex(key); if (typeof idx !== "number") @@ -19728,14 +20442,14 @@ var require_bool = __commonJS({ var require_stringifyNumber = __commonJS({ ""(exports) { "use strict"; - function stringifyNumber({ format, minFractionDigits, tag, value }) { + function stringifyNumber({ format: format3, minFractionDigits, tag, value }) { if (typeof value === "bigint") return String(value); const num = typeof value === "number" ? value : Number(value); if (!isFinite(num)) return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf"; let n = JSON.stringify(value); - if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) { + if (!format3 && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) { let i = n.indexOf("."); if (i < 0) { i = n.length; @@ -19941,13 +20655,22 @@ var require_schema2 = __commonJS({ var require_binary = __commonJS({ ""(exports) { "use strict"; - var node_buffer = __require("node:buffer"); + var node_buffer = __require("buffer"); var Scalar = require_Scalar(); var stringifyString = require_stringifyString(); var binary = { identify: (value) => value instanceof Uint8Array, + // Buffer inherits from Uint8Array default: false, tag: "tag:yaml.org,2002:binary", + /** + * Returns a Buffer in node and an Uint8Array in browsers + * + * To use the resulting buffer as an image, you'll want to do something like: + * + * const blob = new Blob([buffer], { type: 'image/jpeg' }) + * document.querySelector('#photo').src = URL.createObjectURL(blob) + */ resolve(src, onError) { if (typeof node_buffer.Buffer === "function") { return node_buffer.Buffer.from(src, "base64"); @@ -19977,8 +20700,7 @@ var require_binary = __commonJS({ } else { throw new Error("This environment does not support writing binary tags; either Buffer or btoa is required"); } - if (!type) - type = Scalar.Scalar.BLOCK_LITERAL; + type ?? (type = Scalar.Scalar.BLOCK_LITERAL); if (type !== Scalar.Scalar.QUOTE_DOUBLE) { const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth); const n = Math.ceil(str.length / lineWidth); @@ -20082,7 +20804,7 @@ var require_omap = __commonJS({ var YAMLMap = require_YAMLMap(); var YAMLSeq = require_YAMLSeq(); var pairs = require_pairs(); - var YAMLOMap = class extends YAMLSeq.YAMLSeq { + var YAMLOMap = class _YAMLOMap extends YAMLSeq.YAMLSeq { constructor() { super(); this.add = YAMLMap.YAMLMap.prototype.add.bind(this); @@ -20090,8 +20812,12 @@ var require_omap = __commonJS({ this.get = YAMLMap.YAMLMap.prototype.get.bind(this); this.has = YAMLMap.YAMLMap.prototype.has.bind(this); this.set = YAMLMap.YAMLMap.prototype.set.bind(this); - this.tag = YAMLOMap.tag; + this.tag = _YAMLOMap.tag; } + /** + * If `ctx` is given, the return type is actually `Map`, + * but TypeScript won't allow widening the signature of a child method. + */ toJSON(_, ctx) { if (!ctx) return super.toJSON(_); @@ -20314,10 +21040,10 @@ var require_set = __commonJS({ var identity = require_identity(); var Pair = require_Pair(); var YAMLMap = require_YAMLMap(); - var YAMLSet = class extends YAMLMap.YAMLMap { + var YAMLSet = class _YAMLSet extends YAMLMap.YAMLMap { constructor(schema) { super(schema); - this.tag = YAMLSet.tag; + this.tag = _YAMLSet.tag; } add(key) { let pair; @@ -20331,6 +21057,10 @@ var require_set = __commonJS({ if (!prev) this.items.push(pair); } + /** + * If `keepPair` is `true`, returns the Pair matching `key`. + * Otherwise, returns the value of that Pair's key. + */ get(key, keepPair) { const pair = YAMLMap.findPair(this.items, key); return !keepPair && identity.isPair(pair) ? identity.isScalar(pair.key) ? pair.key.value : pair.key : pair; @@ -20452,6 +21182,9 @@ var require_timestamp = __commonJS({ identify: (value) => value instanceof Date, default: true, tag: "tag:yaml.org,2002:timestamp", + // If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part + // may be omitted altogether, resulting in a date format. In such a case, the time part is + // assumed to be 00:00:00Z (start of day, UTC). test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"), resolve(str) { const match = str.match(timestamp.test); @@ -20489,7 +21222,7 @@ var require_schema3 = __commonJS({ var bool = require_bool2(); var float = require_float2(); var int = require_int2(); - var merge3 = require_merge(); + var merge2 = require_merge(); var omap = require_omap(); var pairs = require_pairs(); var set = require_set(); @@ -20509,7 +21242,7 @@ var require_schema3 = __commonJS({ float.floatExp, float.float, binary.binary, - merge3.merge, + merge2.merge, omap.omap, pairs.pairs, set.set, @@ -20535,7 +21268,7 @@ var require_tags = __commonJS({ var schema = require_schema(); var schema$1 = require_schema2(); var binary = require_binary(); - var merge3 = require_merge(); + var merge2 = require_merge(); var omap = require_omap(); var pairs = require_pairs(); var schema$2 = require_schema3(); @@ -20560,7 +21293,7 @@ var require_tags = __commonJS({ intOct: int.intOct, intTime: timestamp.intTime, map: map.map, - merge: merge3.merge, + merge: merge2.merge, null: _null.nullTag, omap: omap.omap, pairs: pairs.pairs, @@ -20570,7 +21303,7 @@ var require_tags = __commonJS({ }; var coreKnownTags = { "tag:yaml.org,2002:binary": binary.binary, - "tag:yaml.org,2002:merge": merge3.merge, + "tag:yaml.org,2002:merge": merge2.merge, "tag:yaml.org,2002:omap": omap.omap, "tag:yaml.org,2002:pairs": pairs.pairs, "tag:yaml.org,2002:set": set.set, @@ -20579,7 +21312,7 @@ var require_tags = __commonJS({ function getTags(customTags, schemaName, addMergeTag) { const schemaTags = schemas.get(schemaName); if (schemaTags && !customTags) { - return addMergeTag && !schemaTags.includes(merge3.merge) ? schemaTags.concat(merge3.merge) : schemaTags.slice(); + return addMergeTag && !schemaTags.includes(merge2.merge) ? schemaTags.concat(merge2.merge) : schemaTags.slice(); } let tags = schemaTags; if (!tags) { @@ -20597,7 +21330,7 @@ var require_tags = __commonJS({ tags = customTags(tags.slice()); } if (addMergeTag) - tags = tags.concat(merge3.merge); + tags = tags.concat(merge2.merge); return tags.reduce((tags2, tag) => { const tagObj = typeof tag === "string" ? tagsByName[tag] : tag; if (!tagObj) { @@ -20625,12 +21358,12 @@ var require_Schema = __commonJS({ var string = require_string(); var tags = require_tags(); var sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0; - var Schema = class { - constructor({ compat, customTags, merge: merge3, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) { + var Schema = class _Schema { + constructor({ compat, customTags, merge: merge2, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) { this.compat = Array.isArray(compat) ? tags.getTags(compat, "compat") : compat ? tags.getTags(null, compat) : null; this.name = typeof schema === "string" && schema || "core"; this.knownTags = resolveKnownTags ? tags.coreKnownTags : {}; - this.tags = tags.getTags(customTags, this.name, merge3); + this.tags = tags.getTags(customTags, this.name, merge2); this.toStringOptions = toStringDefaults ?? null; Object.defineProperty(this, identity.MAP, { value: map.map }); Object.defineProperty(this, identity.SCALAR, { value: string.string }); @@ -20638,7 +21371,7 @@ var require_Schema = __commonJS({ this.sortMapEntries = typeof sortMapEntries === "function" ? sortMapEntries : sortMapEntries === true ? sortMapEntriesByKey : null; } clone() { - const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this)); + const copy = Object.create(_Schema.prototype, Object.getOwnPropertyDescriptors(this)); copy.tags = this.tags.slice(); return copy; } @@ -20742,7 +21475,7 @@ var require_Document = __commonJS({ var applyReviver = require_applyReviver(); var createNode = require_createNode(); var directives = require_directives(); - var Document = class { + var Document = class _Document { constructor(value, replacer, options) { this.commentBefore = null; this.comment = null; @@ -20777,8 +21510,13 @@ var require_Document = __commonJS({ this.setSchema(version, options); this.contents = value === void 0 ? null : this.createNode(value, _replacer, options); } + /** + * Create a deep copy of this Document and its contents. + * + * Custom Node values that inherit from `Object` still refer to their original instances. + */ clone() { - const copy = Object.create(Document.prototype, { + const copy = Object.create(_Document.prototype, { [identity.NODE_TYPE]: { value: identity.DOC } }); copy.commentBefore = this.commentBefore; @@ -20794,18 +21532,30 @@ var require_Document = __commonJS({ copy.range = this.range.slice(); return copy; } + /** Adds a value to the document. */ add(value) { if (assertCollection(this.contents)) this.contents.add(value); } + /** Adds a value to the document. */ addIn(path, value) { if (assertCollection(this.contents)) this.contents.addIn(path, value); } + /** + * Create a new `Alias` node, ensuring that the target `node` has the required anchor. + * + * If `node` already has an anchor, `name` is ignored. + * Otherwise, the `node.anchor` value will be set to `name`, + * or if an anchor with that name is already present in the document, + * `name` will be used as a prefix for a new unique anchor. + * If `name` is undefined, the generated anchor will use 'a' as a prefix. + */ createAlias(node, name) { if (!node.anchor) { const prev = anchors.anchorNames(this); - node.anchor = !name || prev.has(name) ? anchors.findNewAnchor(name || "a", prev) : name; + node.anchor = // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + !name || prev.has(name) ? anchors.findNewAnchor(name || "a", prev) : name; } return new Alias.Alias(node.anchor); } @@ -20827,6 +21577,7 @@ var require_Document = __commonJS({ const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {}; const { onAnchor, setAnchors, sourceObjects } = anchors.createNodeAnchors( this, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing anchorPrefix || "a" ); const ctx = { @@ -20844,14 +21595,26 @@ var require_Document = __commonJS({ setAnchors(); return node; } + /** + * Convert a key and a value into a `Pair` using the current schema, + * recursively wrapping all values as `Scalar` or `Collection` nodes. + */ createPair(key, value, options = {}) { const k = this.createNode(key, null, options); const v = this.createNode(value, null, options); return new Pair.Pair(k, v); } + /** + * Removes a value from the document. + * @returns `true` if the item was found and removed. + */ delete(key) { return assertCollection(this.contents) ? this.contents.delete(key) : false; } + /** + * Removes a value from the document. + * @returns `true` if the item was found and removed. + */ deleteIn(path) { if (Collection2.isEmptyPath(path)) { if (this.contents == null) @@ -20861,22 +21624,42 @@ var require_Document = __commonJS({ } return assertCollection(this.contents) ? this.contents.deleteIn(path) : false; } + /** + * Returns item at `key`, or `undefined` if not found. By default unwraps + * scalar values from their surrounding node; to disable set `keepScalar` to + * `true` (collections are always returned intact). + */ get(key, keepScalar) { return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : void 0; } + /** + * Returns item at `path`, or `undefined` if not found. By default unwraps + * scalar values from their surrounding node; to disable set `keepScalar` to + * `true` (collections are always returned intact). + */ getIn(path, keepScalar) { if (Collection2.isEmptyPath(path)) return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents; return identity.isCollection(this.contents) ? this.contents.getIn(path, keepScalar) : void 0; } + /** + * Checks if the document includes a value with the key `key`. + */ has(key) { return identity.isCollection(this.contents) ? this.contents.has(key) : false; } + /** + * Checks if the document includes a value at `path`. + */ hasIn(path) { if (Collection2.isEmptyPath(path)) return this.contents !== void 0; return identity.isCollection(this.contents) ? this.contents.hasIn(path) : false; } + /** + * Sets a value in this document. For `!!set`, `value` needs to be a + * boolean to add/remove the item from the set. + */ set(key, value) { if (this.contents == null) { this.contents = Collection2.collectionFromPath(this.schema, [key], value); @@ -20884,6 +21667,10 @@ var require_Document = __commonJS({ this.contents.set(key, value); } } + /** + * Sets a value in this document. For `!!set`, `value` needs to be a + * boolean to add/remove the item from the set. + */ setIn(path, value) { if (Collection2.isEmptyPath(path)) { this.contents = value; @@ -20893,6 +21680,13 @@ var require_Document = __commonJS({ this.contents.setIn(path, value); } } + /** + * Change the YAML version and schema used by the document. + * A `null` version disables support for directives, explicit tags, anchors, and aliases. + * It also requires the `schema` option to be given as a `Schema` instance value. + * + * Overrides all previously set schema options. + */ setSchema(version, options = {}) { if (typeof version === "number") version = String(version); @@ -20930,6 +21724,7 @@ var require_Document = __commonJS({ else throw new Error(`With a null YAML version, the { schema: Schema } option is required`); } + // json & jsonArg are only used from toJSON() toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) { const ctx = { anchors: /* @__PURE__ */ new Map(), @@ -20945,9 +21740,16 @@ var require_Document = __commonJS({ onAnchor(res2, count); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } + /** + * A JSON representation of the document `contents`. + * + * @param jsonArg Used by `JSON.stringify` to indicate the array index or + * property name. + */ toJSON(jsonArg, onAnchor) { return this.toJS({ json: true, jsonArg, mapAsMap: false, onAnchor }); } + /** A YAML representation of the document. */ toString(options = {}) { if (this.errors.length > 0) throw new Error("Document with errors cannot be stringified"); @@ -21102,8 +21904,7 @@ var require_resolve_props = __commonJS({ if (token.source.endsWith(":")) onError(token.offset + token.source.length - 1, "BAD_ALIAS", "Anchor ending in : is ambiguous", true); anchor = token; - if (start === null) - start = token.offset; + start ?? (start = token.offset); atNewline = false; hasSpace = false; reqSpace = true; @@ -21112,8 +21913,7 @@ var require_resolve_props = __commonJS({ if (tag) onError(token, "MULTIPLE_TAGS", "A node can have at most one tag"); tag = token; - if (start === null) - start = token.offset; + start ?? (start = token.offset); atNewline = false; hasSpace = false; reqSpace = true; @@ -21501,6 +22301,7 @@ var require_resolve_flow_collection = __commonJS({ if (!isMap && ctx.options.strict && utilContainsNewline.containsNewline(key)) onError( key, + // checked by containsNewline() "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line" ); @@ -22056,18 +22857,31 @@ var require_resolve_flow_scalar = __commonJS({ } var escapeCodes = { "0": "\0", + // null character a: "\x07", + // bell character b: "\b", + // backspace e: "\x1B", + // escape character f: "\f", + // form feed n: "\n", + // line feed r: "\r", + // carriage return t: " ", + // horizontal tab v: "\v", + // vertical tab N: "\x85", + // Unicode next line _: "\xA0", + // Unicode non-breaking space L: "\u2028", + // Unicode line separator P: "\u2029", + // Unicode paragraph separator " ": " ", '"': '"', "/": "/", @@ -22176,8 +22990,7 @@ var require_util_empty_scalar_position = __commonJS({ "use strict"; function emptyScalarPosition(offset, before, pos) { if (before) { - if (pos === null) - pos = before.length; + pos ?? (pos = before.length); for (let i = pos - 1; i >= 0; --i) { let st = before[i]; switch (st.type) { @@ -22349,7 +23162,7 @@ var require_compose_doc = __commonJS({ var require_composer = __commonJS({ ""(exports) { "use strict"; - var node_process = __require("node:process"); + var node_process = __require("process"); var directives = require_directives(); var Document = require_Document(); var errors = require_errors(); @@ -22439,6 +23252,11 @@ ${cb}` : comment; this.errors = []; this.warnings = []; } + /** + * Current stream status information. + * + * Mostly useful at the end of input for an empty stream. + */ streamInfo() { return { comment: parsePrelude(this.prelude).comment, @@ -22447,11 +23265,18 @@ ${cb}` : comment; warnings: this.warnings }; } + /** + * Compose tokens into documents. + * + * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document. + * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly. + */ *compose(tokens, forceDoc = false, endOffset = -1) { for (const token of tokens) yield* this.next(token); yield* this.end(forceDoc, endOffset); } + /** Advance the composer by one CST token. */ *next(token) { if (node_process.env.LOG_STREAM) console.dir(token, { depth: null }); @@ -22513,6 +23338,12 @@ ${end.comment}` : end.comment; this.errors.push(new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", `Unsupported token ${token.type}`)); } } + /** + * Call at end of input to yield any remaining document. + * + * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document. + * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly. + */ *end(forceDoc = false, endOffset = -1) { if (this.doc) { this.decorate(this.doc, true); @@ -22979,6 +23810,12 @@ var require_lexer = __commonJS({ this.next = null; this.pos = 0; } + /** + * Generate YAML tokens from the `source` string. If `incomplete`, + * a part of the last line may be left as a buffer for the next call. + * + * @returns A generator of lexical tokens + */ *lex(source, incomplete = false) { if (source) { if (typeof source !== "string") @@ -23547,7 +24384,7 @@ var require_line_counter = __commonJS({ var require_parser = __commonJS({ ""(exports) { "use strict"; - var node_process = __require("node:process"); + var node_process = __require("process"); var cst = require_cst(); var lexer = require_lexer(); function includesToken(list, type) { @@ -23633,7 +24470,11 @@ var require_parser = __commonJS({ } } } - var Parser = class { + var Parser2 = class { + /** + * @param onNewLine - If defined, called separately with the start position of + * each new line (in `parse()`, including the start of input). + */ constructor(onNewLine) { this.atNewLine = true; this.atScalar = false; @@ -23646,6 +24487,14 @@ var require_parser = __commonJS({ this.lexer = new lexer.Lexer(); this.onNewLine = onNewLine; } + /** + * Parse `source` as a YAML stream. + * If `incomplete`, a part of the last line may be left as a buffer for the next call. + * + * Errors are not thrown, but yielded as `{ type: 'error', message }` tokens. + * + * @returns A generator of tokens representing each directive, document, and other structure. + */ *parse(source, incomplete = false) { if (this.onNewLine && this.offset === 0) this.onNewLine(0); @@ -23654,6 +24503,9 @@ var require_parser = __commonJS({ if (!incomplete) yield* this.end(); } + /** + * Advance the parser by the `source` of one lexical token. + */ *next(source) { this.source = source; if (node_process.env.LOG_TOKENS) @@ -23702,6 +24554,7 @@ var require_parser = __commonJS({ this.offset += source.length; } } + /** Call at end of input to push out any remaining constructions */ *end() { while (this.stack.length > 0) yield* this.pop(); @@ -23716,8 +24569,8 @@ var require_parser = __commonJS({ return st; } *step() { - const top = this.peek(1); - if (this.type === "doc-end" && (!top || top.type !== "doc-end")) { + const top2 = this.peek(1); + if (this.type === "doc-end" && (!top2 || top2.type !== "doc-end")) { while (this.stack.length > 0) yield* this.pop(); this.stack.push({ @@ -23727,26 +24580,26 @@ var require_parser = __commonJS({ }); return; } - if (!top) + if (!top2) return yield* this.stream(); - switch (top.type) { + switch (top2.type) { case "document": - return yield* this.document(top); + return yield* this.document(top2); case "alias": case "scalar": case "single-quoted-scalar": case "double-quoted-scalar": - return yield* this.scalar(top); + return yield* this.scalar(top2); case "block-scalar": - return yield* this.blockScalar(top); + return yield* this.blockScalar(top2); case "block-map": - return yield* this.blockMap(top); + return yield* this.blockMap(top2); case "block-seq": - return yield* this.blockSequence(top); + return yield* this.blockSequence(top2); case "flow-collection": - return yield* this.flowCollection(top); + return yield* this.flowCollection(top2); case "doc-end": - return yield* this.documentEnd(top); + return yield* this.documentEnd(top2); } yield* this.pop(); } @@ -23761,25 +24614,25 @@ var require_parser = __commonJS({ } else if (this.stack.length === 0) { yield token; } else { - const top = this.peek(1); + const top2 = this.peek(1); if (token.type === "block-scalar") { - token.indent = "indent" in top ? top.indent : 0; - } else if (token.type === "flow-collection" && top.type === "document") { + token.indent = "indent" in top2 ? top2.indent : 0; + } else if (token.type === "flow-collection" && top2.type === "document") { token.indent = 0; } if (token.type === "flow-collection") fixFlowSeqItems(token); - switch (top.type) { + switch (top2.type) { case "document": - top.value = token; + top2.value = token; break; case "block-scalar": - top.props.push(token); + top2.props.push(token); break; case "block-map": { - const it = top.items[top.items.length - 1]; + const it = top2.items[top2.items.length - 1]; if (it.value) { - top.items.push({ start: [], key: token, sep: [] }); + top2.items.push({ start: [], key: token, sep: [] }); this.onKeyLine = true; return; } else if (it.sep) { @@ -23792,17 +24645,17 @@ var require_parser = __commonJS({ break; } case "block-seq": { - const it = top.items[top.items.length - 1]; + const it = top2.items[top2.items.length - 1]; if (it.value) - top.items.push({ start: [], value: token }); + top2.items.push({ start: [], value: token }); else it.value = token; break; } case "flow-collection": { - const it = top.items[top.items.length - 1]; + const it = top2.items[top2.items.length - 1]; if (!it || it.value) - top.items.push({ start: [], key: token, sep: [] }); + top2.items.push({ start: [], key: token, sep: [] }); else if (it.sep) it.value = token; else @@ -23813,13 +24666,13 @@ var require_parser = __commonJS({ yield* this.pop(); yield* this.pop(token); } - if ((top.type === "document" || top.type === "block-map" || top.type === "block-seq") && (token.type === "block-map" || token.type === "block-seq")) { + if ((top2.type === "document" || top2.type === "block-map" || top2.type === "block-seq") && (token.type === "block-map" || token.type === "block-seq")) { const last = token.items[token.items.length - 1]; if (last && !last.sep && !last.value && last.start.length > 0 && findNonEmptyIndex(last.start) === -1 && (token.indent === 0 || last.start.every((st) => st.type !== "comment" || st.indent < token.indent))) { - if (top.type === "document") - top.end = last.start; + if (top2.type === "document") + top2.end = last.start; else - top.items.push({ start: last.start }); + top2.items.push({ start: last.start }); token.items.splice(-1, 1); } } @@ -24189,11 +25042,11 @@ var require_parser = __commonJS({ *flowCollection(fc) { const it = fc.items[fc.items.length - 1]; if (this.type === "flow-error-end") { - let top; + let top2; do { yield* this.pop(); - top = this.peek(1); - } while (top && top.type === "flow-collection"); + top2 = this.peek(1); + } while (top2 && top2.type === "flow-collection"); } else if (fc.end.length === 0) { switch (this.type) { case "comma": @@ -24387,7 +25240,7 @@ var require_parser = __commonJS({ } } }; - exports.Parser = Parser; + exports.Parser = Parser2; } }); @@ -24401,7 +25254,7 @@ var require_public_api = __commonJS({ var log = require_log(); var identity = require_identity(); var lineCounter = require_line_counter(); - var parser = require_parser(); + var parser2 = require_parser(); function parseOptions(options) { const prettyErrors = options.prettyErrors !== false; const lineCounter$1 = options.lineCounter || prettyErrors && new lineCounter.LineCounter() || null; @@ -24409,7 +25262,7 @@ var require_public_api = __commonJS({ } function parseAllDocuments(source, options = {}) { const { lineCounter: lineCounter2, prettyErrors } = parseOptions(options); - const parser$1 = new parser.Parser(lineCounter2?.addNewLine); + const parser$1 = new parser2.Parser(lineCounter2?.addNewLine); const composer$1 = new composer.Composer(options); const docs = Array.from(composer$1.compose(parser$1.parse(source))); if (prettyErrors && lineCounter2) @@ -24423,7 +25276,7 @@ var require_public_api = __commonJS({ } function parseDocument(source, options = {}) { const { lineCounter: lineCounter2, prettyErrors } = parseOptions(options); - const parser$1 = new parser.Parser(lineCounter2?.addNewLine); + const parser$1 = new parser2.Parser(lineCounter2?.addNewLine); const composer$1 = new composer.Composer(options); let doc = null; for (const _doc of composer$1.compose(parser$1.parse(source), true, source.length)) { @@ -24440,7 +25293,7 @@ var require_public_api = __commonJS({ } return doc; } - function parse3(src, reviver, options) { + function parse2(src, reviver, options) { let _reviver = void 0; if (typeof reviver === "function") { _reviver = reviver; @@ -24481,7 +25334,7 @@ var require_public_api = __commonJS({ return value.toString(options); return new Document.Document(value, _replacer, options).toString(options); } - exports.parse = parse3; + exports.parse = parse2; exports.parseAllDocuments = parseAllDocuments; exports.parseDocument = parseDocument; exports.stringify = stringify; @@ -24505,7 +25358,7 @@ var require_dist2 = __commonJS({ var cst = require_cst(); var lexer = require_lexer(); var lineCounter = require_line_counter(); - var parser = require_parser(); + var parser2 = require_parser(); var publicApi = require_public_api(); var visit = require_visit(); exports.Composer = composer.Composer; @@ -24530,7 +25383,7 @@ var require_dist2 = __commonJS({ exports.CST = cst; exports.Lexer = lexer.Lexer; exports.LineCounter = lineCounter.LineCounter; - exports.Parser = parser.Parser; + exports.Parser = parser2.Parser; exports.parse = publicApi.parse; exports.parseAllDocuments = publicApi.parseAllDocuments; exports.parseDocument = publicApi.parseDocument; @@ -24540,17 +25393,17 @@ var require_dist2 = __commonJS({ } }); -// +// .github/actions/deploy-docs-site/lib/main.mts var import_core3 = __toESM(require_core(), 1); var import_github3 = __toESM(require_github(), 1); -// -import { cp, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +// .github/actions/deploy-docs-site/lib/deploy.mjs +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { spawnSync } from "node:child_process"; -// +// .github/actions/deploy-docs-site/lib/credential.mjs var import_tmp = __toESM(require_tmp(), 1); var import_core = __toESM(require_core(), 1); import { writeSync } from "node:fs"; @@ -24568,25 +25421,22 @@ var githubReleaseTrainReadToken = (0, import_core.getInput)("githubReleaseTrainR required: true }); -// -async function deployToFirebase(deployment, configPath, distDirPath) { +// .github/actions/deploy-docs-site/lib/deploy.mjs +async function deployToFirebase(deployment, configPath, stagingDir) { if (deployment.destination == void 0) { console.log(`No deployment necessary for docs created from: ${deployment.branch}`); return; } console.log("Preparing for deployment to firebase..."); - const tmpDeployDir = await mkdtemp(join(tmpdir(), "deploy-directory")); - const deployConfigPath = join(tmpDeployDir, "firebase.json"); + const deployConfigPath = join(stagingDir, "firebase.json"); const config = JSON.parse(await readFile(configPath, { encoding: "utf-8" })); - config["hosting"]["public"] = "./dist"; + config["hosting"]["public"] = "./browser"; await writeFile(deployConfigPath, JSON.stringify(config, null, 2)); - await cp(distDirPath, join(tmpDeployDir, "dist"), { recursive: true }); - spawnSync(`chmod 777 -R ${tmpDeployDir}`, { encoding: "utf-8", shell: true }); - firebase(`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`, tmpDeployDir); - firebase(`target:apply --config ${deployConfigPath} --project angular-dev-site hosting angular-docs ${deployment.destination}`, tmpDeployDir); - firebase(`deploy --config ${deployConfigPath} --project angular-dev-site --only hosting --non-interactive`, tmpDeployDir); - firebase(`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`, tmpDeployDir); - await rm(tmpDeployDir, { recursive: true }); + firebase(`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`, stagingDir); + firebase(`target:apply --config ${deployConfigPath} --project angular-dev-site hosting angular-docs ${deployment.destination}`, stagingDir); + firebase(`deploy --config ${deployConfigPath} --project angular-dev-site --only hosting --non-interactive`, stagingDir); + firebase(`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`, stagingDir); + await rm(stagingDir, { recursive: true }); } async function setupRedirect(deployment) { if (deployment.redirect === void 0) { @@ -24617,7 +25467,7 @@ async function setupRedirect(deployment) { await rm(tmpRedirectDir, { recursive: true }); } function firebase(cmd, cwd) { - spawnSync("npx", `-y firebase-tools@13.15.1 ${cmd}`.split(" "), { + const { status } = spawnSync("npx", `-y firebase-tools@13.15.1 ${cmd}`.split(" "), { cwd, encoding: "utf-8", shell: true, @@ -24627,216 +25477,53 @@ function firebase(cmd, cwd) { GOOGLE_APPLICATION_CREDENTIALS: getCredentialFilePath() } }); + if (status !== 0) { + console.error("Firebase command failed, see log above for details."); + process.exit(status); + } } // -import { pathToFileURL } from "url"; -import { join as join2 } from "path"; +import { join as join3 } from "path"; // -var ANSI_BACKGROUND_OFFSET = 10; -var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`; -var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`; -var wrapAnsi16m = (offset = 0) => (red2, green2, blue2) => `\x1B[${38 + offset};2;${red2};${green2};${blue2}m`; -var styles = { - modifier: { - reset: [0, 0], - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - overline: [53, 55], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - blackBright: [90, 39], - gray: [90, 39], - grey: [90, 39], - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - bgBlackBright: [100, 49], - bgGray: [100, 49], - bgGrey: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] +import { styleText } from "util"; + +// +import process2 from "node:process"; +import os from "node:os"; +import tty from "node:tty"; +function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) { + const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--"; + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf("--"); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +} +var { env } = process2; +var flagForceColor; +if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) { + flagForceColor = 0; +} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) { + flagForceColor = 1; +} +function envForceColor() { + if (!("FORCE_COLOR" in env)) { + return; } -}; -var modifierNames = Object.keys(styles.modifier); -var foregroundColorNames = Object.keys(styles.color); -var backgroundColorNames = Object.keys(styles.bgColor); -var colorNames = [...foregroundColorNames, ...backgroundColorNames]; -function assembleStyles() { - const codes = /* @__PURE__ */ new Map(); - for (const [groupName, group] of Object.entries(styles)) { - for (const [styleName, style] of Object.entries(group)) { - styles[styleName] = { - open: `\x1B[${style[0]}m`, - close: `\x1B[${style[1]}m` - }; - group[styleName] = styles[styleName]; - codes.set(style[0], style[1]); - } - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); + if (env.FORCE_COLOR === "true") { + return 1; } - Object.defineProperty(styles, "codes", { - value: codes, - enumerable: false - }); - styles.color.close = "\x1B[39m"; - styles.bgColor.close = "\x1B[49m"; - styles.color.ansi = wrapAnsi16(); - styles.color.ansi256 = wrapAnsi256(); - styles.color.ansi16m = wrapAnsi16m(); - styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); - styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); - styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); - Object.defineProperties(styles, { - rgbToAnsi256: { - value(red2, green2, blue2) { - if (red2 === green2 && green2 === blue2) { - if (red2 < 8) { - return 16; - } - if (red2 > 248) { - return 231; - } - return Math.round((red2 - 8) / 247 * 24) + 232; - } - return 16 + 36 * Math.round(red2 / 255 * 5) + 6 * Math.round(green2 / 255 * 5) + Math.round(blue2 / 255 * 5); - }, - enumerable: false - }, - hexToRgb: { - value(hex) { - const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16)); - if (!matches) { - return [0, 0, 0]; - } - let [colorString] = matches; - if (colorString.length === 3) { - colorString = [...colorString].map((character) => character + character).join(""); - } - const integer = Number.parseInt(colorString, 16); - return [ - integer >> 16 & 255, - integer >> 8 & 255, - integer & 255 - ]; - }, - enumerable: false - }, - hexToAnsi256: { - value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)), - enumerable: false - }, - ansi256ToAnsi: { - value(code) { - if (code < 8) { - return 30 + code; - } - if (code < 16) { - return 90 + (code - 8); - } - let red2; - let green2; - let blue2; - if (code >= 232) { - red2 = ((code - 232) * 10 + 8) / 255; - green2 = red2; - blue2 = red2; - } else { - code -= 16; - const remainder = code % 36; - red2 = Math.floor(code / 36) / 5; - green2 = Math.floor(remainder / 6) / 5; - blue2 = remainder % 6 / 5; - } - const value = Math.max(red2, green2, blue2) * 2; - if (value === 0) { - return 30; - } - let result = 30 + (Math.round(blue2) << 2 | Math.round(green2) << 1 | Math.round(red2)); - if (value === 2) { - result += 60; - } - return result; - }, - enumerable: false - }, - rgbToAnsi: { - value: (red2, green2, blue2) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red2, green2, blue2)), - enumerable: false - }, - hexToAnsi: { - value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), - enumerable: false - } - }); - return styles; -} -var ansiStyles = assembleStyles(); -var ansi_styles_default = ansiStyles; - -// -import process2 from "node:process"; -import os from "node:os"; -import tty from "node:tty"; -function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) { - const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--"; - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf("--"); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -} -var { env } = process2; -var flagForceColor; -if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) { - flagForceColor = 0; -} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) { - flagForceColor = 1; -} -function envForceColor() { - if ("FORCE_COLOR" in env) { - if (env.FORCE_COLOR === "true") { - return 1; - } - if (env.FORCE_COLOR === "false") { - return 0; - } - return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + if (env.FORCE_COLOR === "false") { + return 0; + } + if (env.FORCE_COLOR.length === 0) { + return 1; } + const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + if (![0, 1, 2, 3].includes(level)) { + return; + } + return level; } function translateLevel(level) { if (level === 0) { @@ -24901,6 +25588,12 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) { if (env.TERM === "xterm-kitty") { return 3; } + if (env.TERM === "xterm-ghostty") { + return 3; + } + if (env.TERM === "wezterm") { + return 3; + } if ("TERM_PROGRAM" in env) { const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10); switch (env.TERM_PROGRAM) { @@ -24936,363 +25629,52 @@ var supportsColor = { }; var supports_color_default = supportsColor; -// -function stringReplaceAll(string, substring, replacer) { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ""; - do { - returnValue += string.slice(endIndex, index) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring, endIndex); - } while (index !== -1); - returnValue += string.slice(endIndex); - return returnValue; -} -function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) { - let endIndex = 0; - let returnValue = ""; - do { - const gotCR = string[index - 1] === "\r"; - returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix; - endIndex = index + 1; - index = string.indexOf("\n", endIndex); - } while (index !== -1); - returnValue += string.slice(endIndex); - return returnValue; -} - -// -var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default; -var GENERATOR = Symbol("GENERATOR"); -var STYLER = Symbol("STYLER"); -var IS_EMPTY = Symbol("IS_EMPTY"); -var levelMapping = [ - "ansi", - "ansi", - "ansi256", - "ansi16m" -]; -var styles2 = /* @__PURE__ */ Object.create(null); -var applyOptions = (object, options = {}) => { - if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { - throw new Error("The `level` option should be an integer from 0 to 3"); - } - const colorLevel = stdoutColor ? stdoutColor.level : 0; - object.level = options.level === void 0 ? colorLevel : options.level; -}; -var chalkFactory = (options) => { - const chalk2 = (...strings) => strings.join(" "); - applyOptions(chalk2, options); - Object.setPrototypeOf(chalk2, createChalk.prototype); - return chalk2; -}; -function createChalk(options) { - return chalkFactory(options); -} -Object.setPrototypeOf(createChalk.prototype, Function.prototype); -for (const [styleName, style] of Object.entries(ansi_styles_default)) { - styles2[styleName] = { - get() { - const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]); - Object.defineProperty(this, styleName, { value: builder }); - return builder; - } - }; -} -styles2.visible = { - get() { - const builder = createBuilder(this, this[STYLER], true); - Object.defineProperty(this, "visible", { value: builder }); - return builder; - } -}; -var getModelAnsi = (model, level, type, ...arguments_) => { - if (model === "rgb") { - if (level === "ansi16m") { - return ansi_styles_default[type].ansi16m(...arguments_); - } - if (level === "ansi256") { - return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_)); - } - return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_)); - } - if (model === "hex") { - return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_)); - } - return ansi_styles_default[type][model](...arguments_); -}; -var usedModels = ["rgb", "hex", "ansi256"]; -for (const model of usedModels) { - styles2[model] = { - get() { - const { level } = this; - return function(...arguments_) { - const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]); - return createBuilder(this, styler, this[IS_EMPTY]); - }; - } - }; - const bgModel = "bg" + model[0].toUpperCase() + model.slice(1); - styles2[bgModel] = { - get() { - const { level } = this; - return function(...arguments_) { - const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]); - return createBuilder(this, styler, this[IS_EMPTY]); - }; - } - }; -} -var proto = Object.defineProperties(() => { -}, { - ...styles2, - level: { - enumerable: true, - get() { - return this[GENERATOR].level; - }, - set(level) { - this[GENERATOR].level = level; - } - } -}); -var createStyler = (open, close, parent) => { - let openAll; - let closeAll; - if (parent === void 0) { - openAll = open; - closeAll = close; - } else { - openAll = parent.openAll + open; - closeAll = close + parent.closeAll; - } - return { - open, - close, - openAll, - closeAll, - parent - }; -}; -var createBuilder = (self2, _styler, _isEmpty) => { - const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" ")); - Object.setPrototypeOf(builder, proto); - builder[GENERATOR] = self2; - builder[STYLER] = _styler; - builder[IS_EMPTY] = _isEmpty; - return builder; -}; -var applyStyle = (self2, string) => { - if (self2.level <= 0 || !string) { - return self2[IS_EMPTY] ? "" : string; - } - let styler = self2[STYLER]; - if (styler === void 0) { - return string; - } - const { openAll, closeAll } = styler; - if (string.includes("\x1B")) { - while (styler !== void 0) { - string = stringReplaceAll(string, styler.close, styler.open); - styler = styler.parent; - } - } - const lfIndex = string.indexOf("\n"); - if (lfIndex !== -1) { - string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); - } - return openAll + string + closeAll; -}; -Object.defineProperties(createChalk.prototype, styles2); -var chalk = createChalk(); -var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 }); -var source_default = chalk; - -// -import process3 from "node:process"; -import os2 from "node:os"; -import tty2 from "node:tty"; -function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process3.argv) { - const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--"; - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf("--"); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -} -var { env: env2 } = process3; -var flagForceColor2; -if (hasFlag2("no-color") || hasFlag2("no-colors") || hasFlag2("color=false") || hasFlag2("color=never")) { - flagForceColor2 = 0; -} else if (hasFlag2("color") || hasFlag2("colors") || hasFlag2("color=true") || hasFlag2("color=always")) { - flagForceColor2 = 1; -} -function envForceColor2() { - if (!("FORCE_COLOR" in env2)) { - return; - } - if (env2.FORCE_COLOR === "true") { - return 1; - } - if (env2.FORCE_COLOR === "false") { - return 0; - } - if (env2.FORCE_COLOR.length === 0) { - return 1; - } - const level = Math.min(Number.parseInt(env2.FORCE_COLOR, 10), 3); - if (![0, 1, 2, 3].includes(level)) { - return; - } - return level; -} -function translateLevel2(level) { - if (level === 0) { - return false; - } - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} -function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) { - const noFlagForceColor = envForceColor2(); - if (noFlagForceColor !== void 0) { - flagForceColor2 = noFlagForceColor; - } - const forceColor = sniffFlags ? flagForceColor2 : noFlagForceColor; - if (forceColor === 0) { - return 0; - } - if (sniffFlags) { - if (hasFlag2("color=16m") || hasFlag2("color=full") || hasFlag2("color=truecolor")) { - return 3; - } - if (hasFlag2("color=256")) { - return 2; - } - } - if ("TF_BUILD" in env2 && "AGENT_NAME" in env2) { - return 1; - } - if (haveStream && !streamIsTTY && forceColor === void 0) { - return 0; - } - const min = forceColor || 0; - if (env2.TERM === "dumb") { - return min; - } - if (process3.platform === "win32") { - const osRelease = os2.release().split("."); - if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - return 1; - } - if ("CI" in env2) { - if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env2)) { - return 3; - } - if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env2) || env2.CI_NAME === "codeship") { - return 1; - } - return min; - } - if ("TEAMCITY_VERSION" in env2) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env2.TEAMCITY_VERSION) ? 1 : 0; - } - if (env2.COLORTERM === "truecolor") { - return 3; - } - if (env2.TERM === "xterm-kitty") { - return 3; - } - if ("TERM_PROGRAM" in env2) { - const version = Number.parseInt((env2.TERM_PROGRAM_VERSION || "").split(".")[0], 10); - switch (env2.TERM_PROGRAM) { - case "iTerm.app": { - return version >= 3 ? 3 : 2; - } - case "Apple_Terminal": { - return 2; - } - } - } - if (/-256(color)?$/i.test(env2.TERM)) { - return 2; - } - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env2.TERM)) { - return 1; - } - if ("COLORTERM" in env2) { - return 1; - } - return min; -} -function createSupportsColor2(stream, options = {}) { - const level = _supportsColor2(stream, { - streamIsTTY: stream && stream.isTTY, - ...options - }); - return translateLevel2(level); -} -var supportsColor2 = { - stdout: createSupportsColor2({ isTTY: tty2.isatty(1) }), - stderr: createSupportsColor2({ isTTY: tty2.isatty(2) }) -}; -var supports_color_default2 = supportsColor2; - // import { spawn as _spawn, spawnSync as _spawnSync, exec as _exec } from "child_process"; import assert from "assert"; var ChildProcess = class { - static spawnInteractive(command, args, options = {}) { - return new Promise((resolve, reject) => { - const commandText = `${command} ${args.join(" ")}`; + static spawnInteractive(command2, args, options = {}) { + return new Promise((resolve5, reject) => { + const commandText = `${command2} ${args.join(" ")}`; Log.debug(`Executing command: ${commandText}`); - const childProcess = _spawn(command, args, { ...options, shell: true, stdio: "inherit" }); - childProcess.on("close", (status) => status === 0 ? resolve() : reject(status)); + const childProcess = _spawn(command2, args, { ...options, shell: true, stdio: "inherit" }); + childProcess.on("close", (status) => status === 0 ? resolve5() : reject(status)); }); } - static spawnSync(command, args, options = {}) { - const commandText = `${command} ${args.join(" ")}`; + static spawnSync(command2, args, options = {}) { + const commandText = `${command2} ${args.join(" ")}`; const env3 = getEnvironmentForNonInteractiveCommand(options.env); Log.debug(`Executing command: ${commandText}`); - const { status: exitCode, signal, stdout, stderr } = _spawnSync(command, args, { ...options, env: env3, encoding: "utf8", shell: true, stdio: "pipe" }); + const { status: exitCode, signal, stdout, stderr } = _spawnSync(command2, args, { ...options, env: env3, encoding: "utf8", shell: true, stdio: "pipe" }); const status = statusFromExitCodeAndSignal(exitCode, signal); if (status === 0 || options.suppressErrorOnFailingExitCode) { return { status, stdout, stderr }; } throw new Error(stderr); } - static spawn(command, args, options = {}) { - const commandText = `${command} ${args.join(" ")}`; + static spawn(command2, args, options = {}) { + const commandText = `${command2} ${args.join(" ")}`; const env3 = getEnvironmentForNonInteractiveCommand(options.env); - return processAsyncCmd(commandText, options, _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" })); + return processAsyncCmd(commandText, options, _spawn(command2, args, { ...options, env: env3, shell: true, stdio: "pipe" })); } - static exec(command, options = {}) { + static exec(command2, options = {}) { const env3 = getEnvironmentForNonInteractiveCommand(options.env); - return processAsyncCmd(command, options, _exec(command, { ...options, env: env3 })); + return processAsyncCmd(command2, options, _exec(command2, { ...options, env: env3 })); } }; function statusFromExitCodeAndSignal(exitCode, signal) { return exitCode ?? signal ?? -1; } function getEnvironmentForNonInteractiveCommand(userProvidedEnv) { - const forceColorValue = supports_color_default2.stdout !== false ? supports_color_default2.stdout.level.toString() : void 0; + const forceColorValue = supports_color_default.stdout !== false ? supports_color_default.stdout.level.toString() : void 0; return { FORCE_COLOR: forceColorValue, ...userProvidedEnv ?? process.env }; } -function processAsyncCmd(command, options, childProcess) { - return new Promise((resolve, reject) => { +function processAsyncCmd(command2, options, childProcess) { + return new Promise((resolve5, reject) => { let logOutput = ""; let stdout = ""; let stderr = ""; - Log.debug(`Executing command: ${command}`); + Log.debug(`Executing command: ${command2}`); if (options.input !== void 0) { assert(childProcess.stdin, "Cannot write process `input` if there is no pipe `stdin` channel."); childProcess.stdin.write(options.input); @@ -25316,11 +25698,11 @@ function processAsyncCmd(command, options, childProcess) { const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; const printFn = options.mode === "on-error" ? Log.error : Log.debug; const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${command}" completed with ${exitDescription}.`); + printFn(`Command "${command2}" completed with ${exitDescription}.`); printFn(`Process output: ${logOutput}`); if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); + resolve5({ stdout, stderr, status }); } else { reject(options.mode === "silent" ? logOutput : void 0); } @@ -25341,1389 +25723,6129 @@ ${stderr}`); } // -import { appendFile } from "fs/promises"; import { stripVTControlCharacters } from "util"; -var LogLevel; -(function(LogLevel2) { - LogLevel2[LogLevel2["SILENT"] = 0] = "SILENT"; - LogLevel2[LogLevel2["ERROR"] = 1] = "ERROR"; - LogLevel2[LogLevel2["WARN"] = 2] = "WARN"; - LogLevel2[LogLevel2["LOG"] = 3] = "LOG"; - LogLevel2[LogLevel2["INFO"] = 4] = "INFO"; - LogLevel2[LogLevel2["DEBUG"] = 5] = "DEBUG"; -})(LogLevel || (LogLevel = {})); -var DEFAULT_LOG_LEVEL = LogLevel.INFO; -var red = source_default.red; -var reset = source_default.reset; -var green = source_default.green; -var yellow = source_default.yellow; -var bold = source_default.bold; -var blue = source_default.blue; -var underline = source_default.underline; -var Log = class { + +// +import { notStrictEqual, strictEqual } from "assert"; + +// +var align = { + right: alignRight, + center: alignCenter }; -Log.info = buildLogLevelFunction(() => console.info, LogLevel.INFO, null); -Log.error = buildLogLevelFunction(() => console.error, LogLevel.ERROR, source_default.red); -Log.debug = buildLogLevelFunction(() => console.debug, LogLevel.DEBUG, null); -Log.log = buildLogLevelFunction(() => console.log, LogLevel.LOG, null); -Log.warn = buildLogLevelFunction(() => console.warn, LogLevel.WARN, source_default.yellow); -function buildLogLevelFunction(loadCommand, level, defaultColor) { - const loggingFunction = (...values) => { - runConsoleCommand( - loadCommand, - level, - ...values.map((v) => typeof v === "string" && defaultColor ? defaultColor(v) : v) - ); - }; - loggingFunction.group = (label, collapsed = false) => { - const command = collapsed ? console.groupCollapsed : console.group; - runConsoleCommand(() => command, level, defaultColor ? defaultColor(label) : label); - }; - loggingFunction.groupEnd = () => { - runConsoleCommand(() => console.groupEnd, level); - }; - return loggingFunction; +var top = 0; +var right = 1; +var bottom = 2; +var left = 3; +var UI = class { + constructor(opts) { + var _a2; + this.width = opts.width; + this.wrap = (_a2 = opts.wrap) !== null && _a2 !== void 0 ? _a2 : true; + this.rows = []; + } + span(...args) { + const cols = this.div(...args); + cols.span = true; + } + resetOutput() { + this.rows = []; + } + div(...args) { + if (args.length === 0) { + this.div(""); + } + if (this.wrap && this.shouldApplyLayoutDSL(...args) && typeof args[0] === "string") { + return this.applyLayoutDSL(args[0]); + } + const cols = args.map((arg) => { + if (typeof arg === "string") { + return this.colFromString(arg); + } + return arg; + }); + this.rows.push(cols); + return cols; + } + shouldApplyLayoutDSL(...args) { + return args.length === 1 && typeof args[0] === "string" && /[\t\n]/.test(args[0]); + } + applyLayoutDSL(str) { + const rows = str.split("\n").map((row) => row.split(" ")); + let leftColumnWidth = 0; + rows.forEach((columns) => { + if (columns.length > 1 && mixin.stringWidth(columns[0]) > leftColumnWidth) { + leftColumnWidth = Math.min(Math.floor(this.width * 0.5), mixin.stringWidth(columns[0])); + } + }); + rows.forEach((columns) => { + this.div(...columns.map((r, i) => { + return { + text: r.trim(), + padding: this.measurePadding(r), + width: i === 0 && columns.length > 1 ? leftColumnWidth : void 0 + }; + })); + }); + return this.rows[this.rows.length - 1]; + } + colFromString(text) { + return { + text, + padding: this.measurePadding(text) + }; + } + measurePadding(str) { + const noAnsi = mixin.stripAnsi(str); + return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]; + } + toString() { + const lines = []; + this.rows.forEach((row) => { + this.rowToString(row, lines); + }); + return lines.filter((line) => !line.hidden).map((line) => line.text).join("\n"); + } + rowToString(row, lines) { + this.rasterize(row).forEach((rrow, r) => { + let str = ""; + rrow.forEach((col, c) => { + const { width } = row[c]; + const wrapWidth = this.negatePadding(row[c]); + let ts = col; + if (wrapWidth > mixin.stringWidth(col)) { + ts += " ".repeat(wrapWidth - mixin.stringWidth(col)); + } + if (row[c].align && row[c].align !== "left" && this.wrap) { + const fn = align[row[c].align]; + ts = fn(ts, wrapWidth); + if (mixin.stringWidth(ts) < wrapWidth) { + ts += " ".repeat((width || 0) - mixin.stringWidth(ts) - 1); + } + } + const padding = row[c].padding || [0, 0, 0, 0]; + if (padding[left]) { + str += " ".repeat(padding[left]); + } + str += addBorder(row[c], ts, "| "); + str += ts; + str += addBorder(row[c], ts, " |"); + if (padding[right]) { + str += " ".repeat(padding[right]); + } + if (r === 0 && lines.length > 0) { + str = this.renderInline(str, lines[lines.length - 1]); + } + }); + lines.push({ + text: str.replace(/ +$/, ""), + span: row.span + }); + }); + return lines; + } + // if the full 'source' can render in + // the target line, do so. + renderInline(source, previousLine) { + const match = source.match(/^ */); + const leadingWhitespace = match ? match[0].length : 0; + const target = previousLine.text; + const targetTextWidth = mixin.stringWidth(target.trimRight()); + if (!previousLine.span) { + return source; + } + if (!this.wrap) { + previousLine.hidden = true; + return target + source; + } + if (leadingWhitespace < targetTextWidth) { + return source; + } + previousLine.hidden = true; + return target.trimRight() + " ".repeat(leadingWhitespace - targetTextWidth) + source.trimLeft(); + } + rasterize(row) { + const rrows = []; + const widths = this.columnWidths(row); + let wrapped; + row.forEach((col, c) => { + col.width = widths[c]; + if (this.wrap) { + wrapped = mixin.wrap(col.text, this.negatePadding(col), { hard: true }).split("\n"); + } else { + wrapped = col.text.split("\n"); + } + if (col.border) { + wrapped.unshift("." + "-".repeat(this.negatePadding(col) + 2) + "."); + wrapped.push("'" + "-".repeat(this.negatePadding(col) + 2) + "'"); + } + if (col.padding) { + wrapped.unshift(...new Array(col.padding[top] || 0).fill("")); + wrapped.push(...new Array(col.padding[bottom] || 0).fill("")); + } + wrapped.forEach((str, r) => { + if (!rrows[r]) { + rrows.push([]); + } + const rrow = rrows[r]; + for (let i = 0; i < c; i++) { + if (rrow[i] === void 0) { + rrow.push(""); + } + } + rrow.push(str); + }); + }); + return rrows; + } + negatePadding(col) { + let wrapWidth = col.width || 0; + if (col.padding) { + wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0); + } + if (col.border) { + wrapWidth -= 4; + } + return wrapWidth; + } + columnWidths(row) { + if (!this.wrap) { + return row.map((col) => { + return col.width || mixin.stringWidth(col.text); + }); + } + let unset = row.length; + let remainingWidth = this.width; + const widths = row.map((col) => { + if (col.width) { + unset--; + remainingWidth -= col.width; + return col.width; + } + return void 0; + }); + const unsetWidth = unset ? Math.floor(remainingWidth / unset) : 0; + return widths.map((w, i) => { + if (w === void 0) { + return Math.max(unsetWidth, _minWidth(row[i])); + } + return w; + }); + } +}; +function addBorder(col, ts, style) { + if (col.border) { + if (/[.']-+[.']/.test(ts)) { + return ""; + } + if (ts.trim().length !== 0) { + return style; + } + return " "; + } + return ""; } -function runConsoleCommand(loadCommand, logLevel, ...text) { - if (getLogLevel() >= logLevel) { - loadCommand()(...text); +function _minWidth(col) { + const padding = col.padding || []; + const minWidth = 1 + (padding[left] || 0) + (padding[right] || 0); + if (col.border) { + return minWidth + 4; } - appendToLogFile(logLevel, ...text); + return minWidth; } -function getLogLevel() { - const logLevel = Object.keys(LogLevel).indexOf((process.env[`LOG_LEVEL`] || "").toUpperCase()); - if (logLevel === -1) { - return DEFAULT_LOG_LEVEL; +function getWindowWidth() { + if (typeof process === "object" && process.stdout && process.stdout.columns) { + return process.stdout.columns; } - return logLevel; + return 80; } -var LOG_LEVEL_COLUMNS = 7; -var logFilePath = void 0; -function appendToLogFile(logLevel, ...text) { - if (logFilePath === void 0) { - return; +function alignRight(str, width) { + str = str.trim(); + const strWidth = mixin.stringWidth(str); + if (strWidth < width) { + return " ".repeat(width - strWidth) + str; } - if (logLevel === void 0) { - appendFile(logFilePath, text.join(" ")); - return; + return str; +} +function alignCenter(str, width) { + str = str.trim(); + const strWidth = mixin.stringWidth(str); + if (strWidth >= width) { + return str; } - const logLevelText = `${LogLevel[logLevel]}:`.padEnd(LOG_LEVEL_COLUMNS); - appendFile( - logFilePath, - stripVTControlCharacters(text.join(" ").split("\n").map((l) => `${logLevelText} ${l} -`).join("")) - ); + return " ".repeat(width - strWidth >> 1) + str; +} +var mixin; +function cliui(opts, _mixin) { + mixin = _mixin; + return new UI({ + width: (opts === null || opts === void 0 ? void 0 : opts.width) || getWindowWidth(), + wrap: opts === null || opts === void 0 ? void 0 : opts.wrap + }); } // -var cachedConfig = null; -function setCachedConfig(config) { - cachedConfig = config; +function ansiRegex({ onlyFirst = false } = {}) { + const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)"; + const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`; + const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]"; + const pattern = `${osc}|${csi}`; + return new RegExp(pattern, onlyFirst ? void 0 : "g"); } -function getCachedConfig() { - return cachedConfig; + +// +var regex = ansiRegex(); +function stripAnsi(string) { + if (typeof string !== "string") { + throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); + } + return string.replace(regex, ""); } // -var CONFIG_FILE_PATH = ".ng-dev/config.mts"; -var setConfig = setCachedConfig; -async function getConfig(baseDirOrAssertions) { - let cachedConfig2 = getCachedConfig(); - if (cachedConfig2 === null) { - let baseDir; - if (typeof baseDirOrAssertions === "string") { - baseDir = baseDirOrAssertions; - } else { - baseDir = determineRepoBaseDirFromCwd(); - } - const configPath = join2(baseDir, CONFIG_FILE_PATH); - cachedConfig2 = await readConfigFile(configPath); - setCachedConfig(cachedConfig2); +function isAmbiguous(x) { + return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109; +} +function isFullWidth(x) { + return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510; +} +function isWide(x) { + return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141; +} + +// +function validate(codePoint) { + if (!Number.isSafeInteger(codePoint)) { + throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`); } - if (Array.isArray(baseDirOrAssertions)) { - for (const assertion of baseDirOrAssertions) { - assertion(cachedConfig2); - } +} +function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) { + validate(codePoint); + if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) { + return 2; } - return { ...cachedConfig2, __isNgDevConfigObject: true }; + return 1; } -var ConfigValidationError = class extends Error { - constructor(message, errors = []) { - super(message); - this.errors = errors; + +// +var import_emoji_regex = __toESM(require_emoji_regex()); +var segmenter = new Intl.Segmenter(); +var defaultIgnorableCodePointRegex = new RegExp("^\\p{Default_Ignorable_Code_Point}$", "u"); +function stringWidth(string, options = {}) { + if (typeof string !== "string" || string.length === 0) { + return 0; } -}; -function assertValidGithubConfig(config) { - const errors = []; - if (config.github === void 0) { - errors.push(`Github repository not configured. Set the "github" option.`); - } else { - if (config.github.name === void 0) { - errors.push(`"github.name" is not defined`); - } - if (config.github.owner === void 0) { - errors.push(`"github.owner" is not defined`); - } + const { + ambiguousIsNarrow = true, + countAnsiEscapeCodes = false + } = options; + if (!countAnsiEscapeCodes) { + string = stripAnsi(string); } - if (errors.length) { - throw new ConfigValidationError("Invalid `github` configuration", errors); + if (string.length === 0) { + return 0; } -} -async function readConfigFile(configPath, returnEmptyObjectOnError = false) { - try { - return await import(pathToFileURL(configPath).toString()); - } catch (e) { - if (returnEmptyObjectOnError) { - Log.debug(`Could not read configuration file at ${configPath}, returning empty object instead.`); - Log.debug(e); - return {}; + let width = 0; + const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow }; + for (const { segment: character } of segmenter.segment(string)) { + const codePoint = character.codePointAt(0); + if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) { + continue; } - Log.error(`Could not read configuration file at ${configPath}.`); - Log.error(e); - process.exit(1); + if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) { + continue; + } + if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) { + continue; + } + if (codePoint >= 55296 && codePoint <= 57343) { + continue; + } + if (codePoint >= 65024 && codePoint <= 65039) { + continue; + } + if (defaultIgnorableCodePointRegex.test(character)) { + continue; + } + if ((0, import_emoji_regex.default)().test(character)) { + width += 2; + continue; + } + width += eastAsianWidth(codePoint, eastAsianWidthOptions); } + return width; } // -var ScopeRequirement; -(function(ScopeRequirement2) { - ScopeRequirement2[ScopeRequirement2["Required"] = 0] = "Required"; - ScopeRequirement2[ScopeRequirement2["Optional"] = 1] = "Optional"; - ScopeRequirement2[ScopeRequirement2["Forbidden"] = 2] = "Forbidden"; -})(ScopeRequirement || (ScopeRequirement = {})); -var ReleaseNotesLevel; -(function(ReleaseNotesLevel2) { - ReleaseNotesLevel2[ReleaseNotesLevel2["Hidden"] = 0] = "Hidden"; - ReleaseNotesLevel2[ReleaseNotesLevel2["Visible"] = 1] = "Visible"; -})(ReleaseNotesLevel || (ReleaseNotesLevel = {})); -var COMMIT_TYPES = { - build: { - name: "build", - description: "Changes to local repository build system and tooling", - scope: ScopeRequirement.Optional, - releaseNotesLevel: ReleaseNotesLevel.Hidden - }, - ci: { - name: "ci", - description: "Changes to CI configuration and CI specific tooling", - scope: ScopeRequirement.Forbidden, - releaseNotesLevel: ReleaseNotesLevel.Hidden - }, - docs: { - name: "docs", - description: "Changes which exclusively affects documentation.", - scope: ScopeRequirement.Optional, - releaseNotesLevel: ReleaseNotesLevel.Hidden - }, - feat: { - name: "feat", - description: "Creates a new feature", - scope: ScopeRequirement.Required, - releaseNotesLevel: ReleaseNotesLevel.Visible - }, - fix: { - name: "fix", - description: "Fixes a previously discovered failure/bug", - scope: ScopeRequirement.Required, - releaseNotesLevel: ReleaseNotesLevel.Visible - }, - perf: { - name: "perf", - description: "Improves performance without any change in functionality or API", - scope: ScopeRequirement.Required, - releaseNotesLevel: ReleaseNotesLevel.Visible +var ANSI_BACKGROUND_OFFSET = 10; +var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`; +var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`; +var wrapAnsi16m = (offset = 0) => (red2, green2, blue2) => `\x1B[${38 + offset};2;${red2};${green2};${blue2}m`; +var styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + overline: [53, 55], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] }, - refactor: { - name: "refactor", - description: "Refactor without any change in functionality or API (includes style changes)", - scope: ScopeRequirement.Optional, - releaseNotesLevel: ReleaseNotesLevel.Hidden + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + // Bright color + blackBright: [90, 39], + gray: [90, 39], + // Alias of `blackBright` + grey: [90, 39], + // Alias of `blackBright` + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] }, - release: { - name: "release", - description: "A release point in the repository", - scope: ScopeRequirement.Forbidden, - releaseNotesLevel: ReleaseNotesLevel.Hidden + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + // Bright color + bgBlackBright: [100, 49], + bgGray: [100, 49], + // Alias of `bgBlackBright` + bgGrey: [100, 49], + // Alias of `bgBlackBright` + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } +}; +var modifierNames = Object.keys(styles.modifier); +var foregroundColorNames = Object.keys(styles.color); +var backgroundColorNames = Object.keys(styles.bgColor); +var colorNames = [...foregroundColorNames, ...backgroundColorNames]; +function assembleStyles() { + const codes = /* @__PURE__ */ new Map(); + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { + styles[styleName] = { + open: `\x1B[${style[0]}m`, + close: `\x1B[${style[1]}m` + }; + group[styleName] = styles[styleName]; + codes.set(style[0], style[1]); + } + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); + } + Object.defineProperty(styles, "codes", { + value: codes, + enumerable: false + }); + styles.color.close = "\x1B[39m"; + styles.bgColor.close = "\x1B[49m"; + styles.color.ansi = wrapAnsi16(); + styles.color.ansi256 = wrapAnsi256(); + styles.color.ansi16m = wrapAnsi16m(); + styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); + styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); + styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); + Object.defineProperties(styles, { + rgbToAnsi256: { + value(red2, green2, blue2) { + if (red2 === green2 && green2 === blue2) { + if (red2 < 8) { + return 16; + } + if (red2 > 248) { + return 231; + } + return Math.round((red2 - 8) / 247 * 24) + 232; + } + return 16 + 36 * Math.round(red2 / 255 * 5) + 6 * Math.round(green2 / 255 * 5) + Math.round(blue2 / 255 * 5); + }, + enumerable: false + }, + hexToRgb: { + value(hex) { + const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16)); + if (!matches) { + return [0, 0, 0]; + } + let [colorString] = matches; + if (colorString.length === 3) { + colorString = [...colorString].map((character) => character + character).join(""); + } + const integer = Number.parseInt(colorString, 16); + return [ + /* eslint-disable no-bitwise */ + integer >> 16 & 255, + integer >> 8 & 255, + integer & 255 + /* eslint-enable no-bitwise */ + ]; + }, + enumerable: false + }, + hexToAnsi256: { + value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)), + enumerable: false + }, + ansi256ToAnsi: { + value(code) { + if (code < 8) { + return 30 + code; + } + if (code < 16) { + return 90 + (code - 8); + } + let red2; + let green2; + let blue2; + if (code >= 232) { + red2 = ((code - 232) * 10 + 8) / 255; + green2 = red2; + blue2 = red2; + } else { + code -= 16; + const remainder = code % 36; + red2 = Math.floor(code / 36) / 5; + green2 = Math.floor(remainder / 6) / 5; + blue2 = remainder % 6 / 5; + } + const value = Math.max(red2, green2, blue2) * 2; + if (value === 0) { + return 30; + } + let result = 30 + (Math.round(blue2) << 2 | Math.round(green2) << 1 | Math.round(red2)); + if (value === 2) { + result += 60; + } + return result; + }, + enumerable: false + }, + rgbToAnsi: { + value: (red2, green2, blue2) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red2, green2, blue2)), + enumerable: false + }, + hexToAnsi: { + value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), + enumerable: false + } + }); + return styles; +} +var ansiStyles = assembleStyles(); +var ansi_styles_default = ansiStyles; + +// +var ESCAPES = /* @__PURE__ */ new Set([ + "\x1B", + "\x9B" +]); +var END_CODE = 39; +var ANSI_ESCAPE_BELL = "\x07"; +var ANSI_CSI = "["; +var ANSI_OSC = "]"; +var ANSI_SGR_TERMINATOR = "m"; +var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`; +var wrapAnsiCode = (code) => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`; +var wrapAnsiHyperlink = (url) => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`; +var wordLengths = (string) => string.split(" ").map((character) => stringWidth(character)); +var wrapWord = (rows, word, columns) => { + const characters = [...word]; + let isInsideEscape = false; + let isInsideLinkEscape = false; + let visible = stringWidth(stripAnsi(rows.at(-1))); + for (const [index, character] of characters.entries()) { + const characterLength = stringWidth(character); + if (visible + characterLength <= columns) { + rows[rows.length - 1] += character; + } else { + rows.push(character); + visible = 0; + } + if (ESCAPES.has(character)) { + isInsideEscape = true; + const ansiEscapeLinkCandidate = characters.slice(index + 1, index + 1 + ANSI_ESCAPE_LINK.length).join(""); + isInsideLinkEscape = ansiEscapeLinkCandidate === ANSI_ESCAPE_LINK; + } + if (isInsideEscape) { + if (isInsideLinkEscape) { + if (character === ANSI_ESCAPE_BELL) { + isInsideEscape = false; + isInsideLinkEscape = false; + } + } else if (character === ANSI_SGR_TERMINATOR) { + isInsideEscape = false; + } + continue; + } + visible += characterLength; + if (visible === columns && index < characters.length - 1) { + rows.push(""); + visible = 0; + } + } + if (!visible && rows.at(-1).length > 0 && rows.length > 1) { + rows[rows.length - 2] += rows.pop(); + } +}; +var stringVisibleTrimSpacesRight = (string) => { + const words = string.split(" "); + let last = words.length; + while (last > 0) { + if (stringWidth(words[last - 1]) > 0) { + break; + } + last--; + } + if (last === words.length) { + return string; + } + return words.slice(0, last).join(" ") + words.slice(last).join(""); +}; +var exec = (string, columns, options = {}) => { + if (options.trim !== false && string.trim() === "") { + return ""; + } + let returnValue = ""; + let escapeCode; + let escapeUrl; + const lengths = wordLengths(string); + let rows = [""]; + for (const [index, word] of string.split(" ").entries()) { + if (options.trim !== false) { + rows[rows.length - 1] = rows.at(-1).trimStart(); + } + let rowLength = stringWidth(rows.at(-1)); + if (index !== 0) { + if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) { + rows.push(""); + rowLength = 0; + } + if (rowLength > 0 || options.trim === false) { + rows[rows.length - 1] += " "; + rowLength++; + } + } + if (options.hard && lengths[index] > columns) { + const remainingColumns = columns - rowLength; + const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns); + const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns); + if (breaksStartingNextLine < breaksStartingThisLine) { + rows.push(""); + } + wrapWord(rows, word, columns); + continue; + } + if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) { + if (options.wordWrap === false && rowLength < columns) { + wrapWord(rows, word, columns); + continue; + } + rows.push(""); + } + if (rowLength + lengths[index] > columns && options.wordWrap === false) { + wrapWord(rows, word, columns); + continue; + } + rows[rows.length - 1] += word; + } + if (options.trim !== false) { + rows = rows.map((row) => stringVisibleTrimSpacesRight(row)); + } + const preString = rows.join("\n"); + const pre = [...preString]; + let preStringIndex = 0; + for (const [index, character] of pre.entries()) { + returnValue += character; + if (ESCAPES.has(character)) { + const { groups } = new RegExp(`(?:\\${ANSI_CSI}(?\\d+)m|\\${ANSI_ESCAPE_LINK}(?.*)${ANSI_ESCAPE_BELL})`).exec(preString.slice(preStringIndex)) || { groups: {} }; + if (groups.code !== void 0) { + const code2 = Number.parseFloat(groups.code); + escapeCode = code2 === END_CODE ? void 0 : code2; + } else if (groups.uri !== void 0) { + escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri; + } + } + const code = ansi_styles_default.codes.get(Number(escapeCode)); + if (pre[index + 1] === "\n") { + if (escapeUrl) { + returnValue += wrapAnsiHyperlink(""); + } + if (escapeCode && code) { + returnValue += wrapAnsiCode(code); + } + } else if (character === "\n") { + if (escapeCode && code) { + returnValue += wrapAnsiCode(escapeCode); + } + if (escapeUrl) { + returnValue += wrapAnsiHyperlink(escapeUrl); + } + } + preStringIndex += character.length; + } + return returnValue; +}; +function wrapAnsi(string, columns, options) { + return String(string).normalize().replaceAll("\r\n", "\n").split("\n").map((line) => exec(line, columns, options)).join("\n"); +} + +// +function ui(opts) { + return cliui(opts, { + stringWidth, + stripAnsi, + wrap: wrapAnsi + }); +} + +// +import { dirname, resolve } from "path"; +import { readdirSync, statSync } from "fs"; +function sync_default(start, callback) { + let dir = resolve(".", start); + let tmp, stats = statSync(dir); + if (!stats.isDirectory()) { + dir = dirname(dir); + } + while (true) { + tmp = callback(dir, readdirSync(dir)); + if (tmp) + return resolve(dir, tmp); + dir = dirname(tmp = dir); + if (tmp === dir) + break; + } +} + +// +import { inspect } from "util"; +import { fileURLToPath } from "url"; + +// +import { format } from "util"; +import { normalize, resolve as resolve2 } from "path"; + +// +function camelCase(str) { + const isCamelCase = str !== str.toLowerCase() && str !== str.toUpperCase(); + if (!isCamelCase) { + str = str.toLowerCase(); + } + if (str.indexOf("-") === -1 && str.indexOf("_") === -1) { + return str; + } else { + let camelcase = ""; + let nextChrUpper = false; + const leadingHyphens = str.match(/^-+/); + for (let i = leadingHyphens ? leadingHyphens[0].length : 0; i < str.length; i++) { + let chr = str.charAt(i); + if (nextChrUpper) { + nextChrUpper = false; + chr = chr.toUpperCase(); + } + if (i !== 0 && (chr === "-" || chr === "_")) { + nextChrUpper = true; + } else if (chr !== "-" && chr !== "_") { + camelcase += chr; + } + } + return camelcase; + } +} +function decamelize(str, joinString) { + const lowercase = str.toLowerCase(); + joinString = joinString || "-"; + let notCamelcase = ""; + for (let i = 0; i < str.length; i++) { + const chrLower = lowercase.charAt(i); + const chrString = str.charAt(i); + if (chrLower !== chrString && i > 0) { + notCamelcase += `${joinString}${lowercase.charAt(i)}`; + } else { + notCamelcase += chrString; + } + } + return notCamelcase; +} +function looksLikeNumber(x) { + if (x === null || x === void 0) + return false; + if (typeof x === "number") + return true; + if (/^0x[0-9a-f]+$/i.test(x)) + return true; + if (/^0[^.]/.test(x)) + return false; + return /^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} + +// +function tokenizeArgString(argString) { + if (Array.isArray(argString)) { + return argString.map((e) => typeof e !== "string" ? e + "" : e); + } + argString = argString.trim(); + let i = 0; + let prevC = null; + let c = null; + let opening = null; + const args = []; + for (let ii = 0; ii < argString.length; ii++) { + prevC = c; + c = argString.charAt(ii); + if (c === " " && !opening) { + if (!(prevC === " ")) { + i++; + } + continue; + } + if (c === opening) { + opening = null; + } else if ((c === "'" || c === '"') && !opening) { + opening = c; + } + if (!args[i]) + args[i] = ""; + args[i] += c; + } + return args; +} + +// +var DefaultValuesForTypeKey; +(function(DefaultValuesForTypeKey2) { + DefaultValuesForTypeKey2["BOOLEAN"] = "boolean"; + DefaultValuesForTypeKey2["STRING"] = "string"; + DefaultValuesForTypeKey2["NUMBER"] = "number"; + DefaultValuesForTypeKey2["ARRAY"] = "array"; +})(DefaultValuesForTypeKey || (DefaultValuesForTypeKey = {})); + +// +var mixin2; +var YargsParser = class { + constructor(_mixin) { + mixin2 = _mixin; + } + parse(argsInput, options) { + const opts = Object.assign({ + alias: void 0, + array: void 0, + boolean: void 0, + config: void 0, + configObjects: void 0, + configuration: void 0, + coerce: void 0, + count: void 0, + default: void 0, + envPrefix: void 0, + narg: void 0, + normalize: void 0, + string: void 0, + number: void 0, + __: void 0, + key: void 0 + }, options); + const args = tokenizeArgString(argsInput); + const inputIsString = typeof argsInput === "string"; + const aliases = combineAliases(Object.assign(/* @__PURE__ */ Object.create(null), opts.alias)); + const configuration = Object.assign({ + "boolean-negation": true, + "camel-case-expansion": true, + "combine-arrays": false, + "dot-notation": true, + "duplicate-arguments-array": true, + "flatten-duplicate-arrays": true, + "greedy-arrays": true, + "halt-at-non-option": false, + "nargs-eats-options": false, + "negation-prefix": "no-", + "parse-numbers": true, + "parse-positional-numbers": true, + "populate--": false, + "set-placeholder-key": false, + "short-option-groups": true, + "strip-aliased": false, + "strip-dashed": false, + "unknown-options-as-args": false + }, opts.configuration); + const defaults = Object.assign(/* @__PURE__ */ Object.create(null), opts.default); + const configObjects = opts.configObjects || []; + const envPrefix = opts.envPrefix; + const notFlagsOption = configuration["populate--"]; + const notFlagsArgv = notFlagsOption ? "--" : "_"; + const newAliases = /* @__PURE__ */ Object.create(null); + const defaulted = /* @__PURE__ */ Object.create(null); + const __ = opts.__ || mixin2.format; + const flags = { + aliases: /* @__PURE__ */ Object.create(null), + arrays: /* @__PURE__ */ Object.create(null), + bools: /* @__PURE__ */ Object.create(null), + strings: /* @__PURE__ */ Object.create(null), + numbers: /* @__PURE__ */ Object.create(null), + counts: /* @__PURE__ */ Object.create(null), + normalize: /* @__PURE__ */ Object.create(null), + configs: /* @__PURE__ */ Object.create(null), + nargs: /* @__PURE__ */ Object.create(null), + coercions: /* @__PURE__ */ Object.create(null), + keys: [] + }; + const negative = /^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/; + const negatedBoolean = new RegExp("^--" + configuration["negation-prefix"] + "(.+)"); + [].concat(opts.array || []).filter(Boolean).forEach(function(opt) { + const key = typeof opt === "object" ? opt.key : opt; + const assignment = Object.keys(opt).map(function(key2) { + const arrayFlagKeys = { + boolean: "bools", + string: "strings", + number: "numbers" + }; + return arrayFlagKeys[key2]; + }).filter(Boolean).pop(); + if (assignment) { + flags[assignment][key] = true; + } + flags.arrays[key] = true; + flags.keys.push(key); + }); + [].concat(opts.boolean || []).filter(Boolean).forEach(function(key) { + flags.bools[key] = true; + flags.keys.push(key); + }); + [].concat(opts.string || []).filter(Boolean).forEach(function(key) { + flags.strings[key] = true; + flags.keys.push(key); + }); + [].concat(opts.number || []).filter(Boolean).forEach(function(key) { + flags.numbers[key] = true; + flags.keys.push(key); + }); + [].concat(opts.count || []).filter(Boolean).forEach(function(key) { + flags.counts[key] = true; + flags.keys.push(key); + }); + [].concat(opts.normalize || []).filter(Boolean).forEach(function(key) { + flags.normalize[key] = true; + flags.keys.push(key); + }); + if (typeof opts.narg === "object") { + Object.entries(opts.narg).forEach(([key, value]) => { + if (typeof value === "number") { + flags.nargs[key] = value; + flags.keys.push(key); + } + }); + } + if (typeof opts.coerce === "object") { + Object.entries(opts.coerce).forEach(([key, value]) => { + if (typeof value === "function") { + flags.coercions[key] = value; + flags.keys.push(key); + } + }); + } + if (typeof opts.config !== "undefined") { + if (Array.isArray(opts.config) || typeof opts.config === "string") { + ; + [].concat(opts.config).filter(Boolean).forEach(function(key) { + flags.configs[key] = true; + }); + } else if (typeof opts.config === "object") { + Object.entries(opts.config).forEach(([key, value]) => { + if (typeof value === "boolean" || typeof value === "function") { + flags.configs[key] = value; + } + }); + } + } + extendAliases(opts.key, aliases, opts.default, flags.arrays); + Object.keys(defaults).forEach(function(key) { + (flags.aliases[key] || []).forEach(function(alias) { + defaults[alias] = defaults[key]; + }); + }); + let error = null; + checkConfiguration(); + let notFlags = []; + const argv = Object.assign(/* @__PURE__ */ Object.create(null), { _: [] }); + const argvReturn = {}; + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + const truncatedArg = arg.replace(/^-{3,}/, "---"); + let broken; + let key; + let letters; + let m; + let next; + let value; + if (arg !== "--" && /^-/.test(arg) && isUnknownOptionAsArg(arg)) { + pushPositional(arg); + } else if (truncatedArg.match(/^---+(=|$)/)) { + pushPositional(arg); + continue; + } else if (arg.match(/^--.+=/) || !configuration["short-option-groups"] && arg.match(/^-.+=/)) { + m = arg.match(/^--?([^=]+)=([\s\S]*)$/); + if (m !== null && Array.isArray(m) && m.length >= 3) { + if (checkAllAliases(m[1], flags.arrays)) { + i = eatArray(i, m[1], args, m[2]); + } else if (checkAllAliases(m[1], flags.nargs) !== false) { + i = eatNargs(i, m[1], args, m[2]); + } else { + setArg(m[1], m[2], true); + } + } + } else if (arg.match(negatedBoolean) && configuration["boolean-negation"]) { + m = arg.match(negatedBoolean); + if (m !== null && Array.isArray(m) && m.length >= 2) { + key = m[1]; + setArg(key, checkAllAliases(key, flags.arrays) ? [false] : false); + } + } else if (arg.match(/^--.+/) || !configuration["short-option-groups"] && arg.match(/^-[^-]+/)) { + m = arg.match(/^--?(.+)/); + if (m !== null && Array.isArray(m) && m.length >= 2) { + key = m[1]; + if (checkAllAliases(key, flags.arrays)) { + i = eatArray(i, key, args); + } else if (checkAllAliases(key, flags.nargs) !== false) { + i = eatNargs(i, key, args); + } else { + next = args[i + 1]; + if (next !== void 0 && (!next.match(/^-/) || next.match(negative)) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { + setArg(key, next); + i++; + } else if (/^(true|false)$/.test(next)) { + setArg(key, next); + i++; + } else { + setArg(key, defaultValue(key)); + } + } + } + } else if (arg.match(/^-.\..+=/)) { + m = arg.match(/^-([^=]+)=([\s\S]*)$/); + if (m !== null && Array.isArray(m) && m.length >= 3) { + setArg(m[1], m[2]); + } + } else if (arg.match(/^-.\..+/) && !arg.match(negative)) { + next = args[i + 1]; + m = arg.match(/^-(.\..+)/); + if (m !== null && Array.isArray(m) && m.length >= 2) { + key = m[1]; + if (next !== void 0 && !next.match(/^-/) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { + setArg(key, next); + i++; + } else { + setArg(key, defaultValue(key)); + } + } + } else if (arg.match(/^-[^-]+/) && !arg.match(negative)) { + letters = arg.slice(1, -1).split(""); + broken = false; + for (let j = 0; j < letters.length; j++) { + next = arg.slice(j + 2); + if (letters[j + 1] && letters[j + 1] === "=") { + value = arg.slice(j + 3); + key = letters[j]; + if (checkAllAliases(key, flags.arrays)) { + i = eatArray(i, key, args, value); + } else if (checkAllAliases(key, flags.nargs) !== false) { + i = eatNargs(i, key, args, value); + } else { + setArg(key, value); + } + broken = true; + break; + } + if (next === "-") { + setArg(letters[j], next); + continue; + } + if (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) && checkAllAliases(next, flags.bools) === false) { + setArg(letters[j], next); + broken = true; + break; + } + if (letters[j + 1] && letters[j + 1].match(/\W/)) { + setArg(letters[j], next); + broken = true; + break; + } else { + setArg(letters[j], defaultValue(letters[j])); + } + } + key = arg.slice(-1)[0]; + if (!broken && key !== "-") { + if (checkAllAliases(key, flags.arrays)) { + i = eatArray(i, key, args); + } else if (checkAllAliases(key, flags.nargs) !== false) { + i = eatNargs(i, key, args); + } else { + next = args[i + 1]; + if (next !== void 0 && (!/^(-|--)[^-]/.test(next) || next.match(negative)) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { + setArg(key, next); + i++; + } else if (/^(true|false)$/.test(next)) { + setArg(key, next); + i++; + } else { + setArg(key, defaultValue(key)); + } + } + } + } else if (arg.match(/^-[0-9]$/) && arg.match(negative) && checkAllAliases(arg.slice(1), flags.bools)) { + key = arg.slice(1); + setArg(key, defaultValue(key)); + } else if (arg === "--") { + notFlags = args.slice(i + 1); + break; + } else if (configuration["halt-at-non-option"]) { + notFlags = args.slice(i); + break; + } else { + pushPositional(arg); + } + } + applyEnvVars(argv, true); + applyEnvVars(argv, false); + setConfig2(argv); + setConfigObjects(); + applyDefaultsAndAliases(argv, flags.aliases, defaults, true); + applyCoercions(argv); + if (configuration["set-placeholder-key"]) + setPlaceholderKeys(argv); + Object.keys(flags.counts).forEach(function(key) { + if (!hasKey(argv, key.split("."))) + setArg(key, 0); + }); + if (notFlagsOption && notFlags.length) + argv[notFlagsArgv] = []; + notFlags.forEach(function(key) { + argv[notFlagsArgv].push(key); + }); + if (configuration["camel-case-expansion"] && configuration["strip-dashed"]) { + Object.keys(argv).filter((key) => key !== "--" && key.includes("-")).forEach((key) => { + delete argv[key]; + }); + } + if (configuration["strip-aliased"]) { + ; + [].concat(...Object.keys(aliases).map((k) => aliases[k])).forEach((alias) => { + if (configuration["camel-case-expansion"] && alias.includes("-")) { + delete argv[alias.split(".").map((prop) => camelCase(prop)).join(".")]; + } + delete argv[alias]; + }); + } + function pushPositional(arg) { + const maybeCoercedNumber = maybeCoerceNumber("_", arg); + if (typeof maybeCoercedNumber === "string" || typeof maybeCoercedNumber === "number") { + argv._.push(maybeCoercedNumber); + } + } + function eatNargs(i, key, args2, argAfterEqualSign) { + let ii; + let toEat = checkAllAliases(key, flags.nargs); + toEat = typeof toEat !== "number" || isNaN(toEat) ? 1 : toEat; + if (toEat === 0) { + if (!isUndefined(argAfterEqualSign)) { + error = Error(__("Argument unexpected for: %s", key)); + } + setArg(key, defaultValue(key)); + return i; + } + let available = isUndefined(argAfterEqualSign) ? 0 : 1; + if (configuration["nargs-eats-options"]) { + if (args2.length - (i + 1) + available < toEat) { + error = Error(__("Not enough arguments following: %s", key)); + } + available = toEat; + } else { + for (ii = i + 1; ii < args2.length; ii++) { + if (!args2[ii].match(/^-[^0-9]/) || args2[ii].match(negative) || isUnknownOptionAsArg(args2[ii])) + available++; + else + break; + } + if (available < toEat) + error = Error(__("Not enough arguments following: %s", key)); + } + let consumed = Math.min(available, toEat); + if (!isUndefined(argAfterEqualSign) && consumed > 0) { + setArg(key, argAfterEqualSign); + consumed--; + } + for (ii = i + 1; ii < consumed + i + 1; ii++) { + setArg(key, args2[ii]); + } + return i + consumed; + } + function eatArray(i, key, args2, argAfterEqualSign) { + let argsToSet = []; + let next = argAfterEqualSign || args2[i + 1]; + const nargsCount = checkAllAliases(key, flags.nargs); + if (checkAllAliases(key, flags.bools) && !/^(true|false)$/.test(next)) { + argsToSet.push(true); + } else if (isUndefined(next) || isUndefined(argAfterEqualSign) && /^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) { + if (defaults[key] !== void 0) { + const defVal = defaults[key]; + argsToSet = Array.isArray(defVal) ? defVal : [defVal]; + } + } else { + if (!isUndefined(argAfterEqualSign)) { + argsToSet.push(processValue(key, argAfterEqualSign, true)); + } + for (let ii = i + 1; ii < args2.length; ii++) { + if (!configuration["greedy-arrays"] && argsToSet.length > 0 || nargsCount && typeof nargsCount === "number" && argsToSet.length >= nargsCount) + break; + next = args2[ii]; + if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) + break; + i = ii; + argsToSet.push(processValue(key, next, inputIsString)); + } + } + if (typeof nargsCount === "number" && (nargsCount && argsToSet.length < nargsCount || isNaN(nargsCount) && argsToSet.length === 0)) { + error = Error(__("Not enough arguments following: %s", key)); + } + setArg(key, argsToSet); + return i; + } + function setArg(key, val, shouldStripQuotes = inputIsString) { + if (/-/.test(key) && configuration["camel-case-expansion"]) { + const alias = key.split(".").map(function(prop) { + return camelCase(prop); + }).join("."); + addNewAlias(key, alias); + } + const value = processValue(key, val, shouldStripQuotes); + const splitKey = key.split("."); + setKey(argv, splitKey, value); + if (flags.aliases[key]) { + flags.aliases[key].forEach(function(x) { + const keyProperties = x.split("."); + setKey(argv, keyProperties, value); + }); + } + if (splitKey.length > 1 && configuration["dot-notation"]) { + ; + (flags.aliases[splitKey[0]] || []).forEach(function(x) { + let keyProperties = x.split("."); + const a = [].concat(splitKey); + a.shift(); + keyProperties = keyProperties.concat(a); + if (!(flags.aliases[key] || []).includes(keyProperties.join("."))) { + setKey(argv, keyProperties, value); + } + }); + } + if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) { + const keys = [key].concat(flags.aliases[key] || []); + keys.forEach(function(key2) { + Object.defineProperty(argvReturn, key2, { + enumerable: true, + get() { + return val; + }, + set(value2) { + val = typeof value2 === "string" ? mixin2.normalize(value2) : value2; + } + }); + }); + } + } + function addNewAlias(key, alias) { + if (!(flags.aliases[key] && flags.aliases[key].length)) { + flags.aliases[key] = [alias]; + newAliases[alias] = true; + } + if (!(flags.aliases[alias] && flags.aliases[alias].length)) { + addNewAlias(alias, key); + } + } + function processValue(key, val, shouldStripQuotes) { + if (shouldStripQuotes) { + val = stripQuotes(val); + } + if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) { + if (typeof val === "string") + val = val === "true"; + } + let value = Array.isArray(val) ? val.map(function(v) { + return maybeCoerceNumber(key, v); + }) : maybeCoerceNumber(key, val); + if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === "boolean")) { + value = increment(); + } + if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) { + if (Array.isArray(val)) + value = val.map((val2) => { + return mixin2.normalize(val2); + }); + else + value = mixin2.normalize(val); + } + return value; + } + function maybeCoerceNumber(key, value) { + if (!configuration["parse-positional-numbers"] && key === "_") + return value; + if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.bools) && !Array.isArray(value)) { + const shouldCoerceNumber = looksLikeNumber(value) && configuration["parse-numbers"] && Number.isSafeInteger(Math.floor(parseFloat(`${value}`))); + if (shouldCoerceNumber || !isUndefined(value) && checkAllAliases(key, flags.numbers)) { + value = Number(value); + } + } + return value; + } + function setConfig2(argv2) { + const configLookup = /* @__PURE__ */ Object.create(null); + applyDefaultsAndAliases(configLookup, flags.aliases, defaults); + Object.keys(flags.configs).forEach(function(configKey) { + const configPath = argv2[configKey] || configLookup[configKey]; + if (configPath) { + try { + let config = null; + const resolvedConfigPath = mixin2.resolve(mixin2.cwd(), configPath); + const resolveConfig = flags.configs[configKey]; + if (typeof resolveConfig === "function") { + try { + config = resolveConfig(resolvedConfigPath); + } catch (e) { + config = e; + } + if (config instanceof Error) { + error = config; + return; + } + } else { + config = mixin2.require(resolvedConfigPath); + } + setConfigObject(config); + } catch (ex) { + if (ex.name === "PermissionDenied") + error = ex; + else if (argv2[configKey]) + error = Error(__("Invalid JSON config file: %s", configPath)); + } + } + }); + } + function setConfigObject(config, prev) { + Object.keys(config).forEach(function(key) { + const value = config[key]; + const fullKey = prev ? prev + "." + key : key; + if (typeof value === "object" && value !== null && !Array.isArray(value) && configuration["dot-notation"]) { + setConfigObject(value, fullKey); + } else { + if (!hasKey(argv, fullKey.split(".")) || checkAllAliases(fullKey, flags.arrays) && configuration["combine-arrays"]) { + setArg(fullKey, value); + } + } + }); + } + function setConfigObjects() { + if (typeof configObjects !== "undefined") { + configObjects.forEach(function(configObject) { + setConfigObject(configObject); + }); + } + } + function applyEnvVars(argv2, configOnly) { + if (typeof envPrefix === "undefined") + return; + const prefix = typeof envPrefix === "string" ? envPrefix : ""; + const env3 = mixin2.env(); + Object.keys(env3).forEach(function(envVar) { + if (prefix === "" || envVar.lastIndexOf(prefix, 0) === 0) { + const keys = envVar.split("__").map(function(key, i) { + if (i === 0) { + key = key.substring(prefix.length); + } + return camelCase(key); + }); + if ((configOnly && flags.configs[keys.join(".")] || !configOnly) && !hasKey(argv2, keys)) { + setArg(keys.join("."), env3[envVar]); + } + } + }); + } + function applyCoercions(argv2) { + let coerce; + const applied = /* @__PURE__ */ new Set(); + Object.keys(argv2).forEach(function(key) { + if (!applied.has(key)) { + coerce = checkAllAliases(key, flags.coercions); + if (typeof coerce === "function") { + try { + const value = maybeCoerceNumber(key, coerce(argv2[key])); + [].concat(flags.aliases[key] || [], key).forEach((ali) => { + applied.add(ali); + argv2[ali] = value; + }); + } catch (err) { + error = err; + } + } + } + }); + } + function setPlaceholderKeys(argv2) { + flags.keys.forEach((key) => { + if (~key.indexOf(".")) + return; + if (typeof argv2[key] === "undefined") + argv2[key] = void 0; + }); + return argv2; + } + function applyDefaultsAndAliases(obj, aliases2, defaults2, canLog = false) { + Object.keys(defaults2).forEach(function(key) { + if (!hasKey(obj, key.split("."))) { + setKey(obj, key.split("."), defaults2[key]); + if (canLog) + defaulted[key] = true; + (aliases2[key] || []).forEach(function(x) { + if (hasKey(obj, x.split("."))) + return; + setKey(obj, x.split("."), defaults2[key]); + }); + } + }); + } + function hasKey(obj, keys) { + let o = obj; + if (!configuration["dot-notation"]) + keys = [keys.join(".")]; + keys.slice(0, -1).forEach(function(key2) { + o = o[key2] || {}; + }); + const key = keys[keys.length - 1]; + if (typeof o !== "object") + return false; + else + return key in o; + } + function setKey(obj, keys, value) { + let o = obj; + if (!configuration["dot-notation"]) + keys = [keys.join(".")]; + keys.slice(0, -1).forEach(function(key2) { + key2 = sanitizeKey(key2); + if (typeof o === "object" && o[key2] === void 0) { + o[key2] = {}; + } + if (typeof o[key2] !== "object" || Array.isArray(o[key2])) { + if (Array.isArray(o[key2])) { + o[key2].push({}); + } else { + o[key2] = [o[key2], {}]; + } + o = o[key2][o[key2].length - 1]; + } else { + o = o[key2]; + } + }); + const key = sanitizeKey(keys[keys.length - 1]); + const isTypeArray = checkAllAliases(keys.join("."), flags.arrays); + const isValueArray = Array.isArray(value); + let duplicate = configuration["duplicate-arguments-array"]; + if (!duplicate && checkAllAliases(key, flags.nargs)) { + duplicate = true; + if (!isUndefined(o[key]) && flags.nargs[key] === 1 || Array.isArray(o[key]) && o[key].length === flags.nargs[key]) { + o[key] = void 0; + } + } + if (value === increment()) { + o[key] = increment(o[key]); + } else if (Array.isArray(o[key])) { + if (duplicate && isTypeArray && isValueArray) { + o[key] = configuration["flatten-duplicate-arrays"] ? o[key].concat(value) : (Array.isArray(o[key][0]) ? o[key] : [o[key]]).concat([value]); + } else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) { + o[key] = value; + } else { + o[key] = o[key].concat([value]); + } + } else if (o[key] === void 0 && isTypeArray) { + o[key] = isValueArray ? value : [value]; + } else if (duplicate && !(o[key] === void 0 || checkAllAliases(key, flags.counts) || checkAllAliases(key, flags.bools))) { + o[key] = [o[key], value]; + } else { + o[key] = value; + } + } + function extendAliases(...args2) { + args2.forEach(function(obj) { + Object.keys(obj || {}).forEach(function(key) { + if (flags.aliases[key]) + return; + flags.aliases[key] = [].concat(aliases[key] || []); + flags.aliases[key].concat(key).forEach(function(x) { + if (/-/.test(x) && configuration["camel-case-expansion"]) { + const c = camelCase(x); + if (c !== key && flags.aliases[key].indexOf(c) === -1) { + flags.aliases[key].push(c); + newAliases[c] = true; + } + } + }); + flags.aliases[key].concat(key).forEach(function(x) { + if (x.length > 1 && /[A-Z]/.test(x) && configuration["camel-case-expansion"]) { + const c = decamelize(x, "-"); + if (c !== key && flags.aliases[key].indexOf(c) === -1) { + flags.aliases[key].push(c); + newAliases[c] = true; + } + } + }); + flags.aliases[key].forEach(function(x) { + flags.aliases[x] = [key].concat(flags.aliases[key].filter(function(y) { + return x !== y; + })); + }); + }); + }); + } + function checkAllAliases(key, flag) { + const toCheck = [].concat(flags.aliases[key] || [], key); + const keys = Object.keys(flag); + const setAlias = toCheck.find((key2) => keys.includes(key2)); + return setAlias ? flag[setAlias] : false; + } + function hasAnyFlag(key) { + const flagsKeys = Object.keys(flags); + const toCheck = [].concat(flagsKeys.map((k) => flags[k])); + return toCheck.some(function(flag) { + return Array.isArray(flag) ? flag.includes(key) : flag[key]; + }); + } + function hasFlagsMatching(arg, ...patterns) { + const toCheck = [].concat(...patterns); + return toCheck.some(function(pattern) { + const match = arg.match(pattern); + return match && hasAnyFlag(match[1]); + }); + } + function hasAllShortFlags(arg) { + if (arg.match(negative) || !arg.match(/^-[^-]+/)) { + return false; + } + let hasAllFlags = true; + let next; + const letters = arg.slice(1).split(""); + for (let j = 0; j < letters.length; j++) { + next = arg.slice(j + 2); + if (!hasAnyFlag(letters[j])) { + hasAllFlags = false; + break; + } + if (letters[j + 1] && letters[j + 1] === "=" || next === "-" || /[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) || letters[j + 1] && letters[j + 1].match(/\W/)) { + break; + } + } + return hasAllFlags; + } + function isUnknownOptionAsArg(arg) { + return configuration["unknown-options-as-args"] && isUnknownOption(arg); + } + function isUnknownOption(arg) { + arg = arg.replace(/^-{3,}/, "--"); + if (arg.match(negative)) { + return false; + } + if (hasAllShortFlags(arg)) { + return false; + } + const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/; + const normalFlag = /^-+([^=]+?)$/; + const flagEndingInHyphen = /^-+([^=]+?)-$/; + const flagEndingInDigits = /^-+([^=]+?\d+)$/; + const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/; + return !hasFlagsMatching(arg, flagWithEquals, negatedBoolean, normalFlag, flagEndingInHyphen, flagEndingInDigits, flagEndingInNonWordCharacters); + } + function defaultValue(key) { + if (!checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts) && `${key}` in defaults) { + return defaults[key]; + } else { + return defaultForType(guessType2(key)); + } + } + function defaultForType(type) { + const def = { + [DefaultValuesForTypeKey.BOOLEAN]: true, + [DefaultValuesForTypeKey.STRING]: "", + [DefaultValuesForTypeKey.NUMBER]: void 0, + [DefaultValuesForTypeKey.ARRAY]: [] + }; + return def[type]; + } + function guessType2(key) { + let type = DefaultValuesForTypeKey.BOOLEAN; + if (checkAllAliases(key, flags.strings)) + type = DefaultValuesForTypeKey.STRING; + else if (checkAllAliases(key, flags.numbers)) + type = DefaultValuesForTypeKey.NUMBER; + else if (checkAllAliases(key, flags.bools)) + type = DefaultValuesForTypeKey.BOOLEAN; + else if (checkAllAliases(key, flags.arrays)) + type = DefaultValuesForTypeKey.ARRAY; + return type; + } + function isUndefined(num) { + return num === void 0; + } + function checkConfiguration() { + Object.keys(flags.counts).find((key) => { + if (checkAllAliases(key, flags.arrays)) { + error = Error(__("Invalid configuration: %s, opts.count excludes opts.array.", key)); + return true; + } else if (checkAllAliases(key, flags.nargs)) { + error = Error(__("Invalid configuration: %s, opts.count excludes opts.narg.", key)); + return true; + } + return false; + }); + } + return { + aliases: Object.assign({}, flags.aliases), + argv: Object.assign(argvReturn, argv), + configuration, + defaulted: Object.assign({}, defaulted), + error, + newAliases: Object.assign({}, newAliases) + }; + } +}; +function combineAliases(aliases) { + const aliasArrays = []; + const combined = /* @__PURE__ */ Object.create(null); + let change = true; + Object.keys(aliases).forEach(function(key) { + aliasArrays.push([].concat(aliases[key], key)); + }); + while (change) { + change = false; + for (let i = 0; i < aliasArrays.length; i++) { + for (let ii = i + 1; ii < aliasArrays.length; ii++) { + const intersect = aliasArrays[i].filter(function(v) { + return aliasArrays[ii].indexOf(v) !== -1; + }); + if (intersect.length) { + aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]); + aliasArrays.splice(ii, 1); + change = true; + break; + } + } + } + } + aliasArrays.forEach(function(aliasArray) { + aliasArray = aliasArray.filter(function(v, i, self2) { + return self2.indexOf(v) === i; + }); + const lastAlias = aliasArray.pop(); + if (lastAlias !== void 0 && typeof lastAlias === "string") { + combined[lastAlias] = aliasArray; + } + }); + return combined; +} +function increment(orig) { + return orig !== void 0 ? orig + 1 : 1; +} +function sanitizeKey(key) { + if (key === "__proto__") + return "___proto___"; + return key; +} +function stripQuotes(val) { + return typeof val === "string" && (val[0] === "'" || val[0] === '"') && val[val.length - 1] === val[0] ? val.substring(1, val.length - 1) : val; +} + +// +import { readFileSync } from "fs"; +import { createRequire } from "node:module"; +var _a; +var _b; +var _c; +var minNodeVersion = process && process.env && process.env.YARGS_MIN_NODE_VERSION ? Number(process.env.YARGS_MIN_NODE_VERSION) : 20; +var nodeVersion = (_b = (_a = process === null || process === void 0 ? void 0 : process.versions) === null || _a === void 0 ? void 0 : _a.node) !== null && _b !== void 0 ? _b : (_c = process === null || process === void 0 ? void 0 : process.version) === null || _c === void 0 ? void 0 : _c.slice(1); +if (nodeVersion) { + const major = Number(nodeVersion.match(/^([^.]+)/)[1]); + if (major < minNodeVersion) { + throw Error(`yargs parser supports a minimum Node.js version of ${minNodeVersion}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`); + } +} +var env2 = process ? process.env : {}; +var require2 = createRequire ? createRequire(import.meta.url) : void 0; +var parser = new YargsParser({ + cwd: process.cwd, + env: () => { + return env2; }, - test: { - name: "test", - description: "Improvements or corrections made to the project's test suite", - scope: ScopeRequirement.Optional, - releaseNotesLevel: ReleaseNotesLevel.Hidden + format, + normalize, + resolve: resolve2, + require: (path) => { + if (typeof require2 !== "undefined") { + return require2(path); + } else if (path.match(/\.json$/)) { + return JSON.parse(readFileSync(path, "utf8")); + } else { + throw Error("only .json config files are supported in ESM"); + } + } +}); +var yargsParser = function Parser(args, opts) { + const result = parser.parse(args.slice(), opts); + return result.argv; +}; +yargsParser.detailed = function(args, opts) { + return parser.parse(args.slice(), opts); +}; +yargsParser.camelCase = camelCase; +yargsParser.decamelize = decamelize; +yargsParser.looksLikeNumber = looksLikeNumber; +var lib_default = yargsParser; + +// +import { basename, dirname as dirname2, extname, relative, resolve as resolve4, join as join2 } from "path"; + +// +function getProcessArgvBinIndex() { + if (isBundledElectronApp()) + return 0; + return 1; +} +function isBundledElectronApp() { + return isElectronApp() && !process.defaultApp; +} +function isElectronApp() { + return !!process.versions.electron; +} +function getProcessArgvBin() { + return process.argv[getProcessArgvBinIndex()]; +} + +// +import { readFileSync as readFileSync2, statSync as statSync2, writeFile as writeFile2 } from "fs"; +import { format as format2 } from "util"; +import { resolve as resolve3 } from "path"; +var node_default = { + fs: { + readFileSync: readFileSync2, + writeFile: writeFile2 + }, + format: format2, + resolve: resolve3, + exists: (file) => { + try { + return statSync2(file).isFile(); + } catch (err) { + return false; + } + } +}; + +// +var shim; +var Y18N = class { + constructor(opts) { + opts = opts || {}; + this.directory = opts.directory || "./locales"; + this.updateFiles = typeof opts.updateFiles === "boolean" ? opts.updateFiles : true; + this.locale = opts.locale || "en"; + this.fallbackToLanguage = typeof opts.fallbackToLanguage === "boolean" ? opts.fallbackToLanguage : true; + this.cache = /* @__PURE__ */ Object.create(null); + this.writeQueue = []; + } + __(...args) { + if (typeof arguments[0] !== "string") { + return this._taggedLiteral(arguments[0], ...arguments); + } + const str = args.shift(); + let cb = function() { + }; + if (typeof args[args.length - 1] === "function") + cb = args.pop(); + cb = cb || function() { + }; + if (!this.cache[this.locale]) + this._readLocaleFile(); + if (!this.cache[this.locale][str] && this.updateFiles) { + this.cache[this.locale][str] = str; + this._enqueueWrite({ + directory: this.directory, + locale: this.locale, + cb + }); + } else { + cb(); + } + return shim.format.apply(shim.format, [this.cache[this.locale][str] || str].concat(args)); + } + __n() { + const args = Array.prototype.slice.call(arguments); + const singular = args.shift(); + const plural = args.shift(); + const quantity = args.shift(); + let cb = function() { + }; + if (typeof args[args.length - 1] === "function") + cb = args.pop(); + if (!this.cache[this.locale]) + this._readLocaleFile(); + let str = quantity === 1 ? singular : plural; + if (this.cache[this.locale][singular]) { + const entry = this.cache[this.locale][singular]; + str = entry[quantity === 1 ? "one" : "other"]; + } + if (!this.cache[this.locale][singular] && this.updateFiles) { + this.cache[this.locale][singular] = { + one: singular, + other: plural + }; + this._enqueueWrite({ + directory: this.directory, + locale: this.locale, + cb + }); + } else { + cb(); + } + const values = [str]; + if (~str.indexOf("%d")) + values.push(quantity); + return shim.format.apply(shim.format, values.concat(args)); + } + setLocale(locale) { + this.locale = locale; + } + getLocale() { + return this.locale; + } + updateLocale(obj) { + if (!this.cache[this.locale]) + this._readLocaleFile(); + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + this.cache[this.locale][key] = obj[key]; + } + } + } + _taggedLiteral(parts, ...args) { + let str = ""; + parts.forEach(function(part, i) { + const arg = args[i + 1]; + str += part; + if (typeof arg !== "undefined") { + str += "%s"; + } + }); + return this.__.apply(this, [str].concat([].slice.call(args, 1))); + } + _enqueueWrite(work) { + this.writeQueue.push(work); + if (this.writeQueue.length === 1) + this._processWriteQueue(); + } + _processWriteQueue() { + const _this = this; + const work = this.writeQueue[0]; + const directory = work.directory; + const locale = work.locale; + const cb = work.cb; + const languageFile = this._resolveLocaleFile(directory, locale); + const serializedLocale = JSON.stringify(this.cache[locale], null, 2); + shim.fs.writeFile(languageFile, serializedLocale, "utf-8", function(err) { + _this.writeQueue.shift(); + if (_this.writeQueue.length > 0) + _this._processWriteQueue(); + cb(err); + }); + } + _readLocaleFile() { + let localeLookup = {}; + const languageFile = this._resolveLocaleFile(this.directory, this.locale); + try { + if (shim.fs.readFileSync) { + localeLookup = JSON.parse(shim.fs.readFileSync(languageFile, "utf-8")); + } + } catch (err) { + if (err instanceof SyntaxError) { + err.message = "syntax error in " + languageFile; + } + if (err.code === "ENOENT") + localeLookup = {}; + else + throw err; + } + this.cache[this.locale] = localeLookup; + } + _resolveLocaleFile(directory, locale) { + let file = shim.resolve(directory, "./", locale + ".json"); + if (this.fallbackToLanguage && !this._fileExistsSync(file) && ~locale.lastIndexOf("_")) { + const languageFile = shim.resolve(directory, "./", locale.split("_")[0] + ".json"); + if (this._fileExistsSync(languageFile)) + file = languageFile; + } + return file; + } + _fileExistsSync(file) { + return shim.exists(file); + } +}; +function y18n(opts, _shim) { + shim = _shim; + const y18n3 = new Y18N(opts); + return { + __: y18n3.__.bind(y18n3), + __n: y18n3.__n.bind(y18n3), + setLocale: y18n3.setLocale.bind(y18n3), + getLocale: y18n3.getLocale.bind(y18n3), + updateLocale: y18n3.updateLocale.bind(y18n3), + locale: y18n3.locale + }; +} + +// +var y18n2 = (opts) => { + return y18n(opts, node_default); +}; +var y18n_default = y18n2; + +// +var import_get_caller_file = __toESM(require_get_caller_file(), 1); +import { createRequire as createRequire2 } from "node:module"; +import { readFileSync as readFileSync3, readdirSync as readdirSync2 } from "node:fs"; +var __dirname2 = fileURLToPath(import.meta.url); +var mainFilename = __dirname2.substring(0, __dirname2.lastIndexOf("node_modules")); +var require3 = createRequire2(import.meta.url); +var esm_default = { + assert: { + notStrictEqual, + strictEqual + }, + cliui: ui, + findUp: sync_default, + getEnv: (key) => { + return process.env[key]; + }, + inspect, + getProcessArgvBin, + mainFilename: mainFilename || process.cwd(), + Parser: lib_default, + path: { + basename, + dirname: dirname2, + extname, + relative, + resolve: resolve4, + join: join2 + }, + process: { + argv: () => process.argv, + cwd: process.cwd, + emitWarning: (warning, type) => process.emitWarning(warning, type), + execPath: () => process.execPath, + exit: (code) => { + process.exit(code); + }, + nextTick: process.nextTick, + stdColumns: typeof process.stdout.columns !== "undefined" ? process.stdout.columns : null + }, + readFileSync: readFileSync3, + readdirSync: readdirSync2, + require: require3, + getCallerFile: () => { + const callerFile = (0, import_get_caller_file.default)(3); + return callerFile.match(/^file:\/\//) ? fileURLToPath(callerFile) : callerFile; + }, + stringWidth, + y18n: y18n_default({ + directory: resolve4(__dirname2, "../../../locales"), + updateFiles: false + }) +}; + +// +function assertNotStrictEqual(actual, expected, shim3, message) { + shim3.assert.notStrictEqual(actual, expected, message); +} +function assertSingleKey(actual, shim3) { + shim3.assert.strictEqual(typeof actual, "string"); +} +function objectKeys(object) { + return Object.keys(object); +} + +// +function isPromise(maybePromise) { + return !!maybePromise && !!maybePromise.then && typeof maybePromise.then === "function"; +} + +// +var YError = class _YError extends Error { + constructor(msg) { + super(msg || "yargs error"); + this.name = "YError"; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, _YError); + } + } +}; + +// +function parseCommand(cmd) { + const extraSpacesStrippedCommand = cmd.replace(/\s{2,}/g, " "); + const splitCommand = extraSpacesStrippedCommand.split(/\s+(?![^[]*]|[^<]*>)/); + const bregex = /\.*[\][<>]/g; + const firstCommand = splitCommand.shift(); + if (!firstCommand) + throw new Error(`No command found in: ${cmd}`); + const parsedCommand = { + cmd: firstCommand.replace(bregex, ""), + demanded: [], + optional: [] + }; + splitCommand.forEach((cmd2, i) => { + let variadic = false; + cmd2 = cmd2.replace(/\s/g, ""); + if (/\.+[\]>]/.test(cmd2) && i === splitCommand.length - 1) + variadic = true; + if (/^\[/.test(cmd2)) { + parsedCommand.optional.push({ + cmd: cmd2.replace(bregex, "").split("|"), + variadic + }); + } else { + parsedCommand.demanded.push({ + cmd: cmd2.replace(bregex, "").split("|"), + variadic + }); + } + }); + return parsedCommand; +} + +// +var positionName = ["first", "second", "third", "fourth", "fifth", "sixth"]; +function argsert(arg1, arg2, arg3) { + function parseArgs() { + return typeof arg1 === "object" ? [{ demanded: [], optional: [] }, arg1, arg2] : [ + parseCommand(`cmd ${arg1}`), + arg2, + arg3 + ]; + } + try { + let position = 0; + const [parsed, callerArguments, _length] = parseArgs(); + const args = [].slice.call(callerArguments); + while (args.length && args[args.length - 1] === void 0) + args.pop(); + const length = _length || args.length; + if (length < parsed.demanded.length) { + throw new YError(`Not enough arguments provided. Expected ${parsed.demanded.length} but received ${args.length}.`); + } + const totalCommands = parsed.demanded.length + parsed.optional.length; + if (length > totalCommands) { + throw new YError(`Too many arguments provided. Expected max ${totalCommands} but received ${length}.`); + } + parsed.demanded.forEach((demanded) => { + const arg = args.shift(); + const observedType = guessType(arg); + const matchingTypes = demanded.cmd.filter((type) => type === observedType || type === "*"); + if (matchingTypes.length === 0) + argumentTypeError(observedType, demanded.cmd, position); + position += 1; + }); + parsed.optional.forEach((optional) => { + if (args.length === 0) + return; + const arg = args.shift(); + const observedType = guessType(arg); + const matchingTypes = optional.cmd.filter((type) => type === observedType || type === "*"); + if (matchingTypes.length === 0) + argumentTypeError(observedType, optional.cmd, position); + position += 1; + }); + } catch (err) { + console.warn(err.stack); + } +} +function guessType(arg) { + if (Array.isArray(arg)) { + return "array"; + } else if (arg === null) { + return "null"; + } + return typeof arg; +} +function argumentTypeError(observedType, allowedTypes, position) { + throw new YError(`Invalid ${positionName[position] || "manyith"} argument. Expected ${allowedTypes.join(" or ")} but received ${observedType}.`); +} + +// +var GlobalMiddleware = class { + constructor(yargs) { + this.globalMiddleware = []; + this.frozens = []; + this.yargs = yargs; + } + addMiddleware(callback, applyBeforeValidation, global = true, mutates = false) { + argsert(" [boolean] [boolean] [boolean]", [callback, applyBeforeValidation, global], arguments.length); + if (Array.isArray(callback)) { + for (let i = 0; i < callback.length; i++) { + if (typeof callback[i] !== "function") { + throw Error("middleware must be a function"); + } + const m = callback[i]; + m.applyBeforeValidation = applyBeforeValidation; + m.global = global; + } + Array.prototype.push.apply(this.globalMiddleware, callback); + } else if (typeof callback === "function") { + const m = callback; + m.applyBeforeValidation = applyBeforeValidation; + m.global = global; + m.mutates = mutates; + this.globalMiddleware.push(callback); + } + return this.yargs; + } + addCoerceMiddleware(callback, option) { + const aliases = this.yargs.getAliases(); + this.globalMiddleware = this.globalMiddleware.filter((m) => { + const toCheck = [...aliases[option] || [], option]; + if (!m.option) + return true; + else + return !toCheck.includes(m.option); + }); + callback.option = option; + return this.addMiddleware(callback, true, true, true); + } + getMiddleware() { + return this.globalMiddleware; + } + freeze() { + this.frozens.push([...this.globalMiddleware]); + } + unfreeze() { + const frozen = this.frozens.pop(); + if (frozen !== void 0) + this.globalMiddleware = frozen; + } + reset() { + this.globalMiddleware = this.globalMiddleware.filter((m) => m.global); } }; +function commandMiddlewareFactory(commandMiddleware) { + if (!commandMiddleware) + return []; + return commandMiddleware.map((middleware) => { + middleware.applyBeforeValidation = false; + return middleware; + }); +} +function applyMiddleware(argv, yargs, middlewares, beforeValidation) { + return middlewares.reduce((acc, middleware) => { + if (middleware.applyBeforeValidation !== beforeValidation) { + return acc; + } + if (middleware.mutates) { + if (middleware.applied) + return acc; + middleware.applied = true; + } + if (isPromise(acc)) { + return acc.then((initialObj) => Promise.all([initialObj, middleware(initialObj, yargs)])).then(([initialObj, middlewareObj]) => Object.assign(initialObj, middlewareObj)); + } else { + const result = middleware(acc, yargs); + return isPromise(result) ? result.then((middlewareObj) => Object.assign(acc, middlewareObj)) : Object.assign(acc, result); + } + }, argv); +} // -var createTypedObject = (LabelConstructor) => { - return (val) => { - for (const key in val) { - val[key] = new LabelConstructor(val[key]); +function maybeAsyncResult(getResult, resultHandler, errorHandler = (err) => { + throw err; +}) { + try { + const result = isFunction(getResult) ? getResult() : getResult; + return isPromise(result) ? result.then((result2) => resultHandler(result2)) : resultHandler(result); + } catch (err) { + return errorHandler(err); + } +} +function isFunction(arg) { + return typeof arg === "function"; +} + +// +var DEFAULT_MARKER = /(^\*)|(^\$0)/; +var CommandInstance = class { + constructor(usage2, validation2, globalMiddleware, shim3) { + this.requireCache = /* @__PURE__ */ new Set(); + this.handlers = {}; + this.aliasMap = {}; + this.frozens = []; + this.shim = shim3; + this.usage = usage2; + this.globalMiddleware = globalMiddleware; + this.validation = validation2; + } + addDirectory(dir, req, callerFile, opts) { + opts = opts || {}; + this.requireCache.add(callerFile); + const fullDirPath = this.shim.path.resolve(this.shim.path.dirname(callerFile), dir); + const files = this.shim.readdirSync(fullDirPath, { + recursive: opts.recurse ? true : false + }); + if (!Array.isArray(opts.extensions)) + opts.extensions = ["js"]; + const visit = typeof opts.visit === "function" ? opts.visit : (o) => o; + for (const fileb of files) { + const file = fileb.toString(); + if (opts.exclude) { + let exclude = false; + if (typeof opts.exclude === "function") { + exclude = opts.exclude(file); + } else { + exclude = opts.exclude.test(file); + } + if (exclude) + continue; + } + if (opts.include) { + let include = false; + if (typeof opts.include === "function") { + include = opts.include(file); + } else { + include = opts.include.test(file); + } + if (!include) + continue; + } + let supportedExtension = false; + for (const ext of opts.extensions) { + if (file.endsWith(ext)) + supportedExtension = true; + } + if (supportedExtension) { + const joined = this.shim.path.join(fullDirPath, file); + const module = req(joined); + const extendableModule = Object.create(null, Object.getOwnPropertyDescriptors({ ...module })); + const visited = visit(extendableModule, joined, file); + if (visited) { + if (this.requireCache.has(joined)) + continue; + else + this.requireCache.add(joined); + if (!extendableModule.command) { + extendableModule.command = this.shim.path.basename(joined, this.shim.path.extname(joined)); + } + this.addHandler(extendableModule); + } + } + } + } + addHandler(cmd, description, builder, handler2, commandMiddleware, deprecated) { + let aliases = []; + const middlewares = commandMiddlewareFactory(commandMiddleware); + handler2 = handler2 || (() => { + }); + if (Array.isArray(cmd)) { + if (isCommandAndAliases(cmd)) { + [cmd, ...aliases] = cmd; + } else { + for (const command2 of cmd) { + this.addHandler(command2); + } + } + } else if (isCommandHandlerDefinition(cmd)) { + let command2 = Array.isArray(cmd.command) || typeof cmd.command === "string" ? cmd.command : null; + if (command2 === null) { + throw new Error(`No command name given for module: ${this.shim.inspect(cmd)}`); + } + if (cmd.aliases) + command2 = [].concat(command2).concat(cmd.aliases); + this.addHandler(command2, this.extractDesc(cmd), cmd.builder, cmd.handler, cmd.middlewares, cmd.deprecated); + return; + } else if (isCommandBuilderDefinition(builder)) { + this.addHandler([cmd].concat(aliases), description, builder.builder, builder.handler, builder.middlewares, builder.deprecated); + return; + } + if (typeof cmd === "string") { + const parsedCommand = parseCommand(cmd); + aliases = aliases.map((alias) => parseCommand(alias).cmd); + let isDefault = false; + const parsedAliases = [parsedCommand.cmd].concat(aliases).filter((c) => { + if (DEFAULT_MARKER.test(c)) { + isDefault = true; + return false; + } + return true; + }); + if (parsedAliases.length === 0 && isDefault) + parsedAliases.push("$0"); + if (isDefault) { + parsedCommand.cmd = parsedAliases[0]; + aliases = parsedAliases.slice(1); + cmd = cmd.replace(DEFAULT_MARKER, parsedCommand.cmd); + } + aliases.forEach((alias) => { + this.aliasMap[alias] = parsedCommand.cmd; + }); + if (description !== false) { + this.usage.command(cmd, description, isDefault, aliases, deprecated); + } + this.handlers[parsedCommand.cmd] = { + original: cmd, + description, + handler: handler2, + builder: builder || {}, + middlewares, + deprecated, + demanded: parsedCommand.demanded, + optional: parsedCommand.optional + }; + if (isDefault) + this.defaultCommand = this.handlers[parsedCommand.cmd]; + } + } + getCommandHandlers() { + return this.handlers; + } + getCommands() { + return Object.keys(this.handlers).concat(Object.keys(this.aliasMap)); + } + hasDefaultCommand() { + return !!this.defaultCommand; + } + runCommand(command2, yargs, parsed, commandIndex, helpOnly, helpOrVersionSet) { + const commandHandler = this.handlers[command2] || this.handlers[this.aliasMap[command2]] || this.defaultCommand; + const currentContext = yargs.getInternalMethods().getContext(); + const parentCommands = currentContext.commands.slice(); + const isDefaultCommand = !command2; + if (command2) { + currentContext.commands.push(command2); + currentContext.fullCommands.push(commandHandler.original); + } + const builderResult = this.applyBuilderUpdateUsageAndParse(isDefaultCommand, commandHandler, yargs, parsed.aliases, parentCommands, commandIndex, helpOnly, helpOrVersionSet); + return isPromise(builderResult) ? builderResult.then((result) => this.applyMiddlewareAndGetResult(isDefaultCommand, commandHandler, result.innerArgv, currentContext, helpOnly, result.aliases, yargs)) : this.applyMiddlewareAndGetResult(isDefaultCommand, commandHandler, builderResult.innerArgv, currentContext, helpOnly, builderResult.aliases, yargs); + } + applyBuilderUpdateUsageAndParse(isDefaultCommand, commandHandler, yargs, aliases, parentCommands, commandIndex, helpOnly, helpOrVersionSet) { + const builder = commandHandler.builder; + let innerYargs = yargs; + if (isCommandBuilderCallback(builder)) { + yargs.getInternalMethods().getUsageInstance().freeze(); + const builderOutput = builder(yargs.getInternalMethods().reset(aliases), helpOrVersionSet); + if (isPromise(builderOutput)) { + return builderOutput.then((output) => { + innerYargs = isYargsInstance(output) ? output : yargs; + return this.parseAndUpdateUsage(isDefaultCommand, commandHandler, innerYargs, parentCommands, commandIndex, helpOnly); + }); + } + } else if (isCommandBuilderOptionDefinitions(builder)) { + yargs.getInternalMethods().getUsageInstance().freeze(); + innerYargs = yargs.getInternalMethods().reset(aliases); + Object.keys(commandHandler.builder).forEach((key) => { + innerYargs.option(key, builder[key]); + }); + } + return this.parseAndUpdateUsage(isDefaultCommand, commandHandler, innerYargs, parentCommands, commandIndex, helpOnly); + } + parseAndUpdateUsage(isDefaultCommand, commandHandler, innerYargs, parentCommands, commandIndex, helpOnly) { + if (isDefaultCommand) + innerYargs.getInternalMethods().getUsageInstance().unfreeze(true); + if (this.shouldUpdateUsage(innerYargs)) { + innerYargs.getInternalMethods().getUsageInstance().usage(this.usageFromParentCommandsCommandHandler(parentCommands, commandHandler), commandHandler.description); + } + const innerArgv = innerYargs.getInternalMethods().runYargsParserAndExecuteCommands(null, void 0, true, commandIndex, helpOnly); + return isPromise(innerArgv) ? innerArgv.then((argv) => ({ + aliases: innerYargs.parsed.aliases, + innerArgv: argv + })) : { + aliases: innerYargs.parsed.aliases, + innerArgv + }; + } + shouldUpdateUsage(yargs) { + return !yargs.getInternalMethods().getUsageInstance().getUsageDisabled() && yargs.getInternalMethods().getUsageInstance().getUsage().length === 0; + } + usageFromParentCommandsCommandHandler(parentCommands, commandHandler) { + const c = DEFAULT_MARKER.test(commandHandler.original) ? commandHandler.original.replace(DEFAULT_MARKER, "").trim() : commandHandler.original; + const pc = parentCommands.filter((c2) => { + return !DEFAULT_MARKER.test(c2); + }); + pc.push(c); + return `$0 ${pc.join(" ")}`; + } + handleValidationAndGetResult(isDefaultCommand, commandHandler, innerArgv, currentContext, aliases, yargs, middlewares, positionalMap) { + if (!yargs.getInternalMethods().getHasOutput()) { + const validation2 = yargs.getInternalMethods().runValidation(aliases, positionalMap, yargs.parsed.error, isDefaultCommand); + innerArgv = maybeAsyncResult(innerArgv, (result) => { + validation2(result); + return result; + }); + } + if (commandHandler.handler && !yargs.getInternalMethods().getHasOutput()) { + yargs.getInternalMethods().setHasOutput(); + const populateDoubleDash = !!yargs.getOptions().configuration["populate--"]; + yargs.getInternalMethods().postProcess(innerArgv, populateDoubleDash, false, false); + innerArgv = applyMiddleware(innerArgv, yargs, middlewares, false); + innerArgv = maybeAsyncResult(innerArgv, (result) => { + const handlerResult = commandHandler.handler(result); + return isPromise(handlerResult) ? handlerResult.then(() => result) : result; + }); + if (!isDefaultCommand) { + yargs.getInternalMethods().getUsageInstance().cacheHelpMessage(); + } + if (isPromise(innerArgv) && !yargs.getInternalMethods().hasParseCallback()) { + innerArgv.catch((error) => { + try { + yargs.getInternalMethods().getUsageInstance().fail(null, error); + } catch (_err) { + } + }); + } + } + if (!isDefaultCommand) { + currentContext.commands.pop(); + currentContext.fullCommands.pop(); + } + return innerArgv; + } + applyMiddlewareAndGetResult(isDefaultCommand, commandHandler, innerArgv, currentContext, helpOnly, aliases, yargs) { + let positionalMap = {}; + if (helpOnly) + return innerArgv; + if (!yargs.getInternalMethods().getHasOutput()) { + positionalMap = this.populatePositionals(commandHandler, innerArgv, currentContext, yargs); + } + const middlewares = this.globalMiddleware.getMiddleware().slice(0).concat(commandHandler.middlewares); + const maybePromiseArgv = applyMiddleware(innerArgv, yargs, middlewares, true); + return isPromise(maybePromiseArgv) ? maybePromiseArgv.then((resolvedInnerArgv) => this.handleValidationAndGetResult(isDefaultCommand, commandHandler, resolvedInnerArgv, currentContext, aliases, yargs, middlewares, positionalMap)) : this.handleValidationAndGetResult(isDefaultCommand, commandHandler, maybePromiseArgv, currentContext, aliases, yargs, middlewares, positionalMap); + } + populatePositionals(commandHandler, argv, context2, yargs) { + argv._ = argv._.slice(context2.commands.length); + const demanded = commandHandler.demanded.slice(0); + const optional = commandHandler.optional.slice(0); + const positionalMap = {}; + this.validation.positionalCount(demanded.length, argv._.length); + while (demanded.length) { + const demand = demanded.shift(); + this.populatePositional(demand, argv, positionalMap); + } + while (optional.length) { + const maybe = optional.shift(); + this.populatePositional(maybe, argv, positionalMap); + } + argv._ = context2.commands.concat(argv._.map((a) => "" + a)); + this.postProcessPositionals(argv, positionalMap, this.cmdToParseOptions(commandHandler.original), yargs); + return positionalMap; + } + populatePositional(positional, argv, positionalMap) { + const cmd = positional.cmd[0]; + if (positional.variadic) { + positionalMap[cmd] = argv._.splice(0).map(String); + } else { + if (argv._.length) + positionalMap[cmd] = [String(argv._.shift())]; + } + } + cmdToParseOptions(cmdString) { + const parseOptions = { + array: [], + default: {}, + alias: {}, + demand: {} + }; + const parsed = parseCommand(cmdString); + parsed.demanded.forEach((d) => { + const [cmd, ...aliases] = d.cmd; + if (d.variadic) { + parseOptions.array.push(cmd); + parseOptions.default[cmd] = []; + } + parseOptions.alias[cmd] = aliases; + parseOptions.demand[cmd] = true; + }); + parsed.optional.forEach((o) => { + const [cmd, ...aliases] = o.cmd; + if (o.variadic) { + parseOptions.array.push(cmd); + parseOptions.default[cmd] = []; + } + parseOptions.alias[cmd] = aliases; + }); + return parseOptions; + } + postProcessPositionals(argv, positionalMap, parseOptions, yargs) { + const options = Object.assign({}, yargs.getOptions()); + options.default = Object.assign(parseOptions.default, options.default); + for (const key of Object.keys(parseOptions.alias)) { + options.alias[key] = (options.alias[key] || []).concat(parseOptions.alias[key]); + } + options.array = options.array.concat(parseOptions.array); + options.config = {}; + const unparsed = []; + Object.keys(positionalMap).forEach((key) => { + positionalMap[key].map((value) => { + if (options.configuration["unknown-options-as-args"]) + options.key[key] = true; + unparsed.push(`--${key}`); + unparsed.push(value); + }); + }); + if (!unparsed.length) + return; + const config = Object.assign({}, options.configuration, { + "populate--": false + }); + const parsed = this.shim.Parser.detailed(unparsed, Object.assign({}, options, { + configuration: config + })); + if (parsed.error) { + yargs.getInternalMethods().getUsageInstance().fail(parsed.error.message, parsed.error); + } else { + const positionalKeys = Object.keys(positionalMap); + Object.keys(positionalMap).forEach((key) => { + positionalKeys.push(...parsed.aliases[key]); + }); + Object.keys(parsed.argv).forEach((key) => { + if (positionalKeys.includes(key)) { + if (!positionalMap[key]) + positionalMap[key] = parsed.argv[key]; + if (!this.isInConfigs(yargs, key) && !this.isDefaulted(yargs, key) && Object.prototype.hasOwnProperty.call(argv, key) && Object.prototype.hasOwnProperty.call(parsed.argv, key) && (Array.isArray(argv[key]) || Array.isArray(parsed.argv[key]))) { + argv[key] = [].concat(argv[key], parsed.argv[key]); + } else { + argv[key] = parsed.argv[key]; + } + } + }); + } + } + isDefaulted(yargs, key) { + const { default: defaults } = yargs.getOptions(); + return Object.prototype.hasOwnProperty.call(defaults, key) || Object.prototype.hasOwnProperty.call(defaults, this.shim.Parser.camelCase(key)); + } + isInConfigs(yargs, key) { + const { configObjects } = yargs.getOptions(); + return configObjects.some((c) => Object.prototype.hasOwnProperty.call(c, key)) || configObjects.some((c) => Object.prototype.hasOwnProperty.call(c, this.shim.Parser.camelCase(key))); + } + runDefaultBuilderOn(yargs) { + if (!this.defaultCommand) + return; + if (this.shouldUpdateUsage(yargs)) { + const commandString = DEFAULT_MARKER.test(this.defaultCommand.original) ? this.defaultCommand.original : this.defaultCommand.original.replace(/^[^[\]<>]*/, "$0 "); + yargs.getInternalMethods().getUsageInstance().usage(commandString, this.defaultCommand.description); + } + const builder = this.defaultCommand.builder; + if (isCommandBuilderCallback(builder)) { + return builder(yargs, true); + } else if (!isCommandBuilderDefinition(builder)) { + Object.keys(builder).forEach((key) => { + yargs.option(key, builder[key]); + }); + } + return void 0; + } + extractDesc({ describe, description, desc }) { + for (const test of [describe, description, desc]) { + if (typeof test === "string" || test === false) + return test; + assertNotStrictEqual(test, true, this.shim); + } + return false; + } + freeze() { + this.frozens.push({ + handlers: this.handlers, + aliasMap: this.aliasMap, + defaultCommand: this.defaultCommand + }); + } + unfreeze() { + const frozen = this.frozens.pop(); + assertNotStrictEqual(frozen, void 0, this.shim); + ({ + handlers: this.handlers, + aliasMap: this.aliasMap, + defaultCommand: this.defaultCommand + } = frozen); + } + reset() { + this.handlers = {}; + this.aliasMap = {}; + this.defaultCommand = void 0; + this.requireCache = /* @__PURE__ */ new Set(); + return this; + } +}; +function command(usage2, validation2, globalMiddleware, shim3) { + return new CommandInstance(usage2, validation2, globalMiddleware, shim3); +} +function isCommandBuilderDefinition(builder) { + return typeof builder === "object" && !!builder.builder && typeof builder.handler === "function"; +} +function isCommandAndAliases(cmd) { + return cmd.every((c) => typeof c === "string"); +} +function isCommandBuilderCallback(builder) { + return typeof builder === "function"; +} +function isCommandBuilderOptionDefinitions(builder) { + return typeof builder === "object"; +} +function isCommandHandlerDefinition(cmd) { + return typeof cmd === "object" && !Array.isArray(cmd); +} + +// +function objFilter(original = {}, filter = () => true) { + const obj = {}; + objectKeys(original).forEach((key) => { + if (filter(key, original[key])) { + obj[key] = original[key]; + } + }); + return obj; +} + +// +function setBlocking(blocking) { + if (typeof process === "undefined") + return; + [process.stdout, process.stderr].forEach((_stream) => { + const stream = _stream; + if (stream._handle && stream.isTTY && typeof stream._handle.setBlocking === "function") { + stream._handle.setBlocking(blocking); + } + }); +} + +// +function isBoolean(fail) { + return typeof fail === "boolean"; +} +function usage(yargs, shim3) { + const __ = shim3.y18n.__; + const self2 = {}; + const fails = []; + self2.failFn = function failFn(f) { + fails.push(f); + }; + let failMessage = null; + let globalFailMessage = null; + let showHelpOnFail = true; + self2.showHelpOnFail = function showHelpOnFailFn(arg1 = true, arg2) { + const [enabled, message] = typeof arg1 === "string" ? [true, arg1] : [arg1, arg2]; + if (yargs.getInternalMethods().isGlobalContext()) { + globalFailMessage = message; + } + failMessage = message; + showHelpOnFail = enabled; + return self2; + }; + let failureOutput = false; + self2.fail = function fail(msg, err) { + const logger = yargs.getInternalMethods().getLoggerInstance(); + if (fails.length) { + for (let i = fails.length - 1; i >= 0; --i) { + const fail2 = fails[i]; + if (isBoolean(fail2)) { + if (err) + throw err; + else if (msg) + throw Error(msg); + } else { + fail2(msg, err, self2); + } + } + } else { + if (yargs.getExitProcess()) + setBlocking(true); + if (!failureOutput) { + failureOutput = true; + if (showHelpOnFail) { + yargs.showHelp("error"); + logger.error(); + } + if (msg || err) + logger.error(msg || err); + const globalOrCommandFailMessage = failMessage || globalFailMessage; + if (globalOrCommandFailMessage) { + if (msg || err) + logger.error(""); + logger.error(globalOrCommandFailMessage); + } + } + err = err || new YError(msg); + if (yargs.getExitProcess()) { + return yargs.exit(1); + } else if (yargs.getInternalMethods().hasParseCallback()) { + return yargs.exit(1, err); + } else { + throw err; + } + } + }; + let usages = []; + let usageDisabled = false; + self2.usage = (msg, description) => { + if (msg === null) { + usageDisabled = true; + usages = []; + return self2; + } + usageDisabled = false; + usages.push([msg, description || ""]); + return self2; + }; + self2.getUsage = () => { + return usages; + }; + self2.getUsageDisabled = () => { + return usageDisabled; + }; + self2.getPositionalGroupName = () => { + return __("Positionals:"); + }; + let examples = []; + self2.example = (cmd, description) => { + examples.push([cmd, description || ""]); + }; + let commands = []; + self2.command = function command2(cmd, description, isDefault, aliases, deprecated = false) { + if (isDefault) { + commands = commands.map((cmdArray) => { + cmdArray[2] = false; + return cmdArray; + }); + } + commands.push([cmd, description || "", isDefault, aliases, deprecated]); + }; + self2.getCommands = () => commands; + let descriptions = {}; + self2.describe = function describe(keyOrKeys, desc) { + if (Array.isArray(keyOrKeys)) { + keyOrKeys.forEach((k) => { + self2.describe(k, desc); + }); + } else if (typeof keyOrKeys === "object") { + Object.keys(keyOrKeys).forEach((k) => { + self2.describe(k, keyOrKeys[k]); + }); + } else { + descriptions[keyOrKeys] = desc; + } + }; + self2.getDescriptions = () => descriptions; + let epilogs = []; + self2.epilog = (msg) => { + epilogs.push(msg); + }; + let wrapSet = false; + let wrap; + self2.wrap = (cols) => { + wrapSet = true; + wrap = cols; + }; + self2.getWrap = () => { + if (shim3.getEnv("YARGS_DISABLE_WRAP")) { + return null; + } + if (!wrapSet) { + wrap = windowWidth(); + wrapSet = true; + } + return wrap; + }; + const deferY18nLookupPrefix = "__yargsString__:"; + self2.deferY18nLookup = (str) => deferY18nLookupPrefix + str; + self2.help = function help() { + if (cachedHelpMessage) + return cachedHelpMessage; + normalizeAliases(); + const base$0 = yargs.customScriptName ? yargs.$0 : shim3.path.basename(yargs.$0); + const demandedOptions = yargs.getDemandedOptions(); + const demandedCommands = yargs.getDemandedCommands(); + const deprecatedOptions = yargs.getDeprecatedOptions(); + const groups = yargs.getGroups(); + const options = yargs.getOptions(); + let keys = []; + keys = keys.concat(Object.keys(descriptions)); + keys = keys.concat(Object.keys(demandedOptions)); + keys = keys.concat(Object.keys(demandedCommands)); + keys = keys.concat(Object.keys(options.default)); + keys = keys.filter(filterHiddenOptions); + keys = Object.keys(keys.reduce((acc, key) => { + if (key !== "_") + acc[key] = true; + return acc; + }, {})); + const theWrap = self2.getWrap(); + const ui2 = shim3.cliui({ + width: theWrap, + wrap: !!theWrap + }); + if (!usageDisabled) { + if (usages.length) { + usages.forEach((usage2) => { + ui2.div({ text: `${usage2[0].replace(/\$0/g, base$0)}` }); + if (usage2[1]) { + ui2.div({ text: `${usage2[1]}`, padding: [1, 0, 0, 0] }); + } + }); + ui2.div(); + } else if (commands.length) { + let u = null; + if (demandedCommands._) { + u = `${base$0} <${__("command")}> +`; + } else { + u = `${base$0} [${__("command")}] +`; + } + ui2.div(`${u}`); + } + } + if (commands.length > 1 || commands.length === 1 && !commands[0][2]) { + ui2.div(__("Commands:")); + const context2 = yargs.getInternalMethods().getContext(); + const parentCommands = context2.commands.length ? `${context2.commands.join(" ")} ` : ""; + if (yargs.getInternalMethods().getParserConfiguration()["sort-commands"] === true) { + commands = commands.sort((a, b) => a[0].localeCompare(b[0])); + } + const prefix = base$0 ? `${base$0} ` : ""; + commands.forEach((command2) => { + const commandString = `${prefix}${parentCommands}${command2[0].replace(/^\$0 ?/, "")}`; + ui2.span({ + text: commandString, + padding: [0, 2, 0, 2], + width: maxWidth(commands, theWrap, `${base$0}${parentCommands}`) + 4 + }, { text: command2[1] }); + const hints = []; + if (command2[2]) + hints.push(`[${__("default")}]`); + if (command2[3] && command2[3].length) { + hints.push(`[${__("aliases:")} ${command2[3].join(", ")}]`); + } + if (command2[4]) { + if (typeof command2[4] === "string") { + hints.push(`[${__("deprecated: %s", command2[4])}]`); + } else { + hints.push(`[${__("deprecated")}]`); + } + } + if (hints.length) { + ui2.div({ + text: hints.join(" "), + padding: [0, 0, 0, 2], + align: "right" + }); + } else { + ui2.div(); + } + }); + ui2.div(); + } + const aliasKeys = (Object.keys(options.alias) || []).concat(Object.keys(yargs.parsed.newAliases) || []); + keys = keys.filter((key) => !yargs.parsed.newAliases[key] && aliasKeys.every((alias) => (options.alias[alias] || []).indexOf(key) === -1)); + const defaultGroup = __("Options:"); + if (!groups[defaultGroup]) + groups[defaultGroup] = []; + addUngroupedKeys(keys, options.alias, groups, defaultGroup); + const isLongSwitch = (sw) => /^--/.test(getText(sw)); + const displayedGroups = Object.keys(groups).filter((groupName) => groups[groupName].length > 0).map((groupName) => { + const normalizedKeys = groups[groupName].filter(filterHiddenOptions).map((key) => { + if (aliasKeys.includes(key)) + return key; + for (let i = 0, aliasKey; (aliasKey = aliasKeys[i]) !== void 0; i++) { + if ((options.alias[aliasKey] || []).includes(key)) + return aliasKey; + } + return key; + }); + return { groupName, normalizedKeys }; + }).filter(({ normalizedKeys }) => normalizedKeys.length > 0).map(({ groupName, normalizedKeys }) => { + const switches = normalizedKeys.reduce((acc, key) => { + acc[key] = [key].concat(options.alias[key] || []).map((sw) => { + if (groupName === self2.getPositionalGroupName()) + return sw; + else { + return (/^[0-9]$/.test(sw) ? options.boolean.includes(key) ? "-" : "--" : sw.length > 1 ? "--" : "-") + sw; + } + }).sort((sw1, sw2) => isLongSwitch(sw1) === isLongSwitch(sw2) ? 0 : isLongSwitch(sw1) ? 1 : -1).join(", "); + return acc; + }, {}); + return { groupName, normalizedKeys, switches }; + }); + const shortSwitchesUsed = displayedGroups.filter(({ groupName }) => groupName !== self2.getPositionalGroupName()).some(({ normalizedKeys, switches }) => !normalizedKeys.every((key) => isLongSwitch(switches[key]))); + if (shortSwitchesUsed) { + displayedGroups.filter(({ groupName }) => groupName !== self2.getPositionalGroupName()).forEach(({ normalizedKeys, switches }) => { + normalizedKeys.forEach((key) => { + if (isLongSwitch(switches[key])) { + switches[key] = addIndentation(switches[key], "-x, ".length); + } + }); + }); + } + displayedGroups.forEach(({ groupName, normalizedKeys, switches }) => { + ui2.div(groupName); + normalizedKeys.forEach((key) => { + const kswitch = switches[key]; + let desc = descriptions[key] || ""; + let type = null; + if (desc.includes(deferY18nLookupPrefix)) + desc = __(desc.substring(deferY18nLookupPrefix.length)); + if (options.boolean.includes(key)) + type = `[${__("boolean")}]`; + if (options.count.includes(key)) + type = `[${__("count")}]`; + if (options.string.includes(key)) + type = `[${__("string")}]`; + if (options.normalize.includes(key)) + type = `[${__("string")}]`; + if (options.array.includes(key)) + type = `[${__("array")}]`; + if (options.number.includes(key)) + type = `[${__("number")}]`; + const deprecatedExtra = (deprecated) => typeof deprecated === "string" ? `[${__("deprecated: %s", deprecated)}]` : `[${__("deprecated")}]`; + const extra = [ + key in deprecatedOptions ? deprecatedExtra(deprecatedOptions[key]) : null, + type, + key in demandedOptions ? `[${__("required")}]` : null, + options.choices && options.choices[key] ? `[${__("choices:")} ${self2.stringifiedValues(options.choices[key])}]` : null, + defaultString(options.default[key], options.defaultDescription[key]) + ].filter(Boolean).join(" "); + ui2.span({ + text: getText(kswitch), + padding: [0, 2, 0, 2 + getIndentation(kswitch)], + width: maxWidth(switches, theWrap) + 4 + }, desc); + const shouldHideOptionExtras = yargs.getInternalMethods().getUsageConfiguration()["hide-types"] === true; + if (extra && !shouldHideOptionExtras) + ui2.div({ text: extra, padding: [0, 0, 0, 2], align: "right" }); + else + ui2.div(); + }); + ui2.div(); + }); + if (examples.length) { + ui2.div(__("Examples:")); + examples.forEach((example) => { + example[0] = example[0].replace(/\$0/g, base$0); + }); + examples.forEach((example) => { + if (example[1] === "") { + ui2.div({ + text: example[0], + padding: [0, 2, 0, 2] + }); + } else { + ui2.div({ + text: example[0], + padding: [0, 2, 0, 2], + width: maxWidth(examples, theWrap) + 4 + }, { + text: example[1] + }); + } + }); + ui2.div(); + } + if (epilogs.length > 0) { + const e = epilogs.map((epilog) => epilog.replace(/\$0/g, base$0)).join("\n"); + ui2.div(`${e} +`); + } + return ui2.toString().replace(/\s*$/, ""); + }; + function maxWidth(table, theWrap, modifier) { + let width = 0; + if (!Array.isArray(table)) { + table = Object.values(table).map((v) => [v]); + } + table.forEach((v) => { + width = Math.max(shim3.stringWidth(modifier ? `${modifier} ${getText(v[0])}` : getText(v[0])) + getIndentation(v[0]), width); + }); + if (theWrap) + width = Math.min(width, parseInt((theWrap * 0.5).toString(), 10)); + return width; + } + function normalizeAliases() { + const demandedOptions = yargs.getDemandedOptions(); + const options = yargs.getOptions(); + (Object.keys(options.alias) || []).forEach((key) => { + options.alias[key].forEach((alias) => { + if (descriptions[alias]) + self2.describe(key, descriptions[alias]); + if (alias in demandedOptions) + yargs.demandOption(key, demandedOptions[alias]); + if (options.boolean.includes(alias)) + yargs.boolean(key); + if (options.count.includes(alias)) + yargs.count(key); + if (options.string.includes(alias)) + yargs.string(key); + if (options.normalize.includes(alias)) + yargs.normalize(key); + if (options.array.includes(alias)) + yargs.array(key); + if (options.number.includes(alias)) + yargs.number(key); + }); + }); + } + let cachedHelpMessage; + self2.cacheHelpMessage = function() { + cachedHelpMessage = this.help(); + }; + self2.clearCachedHelpMessage = function() { + cachedHelpMessage = void 0; + }; + self2.hasCachedHelpMessage = function() { + return !!cachedHelpMessage; + }; + function addUngroupedKeys(keys, aliases, groups, defaultGroup) { + let groupedKeys = []; + let toCheck = null; + Object.keys(groups).forEach((group) => { + groupedKeys = groupedKeys.concat(groups[group]); + }); + keys.forEach((key) => { + toCheck = [key].concat(aliases[key]); + if (!toCheck.some((k) => groupedKeys.indexOf(k) !== -1)) { + groups[defaultGroup].push(key); + } + }); + return groupedKeys; + } + function filterHiddenOptions(key) { + return yargs.getOptions().hiddenOptions.indexOf(key) < 0 || yargs.parsed.argv[yargs.getOptions().showHiddenOpt]; + } + self2.showHelp = (level) => { + const logger = yargs.getInternalMethods().getLoggerInstance(); + if (!level) + level = "error"; + const emit = typeof level === "function" ? level : logger[level]; + emit(self2.help()); + }; + self2.functionDescription = (fn) => { + const description = fn.name ? shim3.Parser.decamelize(fn.name, "-") : __("generated-value"); + return ["(", description, ")"].join(""); + }; + self2.stringifiedValues = function stringifiedValues(values, separator) { + let string = ""; + const sep2 = separator || ", "; + const array = [].concat(values); + if (!values || !array.length) + return string; + array.forEach((value) => { + if (string.length) + string += sep2; + string += JSON.stringify(value); + }); + return string; + }; + function defaultString(value, defaultDescription) { + let string = `[${__("default:")} `; + if (value === void 0 && !defaultDescription) + return null; + if (defaultDescription) { + string += defaultDescription; + } else { + switch (typeof value) { + case "string": + string += `"${value}"`; + break; + case "object": + string += JSON.stringify(value); + break; + default: + string += value; + } + } + return `${string}]`; + } + function windowWidth() { + const maxWidth2 = 80; + if (shim3.process.stdColumns) { + return Math.min(maxWidth2, shim3.process.stdColumns); + } else { + return maxWidth2; + } + } + let version = null; + self2.version = (ver) => { + version = ver; + }; + self2.showVersion = (level) => { + const logger = yargs.getInternalMethods().getLoggerInstance(); + if (!level) + level = "error"; + const emit = typeof level === "function" ? level : logger[level]; + emit(version); + }; + self2.reset = function reset(localLookup) { + failMessage = null; + failureOutput = false; + usages = []; + usageDisabled = false; + epilogs = []; + examples = []; + commands = []; + descriptions = objFilter(descriptions, (k) => !localLookup[k]); + return self2; + }; + const frozens = []; + self2.freeze = function freeze() { + frozens.push({ + failMessage, + failureOutput, + usages, + usageDisabled, + epilogs, + examples, + commands, + descriptions + }); + }; + self2.unfreeze = function unfreeze(defaultCommand = false) { + const frozen = frozens.pop(); + if (!frozen) + return; + if (defaultCommand) { + descriptions = { ...frozen.descriptions, ...descriptions }; + commands = [...frozen.commands, ...commands]; + usages = [...frozen.usages, ...usages]; + examples = [...frozen.examples, ...examples]; + epilogs = [...frozen.epilogs, ...epilogs]; + } else { + ({ + failMessage, + failureOutput, + usages, + usageDisabled, + epilogs, + examples, + commands, + descriptions + } = frozen); + } + }; + return self2; +} +function isIndentedText(text) { + return typeof text === "object"; +} +function addIndentation(text, indent) { + return isIndentedText(text) ? { text: text.text, indentation: text.indentation + indent } : { text, indentation: indent }; +} +function getIndentation(text) { + return isIndentedText(text) ? text.indentation : 0; +} +function getText(text) { + return isIndentedText(text) ? text.text : text; +} + +// +var completionShTemplate = `###-begin-{{app_name}}-completions-### +# +# yargs command completion script +# +# Installation: {{app_path}} {{completion_command}} >> ~/.bashrc +# or {{app_path}} {{completion_command}} >> ~/.bash_profile on OSX. +# +_{{app_name}}_yargs_completions() +{ + local cur_word args type_list + + cur_word="\${COMP_WORDS[COMP_CWORD]}" + args=("\${COMP_WORDS[@]}") + + # ask yargs to generate completions. + # see https://stackoverflow.com/a/40944195/7080036 for the spaces-handling awk + mapfile -t type_list < <({{app_path}} --get-yargs-completions "\${args[@]}") + mapfile -t COMPREPLY < <(compgen -W "$( printf '%q ' "\${type_list[@]}" )" -- "\${cur_word}" | + awk '/ / { print "\\""$0"\\"" } /^[^ ]+$/ { print $0 }') + + # if no match was found, fall back to filename completion + if [ \${#COMPREPLY[@]} -eq 0 ]; then + COMPREPLY=() + fi + + return 0 +} +complete -o bashdefault -o default -F _{{app_name}}_yargs_completions {{app_name}} +###-end-{{app_name}}-completions-### +`; +var completionZshTemplate = `#compdef {{app_name}} +###-begin-{{app_name}}-completions-### +# +# yargs command completion script +# +# Installation: {{app_path}} {{completion_command}} >> ~/.zshrc +# or {{app_path}} {{completion_command}} >> ~/.zprofile on OSX. +# +_{{app_name}}_yargs_completions() +{ + local reply + local si=$IFS + IFS=$' +' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" {{app_path}} --get-yargs-completions "\${words[@]}")) + IFS=$si + if [[ \${#reply} -gt 0 ]]; then + _describe 'values' reply + else + _default + fi +} +if [[ "'\${zsh_eval_context[-1]}" == "loadautofunc" ]]; then + _{{app_name}}_yargs_completions "$@" +else + compdef _{{app_name}}_yargs_completions {{app_name}} +fi +###-end-{{app_name}}-completions-### +`; + +// +var Completion = class { + constructor(yargs, usage2, command2, shim3) { + var _a2, _b2, _c2; + this.yargs = yargs; + this.usage = usage2; + this.command = command2; + this.shim = shim3; + this.completionKey = "get-yargs-completions"; + this.aliases = null; + this.customCompletionFunction = null; + this.indexAfterLastReset = 0; + this.zshShell = (_c2 = ((_a2 = this.shim.getEnv("SHELL")) === null || _a2 === void 0 ? void 0 : _a2.includes("zsh")) || ((_b2 = this.shim.getEnv("ZSH_NAME")) === null || _b2 === void 0 ? void 0 : _b2.includes("zsh"))) !== null && _c2 !== void 0 ? _c2 : false; + } + defaultCompletion(args, argv, current, done) { + const handlers = this.command.getCommandHandlers(); + for (let i = 0, ii = args.length; i < ii; ++i) { + if (handlers[args[i]] && handlers[args[i]].builder) { + const builder = handlers[args[i]].builder; + if (isCommandBuilderCallback(builder)) { + this.indexAfterLastReset = i + 1; + const y = this.yargs.getInternalMethods().reset(); + builder(y, true); + return y.argv; + } + } + } + const completions = []; + this.commandCompletions(completions, args, current); + this.optionCompletions(completions, args, argv, current); + this.choicesFromOptionsCompletions(completions, args, argv, current); + this.choicesFromPositionalsCompletions(completions, args, argv, current); + done(null, completions); + } + commandCompletions(completions, args, current) { + const parentCommands = this.yargs.getInternalMethods().getContext().commands; + if (!current.match(/^-/) && parentCommands[parentCommands.length - 1] !== current && !this.previousArgHasChoices(args)) { + this.usage.getCommands().forEach((usageCommand) => { + const commandName = parseCommand(usageCommand[0]).cmd; + if (args.indexOf(commandName) === -1) { + if (!this.zshShell) { + completions.push(commandName); + } else { + const desc = usageCommand[1] || ""; + completions.push(commandName.replace(/:/g, "\\:") + ":" + desc); + } + } + }); + } + } + optionCompletions(completions, args, argv, current) { + if ((current.match(/^-/) || current === "" && completions.length === 0) && !this.previousArgHasChoices(args)) { + const options = this.yargs.getOptions(); + const positionalKeys = this.yargs.getGroups()[this.usage.getPositionalGroupName()] || []; + Object.keys(options.key).forEach((key) => { + const negable = !!options.configuration["boolean-negation"] && options.boolean.includes(key); + const isPositionalKey = positionalKeys.includes(key); + if (!isPositionalKey && !options.hiddenOptions.includes(key) && !this.argsContainKey(args, key, negable)) { + this.completeOptionKey(key, completions, current, negable && !!options.default[key]); + } + }); + } + } + choicesFromOptionsCompletions(completions, args, argv, current) { + if (this.previousArgHasChoices(args)) { + const choices = this.getPreviousArgChoices(args); + if (choices && choices.length > 0) { + completions.push(...choices.map((c) => c.replace(/:/g, "\\:"))); + } + } + } + choicesFromPositionalsCompletions(completions, args, argv, current) { + if (current === "" && completions.length > 0 && this.previousArgHasChoices(args)) { + return; } - return val; - }; -}; -var Label = class { - constructor(params2) { - this.params = params2; - this.repositories = this.params.repositories || [ - ManagedRepositories.ANGULAR, - ManagedRepositories.ANGULAR_CLI, - ManagedRepositories.COMPONENTS, - ManagedRepositories.DEV_INFRA + const positionalKeys = this.yargs.getGroups()[this.usage.getPositionalGroupName()] || []; + const offset = Math.max(this.indexAfterLastReset, this.yargs.getInternalMethods().getContext().commands.length + 1); + const positionalKey = positionalKeys[argv._.length - offset - 1]; + if (!positionalKey) { + return; + } + const choices = this.yargs.getOptions().choices[positionalKey] || []; + for (const choice of choices) { + if (choice.startsWith(current)) { + completions.push(choice.replace(/:/g, "\\:")); + } + } + } + getPreviousArgChoices(args) { + if (args.length < 1) + return; + let previousArg = args[args.length - 1]; + let filter = ""; + if (!previousArg.startsWith("-") && args.length > 1) { + filter = previousArg; + previousArg = args[args.length - 2]; + } + if (!previousArg.startsWith("-")) + return; + const previousArgKey = previousArg.replace(/^-+/, ""); + const options = this.yargs.getOptions(); + const possibleAliases = [ + previousArgKey, + ...this.yargs.getAliases()[previousArgKey] || [] ]; - this.name = this.params.name; - this.description = this.params.description; - this.color = this.params.color; + let choices; + for (const possibleAlias of possibleAliases) { + if (Object.prototype.hasOwnProperty.call(options.key, possibleAlias) && Array.isArray(options.choices[possibleAlias])) { + choices = options.choices[possibleAlias]; + break; + } + } + if (choices) { + return choices.filter((choice) => !filter || choice.startsWith(filter)); + } } -}; -var ManagedRepositories; -(function(ManagedRepositories2) { - ManagedRepositories2["COMPONENTS"] = "components"; - ManagedRepositories2["ANGULAR"] = "angular"; - ManagedRepositories2["ANGULAR_CLI"] = "angular-cli"; - ManagedRepositories2["DEV_INFRA"] = "dev-infra"; -})(ManagedRepositories || (ManagedRepositories = {})); - -// -var ManagedLabel = class extends Label { - constructor() { - super(...arguments); - this.commitCheck = this.params.commitCheck; + previousArgHasChoices(args) { + const choices = this.getPreviousArgChoices(args); + return choices !== void 0 && choices.length > 0; } -}; -var managedLabels = createTypedObject(ManagedLabel)({ - DETECTED_BREAKING_CHANGE: { - description: "PR contains a commit with a breaking change", - name: "detected: breaking change", - commitCheck: (c) => c.breakingChanges.length !== 0 - }, - DETECTED_DEPRECATION: { - description: "PR contains a commit with a deprecation", - name: "detected: deprecation", - commitCheck: (c) => c.deprecations.length !== 0 - }, - DETECTED_FEATURE: { - description: "PR contains a feature commit", - name: "detected: feature", - commitCheck: (c) => c.type === "feat" - }, - DETECTED_DOCS_CHANGE: { - description: "Related to the documentation", - name: "area: docs", - commitCheck: (c) => c.type === "docs" - }, - DETECTED_INFRA_CHANGE: { - description: "Related the build and CI infrastructure of the project", - name: "area: build & ci", - commitCheck: (c) => c.type === "build" || c.type === "ci" - }, - DETECTED_PERF_CHANGE: { - description: "Issues related to performance", - name: "area: performance", - commitCheck: (c) => c.type === "perf" - }, - DETECTED_HTTP_CHANGE: { - description: "Issues related to HTTP and HTTP Client", - name: "area: common/http", - commitCheck: (c) => c.scope === "common/http" || c.scope === "http", - repositories: [ManagedRepositories.ANGULAR] - }, - DETECTED_COMPILER_CHANGE: { - description: "Issues related to `ngc`, Angular's template compiler", - name: "area: compiler", - commitCheck: (c) => c.scope === "compiler" || c.scope === "compiler-cli", - repositories: [ManagedRepositories.ANGULAR] - }, - DETECTED_PLATFORM_BROWSER_CHANGE: { - description: "Issues related to the framework runtime", - name: "area: core", - commitCheck: (c) => c.scope === "platform-browser" || c.scope === "core" || c.scope === "platform-browser-dynamic", - repositories: [ManagedRepositories.ANGULAR] - }, - DETECTED_PLATFORM_SERVER_CHANGE: { - description: "Issues related to server-side rendering", - name: "area: server", - commitCheck: (c) => c.scope === "platform-server", - repositories: [ManagedRepositories.ANGULAR] - }, - DETECTED_ZONES_CHANGE: { - description: "Issues related to zone.js", - name: "area: zones", - commitCheck: (c) => c.scope === "zone.js", - repositories: [ManagedRepositories.ANGULAR] - }, - DETECTED_LOCALIZE_CHANGE: { - description: "Issues related to localization and internationalization", - name: "area: i18n", - commitCheck: (c) => c.scope === "localize", - repositories: [ManagedRepositories.ANGULAR] + argsContainKey(args, key, negable) { + const argsContains = (s) => args.indexOf((/^[^0-9]$/.test(s) ? "-" : "--") + s) !== -1; + if (argsContains(key)) + return true; + if (negable && argsContains(`no-${key}`)) + return true; + if (this.aliases) { + for (const alias of this.aliases[key]) { + if (argsContains(alias)) + return true; + } + } + return false; } -}); + completeOptionKey(key, completions, current, negable) { + var _a2, _b2, _c2, _d; + let keyWithDesc = key; + if (this.zshShell) { + const descs = this.usage.getDescriptions(); + const aliasKey = (_b2 = (_a2 = this === null || this === void 0 ? void 0 : this.aliases) === null || _a2 === void 0 ? void 0 : _a2[key]) === null || _b2 === void 0 ? void 0 : _b2.find((alias) => { + const desc2 = descs[alias]; + return typeof desc2 === "string" && desc2.length > 0; + }); + const descFromAlias = aliasKey ? descs[aliasKey] : void 0; + const desc = (_d = (_c2 = descs[key]) !== null && _c2 !== void 0 ? _c2 : descFromAlias) !== null && _d !== void 0 ? _d : ""; + keyWithDesc = `${key.replace(/:/g, "\\:")}:${desc.replace("__yargsString__:", "").replace(/(\r\n|\n|\r)/gm, " ")}`; + } + const startsByTwoDashes = (s) => /^--/.test(s); + const isShortOption = (s) => /^[^0-9]$/.test(s); + const dashes = !startsByTwoDashes(current) && isShortOption(key) ? "-" : "--"; + completions.push(dashes + keyWithDesc); + if (negable) { + completions.push(dashes + "no-" + keyWithDesc); + } + } + customCompletion(args, argv, current, done) { + assertNotStrictEqual(this.customCompletionFunction, null, this.shim); + if (isSyncCompletionFunction(this.customCompletionFunction)) { + const result = this.customCompletionFunction(current, argv); + if (isPromise(result)) { + return result.then((list) => { + this.shim.process.nextTick(() => { + done(null, list); + }); + }).catch((err) => { + this.shim.process.nextTick(() => { + done(err, void 0); + }); + }); + } + return done(null, result); + } else if (isFallbackCompletionFunction(this.customCompletionFunction)) { + return this.customCompletionFunction(current, argv, (onCompleted = done) => this.defaultCompletion(args, argv, current, onCompleted), (completions) => { + done(null, completions); + }); + } else { + return this.customCompletionFunction(current, argv, (completions) => { + done(null, completions); + }); + } + } + getCompletion(args, done) { + const current = args.length ? args[args.length - 1] : ""; + const argv = this.yargs.parse(args, true); + const completionFunction = this.customCompletionFunction ? (argv2) => this.customCompletion(args, argv2, current, done) : (argv2) => this.defaultCompletion(args, argv2, current, done); + return isPromise(argv) ? argv.then(completionFunction) : completionFunction(argv); + } + generateCompletionScript($0, cmd) { + let script = this.zshShell ? completionZshTemplate : completionShTemplate; + const name = this.shim.path.basename($0); + if ($0.match(/\.js$/)) + $0 = `./${$0}`; + script = script.replace(/{{app_name}}/g, name); + script = script.replace(/{{completion_command}}/g, cmd); + return script.replace(/{{app_path}}/g, $0); + } + registerFunction(fn) { + this.customCompletionFunction = fn; + } + setParsed(parsed) { + this.aliases = parsed.aliases; + } +}; +function completion(yargs, usage2, command2, shim3) { + return new Completion(yargs, usage2, command2, shim3); +} +function isSyncCompletionFunction(completionFunction) { + return completionFunction.length < 3; +} +function isFallbackCompletionFunction(completionFunction) { + return completionFunction.length > 3; +} // -var ActionLabel = class extends Label { -}; -var actionLabels = createTypedObject(ActionLabel)({ - ACTION_MERGE: { - description: "The PR is ready for merge by the caretaker", - name: "action: merge" - }, - ACTION_CLEANUP: { - description: "The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews", - name: "action: cleanup" - }, - ACTION_PRESUBMIT: { - description: "The PR is in need of a google3 presubmit", - name: "action: presubmit" - }, - ACTION_GLOBAL_PRESUBMIT: { - description: "The PR is in need of a google3 global presubmit", - name: "action: global presubmit" - }, - ACTION_REVIEW: { - description: "The PR is still awaiting reviews from at least one requested reviewer", - name: "action: review" +function levenshtein(a, b) { + if (a.length === 0) + return b.length; + if (b.length === 0) + return a.length; + const matrix = []; + let i; + for (i = 0; i <= b.length; i++) { + matrix[i] = [i]; + } + let j; + for (j = 0; j <= a.length; j++) { + matrix[0][j] = j; + } + for (i = 1; i <= b.length; i++) { + for (j = 1; j <= a.length; j++) { + if (b.charAt(i - 1) === a.charAt(j - 1)) { + matrix[i][j] = matrix[i - 1][j - 1]; + } else { + if (i > 1 && j > 1 && b.charAt(i - 2) === a.charAt(j - 1) && b.charAt(i - 1) === a.charAt(j - 2)) { + matrix[i][j] = matrix[i - 2][j - 2] + 1; + } else { + matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1)); + } + } + } } -}); + return matrix[b.length][a.length]; +} // -var MergeLabel = class extends Label { -}; -var mergeLabels = createTypedObject(MergeLabel)({ - MERGE_PRESERVE_COMMITS: { - description: "When the PR is merged, a rebase and merge should be performed", - name: "merge: preserve commits" - }, - MERGE_SQUASH_COMMITS: { - description: "When the PR is merged, a squash and merge should be performed", - name: "merge: squash commits" - }, - MERGE_FIX_COMMIT_MESSAGE: { - description: "When the PR is merged, rewrites/fixups of the commit messages are needed", - name: "merge: fix commit message", - repositories: [ManagedRepositories.COMPONENTS, ManagedRepositories.ANGULAR_CLI] - }, - MERGE_CARETAKER_NOTE: { - description: "Alert the caretaker performing the merge to check the PR for an out of normal action needed or note", - name: "merge: caretaker note" +var specialKeys = ["$0", "--", "_"]; +function validation(yargs, usage2, shim3) { + const __ = shim3.y18n.__; + const __n = shim3.y18n.__n; + const self2 = {}; + self2.nonOptionCount = function nonOptionCount(argv) { + const demandedCommands = yargs.getDemandedCommands(); + const positionalCount = argv._.length + (argv["--"] ? argv["--"].length : 0); + const _s = positionalCount - yargs.getInternalMethods().getContext().commands.length; + if (demandedCommands._ && (_s < demandedCommands._.min || _s > demandedCommands._.max)) { + if (_s < demandedCommands._.min) { + if (demandedCommands._.minMsg !== void 0) { + usage2.fail(demandedCommands._.minMsg ? demandedCommands._.minMsg.replace(/\$0/g, _s.toString()).replace(/\$1/, demandedCommands._.min.toString()) : null); + } else { + usage2.fail(__n("Not enough non-option arguments: got %s, need at least %s", "Not enough non-option arguments: got %s, need at least %s", _s, _s.toString(), demandedCommands._.min.toString())); + } + } else if (_s > demandedCommands._.max) { + if (demandedCommands._.maxMsg !== void 0) { + usage2.fail(demandedCommands._.maxMsg ? demandedCommands._.maxMsg.replace(/\$0/g, _s.toString()).replace(/\$1/, demandedCommands._.max.toString()) : null); + } else { + usage2.fail(__n("Too many non-option arguments: got %s, maximum of %s", "Too many non-option arguments: got %s, maximum of %s", _s, _s.toString(), demandedCommands._.max.toString())); + } + } + } + }; + self2.positionalCount = function positionalCount(required, observed) { + if (observed < required) { + usage2.fail(__n("Not enough non-option arguments: got %s, need at least %s", "Not enough non-option arguments: got %s, need at least %s", observed, observed + "", required + "")); + } + }; + self2.requiredArguments = function requiredArguments(argv, demandedOptions) { + let missing = null; + for (const key of Object.keys(demandedOptions)) { + if (!Object.prototype.hasOwnProperty.call(argv, key) || typeof argv[key] === "undefined") { + missing = missing || {}; + missing[key] = demandedOptions[key]; + } + } + if (missing) { + const customMsgs = []; + for (const key of Object.keys(missing)) { + const msg = missing[key]; + if (msg && customMsgs.indexOf(msg) < 0) { + customMsgs.push(msg); + } + } + const customMsg = customMsgs.length ? ` +${customMsgs.join("\n")}` : ""; + usage2.fail(__n("Missing required argument: %s", "Missing required arguments: %s", Object.keys(missing).length, Object.keys(missing).join(", ") + customMsg)); + } + }; + self2.unknownArguments = function unknownArguments(argv, aliases, positionalMap, isDefaultCommand, checkPositionals = true) { + var _a2; + const commandKeys = yargs.getInternalMethods().getCommandInstance().getCommands(); + const unknown = []; + const currentContext = yargs.getInternalMethods().getContext(); + Object.keys(argv).forEach((key) => { + if (!specialKeys.includes(key) && !Object.prototype.hasOwnProperty.call(positionalMap, key) && !Object.prototype.hasOwnProperty.call(yargs.getInternalMethods().getParseContext(), key) && !self2.isValidAndSomeAliasIsNotNew(key, aliases)) { + unknown.push(key); + } + }); + if (checkPositionals && (currentContext.commands.length > 0 || commandKeys.length > 0 || isDefaultCommand)) { + argv._.slice(currentContext.commands.length).forEach((key) => { + if (!commandKeys.includes("" + key)) { + unknown.push("" + key); + } + }); + } + if (checkPositionals) { + const demandedCommands = yargs.getDemandedCommands(); + const maxNonOptDemanded = ((_a2 = demandedCommands._) === null || _a2 === void 0 ? void 0 : _a2.max) || 0; + const expected = currentContext.commands.length + maxNonOptDemanded; + if (expected < argv._.length) { + argv._.slice(expected).forEach((key) => { + key = String(key); + if (!currentContext.commands.includes(key) && !unknown.includes(key)) { + unknown.push(key); + } + }); + } + } + if (unknown.length) { + usage2.fail(__n("Unknown argument: %s", "Unknown arguments: %s", unknown.length, unknown.map((s) => s.trim() ? s : `"${s}"`).join(", "))); + } + }; + self2.unknownCommands = function unknownCommands(argv) { + const commandKeys = yargs.getInternalMethods().getCommandInstance().getCommands(); + const unknown = []; + const currentContext = yargs.getInternalMethods().getContext(); + if (currentContext.commands.length > 0 || commandKeys.length > 0) { + argv._.slice(currentContext.commands.length).forEach((key) => { + if (!commandKeys.includes("" + key)) { + unknown.push("" + key); + } + }); + } + if (unknown.length > 0) { + usage2.fail(__n("Unknown command: %s", "Unknown commands: %s", unknown.length, unknown.join(", "))); + return true; + } else { + return false; + } + }; + self2.isValidAndSomeAliasIsNotNew = function isValidAndSomeAliasIsNotNew(key, aliases) { + if (!Object.prototype.hasOwnProperty.call(aliases, key)) { + return false; + } + const newAliases = yargs.parsed.newAliases; + return [key, ...aliases[key]].some((a) => !Object.prototype.hasOwnProperty.call(newAliases, a) || !newAliases[key]); + }; + self2.limitedChoices = function limitedChoices(argv) { + const options = yargs.getOptions(); + const invalid = {}; + if (!Object.keys(options.choices).length) + return; + Object.keys(argv).forEach((key) => { + if (specialKeys.indexOf(key) === -1 && Object.prototype.hasOwnProperty.call(options.choices, key)) { + [].concat(argv[key]).forEach((value) => { + if (options.choices[key].indexOf(value) === -1 && value !== void 0) { + invalid[key] = (invalid[key] || []).concat(value); + } + }); + } + }); + const invalidKeys = Object.keys(invalid); + if (!invalidKeys.length) + return; + let msg = __("Invalid values:"); + invalidKeys.forEach((key) => { + msg += ` + ${__("Argument: %s, Given: %s, Choices: %s", key, usage2.stringifiedValues(invalid[key]), usage2.stringifiedValues(options.choices[key]))}`; + }); + usage2.fail(msg); + }; + let implied = {}; + self2.implies = function implies(key, value) { + argsert(" [array|number|string]", [key, value], arguments.length); + if (typeof key === "object") { + Object.keys(key).forEach((k) => { + self2.implies(k, key[k]); + }); + } else { + yargs.global(key); + if (!implied[key]) { + implied[key] = []; + } + if (Array.isArray(value)) { + value.forEach((i) => self2.implies(key, i)); + } else { + assertNotStrictEqual(value, void 0, shim3); + implied[key].push(value); + } + } + }; + self2.getImplied = function getImplied() { + return implied; + }; + function keyExists(argv, val) { + const num = Number(val); + val = isNaN(num) ? val : num; + if (typeof val === "number") { + val = argv._.length >= val; + } else if (val.match(/^--no-.+/)) { + val = val.match(/^--no-(.+)/)[1]; + val = !Object.prototype.hasOwnProperty.call(argv, val); + } else { + val = Object.prototype.hasOwnProperty.call(argv, val); + } + return val; } -}); + self2.implications = function implications(argv) { + const implyFail = []; + Object.keys(implied).forEach((key) => { + const origKey = key; + (implied[key] || []).forEach((value) => { + let key2 = origKey; + const origValue = value; + key2 = keyExists(argv, key2); + value = keyExists(argv, value); + if (key2 && !value) { + implyFail.push(` ${origKey} -> ${origValue}`); + } + }); + }); + if (implyFail.length) { + let msg = `${__("Implications failed:")} +`; + implyFail.forEach((value) => { + msg += value; + }); + usage2.fail(msg); + } + }; + let conflicting = {}; + self2.conflicts = function conflicts(key, value) { + argsert(" [array|string]", [key, value], arguments.length); + if (typeof key === "object") { + Object.keys(key).forEach((k) => { + self2.conflicts(k, key[k]); + }); + } else { + yargs.global(key); + if (!conflicting[key]) { + conflicting[key] = []; + } + if (Array.isArray(value)) { + value.forEach((i) => self2.conflicts(key, i)); + } else { + conflicting[key].push(value); + } + } + }; + self2.getConflicting = () => conflicting; + self2.conflicting = function conflictingFn(argv) { + Object.keys(argv).forEach((key) => { + if (conflicting[key]) { + conflicting[key].forEach((value) => { + if (value && argv[key] !== void 0 && argv[value] !== void 0) { + usage2.fail(__("Arguments %s and %s are mutually exclusive", key, value)); + } + }); + } + }); + if (yargs.getInternalMethods().getParserConfiguration()["strip-dashed"]) { + Object.keys(conflicting).forEach((key) => { + conflicting[key].forEach((value) => { + if (value && argv[shim3.Parser.camelCase(key)] !== void 0 && argv[shim3.Parser.camelCase(value)] !== void 0) { + usage2.fail(__("Arguments %s and %s are mutually exclusive", key, value)); + } + }); + }); + } + }; + self2.recommendCommands = function recommendCommands(cmd, potentialCommands) { + const threshold = 3; + potentialCommands = potentialCommands.sort((a, b) => b.length - a.length); + let recommended = null; + let bestDistance = Infinity; + for (let i = 0, candidate; (candidate = potentialCommands[i]) !== void 0; i++) { + const d = levenshtein(cmd, candidate); + if (d <= threshold && d < bestDistance) { + bestDistance = d; + recommended = candidate; + } + } + if (recommended) + usage2.fail(__("Did you mean %s?", recommended)); + }; + self2.reset = function reset(localLookup) { + implied = objFilter(implied, (k) => !localLookup[k]); + conflicting = objFilter(conflicting, (k) => !localLookup[k]); + return self2; + }; + const frozens = []; + self2.freeze = function freeze() { + frozens.push({ + implied, + conflicting + }); + }; + self2.unfreeze = function unfreeze() { + const frozen = frozens.pop(); + assertNotStrictEqual(frozen, void 0, shim3); + ({ implied, conflicting } = frozen); + }; + return self2; +} // -var TargetLabel = class extends Label { - constructor() { - super(...arguments); - this.__hasTargetLabelMarker__ = true; +var previouslyVisitedConfigs = []; +var shim2; +function applyExtends(config, cwd, mergeExtends, _shim) { + shim2 = _shim; + let defaultConfig = {}; + if (Object.prototype.hasOwnProperty.call(config, "extends")) { + if (typeof config.extends !== "string") + return defaultConfig; + const isPath = /\.json|\..*rc$/.test(config.extends); + let pathToDefault = null; + if (!isPath) { + try { + pathToDefault = import.meta.resolve(config.extends); + } catch (_err) { + return config; + } + } else { + pathToDefault = getPathToDefaultConfig(cwd, config.extends); + } + checkForCircularExtends(pathToDefault); + previouslyVisitedConfigs.push(pathToDefault); + defaultConfig = isPath ? JSON.parse(shim2.readFileSync(pathToDefault, "utf8")) : _shim.require(config.extends); + delete config.extends; + defaultConfig = applyExtends(defaultConfig, shim2.path.dirname(pathToDefault), mergeExtends, shim2); } -}; -var targetLabels = createTypedObject(TargetLabel)({ - TARGET_FEATURE: { - description: "This PR is targeted for a feature branch (outside of main and semver branches)", - name: "target: feature" - }, - TARGET_LTS: { - description: "This PR is targeting a version currently in long-term support", - name: "target: lts" - }, - TARGET_MAJOR: { - description: "This PR is targeted for the next major release", - name: "target: major" - }, - TARGET_MINOR: { - description: "This PR is targeted for the next minor release", - name: "target: minor" - }, - TARGET_PATCH: { - description: "This PR is targeted for the next patch release", - name: "target: patch" - }, - TARGET_RC: { - description: "This PR is targeted for the next release-candidate", - name: "target: rc" + previouslyVisitedConfigs = []; + return mergeExtends ? mergeDeep(defaultConfig, config) : Object.assign({}, defaultConfig, config); +} +function checkForCircularExtends(cfgPath) { + if (previouslyVisitedConfigs.indexOf(cfgPath) > -1) { + throw new YError(`Circular extended configurations: '${cfgPath}'.`); } -}); - -// -var PriorityLabel = class extends Label { -}; -var priorityLabels = createTypedObject(PriorityLabel)({ - P0: { - name: "P0", - description: "Issue that causes an outage, breakage, or major function to be unusable, with no known workarounds" - }, - P1: { - name: "P1", - description: "Impacts a large percentage of users; if a workaround exists it is partial or overly painful" - }, - P2: { - name: "P2", - description: "The issue is important to a large percentage of users, with a workaround" - }, - P3: { - name: "P3", - description: "An issue that is relevant to core functions, but does not impede progress. Important, but not urgent" - }, - P4: { - name: "P4", - description: "A relatively minor issue that is not relevant to core functions" - }, - P5: { - name: "P5", - description: "The team acknowledges the request but does not plan to address it, it remains open for discussion" +} +function getPathToDefaultConfig(cwd, pathToExtend) { + return shim2.path.resolve(cwd, pathToExtend); +} +function mergeDeep(config1, config2) { + const target = {}; + function isObject(obj) { + return obj && typeof obj === "object" && !Array.isArray(obj); + } + Object.assign(target, config1); + for (const key of Object.keys(config2)) { + if (isObject(config2[key]) && isObject(target[key])) { + target[key] = mergeDeep(config1[key], config2[key]); + } else { + target[key] = config2[key]; + } } -}); + return target; +} // -var FeatureLabel = class extends Label { +var __classPrivateFieldSet = function(receiver, state, value, kind, f) { + if (kind === "m") + throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) + throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) + throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; }; -var featureLabels = createTypedObject(FeatureLabel)({ - FEATURE_IN_BACKLOG: { - name: "feature: in backlog", - description: "Feature request for which voting has completed and is now in the backlog" - }, - FEATURE_VOTES_REQUIRED: { - name: "feature: votes required", - description: "Feature request which is currently still in the voting phase" - }, - FEATURE_UNDER_CONSIDERATION: { - name: "feature: under consideration", - description: "Feature request for which voting has completed and the request is now under consideration" - }, - FEATURE_INSUFFICIENT_VOTES: { - name: "feature: insufficient votes", - description: "Label to add when the not a sufficient number of votes or comments from unique authors" - } -}); - -// -var RequiresLabel = class extends Label { +var __classPrivateFieldGet = function(receiver, state, kind, f) { + if (kind === "a" && !f) + throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) + throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; -var requiresLabels = createTypedObject(RequiresLabel)({ - REQUIRES_TGP: { - name: "requires: TGP", - description: "This PR requires a passing TGP before merging is allowed" +var _YargsInstance_command; +var _YargsInstance_cwd; +var _YargsInstance_context; +var _YargsInstance_completion; +var _YargsInstance_completionCommand; +var _YargsInstance_defaultShowHiddenOpt; +var _YargsInstance_exitError; +var _YargsInstance_detectLocale; +var _YargsInstance_emittedWarnings; +var _YargsInstance_exitProcess; +var _YargsInstance_frozens; +var _YargsInstance_globalMiddleware; +var _YargsInstance_groups; +var _YargsInstance_hasOutput; +var _YargsInstance_helpOpt; +var _YargsInstance_isGlobalContext; +var _YargsInstance_logger; +var _YargsInstance_output; +var _YargsInstance_options; +var _YargsInstance_parentRequire; +var _YargsInstance_parserConfig; +var _YargsInstance_parseFn; +var _YargsInstance_parseContext; +var _YargsInstance_pkgs; +var _YargsInstance_preservedGroups; +var _YargsInstance_processArgs; +var _YargsInstance_recommendCommands; +var _YargsInstance_shim; +var _YargsInstance_strict; +var _YargsInstance_strictCommands; +var _YargsInstance_strictOptions; +var _YargsInstance_usage; +var _YargsInstance_usageConfig; +var _YargsInstance_versionOpt; +var _YargsInstance_validation; +function YargsFactory(_shim) { + return (processArgs = [], cwd = _shim.process.cwd(), parentRequire) => { + const yargs = new YargsInstance(processArgs, cwd, parentRequire, _shim); + Object.defineProperty(yargs, "argv", { + get: () => { + return yargs.parse(); + }, + enumerable: true + }); + yargs.help(); + yargs.version(); + return yargs; + }; +} +var kCopyDoubleDash = Symbol("copyDoubleDash"); +var kCreateLogger = Symbol("copyDoubleDash"); +var kDeleteFromParserHintObject = Symbol("deleteFromParserHintObject"); +var kEmitWarning = Symbol("emitWarning"); +var kFreeze = Symbol("freeze"); +var kGetDollarZero = Symbol("getDollarZero"); +var kGetParserConfiguration = Symbol("getParserConfiguration"); +var kGetUsageConfiguration = Symbol("getUsageConfiguration"); +var kGuessLocale = Symbol("guessLocale"); +var kGuessVersion = Symbol("guessVersion"); +var kParsePositionalNumbers = Symbol("parsePositionalNumbers"); +var kPkgUp = Symbol("pkgUp"); +var kPopulateParserHintArray = Symbol("populateParserHintArray"); +var kPopulateParserHintSingleValueDictionary = Symbol("populateParserHintSingleValueDictionary"); +var kPopulateParserHintArrayDictionary = Symbol("populateParserHintArrayDictionary"); +var kPopulateParserHintDictionary = Symbol("populateParserHintDictionary"); +var kSanitizeKey = Symbol("sanitizeKey"); +var kSetKey = Symbol("setKey"); +var kUnfreeze = Symbol("unfreeze"); +var kValidateAsync = Symbol("validateAsync"); +var kGetCommandInstance = Symbol("getCommandInstance"); +var kGetContext = Symbol("getContext"); +var kGetHasOutput = Symbol("getHasOutput"); +var kGetLoggerInstance = Symbol("getLoggerInstance"); +var kGetParseContext = Symbol("getParseContext"); +var kGetUsageInstance = Symbol("getUsageInstance"); +var kGetValidationInstance = Symbol("getValidationInstance"); +var kHasParseCallback = Symbol("hasParseCallback"); +var kIsGlobalContext = Symbol("isGlobalContext"); +var kPostProcess = Symbol("postProcess"); +var kRebase = Symbol("rebase"); +var kReset = Symbol("reset"); +var kRunYargsParserAndExecuteCommands = Symbol("runYargsParserAndExecuteCommands"); +var kRunValidation = Symbol("runValidation"); +var kSetHasOutput = Symbol("setHasOutput"); +var kTrackManuallySetKeys = Symbol("kTrackManuallySetKeys"); +var DEFAULT_LOCALE = "en_US"; +var YargsInstance = class { + constructor(processArgs = [], cwd, parentRequire, shim3) { + this.customScriptName = false; + this.parsed = false; + _YargsInstance_command.set(this, void 0); + _YargsInstance_cwd.set(this, void 0); + _YargsInstance_context.set(this, { commands: [], fullCommands: [] }); + _YargsInstance_completion.set(this, null); + _YargsInstance_completionCommand.set(this, null); + _YargsInstance_defaultShowHiddenOpt.set(this, "show-hidden"); + _YargsInstance_exitError.set(this, null); + _YargsInstance_detectLocale.set(this, true); + _YargsInstance_emittedWarnings.set(this, {}); + _YargsInstance_exitProcess.set(this, true); + _YargsInstance_frozens.set(this, []); + _YargsInstance_globalMiddleware.set(this, void 0); + _YargsInstance_groups.set(this, {}); + _YargsInstance_hasOutput.set(this, false); + _YargsInstance_helpOpt.set(this, null); + _YargsInstance_isGlobalContext.set(this, true); + _YargsInstance_logger.set(this, void 0); + _YargsInstance_output.set(this, ""); + _YargsInstance_options.set(this, void 0); + _YargsInstance_parentRequire.set(this, void 0); + _YargsInstance_parserConfig.set(this, {}); + _YargsInstance_parseFn.set(this, null); + _YargsInstance_parseContext.set(this, null); + _YargsInstance_pkgs.set(this, {}); + _YargsInstance_preservedGroups.set(this, {}); + _YargsInstance_processArgs.set(this, void 0); + _YargsInstance_recommendCommands.set(this, false); + _YargsInstance_shim.set(this, void 0); + _YargsInstance_strict.set(this, false); + _YargsInstance_strictCommands.set(this, false); + _YargsInstance_strictOptions.set(this, false); + _YargsInstance_usage.set(this, void 0); + _YargsInstance_usageConfig.set(this, {}); + _YargsInstance_versionOpt.set(this, null); + _YargsInstance_validation.set(this, void 0); + __classPrivateFieldSet(this, _YargsInstance_shim, shim3, "f"); + __classPrivateFieldSet(this, _YargsInstance_processArgs, processArgs, "f"); + __classPrivateFieldSet(this, _YargsInstance_cwd, cwd, "f"); + __classPrivateFieldSet(this, _YargsInstance_parentRequire, parentRequire, "f"); + __classPrivateFieldSet(this, _YargsInstance_globalMiddleware, new GlobalMiddleware(this), "f"); + this.$0 = this[kGetDollarZero](); + this[kReset](); + __classPrivateFieldSet(this, _YargsInstance_command, __classPrivateFieldGet(this, _YargsInstance_command, "f"), "f"); + __classPrivateFieldSet(this, _YargsInstance_usage, __classPrivateFieldGet(this, _YargsInstance_usage, "f"), "f"); + __classPrivateFieldSet(this, _YargsInstance_validation, __classPrivateFieldGet(this, _YargsInstance_validation, "f"), "f"); + __classPrivateFieldSet(this, _YargsInstance_options, __classPrivateFieldGet(this, _YargsInstance_options, "f"), "f"); + __classPrivateFieldGet(this, _YargsInstance_options, "f").showHiddenOpt = __classPrivateFieldGet(this, _YargsInstance_defaultShowHiddenOpt, "f"); + __classPrivateFieldSet(this, _YargsInstance_logger, this[kCreateLogger](), "f"); + __classPrivateFieldGet(this, _YargsInstance_shim, "f").y18n.setLocale(DEFAULT_LOCALE); + } + addHelpOpt(opt, msg) { + const defaultHelpOpt = "help"; + argsert("[string|boolean] [string]", [opt, msg], arguments.length); + if (__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")) { + this[kDeleteFromParserHintObject](__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")); + __classPrivateFieldSet(this, _YargsInstance_helpOpt, null, "f"); + } + if (opt === false && msg === void 0) + return this; + __classPrivateFieldSet(this, _YargsInstance_helpOpt, typeof opt === "string" ? opt : defaultHelpOpt, "f"); + this.boolean(__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")); + this.describe(__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f"), msg || __classPrivateFieldGet(this, _YargsInstance_usage, "f").deferY18nLookup("Show help")); + return this; + } + help(opt, msg) { + return this.addHelpOpt(opt, msg); + } + addShowHiddenOpt(opt, msg) { + argsert("[string|boolean] [string]", [opt, msg], arguments.length); + if (opt === false && msg === void 0) + return this; + const showHiddenOpt = typeof opt === "string" ? opt : __classPrivateFieldGet(this, _YargsInstance_defaultShowHiddenOpt, "f"); + this.boolean(showHiddenOpt); + this.describe(showHiddenOpt, msg || __classPrivateFieldGet(this, _YargsInstance_usage, "f").deferY18nLookup("Show hidden options")); + __classPrivateFieldGet(this, _YargsInstance_options, "f").showHiddenOpt = showHiddenOpt; + return this; + } + showHidden(opt, msg) { + return this.addShowHiddenOpt(opt, msg); + } + alias(key, value) { + argsert(" [string|array]", [key, value], arguments.length); + this[kPopulateParserHintArrayDictionary](this.alias.bind(this), "alias", key, value); + return this; + } + array(keys) { + argsert("", [keys], arguments.length); + this[kPopulateParserHintArray]("array", keys); + this[kTrackManuallySetKeys](keys); + return this; + } + boolean(keys) { + argsert("", [keys], arguments.length); + this[kPopulateParserHintArray]("boolean", keys); + this[kTrackManuallySetKeys](keys); + return this; + } + check(f, global) { + argsert(" [boolean]", [f, global], arguments.length); + this.middleware((argv, _yargs) => { + return maybeAsyncResult(() => { + return f(argv, _yargs.getOptions()); + }, (result) => { + if (!result) { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").fail(__classPrivateFieldGet(this, _YargsInstance_shim, "f").y18n.__("Argument check failed: %s", f.toString())); + } else if (typeof result === "string" || result instanceof Error) { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").fail(result.toString(), result); + } + return argv; + }, (err) => { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").fail(err.message ? err.message : err.toString(), err); + return argv; + }); + }, false, global); + return this; } -}); - -// -var allLabels = { - ...managedLabels, - ...actionLabels, - ...mergeLabels, - ...targetLabels, - ...priorityLabels, - ...featureLabels, - ...requiresLabels -}; - -// -var import_semver2 = __toESM(require_semver2(), 1); - -// -var ReleaseTrain = class { - constructor(branchName, version) { - this.branchName = branchName; - this.version = version; - this.isMajor = this.version.minor === 0 && this.version.patch === 0; + choices(key, value) { + argsert(" [string|array]", [key, value], arguments.length); + this[kPopulateParserHintArrayDictionary](this.choices.bind(this), "choices", key, value); + return this; } -}; - -// -var import_semver = __toESM(require_semver2(), 1); -var versionBranchNameRegex = /^(\d+)\.(\d+)\.x$/; -var exceptionalMinorPackageIndicator = "__ngDevExceptionalMinor__"; -async function getVersionInfoForBranch(repo, branchName) { - const { data } = await repo.api.repos.getContent({ - owner: repo.owner, - repo: repo.name, - path: "/package.json", - ref: branchName - }); - const content = data.content; - if (!content) { - throw Error(`Unable to read "package.json" file from repository.`); + coerce(keys, value) { + argsert(" [function]", [keys, value], arguments.length); + if (Array.isArray(keys)) { + if (!value) { + throw new YError("coerce callback must be provided"); + } + for (const key of keys) { + this.coerce(key, value); + } + return this; + } else if (typeof keys === "object") { + for (const key of Object.keys(keys)) { + this.coerce(key, keys[key]); + } + return this; + } + if (!value) { + throw new YError("coerce callback must be provided"); + } + const coerceKey = keys; + __classPrivateFieldGet(this, _YargsInstance_options, "f").key[coerceKey] = true; + __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").addCoerceMiddleware((argv, yargs) => { + var _a2; + const coerceKeyAliases = (_a2 = yargs.getAliases()[coerceKey]) !== null && _a2 !== void 0 ? _a2 : []; + const argvKeys = [coerceKey, ...coerceKeyAliases].filter((key) => Object.prototype.hasOwnProperty.call(argv, key)); + if (argvKeys.length === 0) { + return argv; + } + return maybeAsyncResult(() => { + return value(argv[argvKeys[0]]); + }, (result) => { + argvKeys.forEach((key) => { + argv[key] = result; + }); + return argv; + }, (err) => { + throw new YError(err.message); + }); + }, coerceKey); + return this; + } + conflicts(key1, key2) { + argsert(" [string|array]", [key1, key2], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").conflicts(key1, key2); + return this; + } + config(key = "config", msg, parseFn) { + argsert("[object|string] [string|function] [function]", [key, msg, parseFn], arguments.length); + if (typeof key === "object" && !Array.isArray(key)) { + key = applyExtends(key, __classPrivateFieldGet(this, _YargsInstance_cwd, "f"), this[kGetParserConfiguration]()["deep-merge-config"] || false, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + __classPrivateFieldGet(this, _YargsInstance_options, "f").configObjects = (__classPrivateFieldGet(this, _YargsInstance_options, "f").configObjects || []).concat(key); + return this; + } + if (typeof msg === "function") { + parseFn = msg; + msg = void 0; + } + this.describe(key, msg || __classPrivateFieldGet(this, _YargsInstance_usage, "f").deferY18nLookup("Path to JSON config file")); + (Array.isArray(key) ? key : [key]).forEach((k) => { + __classPrivateFieldGet(this, _YargsInstance_options, "f").config[k] = parseFn || true; + }); + return this; + } + completion(cmd, desc, fn) { + argsert("[string] [string|boolean|function] [function]", [cmd, desc, fn], arguments.length); + if (typeof desc === "function") { + fn = desc; + desc = void 0; + } + __classPrivateFieldSet(this, _YargsInstance_completionCommand, cmd || __classPrivateFieldGet(this, _YargsInstance_completionCommand, "f") || "completion", "f"); + if (!desc && desc !== false) { + desc = "generate completion script"; + } + this.command(__classPrivateFieldGet(this, _YargsInstance_completionCommand, "f"), desc); + if (fn) + __classPrivateFieldGet(this, _YargsInstance_completion, "f").registerFunction(fn); + return this; + } + command(cmd, description, builder, handler2, middlewares, deprecated) { + argsert(" [string|boolean] [function|object] [function] [array] [boolean|string]", [cmd, description, builder, handler2, middlewares, deprecated], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_command, "f").addHandler(cmd, description, builder, handler2, middlewares, deprecated); + return this; + } + commands(cmd, description, builder, handler2, middlewares, deprecated) { + return this.command(cmd, description, builder, handler2, middlewares, deprecated); + } + commandDir(dir, opts) { + argsert(" [object]", [dir, opts], arguments.length); + const req = __classPrivateFieldGet(this, _YargsInstance_parentRequire, "f") || __classPrivateFieldGet(this, _YargsInstance_shim, "f").require; + __classPrivateFieldGet(this, _YargsInstance_command, "f").addDirectory(dir, req, __classPrivateFieldGet(this, _YargsInstance_shim, "f").getCallerFile(), opts); + return this; + } + count(keys) { + argsert("", [keys], arguments.length); + this[kPopulateParserHintArray]("count", keys); + this[kTrackManuallySetKeys](keys); + return this; + } + default(key, value, defaultDescription) { + argsert(" [*] [string]", [key, value, defaultDescription], arguments.length); + if (defaultDescription) { + assertSingleKey(key, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + __classPrivateFieldGet(this, _YargsInstance_options, "f").defaultDescription[key] = defaultDescription; + } + if (typeof value === "function") { + assertSingleKey(key, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + if (!__classPrivateFieldGet(this, _YargsInstance_options, "f").defaultDescription[key]) + __classPrivateFieldGet(this, _YargsInstance_options, "f").defaultDescription[key] = __classPrivateFieldGet(this, _YargsInstance_usage, "f").functionDescription(value); + value = value.call(); + } + this[kPopulateParserHintSingleValueDictionary](this.default.bind(this), "default", key, value); + return this; + } + defaults(key, value, defaultDescription) { + return this.default(key, value, defaultDescription); + } + demandCommand(min = 1, max, minMsg, maxMsg) { + argsert("[number] [number|string] [string|null|undefined] [string|null|undefined]", [min, max, minMsg, maxMsg], arguments.length); + if (typeof max !== "number") { + minMsg = max; + max = Infinity; + } + this.global("_", false); + __classPrivateFieldGet(this, _YargsInstance_options, "f").demandedCommands._ = { + min, + max, + minMsg, + maxMsg + }; + return this; } - const pkgJson = JSON.parse(Buffer.from(content, "base64").toString()); - const parsedVersion = import_semver.default.parse(pkgJson.version); - if (parsedVersion === null) { - throw Error(`Invalid version detected in following branch: ${branchName}.`); + demand(keys, max, msg) { + if (Array.isArray(max)) { + max.forEach((key) => { + assertNotStrictEqual(msg, true, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + this.demandOption(key, msg); + }); + max = Infinity; + } else if (typeof max !== "number") { + msg = max; + max = Infinity; + } + if (typeof keys === "number") { + assertNotStrictEqual(msg, true, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + this.demandCommand(keys, max, msg, msg); + } else if (Array.isArray(keys)) { + keys.forEach((key) => { + assertNotStrictEqual(msg, true, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + this.demandOption(key, msg); + }); + } else { + if (typeof msg === "string") { + this.demandOption(keys, msg); + } else if (msg === true || typeof msg === "undefined") { + this.demandOption(keys); + } + } + return this; + } + demandOption(keys, msg) { + argsert(" [string]", [keys, msg], arguments.length); + this[kPopulateParserHintSingleValueDictionary](this.demandOption.bind(this), "demandedOptions", keys, msg); + return this; + } + deprecateOption(option, message) { + argsert(" [string|boolean]", [option, message], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_options, "f").deprecatedOptions[option] = message; + return this; + } + describe(keys, description) { + argsert(" [string]", [keys, description], arguments.length); + this[kSetKey](keys, true); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").describe(keys, description); + return this; + } + detectLocale(detect) { + argsert("", [detect], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_detectLocale, detect, "f"); + return this; + } + env(prefix) { + argsert("[string|boolean]", [prefix], arguments.length); + if (prefix === false) + delete __classPrivateFieldGet(this, _YargsInstance_options, "f").envPrefix; + else + __classPrivateFieldGet(this, _YargsInstance_options, "f").envPrefix = prefix || ""; + return this; + } + epilogue(msg) { + argsert("", [msg], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").epilog(msg); + return this; + } + epilog(msg) { + return this.epilogue(msg); + } + example(cmd, description) { + argsert(" [string]", [cmd, description], arguments.length); + if (Array.isArray(cmd)) { + cmd.forEach((exampleParams) => this.example(...exampleParams)); + } else { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").example(cmd, description); + } + return this; + } + exit(code, err) { + __classPrivateFieldSet(this, _YargsInstance_hasOutput, true, "f"); + __classPrivateFieldSet(this, _YargsInstance_exitError, err, "f"); + if (__classPrivateFieldGet(this, _YargsInstance_exitProcess, "f")) + __classPrivateFieldGet(this, _YargsInstance_shim, "f").process.exit(code); + } + exitProcess(enabled = true) { + argsert("[boolean]", [enabled], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_exitProcess, enabled, "f"); + return this; + } + fail(f) { + argsert("", [f], arguments.length); + if (typeof f === "boolean" && f !== false) { + throw new YError("Invalid first argument. Expected function or boolean 'false'"); + } + __classPrivateFieldGet(this, _YargsInstance_usage, "f").failFn(f); + return this; + } + getAliases() { + return this.parsed ? this.parsed.aliases : {}; + } + async getCompletion(args, done) { + argsert(" [function]", [args, done], arguments.length); + if (!done) { + return new Promise((resolve5, reject) => { + __classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => { + if (err) + reject(err); + else + resolve5(completions); + }); + }); + } else { + return __classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, done); + } } - return { - version: parsedVersion, - isExceptionalMinor: pkgJson[exceptionalMinorPackageIndicator] === true - }; -} -function isVersionBranch(branchName) { - return versionBranchNameRegex.test(branchName); -} -async function getBranchesForMajorVersions(repo, majorVersions) { - const branchData = await repo.api.paginate(repo.api.repos.listBranches, { - owner: repo.owner, - repo: repo.name, - protected: true - }); - const branches = []; - for (const { name } of branchData) { - if (!isVersionBranch(name)) { - continue; + getDemandedOptions() { + argsert([], 0); + return __classPrivateFieldGet(this, _YargsInstance_options, "f").demandedOptions; + } + getDemandedCommands() { + argsert([], 0); + return __classPrivateFieldGet(this, _YargsInstance_options, "f").demandedCommands; + } + getDeprecatedOptions() { + argsert([], 0); + return __classPrivateFieldGet(this, _YargsInstance_options, "f").deprecatedOptions; + } + getDetectLocale() { + return __classPrivateFieldGet(this, _YargsInstance_detectLocale, "f"); + } + getExitProcess() { + return __classPrivateFieldGet(this, _YargsInstance_exitProcess, "f"); + } + getGroups() { + return Object.assign({}, __classPrivateFieldGet(this, _YargsInstance_groups, "f"), __classPrivateFieldGet(this, _YargsInstance_preservedGroups, "f")); + } + getHelp() { + __classPrivateFieldSet(this, _YargsInstance_hasOutput, true, "f"); + if (!__classPrivateFieldGet(this, _YargsInstance_usage, "f").hasCachedHelpMessage()) { + if (!this.parsed) { + const parse2 = this[kRunYargsParserAndExecuteCommands](__classPrivateFieldGet(this, _YargsInstance_processArgs, "f"), void 0, void 0, 0, true); + if (isPromise(parse2)) { + return parse2.then(() => { + return __classPrivateFieldGet(this, _YargsInstance_usage, "f").help(); + }); + } + } + const builderResponse = __classPrivateFieldGet(this, _YargsInstance_command, "f").runDefaultBuilderOn(this); + if (isPromise(builderResponse)) { + return builderResponse.then(() => { + return __classPrivateFieldGet(this, _YargsInstance_usage, "f").help(); + }); + } + } + return Promise.resolve(__classPrivateFieldGet(this, _YargsInstance_usage, "f").help()); + } + getOptions() { + return __classPrivateFieldGet(this, _YargsInstance_options, "f"); + } + getStrict() { + return __classPrivateFieldGet(this, _YargsInstance_strict, "f"); + } + getStrictCommands() { + return __classPrivateFieldGet(this, _YargsInstance_strictCommands, "f"); + } + getStrictOptions() { + return __classPrivateFieldGet(this, _YargsInstance_strictOptions, "f"); + } + global(globals, global) { + argsert(" [boolean]", [globals, global], arguments.length); + globals = [].concat(globals); + if (global !== false) { + __classPrivateFieldGet(this, _YargsInstance_options, "f").local = __classPrivateFieldGet(this, _YargsInstance_options, "f").local.filter((l) => globals.indexOf(l) === -1); + } else { + globals.forEach((g) => { + if (!__classPrivateFieldGet(this, _YargsInstance_options, "f").local.includes(g)) + __classPrivateFieldGet(this, _YargsInstance_options, "f").local.push(g); + }); + } + return this; + } + group(opts, groupName) { + argsert(" ", [opts, groupName], arguments.length); + const existing = __classPrivateFieldGet(this, _YargsInstance_preservedGroups, "f")[groupName] || __classPrivateFieldGet(this, _YargsInstance_groups, "f")[groupName]; + if (__classPrivateFieldGet(this, _YargsInstance_preservedGroups, "f")[groupName]) { + delete __classPrivateFieldGet(this, _YargsInstance_preservedGroups, "f")[groupName]; + } + const seen = {}; + __classPrivateFieldGet(this, _YargsInstance_groups, "f")[groupName] = (existing || []).concat(opts).filter((key) => { + if (seen[key]) + return false; + return seen[key] = true; + }); + return this; + } + hide(key) { + argsert("", [key], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_options, "f").hiddenOptions.push(key); + return this; + } + implies(key, value) { + argsert(" [number|string|array]", [key, value], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").implies(key, value); + return this; + } + locale(locale) { + argsert("[string]", [locale], arguments.length); + if (locale === void 0) { + this[kGuessLocale](); + return __classPrivateFieldGet(this, _YargsInstance_shim, "f").y18n.getLocale(); + } + __classPrivateFieldSet(this, _YargsInstance_detectLocale, false, "f"); + __classPrivateFieldGet(this, _YargsInstance_shim, "f").y18n.setLocale(locale); + return this; + } + middleware(callback, applyBeforeValidation, global) { + return __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").addMiddleware(callback, !!applyBeforeValidation, global); + } + nargs(key, value) { + argsert(" [number]", [key, value], arguments.length); + this[kPopulateParserHintSingleValueDictionary](this.nargs.bind(this), "narg", key, value); + return this; + } + normalize(keys) { + argsert("", [keys], arguments.length); + this[kPopulateParserHintArray]("normalize", keys); + return this; + } + number(keys) { + argsert("", [keys], arguments.length); + this[kPopulateParserHintArray]("number", keys); + this[kTrackManuallySetKeys](keys); + return this; + } + option(key, opt) { + argsert(" [object]", [key, opt], arguments.length); + if (typeof key === "object") { + Object.keys(key).forEach((k) => { + this.options(k, key[k]); + }); + } else { + if (typeof opt !== "object") { + opt = {}; + } + this[kTrackManuallySetKeys](key); + if (__classPrivateFieldGet(this, _YargsInstance_versionOpt, "f") && (key === "version" || (opt === null || opt === void 0 ? void 0 : opt.alias) === "version")) { + this[kEmitWarning]([ + '"version" is a reserved word.', + "Please do one of the following:", + '- Disable version with `yargs.version(false)` if using "version" as an option', + "- Use the built-in `yargs.version` method instead (if applicable)", + "- Use a different option key", + "https://yargs.js.org/docs/#api-reference-version" + ].join("\n"), void 0, "versionWarning"); + } + __classPrivateFieldGet(this, _YargsInstance_options, "f").key[key] = true; + if (opt.alias) + this.alias(key, opt.alias); + const deprecate = opt.deprecate || opt.deprecated; + if (deprecate) { + this.deprecateOption(key, deprecate); + } + const demand = opt.demand || opt.required || opt.require; + if (demand) { + this.demand(key, demand); + } + if (opt.demandOption) { + this.demandOption(key, typeof opt.demandOption === "string" ? opt.demandOption : void 0); + } + if (opt.conflicts) { + this.conflicts(key, opt.conflicts); + } + if ("default" in opt) { + this.default(key, opt.default); + } + if (opt.implies !== void 0) { + this.implies(key, opt.implies); + } + if (opt.nargs !== void 0) { + this.nargs(key, opt.nargs); + } + if (opt.config) { + this.config(key, opt.configParser); + } + if (opt.normalize) { + this.normalize(key); + } + if (opt.choices) { + this.choices(key, opt.choices); + } + if (opt.coerce) { + this.coerce(key, opt.coerce); + } + if (opt.group) { + this.group(key, opt.group); + } + if (opt.boolean || opt.type === "boolean") { + this.boolean(key); + if (opt.alias) + this.boolean(opt.alias); + } + if (opt.array || opt.type === "array") { + this.array(key); + if (opt.alias) + this.array(opt.alias); + } + if (opt.number || opt.type === "number") { + this.number(key); + if (opt.alias) + this.number(opt.alias); + } + if (opt.string || opt.type === "string") { + this.string(key); + if (opt.alias) + this.string(opt.alias); + } + if (opt.count || opt.type === "count") { + this.count(key); + } + if (typeof opt.global === "boolean") { + this.global(key, opt.global); + } + if (opt.defaultDescription) { + __classPrivateFieldGet(this, _YargsInstance_options, "f").defaultDescription[key] = opt.defaultDescription; + } + if (opt.skipValidation) { + this.skipValidation(key); + } + const desc = opt.describe || opt.description || opt.desc; + const descriptions = __classPrivateFieldGet(this, _YargsInstance_usage, "f").getDescriptions(); + if (!Object.prototype.hasOwnProperty.call(descriptions, key) || typeof desc === "string") { + this.describe(key, desc); + } + if (opt.hidden) { + this.hide(key); + } + if (opt.requiresArg) { + this.requiresArg(key); + } + } + return this; + } + options(key, opt) { + return this.option(key, opt); + } + parse(args, shortCircuit, _parseFn) { + argsert("[string|array] [function|boolean|object] [function]", [args, shortCircuit, _parseFn], arguments.length); + this[kFreeze](); + if (typeof args === "undefined") { + args = __classPrivateFieldGet(this, _YargsInstance_processArgs, "f"); + } + if (typeof shortCircuit === "object") { + __classPrivateFieldSet(this, _YargsInstance_parseContext, shortCircuit, "f"); + shortCircuit = _parseFn; + } + if (typeof shortCircuit === "function") { + __classPrivateFieldSet(this, _YargsInstance_parseFn, shortCircuit, "f"); + shortCircuit = false; + } + if (!shortCircuit) + __classPrivateFieldSet(this, _YargsInstance_processArgs, args, "f"); + if (__classPrivateFieldGet(this, _YargsInstance_parseFn, "f")) + __classPrivateFieldSet(this, _YargsInstance_exitProcess, false, "f"); + const parsed = this[kRunYargsParserAndExecuteCommands](args, !!shortCircuit); + const tmpParsed = this.parsed; + __classPrivateFieldGet(this, _YargsInstance_completion, "f").setParsed(this.parsed); + if (isPromise(parsed)) { + return parsed.then((argv) => { + if (__classPrivateFieldGet(this, _YargsInstance_parseFn, "f")) + __classPrivateFieldGet(this, _YargsInstance_parseFn, "f").call(this, __classPrivateFieldGet(this, _YargsInstance_exitError, "f"), argv, __classPrivateFieldGet(this, _YargsInstance_output, "f")); + return argv; + }).catch((err) => { + if (__classPrivateFieldGet(this, _YargsInstance_parseFn, "f")) { + __classPrivateFieldGet(this, _YargsInstance_parseFn, "f")(err, this.parsed.argv, __classPrivateFieldGet(this, _YargsInstance_output, "f")); + } + throw err; + }).finally(() => { + this[kUnfreeze](); + this.parsed = tmpParsed; + }); + } else { + if (__classPrivateFieldGet(this, _YargsInstance_parseFn, "f")) + __classPrivateFieldGet(this, _YargsInstance_parseFn, "f").call(this, __classPrivateFieldGet(this, _YargsInstance_exitError, "f"), parsed, __classPrivateFieldGet(this, _YargsInstance_output, "f")); + this[kUnfreeze](); + this.parsed = tmpParsed; + } + return parsed; + } + parseAsync(args, shortCircuit, _parseFn) { + const maybePromise = this.parse(args, shortCircuit, _parseFn); + return !isPromise(maybePromise) ? Promise.resolve(maybePromise) : maybePromise; + } + parseSync(args, shortCircuit, _parseFn) { + const maybePromise = this.parse(args, shortCircuit, _parseFn); + if (isPromise(maybePromise)) { + throw new YError(".parseSync() must not be used with asynchronous builders, handlers, or middleware"); + } + return maybePromise; + } + parserConfiguration(config) { + argsert("", [config], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_parserConfig, config, "f"); + return this; + } + pkgConf(key, rootPath) { + argsert(" [string]", [key, rootPath], arguments.length); + let conf = null; + const obj = this[kPkgUp](rootPath || __classPrivateFieldGet(this, _YargsInstance_cwd, "f")); + if (obj[key] && typeof obj[key] === "object") { + conf = applyExtends(obj[key], rootPath || __classPrivateFieldGet(this, _YargsInstance_cwd, "f"), this[kGetParserConfiguration]()["deep-merge-config"] || false, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + __classPrivateFieldGet(this, _YargsInstance_options, "f").configObjects = (__classPrivateFieldGet(this, _YargsInstance_options, "f").configObjects || []).concat(conf); + } + return this; + } + positional(key, opts) { + argsert(" ", [key, opts], arguments.length); + const supportedOpts = [ + "default", + "defaultDescription", + "implies", + "normalize", + "choices", + "conflicts", + "coerce", + "type", + "describe", + "desc", + "description", + "alias" + ]; + opts = objFilter(opts, (k, v) => { + if (k === "type" && !["string", "number", "boolean"].includes(v)) + return false; + return supportedOpts.includes(k); + }); + const fullCommand = __classPrivateFieldGet(this, _YargsInstance_context, "f").fullCommands[__classPrivateFieldGet(this, _YargsInstance_context, "f").fullCommands.length - 1]; + const parseOptions = fullCommand ? __classPrivateFieldGet(this, _YargsInstance_command, "f").cmdToParseOptions(fullCommand) : { + array: [], + alias: {}, + default: {}, + demand: {} + }; + objectKeys(parseOptions).forEach((pk) => { + const parseOption = parseOptions[pk]; + if (Array.isArray(parseOption)) { + if (parseOption.indexOf(key) !== -1) + opts[pk] = true; + } else { + if (parseOption[key] && !(pk in opts)) + opts[pk] = parseOption[key]; + } + }); + this.group(key, __classPrivateFieldGet(this, _YargsInstance_usage, "f").getPositionalGroupName()); + return this.option(key, opts); + } + recommendCommands(recommend = true) { + argsert("[boolean]", [recommend], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_recommendCommands, recommend, "f"); + return this; + } + required(keys, max, msg) { + return this.demand(keys, max, msg); + } + require(keys, max, msg) { + return this.demand(keys, max, msg); + } + requiresArg(keys) { + argsert(" [number]", [keys], arguments.length); + if (typeof keys === "string" && __classPrivateFieldGet(this, _YargsInstance_options, "f").narg[keys]) { + return this; + } else { + this[kPopulateParserHintSingleValueDictionary](this.requiresArg.bind(this), "narg", keys, NaN); + } + return this; + } + showCompletionScript($0, cmd) { + argsert("[string] [string]", [$0, cmd], arguments.length); + $0 = $0 || this.$0; + __classPrivateFieldGet(this, _YargsInstance_logger, "f").log(__classPrivateFieldGet(this, _YargsInstance_completion, "f").generateCompletionScript($0, cmd || __classPrivateFieldGet(this, _YargsInstance_completionCommand, "f") || "completion")); + return this; + } + showHelp(level) { + argsert("[string|function]", [level], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_hasOutput, true, "f"); + if (!__classPrivateFieldGet(this, _YargsInstance_usage, "f").hasCachedHelpMessage()) { + if (!this.parsed) { + const parse2 = this[kRunYargsParserAndExecuteCommands](__classPrivateFieldGet(this, _YargsInstance_processArgs, "f"), void 0, void 0, 0, true); + if (isPromise(parse2)) { + parse2.then(() => { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").showHelp(level); + }); + return this; + } + } + const builderResponse = __classPrivateFieldGet(this, _YargsInstance_command, "f").runDefaultBuilderOn(this); + if (isPromise(builderResponse)) { + builderResponse.then(() => { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").showHelp(level); + }); + return this; + } + } + __classPrivateFieldGet(this, _YargsInstance_usage, "f").showHelp(level); + return this; + } + scriptName(scriptName) { + this.customScriptName = true; + this.$0 = scriptName; + return this; + } + showHelpOnFail(enabled, message) { + argsert("[boolean|string] [string]", [enabled, message], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").showHelpOnFail(enabled, message); + return this; + } + showVersion(level) { + argsert("[string|function]", [level], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").showVersion(level); + return this; + } + skipValidation(keys) { + argsert("", [keys], arguments.length); + this[kPopulateParserHintArray]("skipValidation", keys); + return this; + } + strict(enabled) { + argsert("[boolean]", [enabled], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_strict, enabled !== false, "f"); + return this; + } + strictCommands(enabled) { + argsert("[boolean]", [enabled], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_strictCommands, enabled !== false, "f"); + return this; + } + strictOptions(enabled) { + argsert("[boolean]", [enabled], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_strictOptions, enabled !== false, "f"); + return this; + } + string(keys) { + argsert("", [keys], arguments.length); + this[kPopulateParserHintArray]("string", keys); + this[kTrackManuallySetKeys](keys); + return this; + } + terminalWidth() { + argsert([], 0); + return __classPrivateFieldGet(this, _YargsInstance_shim, "f").process.stdColumns; + } + updateLocale(obj) { + return this.updateStrings(obj); + } + updateStrings(obj) { + argsert("", [obj], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_detectLocale, false, "f"); + __classPrivateFieldGet(this, _YargsInstance_shim, "f").y18n.updateLocale(obj); + return this; + } + usage(msg, description, builder, handler2) { + argsert(" [string|boolean] [function|object] [function]", [msg, description, builder, handler2], arguments.length); + if (description !== void 0) { + assertNotStrictEqual(msg, null, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + if ((msg || "").match(/^\$0( |$)/)) { + return this.command(msg, description, builder, handler2); + } else { + throw new YError(".usage() description must start with $0 if being used as alias for .command()"); + } + } else { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").usage(msg); + return this; + } + } + usageConfiguration(config) { + argsert("", [config], arguments.length); + __classPrivateFieldSet(this, _YargsInstance_usageConfig, config, "f"); + return this; + } + version(opt, msg, ver) { + const defaultVersionOpt = "version"; + argsert("[boolean|string] [string] [string]", [opt, msg, ver], arguments.length); + if (__classPrivateFieldGet(this, _YargsInstance_versionOpt, "f")) { + this[kDeleteFromParserHintObject](__classPrivateFieldGet(this, _YargsInstance_versionOpt, "f")); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").version(void 0); + __classPrivateFieldSet(this, _YargsInstance_versionOpt, null, "f"); + } + if (arguments.length === 0) { + ver = this[kGuessVersion](); + opt = defaultVersionOpt; + } else if (arguments.length === 1) { + if (opt === false) { + return this; + } + ver = opt; + opt = defaultVersionOpt; + } else if (arguments.length === 2) { + ver = msg; + msg = void 0; + } + __classPrivateFieldSet(this, _YargsInstance_versionOpt, typeof opt === "string" ? opt : defaultVersionOpt, "f"); + msg = msg || __classPrivateFieldGet(this, _YargsInstance_usage, "f").deferY18nLookup("Show version number"); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").version(ver || void 0); + this.boolean(__classPrivateFieldGet(this, _YargsInstance_versionOpt, "f")); + this.describe(__classPrivateFieldGet(this, _YargsInstance_versionOpt, "f"), msg); + return this; + } + wrap(cols) { + argsert("", [cols], arguments.length); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").wrap(cols); + return this; + } + [(_YargsInstance_command = /* @__PURE__ */ new WeakMap(), _YargsInstance_cwd = /* @__PURE__ */ new WeakMap(), _YargsInstance_context = /* @__PURE__ */ new WeakMap(), _YargsInstance_completion = /* @__PURE__ */ new WeakMap(), _YargsInstance_completionCommand = /* @__PURE__ */ new WeakMap(), _YargsInstance_defaultShowHiddenOpt = /* @__PURE__ */ new WeakMap(), _YargsInstance_exitError = /* @__PURE__ */ new WeakMap(), _YargsInstance_detectLocale = /* @__PURE__ */ new WeakMap(), _YargsInstance_emittedWarnings = /* @__PURE__ */ new WeakMap(), _YargsInstance_exitProcess = /* @__PURE__ */ new WeakMap(), _YargsInstance_frozens = /* @__PURE__ */ new WeakMap(), _YargsInstance_globalMiddleware = /* @__PURE__ */ new WeakMap(), _YargsInstance_groups = /* @__PURE__ */ new WeakMap(), _YargsInstance_hasOutput = /* @__PURE__ */ new WeakMap(), _YargsInstance_helpOpt = /* @__PURE__ */ new WeakMap(), _YargsInstance_isGlobalContext = /* @__PURE__ */ new WeakMap(), _YargsInstance_logger = /* @__PURE__ */ new WeakMap(), _YargsInstance_output = /* @__PURE__ */ new WeakMap(), _YargsInstance_options = /* @__PURE__ */ new WeakMap(), _YargsInstance_parentRequire = /* @__PURE__ */ new WeakMap(), _YargsInstance_parserConfig = /* @__PURE__ */ new WeakMap(), _YargsInstance_parseFn = /* @__PURE__ */ new WeakMap(), _YargsInstance_parseContext = /* @__PURE__ */ new WeakMap(), _YargsInstance_pkgs = /* @__PURE__ */ new WeakMap(), _YargsInstance_preservedGroups = /* @__PURE__ */ new WeakMap(), _YargsInstance_processArgs = /* @__PURE__ */ new WeakMap(), _YargsInstance_recommendCommands = /* @__PURE__ */ new WeakMap(), _YargsInstance_shim = /* @__PURE__ */ new WeakMap(), _YargsInstance_strict = /* @__PURE__ */ new WeakMap(), _YargsInstance_strictCommands = /* @__PURE__ */ new WeakMap(), _YargsInstance_strictOptions = /* @__PURE__ */ new WeakMap(), _YargsInstance_usage = /* @__PURE__ */ new WeakMap(), _YargsInstance_usageConfig = /* @__PURE__ */ new WeakMap(), _YargsInstance_versionOpt = /* @__PURE__ */ new WeakMap(), _YargsInstance_validation = /* @__PURE__ */ new WeakMap(), kCopyDoubleDash)](argv) { + if (!argv._ || !argv["--"]) + return argv; + argv._.push.apply(argv._, argv["--"]); + try { + delete argv["--"]; + } catch (_err) { + } + return argv; + } + [kCreateLogger]() { + return { + log: (...args) => { + if (!this[kHasParseCallback]()) + console.log(...args); + __classPrivateFieldSet(this, _YargsInstance_hasOutput, true, "f"); + if (__classPrivateFieldGet(this, _YargsInstance_output, "f").length) + __classPrivateFieldSet(this, _YargsInstance_output, __classPrivateFieldGet(this, _YargsInstance_output, "f") + "\n", "f"); + __classPrivateFieldSet(this, _YargsInstance_output, __classPrivateFieldGet(this, _YargsInstance_output, "f") + args.join(" "), "f"); + }, + error: (...args) => { + if (!this[kHasParseCallback]()) + console.error(...args); + __classPrivateFieldSet(this, _YargsInstance_hasOutput, true, "f"); + if (__classPrivateFieldGet(this, _YargsInstance_output, "f").length) + __classPrivateFieldSet(this, _YargsInstance_output, __classPrivateFieldGet(this, _YargsInstance_output, "f") + "\n", "f"); + __classPrivateFieldSet(this, _YargsInstance_output, __classPrivateFieldGet(this, _YargsInstance_output, "f") + args.join(" "), "f"); + } + }; + } + [kDeleteFromParserHintObject](optionKey) { + objectKeys(__classPrivateFieldGet(this, _YargsInstance_options, "f")).forEach((hintKey) => { + if (/* @__PURE__ */ ((key) => key === "configObjects")(hintKey)) + return; + const hint = __classPrivateFieldGet(this, _YargsInstance_options, "f")[hintKey]; + if (Array.isArray(hint)) { + if (hint.includes(optionKey)) + hint.splice(hint.indexOf(optionKey), 1); + } else if (typeof hint === "object") { + delete hint[optionKey]; + } + }); + delete __classPrivateFieldGet(this, _YargsInstance_usage, "f").getDescriptions()[optionKey]; + } + [kEmitWarning](warning, type, deduplicationId) { + if (!__classPrivateFieldGet(this, _YargsInstance_emittedWarnings, "f")[deduplicationId]) { + __classPrivateFieldGet(this, _YargsInstance_shim, "f").process.emitWarning(warning, type); + __classPrivateFieldGet(this, _YargsInstance_emittedWarnings, "f")[deduplicationId] = true; + } + } + [kFreeze]() { + __classPrivateFieldGet(this, _YargsInstance_frozens, "f").push({ + options: __classPrivateFieldGet(this, _YargsInstance_options, "f"), + configObjects: __classPrivateFieldGet(this, _YargsInstance_options, "f").configObjects.slice(0), + exitProcess: __classPrivateFieldGet(this, _YargsInstance_exitProcess, "f"), + groups: __classPrivateFieldGet(this, _YargsInstance_groups, "f"), + strict: __classPrivateFieldGet(this, _YargsInstance_strict, "f"), + strictCommands: __classPrivateFieldGet(this, _YargsInstance_strictCommands, "f"), + strictOptions: __classPrivateFieldGet(this, _YargsInstance_strictOptions, "f"), + completionCommand: __classPrivateFieldGet(this, _YargsInstance_completionCommand, "f"), + output: __classPrivateFieldGet(this, _YargsInstance_output, "f"), + exitError: __classPrivateFieldGet(this, _YargsInstance_exitError, "f"), + hasOutput: __classPrivateFieldGet(this, _YargsInstance_hasOutput, "f"), + parsed: this.parsed, + parseFn: __classPrivateFieldGet(this, _YargsInstance_parseFn, "f"), + parseContext: __classPrivateFieldGet(this, _YargsInstance_parseContext, "f") + }); + __classPrivateFieldGet(this, _YargsInstance_usage, "f").freeze(); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").freeze(); + __classPrivateFieldGet(this, _YargsInstance_command, "f").freeze(); + __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").freeze(); + } + [kGetDollarZero]() { + let $0 = ""; + let default$0; + if (/\b(node|iojs|electron)(\.exe)?$/.test(__classPrivateFieldGet(this, _YargsInstance_shim, "f").process.argv()[0])) { + default$0 = __classPrivateFieldGet(this, _YargsInstance_shim, "f").process.argv().slice(1, 2); + } else { + default$0 = __classPrivateFieldGet(this, _YargsInstance_shim, "f").process.argv().slice(0, 1); } - const parsed = convertVersionBranchToSemVer(name); - if (parsed !== null && majorVersions.includes(parsed.major)) { - branches.push({ name, parsed }); + $0 = default$0.map((x) => { + const b = this[kRebase](__classPrivateFieldGet(this, _YargsInstance_cwd, "f"), x); + return x.match(/^(\/|([a-zA-Z]:)?\\)/) && b.length < x.length ? b : x; + }).join(" ").trim(); + if (__classPrivateFieldGet(this, _YargsInstance_shim, "f").getEnv("_") && __classPrivateFieldGet(this, _YargsInstance_shim, "f").getProcessArgvBin() === __classPrivateFieldGet(this, _YargsInstance_shim, "f").getEnv("_")) { + $0 = __classPrivateFieldGet(this, _YargsInstance_shim, "f").getEnv("_").replace(`${__classPrivateFieldGet(this, _YargsInstance_shim, "f").path.dirname(__classPrivateFieldGet(this, _YargsInstance_shim, "f").process.execPath())}/`, ""); } + return $0; } - return branches.sort((a, b) => import_semver.default.rcompare(a.parsed, b.parsed)); -} -function convertVersionBranchToSemVer(branchName) { - return import_semver.default.parse(branchName.replace(versionBranchNameRegex, "$1.$2.0")); -} - -// -var ActiveReleaseTrains = class { - constructor(trains) { - this.trains = trains; - this.releaseCandidate = this.trains.releaseCandidate; - this.next = this.trains.next; - this.latest = this.trains.latest; - this.exceptionalMinor = this.trains.exceptionalMinor; - } - isFeatureFreeze() { - return this.releaseCandidate !== null && this.releaseCandidate.version.prerelease[0] === "next"; + [kGetParserConfiguration]() { + return __classPrivateFieldGet(this, _YargsInstance_parserConfig, "f"); } - static async fetch(repo) { - return fetchActiveReleaseTrains(repo); + [kGetUsageConfiguration]() { + return __classPrivateFieldGet(this, _YargsInstance_usageConfig, "f"); } -}; -async function fetchActiveReleaseTrains(repo) { - const nextBranchName = repo.nextBranchName; - const { version: nextVersion } = await getVersionInfoForBranch(repo, nextBranchName); - const next = new ReleaseTrain(nextBranchName, nextVersion); - const majorVersionsToFetch = []; - const checks = { - canHaveExceptionalMinor: () => false, - isValidReleaseCandidateVersion: () => false, - isValidExceptionalMinorVersion: () => false - }; - if (nextVersion.minor === 0) { - majorVersionsToFetch.push(nextVersion.major - 1, nextVersion.major - 2); - checks.isValidReleaseCandidateVersion = (v) => v.major === nextVersion.major - 1; - checks.canHaveExceptionalMinor = (rc) => rc === null || rc.isMajor; - checks.isValidExceptionalMinorVersion = (v, rc) => v.major === (rc === null ? nextVersion.major : rc.version.major) - 1; - } else if (nextVersion.minor === 1) { - majorVersionsToFetch.push(nextVersion.major, nextVersion.major - 1); - checks.isValidReleaseCandidateVersion = (v) => v.major === nextVersion.major; - checks.canHaveExceptionalMinor = (rc) => rc !== null && rc.isMajor; - checks.isValidExceptionalMinorVersion = (v, rc) => v.major === rc.version.major - 1; - } else { - majorVersionsToFetch.push(nextVersion.major); - checks.isValidReleaseCandidateVersion = (v) => v.major === nextVersion.major; - checks.canHaveExceptionalMinor = () => false; + [kGuessLocale]() { + if (!__classPrivateFieldGet(this, _YargsInstance_detectLocale, "f")) + return; + const locale = __classPrivateFieldGet(this, _YargsInstance_shim, "f").getEnv("LC_ALL") || __classPrivateFieldGet(this, _YargsInstance_shim, "f").getEnv("LC_MESSAGES") || __classPrivateFieldGet(this, _YargsInstance_shim, "f").getEnv("LANG") || __classPrivateFieldGet(this, _YargsInstance_shim, "f").getEnv("LANGUAGE") || "en_US"; + this.locale(locale.replace(/[.:].*/, "")); } - const branches = await getBranchesForMajorVersions(repo, majorVersionsToFetch); - const { latest, releaseCandidate, exceptionalMinor } = await findActiveReleaseTrainsFromVersionBranches(repo, next, branches, checks); - if (latest === null) { - throw Error(`Unable to determine the latest release-train. The following branches have been considered: [${branches.map((b) => b.name).join(", ")}]`); + [kGuessVersion]() { + const obj = this[kPkgUp](); + return obj.version || "unknown"; } - return new ActiveReleaseTrains({ releaseCandidate, next, latest, exceptionalMinor }); -} -async function findActiveReleaseTrainsFromVersionBranches(repo, next, branches, checks) { - const nextReleaseTrainVersion = import_semver2.default.parse(`${next.version.major}.${next.version.minor}.0`); - const nextBranchName = repo.nextBranchName; - let latest = null; - let releaseCandidate = null; - let exceptionalMinor = null; - for (const { name, parsed } of branches) { - if (import_semver2.default.gt(parsed, nextReleaseTrainVersion)) { - throw Error(`Discovered unexpected version-branch "${name}" for a release-train that is more recent than the release-train currently in the "${nextBranchName}" branch. Please either delete the branch if created by accident, or update the outdated version in the next branch (${nextBranchName}).`); - } else if (import_semver2.default.eq(parsed, nextReleaseTrainVersion)) { - throw Error(`Discovered unexpected version-branch "${name}" for a release-train that is already active in the "${nextBranchName}" branch. Please either delete the branch if created by accident, or update the version in the next branch (${nextBranchName}).`); + [kParsePositionalNumbers](argv) { + const args = argv["--"] ? argv["--"] : argv._; + for (let i = 0, arg; (arg = args[i]) !== void 0; i++) { + if (__classPrivateFieldGet(this, _YargsInstance_shim, "f").Parser.looksLikeNumber(arg) && Number.isSafeInteger(Math.floor(parseFloat(`${arg}`)))) { + args[i] = Number(arg); + } } - const { version, isExceptionalMinor } = await getVersionInfoForBranch(repo, name); - const releaseTrain = new ReleaseTrain(name, version); - const isPrerelease = version.prerelease[0] === "rc" || version.prerelease[0] === "next"; - if (isExceptionalMinor) { - if (exceptionalMinor !== null) { - throw Error(`Unable to determine latest release-train. Found an additional exceptional minor version branch: "${name}". Already discovered: ${exceptionalMinor.branchName}.`); + return argv; + } + [kPkgUp](rootPath) { + const npath = rootPath || "*"; + if (__classPrivateFieldGet(this, _YargsInstance_pkgs, "f")[npath]) + return __classPrivateFieldGet(this, _YargsInstance_pkgs, "f")[npath]; + let obj = {}; + try { + let startDir = rootPath || __classPrivateFieldGet(this, _YargsInstance_shim, "f").mainFilename; + if (__classPrivateFieldGet(this, _YargsInstance_shim, "f").path.extname(startDir)) { + startDir = __classPrivateFieldGet(this, _YargsInstance_shim, "f").path.dirname(startDir); } - if (!checks.canHaveExceptionalMinor(releaseCandidate)) { - throw Error(`Unable to determine latest release-train. Found an unexpected exceptional minor version branch: "${name}". No exceptional minor is currently allowed.`); + const pkgJsonPath = __classPrivateFieldGet(this, _YargsInstance_shim, "f").findUp(startDir, (dir, names) => { + if (names.includes("package.json")) { + return "package.json"; + } else { + return void 0; + } + }); + assertNotStrictEqual(pkgJsonPath, void 0, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + obj = JSON.parse(__classPrivateFieldGet(this, _YargsInstance_shim, "f").readFileSync(pkgJsonPath, "utf8")); + } catch (_noop) { + } + __classPrivateFieldGet(this, _YargsInstance_pkgs, "f")[npath] = obj || {}; + return __classPrivateFieldGet(this, _YargsInstance_pkgs, "f")[npath]; + } + [kPopulateParserHintArray](type, keys) { + keys = [].concat(keys); + keys.forEach((key) => { + key = this[kSanitizeKey](key); + __classPrivateFieldGet(this, _YargsInstance_options, "f")[type].push(key); + }); + } + [kPopulateParserHintSingleValueDictionary](builder, type, key, value) { + this[kPopulateParserHintDictionary](builder, type, key, value, (type2, key2, value2) => { + __classPrivateFieldGet(this, _YargsInstance_options, "f")[type2][key2] = value2; + }); + } + [kPopulateParserHintArrayDictionary](builder, type, key, value) { + this[kPopulateParserHintDictionary](builder, type, key, value, (type2, key2, value2) => { + __classPrivateFieldGet(this, _YargsInstance_options, "f")[type2][key2] = (__classPrivateFieldGet(this, _YargsInstance_options, "f")[type2][key2] || []).concat(value2); + }); + } + [kPopulateParserHintDictionary](builder, type, key, value, singleKeyHandler) { + if (Array.isArray(key)) { + key.forEach((k) => { + builder(k, value); + }); + } else if (/* @__PURE__ */ ((key2) => typeof key2 === "object")(key)) { + for (const k of objectKeys(key)) { + builder(k, key[k]); } - if (!checks.isValidExceptionalMinorVersion(version, releaseCandidate)) { - throw Error(`Unable to determine latest release-train. Found an invalid exceptional minor version branch: "${name}". Invalid version: ${version}.`); + } else { + singleKeyHandler(type, this[kSanitizeKey](key), value); + } + } + [kSanitizeKey](key) { + if (key === "__proto__") + return "___proto___"; + return key; + } + [kSetKey](key, set) { + this[kPopulateParserHintSingleValueDictionary](this[kSetKey].bind(this), "key", key, set); + return this; + } + [kUnfreeze]() { + var _a2, _b2, _c2, _d, _e, _f, _g, _h, _j, _k, _l, _m; + const frozen = __classPrivateFieldGet(this, _YargsInstance_frozens, "f").pop(); + assertNotStrictEqual(frozen, void 0, __classPrivateFieldGet(this, _YargsInstance_shim, "f")); + let configObjects; + _a2 = this, _b2 = this, _c2 = this, _d = this, _e = this, _f = this, _g = this, _h = this, _j = this, _k = this, _l = this, _m = this, { + options: { set value(_o) { + __classPrivateFieldSet(_a2, _YargsInstance_options, _o, "f"); + } }.value, + configObjects, + exitProcess: { set value(_o) { + __classPrivateFieldSet(_b2, _YargsInstance_exitProcess, _o, "f"); + } }.value, + groups: { set value(_o) { + __classPrivateFieldSet(_c2, _YargsInstance_groups, _o, "f"); + } }.value, + output: { set value(_o) { + __classPrivateFieldSet(_d, _YargsInstance_output, _o, "f"); + } }.value, + exitError: { set value(_o) { + __classPrivateFieldSet(_e, _YargsInstance_exitError, _o, "f"); + } }.value, + hasOutput: { set value(_o) { + __classPrivateFieldSet(_f, _YargsInstance_hasOutput, _o, "f"); + } }.value, + parsed: this.parsed, + strict: { set value(_o) { + __classPrivateFieldSet(_g, _YargsInstance_strict, _o, "f"); + } }.value, + strictCommands: { set value(_o) { + __classPrivateFieldSet(_h, _YargsInstance_strictCommands, _o, "f"); + } }.value, + strictOptions: { set value(_o) { + __classPrivateFieldSet(_j, _YargsInstance_strictOptions, _o, "f"); + } }.value, + completionCommand: { set value(_o) { + __classPrivateFieldSet(_k, _YargsInstance_completionCommand, _o, "f"); + } }.value, + parseFn: { set value(_o) { + __classPrivateFieldSet(_l, _YargsInstance_parseFn, _o, "f"); + } }.value, + parseContext: { set value(_o) { + __classPrivateFieldSet(_m, _YargsInstance_parseContext, _o, "f"); + } }.value + } = frozen; + __classPrivateFieldGet(this, _YargsInstance_options, "f").configObjects = configObjects; + __classPrivateFieldGet(this, _YargsInstance_usage, "f").unfreeze(); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").unfreeze(); + __classPrivateFieldGet(this, _YargsInstance_command, "f").unfreeze(); + __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").unfreeze(); + } + [kValidateAsync](validation2, argv) { + return maybeAsyncResult(argv, (result) => { + validation2(result); + return result; + }); + } + getInternalMethods() { + return { + getCommandInstance: this[kGetCommandInstance].bind(this), + getContext: this[kGetContext].bind(this), + getHasOutput: this[kGetHasOutput].bind(this), + getLoggerInstance: this[kGetLoggerInstance].bind(this), + getParseContext: this[kGetParseContext].bind(this), + getParserConfiguration: this[kGetParserConfiguration].bind(this), + getUsageConfiguration: this[kGetUsageConfiguration].bind(this), + getUsageInstance: this[kGetUsageInstance].bind(this), + getValidationInstance: this[kGetValidationInstance].bind(this), + hasParseCallback: this[kHasParseCallback].bind(this), + isGlobalContext: this[kIsGlobalContext].bind(this), + postProcess: this[kPostProcess].bind(this), + reset: this[kReset].bind(this), + runValidation: this[kRunValidation].bind(this), + runYargsParserAndExecuteCommands: this[kRunYargsParserAndExecuteCommands].bind(this), + setHasOutput: this[kSetHasOutput].bind(this) + }; + } + [kGetCommandInstance]() { + return __classPrivateFieldGet(this, _YargsInstance_command, "f"); + } + [kGetContext]() { + return __classPrivateFieldGet(this, _YargsInstance_context, "f"); + } + [kGetHasOutput]() { + return __classPrivateFieldGet(this, _YargsInstance_hasOutput, "f"); + } + [kGetLoggerInstance]() { + return __classPrivateFieldGet(this, _YargsInstance_logger, "f"); + } + [kGetParseContext]() { + return __classPrivateFieldGet(this, _YargsInstance_parseContext, "f") || {}; + } + [kGetUsageInstance]() { + return __classPrivateFieldGet(this, _YargsInstance_usage, "f"); + } + [kGetValidationInstance]() { + return __classPrivateFieldGet(this, _YargsInstance_validation, "f"); + } + [kHasParseCallback]() { + return !!__classPrivateFieldGet(this, _YargsInstance_parseFn, "f"); + } + [kIsGlobalContext]() { + return __classPrivateFieldGet(this, _YargsInstance_isGlobalContext, "f"); + } + [kPostProcess](argv, populateDoubleDash, calledFromCommand, runGlobalMiddleware) { + if (calledFromCommand) + return argv; + if (isPromise(argv)) + return argv; + if (!populateDoubleDash) { + argv = this[kCopyDoubleDash](argv); + } + const parsePositionalNumbers = this[kGetParserConfiguration]()["parse-positional-numbers"] || this[kGetParserConfiguration]()["parse-positional-numbers"] === void 0; + if (parsePositionalNumbers) { + argv = this[kParsePositionalNumbers](argv); + } + if (runGlobalMiddleware) { + argv = applyMiddleware(argv, this, __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").getMiddleware(), false); + } + return argv; + } + [kReset](aliases = {}) { + __classPrivateFieldSet(this, _YargsInstance_options, __classPrivateFieldGet(this, _YargsInstance_options, "f") || {}, "f"); + const tmpOptions = {}; + tmpOptions.local = __classPrivateFieldGet(this, _YargsInstance_options, "f").local || []; + tmpOptions.configObjects = __classPrivateFieldGet(this, _YargsInstance_options, "f").configObjects || []; + const localLookup = {}; + tmpOptions.local.forEach((l) => { + localLookup[l] = true; + (aliases[l] || []).forEach((a) => { + localLookup[a] = true; + }); + }); + Object.assign(__classPrivateFieldGet(this, _YargsInstance_preservedGroups, "f"), Object.keys(__classPrivateFieldGet(this, _YargsInstance_groups, "f")).reduce((acc, groupName) => { + const keys = __classPrivateFieldGet(this, _YargsInstance_groups, "f")[groupName].filter((key) => !(key in localLookup)); + if (keys.length > 0) { + acc[groupName] = keys; + } + return acc; + }, {})); + __classPrivateFieldSet(this, _YargsInstance_groups, {}, "f"); + const arrayOptions = [ + "array", + "boolean", + "string", + "skipValidation", + "count", + "normalize", + "number", + "hiddenOptions" + ]; + const objectOptions = [ + "narg", + "key", + "alias", + "default", + "defaultDescription", + "config", + "choices", + "demandedOptions", + "demandedCommands", + "deprecatedOptions" + ]; + arrayOptions.forEach((k) => { + tmpOptions[k] = (__classPrivateFieldGet(this, _YargsInstance_options, "f")[k] || []).filter((k2) => !localLookup[k2]); + }); + objectOptions.forEach((k) => { + tmpOptions[k] = objFilter(__classPrivateFieldGet(this, _YargsInstance_options, "f")[k], (k2) => !localLookup[k2]); + }); + tmpOptions.envPrefix = __classPrivateFieldGet(this, _YargsInstance_options, "f").envPrefix; + __classPrivateFieldSet(this, _YargsInstance_options, tmpOptions, "f"); + __classPrivateFieldSet(this, _YargsInstance_usage, __classPrivateFieldGet(this, _YargsInstance_usage, "f") ? __classPrivateFieldGet(this, _YargsInstance_usage, "f").reset(localLookup) : usage(this, __classPrivateFieldGet(this, _YargsInstance_shim, "f")), "f"); + __classPrivateFieldSet(this, _YargsInstance_validation, __classPrivateFieldGet(this, _YargsInstance_validation, "f") ? __classPrivateFieldGet(this, _YargsInstance_validation, "f").reset(localLookup) : validation(this, __classPrivateFieldGet(this, _YargsInstance_usage, "f"), __classPrivateFieldGet(this, _YargsInstance_shim, "f")), "f"); + __classPrivateFieldSet(this, _YargsInstance_command, __classPrivateFieldGet(this, _YargsInstance_command, "f") ? __classPrivateFieldGet(this, _YargsInstance_command, "f").reset() : command(__classPrivateFieldGet(this, _YargsInstance_usage, "f"), __classPrivateFieldGet(this, _YargsInstance_validation, "f"), __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f"), __classPrivateFieldGet(this, _YargsInstance_shim, "f")), "f"); + if (!__classPrivateFieldGet(this, _YargsInstance_completion, "f")) + __classPrivateFieldSet(this, _YargsInstance_completion, completion(this, __classPrivateFieldGet(this, _YargsInstance_usage, "f"), __classPrivateFieldGet(this, _YargsInstance_command, "f"), __classPrivateFieldGet(this, _YargsInstance_shim, "f")), "f"); + __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").reset(); + __classPrivateFieldSet(this, _YargsInstance_completionCommand, null, "f"); + __classPrivateFieldSet(this, _YargsInstance_output, "", "f"); + __classPrivateFieldSet(this, _YargsInstance_exitError, null, "f"); + __classPrivateFieldSet(this, _YargsInstance_hasOutput, false, "f"); + this.parsed = false; + return this; + } + [kRebase](base, dir) { + return __classPrivateFieldGet(this, _YargsInstance_shim, "f").path.relative(base, dir); + } + [kRunYargsParserAndExecuteCommands](args, shortCircuit, calledFromCommand, commandIndex = 0, helpOnly = false) { + var _a2, _b2, _c2, _d; + let skipValidation = !!calledFromCommand || helpOnly; + args = args || __classPrivateFieldGet(this, _YargsInstance_processArgs, "f"); + __classPrivateFieldGet(this, _YargsInstance_options, "f").__ = __classPrivateFieldGet(this, _YargsInstance_shim, "f").y18n.__; + __classPrivateFieldGet(this, _YargsInstance_options, "f").configuration = this[kGetParserConfiguration](); + const populateDoubleDash = !!__classPrivateFieldGet(this, _YargsInstance_options, "f").configuration["populate--"]; + const config = Object.assign({}, __classPrivateFieldGet(this, _YargsInstance_options, "f").configuration, { + "populate--": true + }); + const parsed = __classPrivateFieldGet(this, _YargsInstance_shim, "f").Parser.detailed(args, Object.assign({}, __classPrivateFieldGet(this, _YargsInstance_options, "f"), { + configuration: { "parse-positional-numbers": false, ...config } + })); + const argv = Object.assign(parsed.argv, __classPrivateFieldGet(this, _YargsInstance_parseContext, "f")); + let argvPromise = void 0; + const aliases = parsed.aliases; + let helpOptSet = false; + let versionOptSet = false; + Object.keys(argv).forEach((key) => { + if (key === __classPrivateFieldGet(this, _YargsInstance_helpOpt, "f") && argv[key]) { + helpOptSet = true; + } else if (key === __classPrivateFieldGet(this, _YargsInstance_versionOpt, "f") && argv[key]) { + versionOptSet = true; } - exceptionalMinor = releaseTrain; - continue; + }); + argv.$0 = this.$0; + this.parsed = parsed; + if (commandIndex === 0) { + __classPrivateFieldGet(this, _YargsInstance_usage, "f").clearCachedHelpMessage(); } - if (isPrerelease) { - if (exceptionalMinor !== null) { - throw Error(`Unable to determine latest release-train. Discovered a feature-freeze/release-candidate version branch (${name}) that is older than an in-progress exceptional minor (${exceptionalMinor.branchName}).`); + try { + this[kGuessLocale](); + if (shortCircuit) { + return this[kPostProcess](argv, populateDoubleDash, !!calledFromCommand, false); + } + if (__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")) { + const helpCmds = [__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")].concat(aliases[__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")] || []).filter((k) => k.length > 1); + if (helpCmds.includes("" + argv._[argv._.length - 1])) { + argv._.pop(); + helpOptSet = true; + } + } + __classPrivateFieldSet(this, _YargsInstance_isGlobalContext, false, "f"); + const handlerKeys = __classPrivateFieldGet(this, _YargsInstance_command, "f").getCommands(); + const requestCompletions = ((_a2 = __classPrivateFieldGet(this, _YargsInstance_completion, "f")) === null || _a2 === void 0 ? void 0 : _a2.completionKey) ? [ + (_b2 = __classPrivateFieldGet(this, _YargsInstance_completion, "f")) === null || _b2 === void 0 ? void 0 : _b2.completionKey, + ...(_d = this.getAliases()[(_c2 = __classPrivateFieldGet(this, _YargsInstance_completion, "f")) === null || _c2 === void 0 ? void 0 : _c2.completionKey]) !== null && _d !== void 0 ? _d : [] + ].some((key) => Object.prototype.hasOwnProperty.call(argv, key)) : false; + const skipRecommendation = helpOptSet || requestCompletions || helpOnly; + if (argv._.length) { + if (handlerKeys.length) { + let firstUnknownCommand; + for (let i = commandIndex || 0, cmd; argv._[i] !== void 0; i++) { + cmd = String(argv._[i]); + if (handlerKeys.includes(cmd) && cmd !== __classPrivateFieldGet(this, _YargsInstance_completionCommand, "f")) { + const innerArgv = __classPrivateFieldGet(this, _YargsInstance_command, "f").runCommand(cmd, this, parsed, i + 1, helpOnly, helpOptSet || versionOptSet || helpOnly); + return this[kPostProcess](innerArgv, populateDoubleDash, !!calledFromCommand, false); + } else if (!firstUnknownCommand && cmd !== __classPrivateFieldGet(this, _YargsInstance_completionCommand, "f")) { + firstUnknownCommand = cmd; + break; + } + } + if (!__classPrivateFieldGet(this, _YargsInstance_command, "f").hasDefaultCommand() && __classPrivateFieldGet(this, _YargsInstance_recommendCommands, "f") && firstUnknownCommand && !skipRecommendation) { + __classPrivateFieldGet(this, _YargsInstance_validation, "f").recommendCommands(firstUnknownCommand, handlerKeys); + } + } + if (__classPrivateFieldGet(this, _YargsInstance_completionCommand, "f") && argv._.includes(__classPrivateFieldGet(this, _YargsInstance_completionCommand, "f")) && !requestCompletions) { + if (__classPrivateFieldGet(this, _YargsInstance_exitProcess, "f")) + setBlocking(true); + this.showCompletionScript(); + this.exit(0); + } } - if (releaseCandidate !== null) { - throw Error(`Unable to determine latest release-train. Found two consecutive pre-release version branches. No exceptional minors are allowed currently, and there cannot be multiple feature-freeze/release-candidate branches: "${name}".`); + if (__classPrivateFieldGet(this, _YargsInstance_command, "f").hasDefaultCommand() && !skipRecommendation) { + const innerArgv = __classPrivateFieldGet(this, _YargsInstance_command, "f").runCommand(null, this, parsed, 0, helpOnly, helpOptSet || versionOptSet || helpOnly); + return this[kPostProcess](innerArgv, populateDoubleDash, !!calledFromCommand, false); } - if (!checks.isValidReleaseCandidateVersion(version)) { - throw Error(`Discovered unexpected old feature-freeze/release-candidate branch. Expected no version-branch in feature-freeze/release-candidate mode for v${version.major}.`); + if (requestCompletions) { + if (__classPrivateFieldGet(this, _YargsInstance_exitProcess, "f")) + setBlocking(true); + args = [].concat(args); + const completionArgs = args.slice(args.indexOf(`--${__classPrivateFieldGet(this, _YargsInstance_completion, "f").completionKey}`) + 1); + __classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(completionArgs, (err, completions) => { + if (err) + throw new YError(err.message); + (completions || []).forEach((completion2) => { + __classPrivateFieldGet(this, _YargsInstance_logger, "f").log(completion2); + }); + this.exit(0); + }); + return this[kPostProcess](argv, !populateDoubleDash, !!calledFromCommand, false); + } + if (!__classPrivateFieldGet(this, _YargsInstance_hasOutput, "f")) { + if (helpOptSet) { + if (__classPrivateFieldGet(this, _YargsInstance_exitProcess, "f")) + setBlocking(true); + skipValidation = true; + this.showHelp((message) => { + __classPrivateFieldGet(this, _YargsInstance_logger, "f").log(message); + this.exit(0); + }); + } else if (versionOptSet) { + if (__classPrivateFieldGet(this, _YargsInstance_exitProcess, "f")) + setBlocking(true); + skipValidation = true; + __classPrivateFieldGet(this, _YargsInstance_usage, "f").showVersion("log"); + this.exit(0); + } + } + if (!skipValidation && __classPrivateFieldGet(this, _YargsInstance_options, "f").skipValidation.length > 0) { + skipValidation = Object.keys(argv).some((key) => __classPrivateFieldGet(this, _YargsInstance_options, "f").skipValidation.indexOf(key) >= 0 && argv[key] === true); + } + if (!skipValidation) { + if (parsed.error) + throw new YError(parsed.error.message); + if (!requestCompletions) { + const validation2 = this[kRunValidation](aliases, {}, parsed.error); + if (!calledFromCommand) { + argvPromise = applyMiddleware(argv, this, __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").getMiddleware(), true); + } + argvPromise = this[kValidateAsync](validation2, argvPromise !== null && argvPromise !== void 0 ? argvPromise : argv); + if (isPromise(argvPromise) && !calledFromCommand) { + argvPromise = argvPromise.then(() => { + return applyMiddleware(argv, this, __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").getMiddleware(), false); + }); + } + } + } + } catch (err) { + if (err instanceof YError) + __classPrivateFieldGet(this, _YargsInstance_usage, "f").fail(err.message, err); + else + throw err; + } + return this[kPostProcess](argvPromise !== null && argvPromise !== void 0 ? argvPromise : argv, populateDoubleDash, !!calledFromCommand, true); + } + [kRunValidation](aliases, positionalMap, parseErrors, isDefaultCommand) { + const demandedOptions = { ...this.getDemandedOptions() }; + return (argv) => { + if (parseErrors) + throw new YError(parseErrors.message); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").nonOptionCount(argv); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").requiredArguments(argv, demandedOptions); + let failedStrictCommands = false; + if (__classPrivateFieldGet(this, _YargsInstance_strictCommands, "f")) { + failedStrictCommands = __classPrivateFieldGet(this, _YargsInstance_validation, "f").unknownCommands(argv); + } + if (__classPrivateFieldGet(this, _YargsInstance_strict, "f") && !failedStrictCommands) { + __classPrivateFieldGet(this, _YargsInstance_validation, "f").unknownArguments(argv, aliases, positionalMap, !!isDefaultCommand); + } else if (__classPrivateFieldGet(this, _YargsInstance_strictOptions, "f")) { + __classPrivateFieldGet(this, _YargsInstance_validation, "f").unknownArguments(argv, aliases, {}, false, false); + } + __classPrivateFieldGet(this, _YargsInstance_validation, "f").limitedChoices(argv); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").implications(argv); + __classPrivateFieldGet(this, _YargsInstance_validation, "f").conflicting(argv); + }; + } + [kSetHasOutput]() { + __classPrivateFieldSet(this, _YargsInstance_hasOutput, true, "f"); + } + [kTrackManuallySetKeys](keys) { + if (typeof keys === "string") { + __classPrivateFieldGet(this, _YargsInstance_options, "f").key[keys] = true; + } else { + for (const k of keys) { + __classPrivateFieldGet(this, _YargsInstance_options, "f").key[k] = true; } - releaseCandidate = releaseTrain; - continue; } - latest = releaseTrain; - break; } - return { releaseCandidate, exceptionalMinor, latest }; +}; +function isYargsInstance(y) { + return !!y && typeof y.getInternalMethods === "function"; } // -var import_semver3 = __toESM(require_semver2(), 1); +var Yargs = YargsFactory(esm_default); // -var _npmPackageInfoCache = {}; -async function fetchProjectNpmPackageInfo(config) { - return await fetchPackageInfoFromNpmRegistry(config.representativeNpmPackage); +var LogLevel; +(function(LogLevel2) { + LogLevel2[LogLevel2["SILENT"] = 0] = "SILENT"; + LogLevel2[LogLevel2["ERROR"] = 1] = "ERROR"; + LogLevel2[LogLevel2["WARN"] = 2] = "WARN"; + LogLevel2[LogLevel2["LOG"] = 3] = "LOG"; + LogLevel2[LogLevel2["INFO"] = 4] = "INFO"; + LogLevel2[LogLevel2["DEBUG"] = 5] = "DEBUG"; +})(LogLevel || (LogLevel = {})); +var DEFAULT_LOG_LEVEL = LogLevel.INFO; +var red = styleText.bind(null, "red"); +var green = styleText.bind(null, "green"); +var yellow = styleText.bind(null, "yellow"); +var bold = styleText.bind(null, "bold"); +var blue = styleText.bind(null, "blue"); +var underline = styleText.bind(null, "underline"); +var Log = class { +}; +Log.info = buildLogLevelFunction(() => console.info, LogLevel.INFO, null); +Log.error = buildLogLevelFunction(() => console.error, LogLevel.ERROR, red); +Log.debug = buildLogLevelFunction(() => console.debug, LogLevel.DEBUG, null); +Log.log = buildLogLevelFunction(() => console.log, LogLevel.LOG, null); +Log.warn = buildLogLevelFunction(() => console.warn, LogLevel.WARN, yellow); +function buildLogLevelFunction(loadCommand, level, defaultColor) { + return (...values) => { + runConsoleCommand(loadCommand, level, ...values.map((v) => typeof v === "string" && defaultColor ? defaultColor(v) : v)); + }; } -async function fetchPackageInfoFromNpmRegistry(pkgName) { - if (_npmPackageInfoCache[pkgName] === void 0) { - _npmPackageInfoCache[pkgName] = fetch(`https://registry.npmjs.org/${pkgName}`).then((r) => r.json()); +function runConsoleCommand(loadCommand, logLevel, ...text) { + if (getLogLevel() >= logLevel) { + loadCommand()(...text); } - return await _npmPackageInfoCache[pkgName]; + appendToLogFile(logLevel, ...text); +} +function getLogLevel() { + const logLevel = Object.keys(LogLevel).indexOf((process.env[`LOG_LEVEL`] || "").toUpperCase()); + if (logLevel === -1) { + return DEFAULT_LOG_LEVEL; + } + return logLevel; +} +var LOG_LEVEL_COLUMNS = 7; +var logStream = void 0; +function appendToLogFile(logLevel, ...text) { + if (logStream === void 0) { + return; + } + if (logLevel === void 0) { + logStream.write(text.join(" ") + "\n"); + return; + } + const logLevelText = `${LogLevel[logLevel]}:`.padEnd(LOG_LEVEL_COLUMNS); + logStream.write(stripVTControlCharacters(text.join(" ").split("\n").map((l) => `${logLevelText} ${l} +`).join(""))); } // -var majorActiveSupportDuration = 6; -var majorLongTermSupportDuration = 12; -var ltsNpmDistTagRegex = /^v(\d+)-lts$/; -async function fetchLongTermSupportBranchesFromNpm(config) { - const { "dist-tags": distTags, time } = await fetchProjectNpmPackageInfo(config); - const today = new Date(); - const active = []; - const inactive = []; - for (const npmDistTag in distTags) { - if (isLtsDistTag(npmDistTag)) { - const version = import_semver3.default.parse(distTags[npmDistTag]); - const branchName = `${version.major}.${version.minor}.x`; - const majorReleaseDate = new Date(time[`${version.major}.0.0`]); - const ltsEndDate = computeLtsEndDateOfMajor(majorReleaseDate); - const ltsBranch = { name: branchName, version, npmDistTag }; - if (today <= ltsEndDate) { - active.push(ltsBranch); - } else { - inactive.push(ltsBranch); - } +var cachedConfig = null; +function setCachedConfig(config) { + cachedConfig = config; +} +function getCachedConfig() { + return cachedConfig; +} + +// +import { pathToFileURL } from "url"; +var CONFIG_FILE_PATH_MATCHER = ".ng-dev/config.mjs"; +var setConfig = setCachedConfig; +async function getConfig(baseDirOrAssertions) { + let cachedConfig2 = getCachedConfig(); + if (cachedConfig2 === null) { + let baseDir; + if (typeof baseDirOrAssertions === "string") { + baseDir = baseDirOrAssertions; + } else { + baseDir = determineRepoBaseDirFromCwd(); + } + const configPath = join3(baseDir, CONFIG_FILE_PATH_MATCHER); + cachedConfig2 = await readConfigFile(configPath); + setCachedConfig(cachedConfig2); + } + if (Array.isArray(baseDirOrAssertions)) { + for (const assertion of baseDirOrAssertions) { + assertion(cachedConfig2); + } + } + return { ...cachedConfig2, __isNgDevConfigObject: true }; +} +var ConfigValidationError = class extends Error { + constructor(message, errors = []) { + super(message); + this.errors = errors; + } +}; +function assertValidGithubConfig(config) { + const errors = []; + if (config.github === void 0) { + errors.push(`Github repository not configured. Set the "github" option.`); + } else { + if (config.github.name === void 0) { + errors.push(`"github.name" is not defined`); + } + if (config.github.owner === void 0) { + errors.push(`"github.owner" is not defined`); } } - active.sort((a, b) => import_semver3.default.rcompare(a.version, b.version)); - inactive.sort((a, b) => import_semver3.default.rcompare(a.version, b.version)); - return { active, inactive }; -} -function isLtsDistTag(tagName) { - return ltsNpmDistTagRegex.test(tagName); + if (errors.length) { + throw new ConfigValidationError("Invalid `github` configuration", errors); + } } -function computeLtsEndDateOfMajor(majorReleaseDate) { - return new Date(majorReleaseDate.getFullYear(), majorReleaseDate.getMonth() + majorActiveSupportDuration + majorLongTermSupportDuration, majorReleaseDate.getDate(), majorReleaseDate.getHours(), majorReleaseDate.getMinutes(), majorReleaseDate.getSeconds(), majorReleaseDate.getMilliseconds()); +async function readConfigFile(configPath, returnEmptyObjectOnError = false) { + try { + return await import(pathToFileURL(configPath).toString()); + } catch (e) { + if (returnEmptyObjectOnError) { + Log.debug(`Could not read configuration file at ${configPath}, returning empty object instead.`); + Log.debug(e); + return {}; + } + Log.error(`Could not read configuration file at ${configPath}.`); + Log.error(e); + process.exit(1); + } } // -var import_typed_graphqlify = __toESM(require_dist(), 1); -var findOwnedForksOfRepoQuery = (0, import_typed_graphqlify.params)({ - $owner: "String!", - $name: "String!" -}, { - repository: (0, import_typed_graphqlify.params)({ owner: "$owner", name: "$name" }, { - forks: (0, import_typed_graphqlify.params)({ affiliations: "OWNER", first: 1, orderBy: { field: "NAME", direction: "ASC" } }, { - nodes: [ - { - owner: { - login: import_typed_graphqlify.types.string - }, - name: import_typed_graphqlify.types.string - } - ] - }) - }) -}); - -// -function isDryRun() { - return process.env["DRY_RUN"] !== void 0; -} -var DryRunError = class extends Error { - constructor() { - super("Cannot call this function in dryRun mode."); +var ScopeRequirement; +(function(ScopeRequirement2) { + ScopeRequirement2[ScopeRequirement2["Required"] = 0] = "Required"; + ScopeRequirement2[ScopeRequirement2["Optional"] = 1] = "Optional"; + ScopeRequirement2[ScopeRequirement2["Forbidden"] = 2] = "Forbidden"; +})(ScopeRequirement || (ScopeRequirement = {})); +var ReleaseNotesLevel; +(function(ReleaseNotesLevel2) { + ReleaseNotesLevel2[ReleaseNotesLevel2["Hidden"] = 0] = "Hidden"; + ReleaseNotesLevel2[ReleaseNotesLevel2["Visible"] = 1] = "Visible"; +})(ReleaseNotesLevel || (ReleaseNotesLevel = {})); +var COMMIT_TYPES = { + build: { + name: "build", + description: "Changes to local repository build system and tooling", + scope: ScopeRequirement.Optional, + releaseNotesLevel: ReleaseNotesLevel.Hidden + }, + ci: { + name: "ci", + description: "Changes to CI configuration and CI specific tooling", + scope: ScopeRequirement.Forbidden, + releaseNotesLevel: ReleaseNotesLevel.Hidden + }, + docs: { + name: "docs", + description: "Changes which exclusively affects documentation.", + scope: ScopeRequirement.Optional, + releaseNotesLevel: ReleaseNotesLevel.Hidden + }, + feat: { + name: "feat", + description: "Creates a new feature", + scope: ScopeRequirement.Required, + releaseNotesLevel: ReleaseNotesLevel.Visible + }, + fix: { + name: "fix", + description: "Fixes a previously discovered failure/bug", + scope: ScopeRequirement.Required, + releaseNotesLevel: ReleaseNotesLevel.Visible + }, + perf: { + name: "perf", + description: "Improves performance without any change in functionality or API", + scope: ScopeRequirement.Required, + releaseNotesLevel: ReleaseNotesLevel.Visible + }, + refactor: { + name: "refactor", + description: "Refactor without any change in functionality or API (includes style changes)", + scope: ScopeRequirement.Optional, + releaseNotesLevel: ReleaseNotesLevel.Hidden + }, + release: { + name: "release", + description: "A release point in the repository", + scope: ScopeRequirement.Forbidden, + releaseNotesLevel: ReleaseNotesLevel.Hidden + }, + test: { + name: "test", + description: "Improvements or corrections made to the project's test suite", + scope: ScopeRequirement.Optional, + releaseNotesLevel: ReleaseNotesLevel.Hidden } }; // -import { spawnSync as spawnSync2 } from "child_process"; +var createTypedObject = (LabelConstructor) => { + return (val) => { + for (const key in val) { + val[key] = new LabelConstructor(val[key]); + } + return val; + }; +}; +var Label = class { + constructor(params2) { + this.params = params2; + this.repositories = this.params.repositories || [ + ManagedRepositories.ANGULAR, + ManagedRepositories.ANGULAR_CLI, + ManagedRepositories.COMPONENTS, + ManagedRepositories.DEV_INFRA + ]; + this.name = this.params.name; + this.description = this.params.description; + this.color = this.params.color; + } +}; +var ManagedRepositories; +(function(ManagedRepositories2) { + ManagedRepositories2["COMPONENTS"] = "components"; + ManagedRepositories2["ANGULAR"] = "angular"; + ManagedRepositories2["ANGULAR_CLI"] = "angular-cli"; + ManagedRepositories2["DEV_INFRA"] = "dev-infra"; +})(ManagedRepositories || (ManagedRepositories = {})); // -function getUserAgent() { - if (typeof navigator === "object" && "userAgent" in navigator) { - return navigator.userAgent; +var ManagedLabel = class extends Label { + constructor() { + super(...arguments); + this.commitCheck = this.params.commitCheck; } - if (typeof process === "object" && process.version !== void 0) { - return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; +}; +var managedLabels = createTypedObject(ManagedLabel)({ + DETECTED_BREAKING_CHANGE: { + description: "PR contains a commit with a breaking change", + name: "detected: breaking change", + commitCheck: (c) => c.breakingChanges.length !== 0 + }, + DETECTED_DEPRECATION: { + description: "PR contains a commit with a deprecation", + name: "detected: deprecation", + commitCheck: (c) => c.deprecations.length !== 0 + }, + DETECTED_FEATURE: { + description: "PR contains a feature commit", + name: "detected: feature", + commitCheck: (c) => c.type === "feat" + }, + DETECTED_DOCS_CHANGE: { + description: "Related to the documentation", + name: "area: docs", + commitCheck: (c) => c.type === "docs" + }, + DETECTED_INFRA_CHANGE: { + description: "Related the build and CI infrastructure of the project", + name: "area: build & ci", + commitCheck: (c) => c.type === "build" || c.type === "ci" + }, + DETECTED_PERF_CHANGE: { + description: "Issues related to performance", + name: "area: performance", + commitCheck: (c) => c.type === "perf" + }, + DETECTED_HTTP_CHANGE: { + description: "Issues related to HTTP and HTTP Client", + name: "area: common/http", + commitCheck: (c) => c.scope === "common/http" || c.scope === "http", + repositories: [ManagedRepositories.ANGULAR] + }, + DETECTED_COMPILER_CHANGE: { + description: "Issues related to `ngc`, Angular's template compiler", + name: "area: compiler", + commitCheck: (c) => c.scope === "compiler" || c.scope === "compiler-cli", + repositories: [ManagedRepositories.ANGULAR] + }, + DETECTED_PLATFORM_BROWSER_CHANGE: { + description: "Issues related to the framework runtime", + name: "area: core", + commitCheck: (c) => c.scope === "platform-browser" || c.scope === "core" || c.scope === "platform-browser-dynamic", + repositories: [ManagedRepositories.ANGULAR] + }, + DETECTED_PLATFORM_SERVER_CHANGE: { + description: "Issues related to server-side rendering", + name: "area: server", + commitCheck: (c) => c.scope === "platform-server", + repositories: [ManagedRepositories.ANGULAR] + }, + DETECTED_ZONES_CHANGE: { + description: "Issues related to zone.js", + name: "area: zones", + commitCheck: (c) => c.scope === "zone.js", + repositories: [ManagedRepositories.ANGULAR] + }, + DETECTED_LOCALIZE_CHANGE: { + description: "Issues related to localization and internationalization", + name: "area: i18n", + commitCheck: (c) => c.scope === "localize", + repositories: [ManagedRepositories.ANGULAR] } - return ""; -} +}); // -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - if (!options) { - options = {}; - } - if (Array.isArray(name)) { - return name.reverse().reduce((callback, name2) => { - return register.bind(null, state, name2, callback, options); - }, method)(); +var ActionLabel = class extends Label { +}; +var actionLabels = createTypedObject(ActionLabel)({ + ACTION_MERGE: { + description: "The PR is ready for merge by the caretaker", + name: "action: merge" + }, + ACTION_CLEANUP: { + description: "The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews", + name: "action: cleanup" + }, + ACTION_PRESUBMIT: { + description: "The PR is in need of a google3 presubmit", + name: "action: presubmit" + }, + ACTION_GLOBAL_PRESUBMIT: { + description: "The PR is in need of a google3 global presubmit", + name: "action: global presubmit" + }, + ACTION_REVIEW: { + description: "The PR is still awaiting reviews from at least one requested reviewer", + name: "action: review" } - return Promise.resolve().then(() => { - if (!state.registry[name]) { - return method(options); - } - return state.registry[name].reduce((method2, registered) => { - return registered.hook.bind(null, method2, options); - }, method)(); - }); -} +}); // -function addHook(state, kind, name, hook2) { - const orig = hook2; - if (!state.registry[name]) { - state.registry[name] = []; - } - if (kind === "before") { - hook2 = (method, options) => { - return Promise.resolve().then(orig.bind(null, options)).then(method.bind(null, options)); - }; - } - if (kind === "after") { - hook2 = (method, options) => { - let result; - return Promise.resolve().then(method.bind(null, options)).then((result_) => { - result = result_; - return orig(result, options); - }).then(() => { - return result; - }); - }; - } - if (kind === "error") { - hook2 = (method, options) => { - return Promise.resolve().then(method.bind(null, options)).catch((error) => { - return orig(error, options); - }); - }; +var MergeLabel = class extends Label { +}; +var mergeLabels = createTypedObject(MergeLabel)({ + MERGE_PRESERVE_COMMITS: { + description: "When the PR is merged, a rebase and merge should be performed", + name: "merge: preserve commits" + }, + MERGE_SQUASH_COMMITS: { + description: "When the PR is merged, a squash and merge should be performed", + name: "merge: squash commits" + }, + MERGE_FIX_COMMIT_MESSAGE: { + description: "When the PR is merged, rewrites/fixups of the commit messages are needed", + name: "merge: fix commit message", + repositories: [ManagedRepositories.COMPONENTS, ManagedRepositories.ANGULAR_CLI] + }, + MERGE_CARETAKER_NOTE: { + description: "Alert the caretaker performing the merge to check the PR for an out of normal action needed or note", + name: "merge: caretaker note" } - state.registry[name].push({ - hook: hook2, - orig - }); -} +}); // -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; +var TargetLabel = class extends Label { + constructor() { + super(...arguments); + this.__hasTargetLabelMarker__ = true; } - const index = state.registry[name].map((registered) => { - return registered.orig; - }).indexOf(method); - if (index === -1) { - return; +}; +var targetLabels = createTypedObject(TargetLabel)({ + TARGET_AUTOMATION: { + description: "This PR is targeted to only merge into the branch defined in Github [bot use only]", + name: "target: automation" + }, + TARGET_FEATURE: { + description: "This PR is targeted for a feature branch (outside of main and semver branches)", + name: "target: feature" + }, + TARGET_LTS: { + description: "This PR is targeting a version currently in long-term support", + name: "target: lts" + }, + TARGET_MAJOR: { + description: "This PR is targeted for the next major release", + name: "target: major" + }, + TARGET_MINOR: { + description: "This PR is targeted for the next minor release", + name: "target: minor" + }, + TARGET_PATCH: { + description: "This PR is targeted for the next patch release", + name: "target: patch" + }, + TARGET_RC: { + description: "This PR is targeted for the next release-candidate", + name: "target: rc" } - state.registry[name].splice(index, 1); -} - -// -var bind = Function.bind; -var bindable = bind.bind(bind); -function bindApi(hook2, state, name) { - const removeHookRef = bindable(removeHook, null).apply( - null, - name ? [state, name] : [state] - ); - hook2.api = { remove: removeHookRef }; - hook2.remove = removeHookRef; - ["before", "error", "after", "wrap"].forEach((kind) => { - const args = name ? [state, kind, name] : [state, kind]; - hook2[kind] = hook2.api[kind] = bindable(addHook, null).apply(null, args); - }); -} -function Singular() { - const singularHookName = Symbol("Singular"); - const singularHookState = { - registry: {} - }; - const singularHook = register.bind(null, singularHookState, singularHookName); - bindApi(singularHook, singularHookState, singularHookName); - return singularHook; -} -function Collection() { - const state = { - registry: {} - }; - const hook2 = register.bind(null, state); - bindApi(hook2, state); - return hook2; -} -var before_after_hook_default = { Singular, Collection }; +}); // -var VERSION = "0.0.0-development"; -var userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`; -var DEFAULTS = { - method: "GET", - baseUrl: "https://api.github.com", - headers: { - accept: "application/vnd.github.v3+json", - "user-agent": userAgent +var PriorityLabel = class extends Label { +}; +var priorityLabels = createTypedObject(PriorityLabel)({ + P0: { + name: "P0", + description: "Issue that causes an outage, breakage, or major function to be unusable, with no known workarounds" }, - mediaType: { - format: "" + P1: { + name: "P1", + description: "Impacts a large percentage of users; if a workaround exists it is partial or overly painful" + }, + P2: { + name: "P2", + description: "The issue is important to a large percentage of users, with a workaround" + }, + P3: { + name: "P3", + description: "An issue that is relevant to core functions, but does not impede progress. Important, but not urgent" + }, + P4: { + name: "P4", + description: "A relatively minor issue that is not relevant to core functions" + }, + P5: { + name: "P5", + description: "The team acknowledges the request but does not plan to address it, it remains open for discussion" } +}); + +// +var FeatureLabel = class extends Label { }; -function lowercaseKeys(object) { - if (!object) { - return {}; - } - return Object.keys(object).reduce((newObj, key) => { - newObj[key.toLowerCase()] = object[key]; - return newObj; - }, {}); -} -function isPlainObject(value) { - if (typeof value !== "object" || value === null) - return false; - if (Object.prototype.toString.call(value) !== "[object Object]") - return false; - const proto2 = Object.getPrototypeOf(value); - if (proto2 === null) - return true; - const Ctor = Object.prototype.hasOwnProperty.call(proto2, "constructor") && proto2.constructor; - return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value); -} -function mergeDeep(defaults, options) { - const result = Object.assign({}, defaults); - Object.keys(options).forEach((key) => { - if (isPlainObject(options[key])) { - if (!(key in defaults)) - Object.assign(result, { [key]: options[key] }); - else - result[key] = mergeDeep(defaults[key], options[key]); - } else { - Object.assign(result, { [key]: options[key] }); - } - }); - return result; -} -function removeUndefinedProperties(obj) { - for (const key in obj) { - if (obj[key] === void 0) { - delete obj[key]; - } - } - return obj; -} -function merge(defaults, route, options) { - if (typeof route === "string") { - let [method, url] = route.split(" "); - options = Object.assign(url ? { method, url } : { url: method }, options); - } else { - options = Object.assign({}, route); - } - options.headers = lowercaseKeys(options.headers); - removeUndefinedProperties(options); - removeUndefinedProperties(options.headers); - const mergedOptions = mergeDeep(defaults || {}, options); - if (options.url === "/graphql") { - if (defaults && defaults.mediaType.previews?.length) { - mergedOptions.mediaType.previews = defaults.mediaType.previews.filter( - (preview) => !mergedOptions.mediaType.previews.includes(preview) - ).concat(mergedOptions.mediaType.previews); - } - mergedOptions.mediaType.previews = (mergedOptions.mediaType.previews || []).map((preview) => preview.replace(/-preview/, "")); - } - return mergedOptions; -} -function addQueryParameters(url, parameters) { - const separator = /\?/.test(url) ? "&" : "?"; - const names = Object.keys(parameters); - if (names.length === 0) { - return url; +var featureLabels = createTypedObject(FeatureLabel)({ + FEATURE_IN_BACKLOG: { + name: "feature: in backlog", + description: "Feature request for which voting has completed and is now in the backlog" + }, + FEATURE_VOTES_REQUIRED: { + name: "feature: votes required", + description: "Feature request which is currently still in the voting phase" + }, + FEATURE_UNDER_CONSIDERATION: { + name: "feature: under consideration", + description: "Feature request for which voting has completed and the request is now under consideration" + }, + FEATURE_INSUFFICIENT_VOTES: { + name: "feature: insufficient votes", + description: "Label to add when the not a sufficient number of votes or comments from unique authors" } - return url + separator + names.map((name) => { - if (name === "q") { - return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+"); - } - return `${name}=${encodeURIComponent(parameters[name])}`; - }).join("&"); -} -var urlVariableRegex = /\{[^{}}]+\}/g; -function removeNonChars(variableName) { - return variableName.replace(/(?:^\W+)|(?:(? a.concat(b), []); -} -function omit(object, keysToOmit) { - const result = { __proto__: null }; - for (const key of Object.keys(object)) { - if (keysToOmit.indexOf(key) === -1) { - result[key] = object[key]; - } +}); + +// +var allLabels = { + ...managedLabels, + ...actionLabels, + ...mergeLabels, + ...targetLabels, + ...priorityLabels, + ...featureLabels, + ...requiresLabels +}; + +// +var import_semver2 = __toESM(require_semver2()); + +// +var ReleaseTrain = class { + constructor(branchName, version) { + this.branchName = branchName; + this.version = version; + this.isMajor = this.version.minor === 0 && this.version.patch === 0; } - return result; -} -function encodeReserved(str) { - return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) { - if (!/%[0-9A-Fa-f]/.test(part)) { - part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); - } - return part; - }).join(""); -} -function encodeUnreserved(str) { - return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { - return "%" + c.charCodeAt(0).toString(16).toUpperCase(); +}; + +// +var import_semver = __toESM(require_semver2()); +var versionBranchNameRegex = /^(\d+)\.(\d+)\.x$/; +var exceptionalMinorPackageIndicator = "__ngDevExceptionalMinor__"; +async function getVersionInfoForBranch(repo, branchName) { + const { data } = await repo.api.repos.getContent({ + owner: repo.owner, + repo: repo.name, + path: "/package.json", + ref: branchName }); -} -function encodeValue(operator, value, key) { - value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); - if (key) { - return encodeUnreserved(key) + "=" + value; - } else { - return value; + const content = data.content; + if (!content) { + throw Error(`Unable to read "package.json" file from repository.`); } + const pkgJson = JSON.parse(Buffer.from(content, "base64").toString()); + const parsedVersion = import_semver.default.parse(pkgJson.version); + if (parsedVersion === null) { + throw Error(`Invalid version detected in following branch: ${branchName}.`); + } + return { + version: parsedVersion, + isExceptionalMinor: pkgJson[exceptionalMinorPackageIndicator] === true + }; } -function isDefined(value) { - return value !== void 0 && value !== null; -} -function isKeyOperator(operator) { - return operator === ";" || operator === "&" || operator === "?"; +function isVersionBranch(branchName) { + return versionBranchNameRegex.test(branchName); } -function getValues(context2, operator, key, modifier) { - var value = context2[key], result = []; - if (isDefined(value) && value !== "") { - if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { - value = value.toString(); - if (modifier && modifier !== "*") { - value = value.substring(0, parseInt(modifier, 10)); - } - result.push( - encodeValue(operator, value, isKeyOperator(operator) ? key : "") - ); - } else { - if (modifier === "*") { - if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { - result.push( - encodeValue(operator, value2, isKeyOperator(operator) ? key : "") - ); - }); - } else { - Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { - result.push(encodeValue(operator, value[k], k)); - } - }); - } - } else { - const tmp = []; - if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { - tmp.push(encodeValue(operator, value2)); - }); - } else { - Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { - tmp.push(encodeUnreserved(k)); - tmp.push(encodeValue(operator, value[k].toString())); - } - }); - } - if (isKeyOperator(operator)) { - result.push(encodeUnreserved(key) + "=" + tmp.join(",")); - } else if (tmp.length !== 0) { - result.push(tmp.join(",")); - } - } +async function getBranchesForMajorVersions(repo, majorVersions) { + const branchData = await repo.api.paginate(repo.api.repos.listBranches, { + owner: repo.owner, + repo: repo.name, + protected: true + }); + const branches = []; + for (const { name } of branchData) { + if (!isVersionBranch(name)) { + continue; } - } else { - if (operator === ";") { - if (isDefined(value)) { - result.push(encodeUnreserved(key)); - } - } else if (value === "" && (operator === "&" || operator === "?")) { - result.push(encodeUnreserved(key) + "="); - } else if (value === "") { - result.push(""); + const parsed = convertVersionBranchToSemVer(name); + if (parsed !== null && majorVersions.includes(parsed.major)) { + branches.push({ name, parsed }); } } - return result; + return branches.sort((a, b) => import_semver.default.rcompare(a.parsed, b.parsed)); } -function parseUrl(template) { - return { - expand: expand.bind(null, template) - }; +function convertVersionBranchToSemVer(branchName) { + return import_semver.default.parse(branchName.replace(versionBranchNameRegex, "$1.$2.0")); } -function expand(template, context2) { - var operators = ["+", "#", ".", "/", ";", "?", "&"]; - template = template.replace( - /\{([^\{\}]+)\}|([^\{\}]+)/g, - function(_, expression, literal) { - if (expression) { - let operator = ""; - const values = []; - if (operators.indexOf(expression.charAt(0)) !== -1) { - operator = expression.charAt(0); - expression = expression.substr(1); - } - expression.split(/,/g).forEach(function(variable) { - var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); - values.push(getValues(context2, operator, tmp[1], tmp[2] || tmp[3])); - }); - if (operator && operator !== "+") { - var separator = ","; - if (operator === "?") { - separator = "&"; - } else if (operator !== "#") { - separator = operator; - } - return (values.length !== 0 ? operator : "") + values.join(separator); - } else { - return values.join(","); - } - } else { - return encodeReserved(literal); - } - } - ); - if (template === "/") { - return template; + +// +var ActiveReleaseTrains = class { + constructor(trains) { + this.trains = trains; + this.releaseCandidate = this.trains.releaseCandidate; + this.next = this.trains.next; + this.latest = this.trains.latest; + this.exceptionalMinor = this.trains.exceptionalMinor; + } + isFeatureFreeze() { + return this.releaseCandidate !== null && this.releaseCandidate.version.prerelease[0] === "next"; + } + static async fetch(repo) { + return fetchActiveReleaseTrains(repo); + } +}; +async function fetchActiveReleaseTrains(repo) { + const nextBranchName = repo.nextBranchName; + const { version: nextVersion } = await getVersionInfoForBranch(repo, nextBranchName); + const next = new ReleaseTrain(nextBranchName, nextVersion); + const majorVersionsToFetch = []; + const checks = { + canHaveExceptionalMinor: () => false, + isValidReleaseCandidateVersion: () => false, + isValidExceptionalMinorVersion: () => false + }; + if (nextVersion.minor === 0) { + majorVersionsToFetch.push(nextVersion.major - 1, nextVersion.major - 2); + checks.isValidReleaseCandidateVersion = (v) => v.major === nextVersion.major - 1; + checks.canHaveExceptionalMinor = (rc) => rc === null || rc.isMajor; + checks.isValidExceptionalMinorVersion = (v, rc) => v.major === (rc === null ? nextVersion.major : rc.version.major) - 1; + } else if (nextVersion.minor === 1) { + majorVersionsToFetch.push(nextVersion.major, nextVersion.major - 1); + checks.isValidReleaseCandidateVersion = (v) => v.major === nextVersion.major; + checks.canHaveExceptionalMinor = (rc) => rc !== null && rc.isMajor; + checks.isValidExceptionalMinorVersion = (v, rc) => v.major === rc.version.major - 1; } else { - return template.replace(/\/$/, ""); + majorVersionsToFetch.push(nextVersion.major); + checks.isValidReleaseCandidateVersion = (v) => v.major === nextVersion.major; + checks.canHaveExceptionalMinor = () => false; } -} -function parse(options) { - let method = options.method.toUpperCase(); - let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); - let headers = Object.assign({}, options.headers); - let body; - let parameters = omit(options, [ - "method", - "baseUrl", - "url", - "headers", - "request", - "mediaType" - ]); - const urlVariableNames = extractUrlVariableNames(url); - url = parseUrl(url).expand(parameters); - if (!/^http/.test(url)) { - url = options.baseUrl + url; + const branches = await getBranchesForMajorVersions(repo, majorVersionsToFetch); + const { latest, releaseCandidate, exceptionalMinor } = await findActiveReleaseTrainsFromVersionBranches(repo, next, branches, checks); + if (latest === null) { + throw Error(`Unable to determine the latest release-train. The following branches have been considered: [${branches.map((b) => b.name).join(", ")}]`); } - const omittedParameters = Object.keys(options).filter((option) => urlVariableNames.includes(option)).concat("baseUrl"); - const remainingParameters = omit(parameters, omittedParameters); - const isBinaryRequest = /application\/octet-stream/i.test(headers.accept); - if (!isBinaryRequest) { - if (options.mediaType.format) { - headers.accept = headers.accept.split(/,/).map( - (format) => format.replace( - /application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, - `application/vnd$1$2.${options.mediaType.format}` - ) - ).join(","); + return new ActiveReleaseTrains({ releaseCandidate, next, latest, exceptionalMinor }); +} +async function findActiveReleaseTrainsFromVersionBranches(repo, next, branches, checks) { + const nextReleaseTrainVersion = import_semver2.default.parse(`${next.version.major}.${next.version.minor}.0`); + const nextBranchName = repo.nextBranchName; + let latest = null; + let releaseCandidate = null; + let exceptionalMinor = null; + for (const { name, parsed } of branches) { + if (import_semver2.default.gt(parsed, nextReleaseTrainVersion)) { + throw Error(`Discovered unexpected version-branch "${name}" for a release-train that is more recent than the release-train currently in the "${nextBranchName}" branch. Please either delete the branch if created by accident, or update the outdated version in the next branch (${nextBranchName}).`); + } else if (import_semver2.default.eq(parsed, nextReleaseTrainVersion)) { + throw Error(`Discovered unexpected version-branch "${name}" for a release-train that is already active in the "${nextBranchName}" branch. Please either delete the branch if created by accident, or update the version in the next branch (${nextBranchName}).`); } - if (url.endsWith("/graphql")) { - if (options.mediaType.previews?.length) { - const previewsFromAcceptHeader = headers.accept.match(/(? { - const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; - return `application/vnd.github.${preview}-preview${format}`; - }).join(","); + const { version, isExceptionalMinor } = await getVersionInfoForBranch(repo, name); + const releaseTrain = new ReleaseTrain(name, version); + const isPrerelease = version.prerelease[0] === "rc" || version.prerelease[0] === "next"; + if (isExceptionalMinor) { + if (exceptionalMinor !== null) { + throw Error(`Unable to determine latest release-train. Found an additional exceptional minor version branch: "${name}". Already discovered: ${exceptionalMinor.branchName}.`); + } + if (!checks.canHaveExceptionalMinor(releaseCandidate)) { + throw Error(`Unable to determine latest release-train. Found an unexpected exceptional minor version branch: "${name}". No exceptional minor is currently allowed.`); } + if (!checks.isValidExceptionalMinorVersion(version, releaseCandidate)) { + throw Error(`Unable to determine latest release-train. Found an invalid exceptional minor version branch: "${name}". Invalid version: ${version}.`); + } + exceptionalMinor = releaseTrain; + continue; } - } - if (["GET", "HEAD"].includes(method)) { - url = addQueryParameters(url, remainingParameters); - } else { - if ("data" in remainingParameters) { - body = remainingParameters.data; - } else { - if (Object.keys(remainingParameters).length) { - body = remainingParameters; + if (isPrerelease) { + if (exceptionalMinor !== null) { + throw Error(`Unable to determine latest release-train. Discovered a feature-freeze/release-candidate version branch (${name}) that is older than an in-progress exceptional minor (${exceptionalMinor.branchName}).`); + } + if (releaseCandidate !== null) { + throw Error(`Unable to determine latest release-train. Found two consecutive pre-release version branches. No exceptional minors are allowed currently, and there cannot be multiple feature-freeze/release-candidate branches: "${name}".`); } + if (!checks.isValidReleaseCandidateVersion(version)) { + throw Error(`Discovered unexpected old feature-freeze/release-candidate branch. Expected no version-branch in feature-freeze/release-candidate mode for v${version.major}.`); + } + releaseCandidate = releaseTrain; + continue; } + latest = releaseTrain; + break; } - if (!headers["content-type"] && typeof body !== "undefined") { - headers["content-type"] = "application/json; charset=utf-8"; - } - if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") { - body = ""; - } - return Object.assign( - { method, url, headers }, - typeof body !== "undefined" ? { body } : null, - options.request ? { request: options.request } : null - ); -} -function endpointWithDefaults(defaults, route, options) { - return parse(merge(defaults, route, options)); -} -function withDefaults(oldDefaults, newDefaults) { - const DEFAULTS22 = merge(oldDefaults, newDefaults); - const endpoint22 = endpointWithDefaults.bind(null, DEFAULTS22); - return Object.assign(endpoint22, { - DEFAULTS: DEFAULTS22, - defaults: withDefaults.bind(null, DEFAULTS22), - merge: merge.bind(null, DEFAULTS22), - parse - }); + return { releaseCandidate, exceptionalMinor, latest }; } -var endpoint = withDefaults(null, DEFAULTS); // -var import_fast_content_type_parse = __toESM(require_fast_content_type_parse(), 1); +var import_semver3 = __toESM(require_semver2()); // -var RequestError = class extends Error { - name; - status; - request; - response; - constructor(message, statusCode, options) { - super(message); - this.name = "HttpError"; - this.status = Number.parseInt(statusCode); - if (Number.isNaN(this.status)) { - this.status = 0; - } - if ("response" in options) { - this.response = options.response; - } - const requestCopy = Object.assign({}, options.request); - if (options.request.headers.authorization) { - requestCopy.headers = Object.assign({}, options.request.headers, { - authorization: options.request.headers.authorization.replace( - /(? r.json()); } -}; + return await _npmPackageInfoCache[pkgName]; +} // -var VERSION2 = "0.0.0-development"; -var defaults_default = { - headers: { - "user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}` - } -}; -function isPlainObject2(value) { - if (typeof value !== "object" || value === null) - return false; - if (Object.prototype.toString.call(value) !== "[object Object]") - return false; - const proto2 = Object.getPrototypeOf(value); - if (proto2 === null) - return true; - const Ctor = Object.prototype.hasOwnProperty.call(proto2, "constructor") && proto2.constructor; - return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value); -} -async function fetchWrapper(requestOptions) { - const fetch2 = requestOptions.request?.fetch || globalThis.fetch; - if (!fetch2) { - throw new Error( - "fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing" - ); - } - const log = requestOptions.request?.log || console; - const parseSuccessResponseBody = requestOptions.request?.parseSuccessResponseBody !== false; - const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body; - const requestHeaders = Object.fromEntries( - Object.entries(requestOptions.headers).map(([name, value]) => [ - name, - String(value) - ]) - ); - let fetchResponse; - try { - fetchResponse = await fetch2(requestOptions.url, { - method: requestOptions.method, - body, - redirect: requestOptions.request?.redirect, - headers: requestHeaders, - signal: requestOptions.request?.signal, - ...requestOptions.body && { duplex: "half" } - }); - } catch (error) { - let message = "Unknown Error"; - if (error instanceof Error) { - if (error.name === "AbortError") { - error.status = 500; - throw error; - } - message = error.message; - if (error.name === "TypeError" && "cause" in error) { - if (error.cause instanceof Error) { - message = error.cause.message; - } else if (typeof error.cause === "string") { - message = error.cause; - } +var majorActiveSupportDuration = 6; +var majorLongTermSupportDuration = 12; +var ltsNpmDistTagRegex = /^v(\d+)-lts$/; +async function fetchLongTermSupportBranchesFromNpm(config) { + const { "dist-tags": distTags, time } = await fetchProjectNpmPackageInfo(config); + const today = /* @__PURE__ */ new Date(); + const active = []; + const inactive = []; + for (const npmDistTag in distTags) { + if (isLtsDistTag(npmDistTag)) { + const version = import_semver3.default.parse(distTags[npmDistTag]); + const branchName = `${version.major}.${version.minor}.x`; + const majorReleaseDate = new Date(time[`${version.major}.0.0`]); + const ltsEndDate = computeLtsEndDateOfMajor(majorReleaseDate); + const ltsBranch = { name: branchName, version, npmDistTag }; + if (today <= ltsEndDate) { + active.push(ltsBranch); + } else { + inactive.push(ltsBranch); } } - const requestError = new RequestError(message, 500, { - request: requestOptions - }); - requestError.cause = error; - throw requestError; - } - const status = fetchResponse.status; - const url = fetchResponse.url; - const responseHeaders = {}; - for (const [key, value] of fetchResponse.headers) { - responseHeaders[key] = value; } - const octokitResponse = { - url, - status, - headers: responseHeaders, - data: "" - }; - if ("deprecation" in responseHeaders) { - const matches = responseHeaders.link && responseHeaders.link.match(/<([^<>]+)>; rel="deprecation"/); - const deprecationLink = matches && matches.pop(); - log.warn( - `[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${responseHeaders.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}` - ); + active.sort((a, b) => import_semver3.default.rcompare(a.version, b.version)); + inactive.sort((a, b) => import_semver3.default.rcompare(a.version, b.version)); + return { active, inactive }; +} +function isLtsDistTag(tagName) { + return ltsNpmDistTagRegex.test(tagName); +} +function computeLtsEndDateOfMajor(majorReleaseDate) { + return new Date(majorReleaseDate.getFullYear(), majorReleaseDate.getMonth() + majorActiveSupportDuration + majorLongTermSupportDuration, majorReleaseDate.getDate(), majorReleaseDate.getHours(), majorReleaseDate.getMinutes(), majorReleaseDate.getSeconds(), majorReleaseDate.getMilliseconds()); +} + +// +var import_typed_graphqlify = __toESM(require_dist()); +var findOwnedForksOfRepoQuery = (0, import_typed_graphqlify.params)({ + $owner: "String!", + $name: "String!" +}, { + repository: (0, import_typed_graphqlify.params)({ owner: "$owner", name: "$name" }, { + forks: (0, import_typed_graphqlify.params)({ affiliations: "OWNER", first: 1, orderBy: { field: "NAME", direction: "ASC" } }, { + nodes: [ + { + owner: { + login: import_typed_graphqlify.types.string + }, + name: import_typed_graphqlify.types.string + } + ] + }) + }) +}); + +// +function isDryRun() { + return process.env["DRY_RUN"] !== void 0; +} +var DryRunError = class extends Error { + constructor() { + super("Cannot call this function in dryRun mode."); } - if (status === 204 || status === 205) { - return octokitResponse; +}; + +// +import { spawnSync as spawnSync2 } from "child_process"; + +// +function getUserAgent() { + if (typeof navigator === "object" && "userAgent" in navigator) { + return navigator.userAgent; } - if (requestOptions.method === "HEAD") { - if (status < 400) { - return octokitResponse; - } - throw new RequestError(fetchResponse.statusText, status, { - response: octokitResponse, - request: requestOptions - }); + if (typeof process === "object" && process.version !== void 0) { + return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; } - if (status === 304) { - octokitResponse.data = await getResponseData(fetchResponse); - throw new RequestError("Not modified", status, { - response: octokitResponse, - request: requestOptions - }); + return ""; +} + +// +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } - if (status >= 400) { - octokitResponse.data = await getResponseData(fetchResponse); - throw new RequestError(toErrorMessage(octokitResponse.data), status, { - response: octokitResponse, - request: requestOptions - }); + if (!options) { + options = {}; } - octokitResponse.data = parseSuccessResponseBody ? await getResponseData(fetchResponse) : fetchResponse.body; - return octokitResponse; -} -async function getResponseData(response) { - const contentType = response.headers.get("content-type"); - if (!contentType) { - return response.text().catch(() => ""); + if (Array.isArray(name)) { + return name.reverse().reduce((callback, name2) => { + return register.bind(null, state, name2, callback, options); + }, method)(); } - const mimetype = (0, import_fast_content_type_parse.safeParse)(contentType); - if (isJSONResponse(mimetype)) { - let text = ""; - try { - text = await response.text(); - return JSON.parse(text); - } catch (err) { - return text; + return Promise.resolve().then(() => { + if (!state.registry[name]) { + return method(options); } - } else if (mimetype.type.startsWith("text/") || mimetype.parameters.charset?.toLowerCase() === "utf-8") { - return response.text().catch(() => ""); - } else { - return response.arrayBuffer().catch(() => new ArrayBuffer(0)); - } -} -function isJSONResponse(mimetype) { - return mimetype.type === "application/json" || mimetype.type === "application/scim+json"; + return state.registry[name].reduce((method2, registered) => { + return registered.hook.bind(null, method2, options); + }, method)(); + }); } -function toErrorMessage(data) { - if (typeof data === "string") { - return data; + +// +function addHook(state, kind, name, hook2) { + const orig = hook2; + if (!state.registry[name]) { + state.registry[name] = []; } - if (data instanceof ArrayBuffer) { - return "Unknown error"; + if (kind === "before") { + hook2 = (method, options) => { + return Promise.resolve().then(orig.bind(null, options)).then(method.bind(null, options)); + }; } - if ("message" in data) { - const suffix = "documentation_url" in data ? ` - ${data.documentation_url}` : ""; - return Array.isArray(data.errors) ? `${data.message}: ${data.errors.map((v) => JSON.stringify(v)).join(", ")}${suffix}` : `${data.message}${suffix}`; + if (kind === "after") { + hook2 = (method, options) => { + let result; + return Promise.resolve().then(method.bind(null, options)).then((result_) => { + result = result_; + return orig(result, options); + }).then(() => { + return result; + }); + }; } - return `Unknown error: ${JSON.stringify(data)}`; -} -function withDefaults2(oldEndpoint, newDefaults) { - const endpoint22 = oldEndpoint.defaults(newDefaults); - const newApi = function(route, parameters) { - const endpointOptions = endpoint22.merge(route, parameters); - if (!endpointOptions.request || !endpointOptions.request.hook) { - return fetchWrapper(endpoint22.parse(endpointOptions)); - } - const request22 = (route2, parameters2) => { - return fetchWrapper( - endpoint22.parse(endpoint22.merge(route2, parameters2)) - ); + if (kind === "error") { + hook2 = (method, options) => { + return Promise.resolve().then(method.bind(null, options)).catch((error) => { + return orig(error, options); + }); }; - Object.assign(request22, { - endpoint: endpoint22, - defaults: withDefaults2.bind(null, endpoint22) - }); - return endpointOptions.request.hook(request22, endpointOptions); - }; - return Object.assign(newApi, { - endpoint: endpoint22, - defaults: withDefaults2.bind(null, endpoint22) + } + state.registry[name].push({ + hook: hook2, + orig }); } -var request = withDefaults2(endpoint, defaults_default); // -function getUserAgent2() { - if (typeof navigator === "object" && "userAgent" in navigator) { - return navigator.userAgent; +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; } - if (typeof process === "object" && process.version !== void 0) { - return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; + const index = state.registry[name].map((registered) => { + return registered.orig; + }).indexOf(method); + if (index === -1) { + return; } - return ""; + state.registry[name].splice(index, 1); } // -var VERSION3 = "0.0.0-development"; -var userAgent2 = `octokit-endpoint.js/${VERSION3} ${getUserAgent2()}`; -var DEFAULTS2 = { +var bind = Function.bind; +var bindable = bind.bind(bind); +function bindApi(hook2, state, name) { + const removeHookRef = bindable(removeHook, null).apply( + null, + name ? [state, name] : [state] + ); + hook2.api = { remove: removeHookRef }; + hook2.remove = removeHookRef; + ["before", "error", "after", "wrap"].forEach((kind) => { + const args = name ? [state, kind, name] : [state, kind]; + hook2[kind] = hook2.api[kind] = bindable(addHook, null).apply(null, args); + }); +} +function Singular() { + const singularHookName = Symbol("Singular"); + const singularHookState = { + registry: {} + }; + const singularHook = register.bind(null, singularHookState, singularHookName); + bindApi(singularHook, singularHookState, singularHookName); + return singularHook; +} +function Collection() { + const state = { + registry: {} + }; + const hook2 = register.bind(null, state); + bindApi(hook2, state); + return hook2; +} +var before_after_hook_default = { Singular, Collection }; + +// +var VERSION = "0.0.0-development"; +var userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`; +var DEFAULTS = { method: "GET", baseUrl: "https://api.github.com", headers: { accept: "application/vnd.github.v3+json", - "user-agent": userAgent2 + "user-agent": userAgent }, mediaType: { format: "" } }; -function lowercaseKeys2(object) { +function lowercaseKeys(object) { if (!object) { return {}; } @@ -26732,21 +31854,21 @@ function lowercaseKeys2(object) { return newObj; }, {}); } -function isPlainObject3(value) { +function isPlainObject(value) { if (typeof value !== "object" || value === null) return false; if (Object.prototype.toString.call(value) !== "[object Object]") return false; - const proto2 = Object.getPrototypeOf(value); - if (proto2 === null) + const proto = Object.getPrototypeOf(value); + if (proto === null) return true; - const Ctor = Object.prototype.hasOwnProperty.call(proto2, "constructor") && proto2.constructor; + const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor; return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value); } function mergeDeep2(defaults, options) { const result = Object.assign({}, defaults); Object.keys(options).forEach((key) => { - if (isPlainObject3(options[key])) { + if (isPlainObject(options[key])) { if (!(key in defaults)) Object.assign(result, { [key]: options[key] }); else @@ -26757,7 +31879,7 @@ function mergeDeep2(defaults, options) { }); return result; } -function removeUndefinedProperties2(obj) { +function removeUndefinedProperties(obj) { for (const key in obj) { if (obj[key] === void 0) { delete obj[key]; @@ -26765,16 +31887,16 @@ function removeUndefinedProperties2(obj) { } return obj; } -function merge2(defaults, route, options) { +function merge(defaults, route, options) { if (typeof route === "string") { let [method, url] = route.split(" "); options = Object.assign(url ? { method, url } : { url: method }, options); } else { options = Object.assign({}, route); } - options.headers = lowercaseKeys2(options.headers); - removeUndefinedProperties2(options); - removeUndefinedProperties2(options.headers); + options.headers = lowercaseKeys(options.headers); + removeUndefinedProperties(options); + removeUndefinedProperties(options.headers); const mergedOptions = mergeDeep2(defaults || {}, options); if (options.url === "/graphql") { if (defaults && defaults.mediaType.previews?.length) { @@ -26786,7 +31908,7 @@ function merge2(defaults, route, options) { } return mergedOptions; } -function addQueryParameters2(url, parameters) { +function addQueryParameters(url, parameters) { const separator = /\?/.test(url) ? "&" : "?"; const names = Object.keys(parameters); if (names.length === 0) { @@ -26799,18 +31921,18 @@ function addQueryParameters2(url, parameters) { return `${name}=${encodeURIComponent(parameters[name])}`; }).join("&"); } -var urlVariableRegex2 = /\{[^{}}]+\}/g; -function removeNonChars2(variableName) { +var urlVariableRegex = /\{[^{}}]+\}/g; +function removeNonChars(variableName) { return variableName.replace(/(?:^\W+)|(?:(? a.concat(b), []); + return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []); } -function omit2(object, keysToOmit) { +function omit(object, keysToOmit) { const result = { __proto__: null }; for (const key of Object.keys(object)) { if (keysToOmit.indexOf(key) === -1) { @@ -26819,7 +31941,7 @@ function omit2(object, keysToOmit) { } return result; } -function encodeReserved2(str) { +function encodeReserved(str) { return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) { if (!/%[0-9A-Fa-f]/.test(part)) { part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); @@ -26827,67 +31949,67 @@ function encodeReserved2(str) { return part; }).join(""); } -function encodeUnreserved2(str) { +function encodeUnreserved(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return "%" + c.charCodeAt(0).toString(16).toUpperCase(); }); } -function encodeValue2(operator, value, key) { - value = operator === "+" || operator === "#" ? encodeReserved2(value) : encodeUnreserved2(value); +function encodeValue(operator, value, key) { + value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); if (key) { - return encodeUnreserved2(key) + "=" + value; + return encodeUnreserved(key) + "=" + value; } else { return value; } } -function isDefined2(value) { +function isDefined(value) { return value !== void 0 && value !== null; } -function isKeyOperator2(operator) { +function isKeyOperator(operator) { return operator === ";" || operator === "&" || operator === "?"; } -function getValues2(context2, operator, key, modifier) { +function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined2(value) && value !== "") { + if (isDefined(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { value = value.substring(0, parseInt(modifier, 10)); } result.push( - encodeValue2(operator, value, isKeyOperator2(operator) ? key : "") + encodeValue(operator, value, isKeyOperator(operator) ? key : "") ); } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined2).forEach(function(value2) { + value.filter(isDefined).forEach(function(value2) { result.push( - encodeValue2(operator, value2, isKeyOperator2(operator) ? key : "") + encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined2(value[k])) { - result.push(encodeValue2(operator, value[k], k)); + if (isDefined(value[k])) { + result.push(encodeValue(operator, value[k], k)); } }); } } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined2).forEach(function(value2) { - tmp.push(encodeValue2(operator, value2)); + value.filter(isDefined).forEach(function(value2) { + tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined2(value[k])) { - tmp.push(encodeUnreserved2(k)); - tmp.push(encodeValue2(operator, value[k].toString())); + if (isDefined(value[k])) { + tmp.push(encodeUnreserved(k)); + tmp.push(encodeValue(operator, value[k].toString())); } }); } - if (isKeyOperator2(operator)) { - result.push(encodeUnreserved2(key) + "=" + tmp.join(",")); + if (isKeyOperator(operator)) { + result.push(encodeUnreserved(key) + "=" + tmp.join(",")); } else if (tmp.length !== 0) { result.push(tmp.join(",")); } @@ -26895,23 +32017,23 @@ function getValues2(context2, operator, key, modifier) { } } else { if (operator === ";") { - if (isDefined2(value)) { - result.push(encodeUnreserved2(key)); + if (isDefined(value)) { + result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { - result.push(encodeUnreserved2(key) + "="); + result.push(encodeUnreserved(key) + "="); } else if (value === "") { result.push(""); } } return result; } -function parseUrl2(template) { +function parseUrl(template) { return { - expand: expand2.bind(null, template) + expand: expand.bind(null, template) }; } -function expand2(template, context2) { +function expand(template, context2) { var operators = ["+", "#", ".", "/", ";", "?", "&"]; template = template.replace( /\{([^\{\}]+)\}|([^\{\}]+)/g, @@ -26925,7 +32047,7 @@ function expand2(template, context2) { } expression.split(/,/g).forEach(function(variable) { var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); - values.push(getValues2(context2, operator, tmp[1], tmp[2] || tmp[3])); + values.push(getValues(context2, operator, tmp[1], tmp[2] || tmp[3])); }); if (operator && operator !== "+") { var separator = ","; @@ -26939,7 +32061,7 @@ function expand2(template, context2) { return values.join(","); } } else { - return encodeReserved2(literal); + return encodeReserved(literal); } } ); @@ -26949,12 +32071,12 @@ function expand2(template, context2) { return template.replace(/\/$/, ""); } } -function parse2(options) { +function parse(options) { let method = options.method.toUpperCase(); let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); let headers = Object.assign({}, options.headers); let body; - let parameters = omit2(options, [ + let parameters = omit(options, [ "method", "baseUrl", "url", @@ -26962,18 +32084,18 @@ function parse2(options) { "request", "mediaType" ]); - const urlVariableNames = extractUrlVariableNames2(url); - url = parseUrl2(url).expand(parameters); + const urlVariableNames = extractUrlVariableNames(url); + url = parseUrl(url).expand(parameters); if (!/^http/.test(url)) { url = options.baseUrl + url; } const omittedParameters = Object.keys(options).filter((option) => urlVariableNames.includes(option)).concat("baseUrl"); - const remainingParameters = omit2(parameters, omittedParameters); + const remainingParameters = omit(parameters, omittedParameters); const isBinaryRequest = /application\/octet-stream/i.test(headers.accept); if (!isBinaryRequest) { if (options.mediaType.format) { headers.accept = headers.accept.split(/,/).map( - (format) => format.replace( + (format3) => format3.replace( /application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}` ) @@ -26983,14 +32105,14 @@ function parse2(options) { if (options.mediaType.previews?.length) { const previewsFromAcceptHeader = headers.accept.match(/(? { - const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; - return `application/vnd.github.${preview}-preview${format}`; + const format3 = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; + return `application/vnd.github.${preview}-preview${format3}`; }).join(","); } } } if (["GET", "HEAD"].includes(method)) { - url = addQueryParameters2(url, remainingParameters); + url = addQueryParameters(url, remainingParameters); } else { if ("data" in remainingParameters) { body = remainingParameters.data; @@ -27012,32 +32134,41 @@ function parse2(options) { options.request ? { request: options.request } : null ); } -function endpointWithDefaults2(defaults, route, options) { - return parse2(merge2(defaults, route, options)); +function endpointWithDefaults(defaults, route, options) { + return parse(merge(defaults, route, options)); } -function withDefaults3(oldDefaults, newDefaults) { - const DEFAULTS22 = merge2(oldDefaults, newDefaults); - const endpoint22 = endpointWithDefaults2.bind(null, DEFAULTS22); - return Object.assign(endpoint22, { - DEFAULTS: DEFAULTS22, - defaults: withDefaults3.bind(null, DEFAULTS22), - merge: merge2.bind(null, DEFAULTS22), - parse: parse2 +function withDefaults(oldDefaults, newDefaults) { + const DEFAULTS2 = merge(oldDefaults, newDefaults); + const endpoint2 = endpointWithDefaults.bind(null, DEFAULTS2); + return Object.assign(endpoint2, { + DEFAULTS: DEFAULTS2, + defaults: withDefaults.bind(null, DEFAULTS2), + merge: merge.bind(null, DEFAULTS2), + parse }); } -var endpoint2 = withDefaults3(null, DEFAULTS2); +var endpoint = withDefaults(null, DEFAULTS); // -var import_fast_content_type_parse2 = __toESM(require_fast_content_type_parse(), 1); +var import_fast_content_type_parse = __toESM(require_fast_content_type_parse()); // -var RequestError2 = class extends Error { +var RequestError = class extends Error { name; + /** + * http status code + */ status; + /** + * Request options that lead to the error. + */ request; + /** + * Response object if a response was received + */ response; constructor(message, statusCode, options) { - super(message); + super(message, { cause: options.cause }); this.name = "HttpError"; this.status = Number.parseInt(statusCode); if (Number.isNaN(this.status)) { @@ -27061,24 +32192,25 @@ var RequestError2 = class extends Error { }; // -var VERSION4 = "0.0.0-development"; -var defaults_default2 = { +var VERSION2 = "10.0.7"; +var defaults_default = { headers: { - "user-agent": `octokit-request.js/${VERSION4} ${getUserAgent2()}` + "user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}` } }; -function isPlainObject4(value) { +function isPlainObject2(value) { if (typeof value !== "object" || value === null) return false; if (Object.prototype.toString.call(value) !== "[object Object]") return false; - const proto2 = Object.getPrototypeOf(value); - if (proto2 === null) + const proto = Object.getPrototypeOf(value); + if (proto === null) return true; - const Ctor = Object.prototype.hasOwnProperty.call(proto2, "constructor") && proto2.constructor; + const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor; return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value); } -async function fetchWrapper2(requestOptions) { +var noop = () => ""; +async function fetchWrapper(requestOptions) { const fetch2 = requestOptions.request?.fetch || globalThis.fetch; if (!fetch2) { throw new Error( @@ -27087,7 +32219,7 @@ async function fetchWrapper2(requestOptions) { } const log = requestOptions.request?.log || console; const parseSuccessResponseBody = requestOptions.request?.parseSuccessResponseBody !== false; - const body = isPlainObject4(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body; + const body = isPlainObject2(requestOptions.body) || Array.isArray(requestOptions.body) ? JSON.stringify(requestOptions.body) : requestOptions.body; const requestHeaders = Object.fromEntries( Object.entries(requestOptions.headers).map(([name, value]) => [ name, @@ -27102,6 +32234,8 @@ async function fetchWrapper2(requestOptions) { redirect: requestOptions.request?.redirect, headers: requestHeaders, signal: requestOptions.request?.signal, + // duplex must be set if request.body is ReadableStream or Async Iterables. + // See https://fetch.spec.whatwg.org/#dom-requestinit-duplex. ...requestOptions.body && { duplex: "half" } }); } catch (error) { @@ -27120,7 +32254,7 @@ async function fetchWrapper2(requestOptions) { } } } - const requestError = new RequestError2(message, 500, { + const requestError = new RequestError(message, 500, { request: requestOptions }); requestError.cause = error; @@ -27152,35 +32286,35 @@ async function fetchWrapper2(requestOptions) { if (status < 400) { return octokitResponse; } - throw new RequestError2(fetchResponse.statusText, status, { + throw new RequestError(fetchResponse.statusText, status, { response: octokitResponse, request: requestOptions }); } if (status === 304) { - octokitResponse.data = await getResponseData2(fetchResponse); - throw new RequestError2("Not modified", status, { + octokitResponse.data = await getResponseData(fetchResponse); + throw new RequestError("Not modified", status, { response: octokitResponse, request: requestOptions }); } if (status >= 400) { - octokitResponse.data = await getResponseData2(fetchResponse); - throw new RequestError2(toErrorMessage2(octokitResponse.data), status, { + octokitResponse.data = await getResponseData(fetchResponse); + throw new RequestError(toErrorMessage(octokitResponse.data), status, { response: octokitResponse, request: requestOptions }); } - octokitResponse.data = parseSuccessResponseBody ? await getResponseData2(fetchResponse) : fetchResponse.body; + octokitResponse.data = parseSuccessResponseBody ? await getResponseData(fetchResponse) : fetchResponse.body; return octokitResponse; } -async function getResponseData2(response) { +async function getResponseData(response) { const contentType = response.headers.get("content-type"); if (!contentType) { - return response.text().catch(() => ""); + return response.text().catch(noop); } - const mimetype = (0, import_fast_content_type_parse2.safeParse)(contentType); - if (isJSONResponse2(mimetype)) { + const mimetype = (0, import_fast_content_type_parse.safeParse)(contentType); + if (isJSONResponse(mimetype)) { let text = ""; try { text = await response.text(); @@ -27189,15 +32323,18 @@ async function getResponseData2(response) { return text; } } else if (mimetype.type.startsWith("text/") || mimetype.parameters.charset?.toLowerCase() === "utf-8") { - return response.text().catch(() => ""); + return response.text().catch(noop); } else { - return response.arrayBuffer().catch(() => new ArrayBuffer(0)); + return response.arrayBuffer().catch( + /* v8 ignore next -- @preserve */ + () => new ArrayBuffer(0) + ); } } -function isJSONResponse2(mimetype) { +function isJSONResponse(mimetype) { return mimetype.type === "application/json" || mimetype.type === "application/scim+json"; } -function toErrorMessage2(data) { +function toErrorMessage(data) { if (typeof data === "string") { return data; } @@ -27210,41 +32347,41 @@ function toErrorMessage2(data) { } return `Unknown error: ${JSON.stringify(data)}`; } -function withDefaults4(oldEndpoint, newDefaults) { - const endpoint22 = oldEndpoint.defaults(newDefaults); +function withDefaults2(oldEndpoint, newDefaults) { + const endpoint2 = oldEndpoint.defaults(newDefaults); const newApi = function(route, parameters) { - const endpointOptions = endpoint22.merge(route, parameters); + const endpointOptions = endpoint2.merge(route, parameters); if (!endpointOptions.request || !endpointOptions.request.hook) { - return fetchWrapper2(endpoint22.parse(endpointOptions)); + return fetchWrapper(endpoint2.parse(endpointOptions)); } - const request22 = (route2, parameters2) => { - return fetchWrapper2( - endpoint22.parse(endpoint22.merge(route2, parameters2)) + const request2 = (route2, parameters2) => { + return fetchWrapper( + endpoint2.parse(endpoint2.merge(route2, parameters2)) ); }; - Object.assign(request22, { - endpoint: endpoint22, - defaults: withDefaults4.bind(null, endpoint22) + Object.assign(request2, { + endpoint: endpoint2, + defaults: withDefaults2.bind(null, endpoint2) }); - return endpointOptions.request.hook(request22, endpointOptions); + return endpointOptions.request.hook(request2, endpointOptions); }; return Object.assign(newApi, { - endpoint: endpoint22, - defaults: withDefaults4.bind(null, endpoint22) + endpoint: endpoint2, + defaults: withDefaults2.bind(null, endpoint2) }); } -var request2 = withDefaults4(endpoint2, defaults_default2); +var request = withDefaults2(endpoint, defaults_default); // -var VERSION5 = "0.0.0-development"; +var VERSION3 = "0.0.0-development"; function _buildMessageForResponseErrors(data) { return `Request failed due to following response errors: ` + data.errors.map((e) => ` - ${e.message}`).join("\n"); } var GraphqlResponseError = class extends Error { - constructor(request22, headers, response) { + constructor(request2, headers, response) { super(_buildMessageForResponseErrors(response)); - this.request = request22; + this.request = request2; this.headers = headers; this.response = response; this.errors = response.errors; @@ -27269,7 +32406,7 @@ var NON_VARIABLE_OPTIONS = [ ]; var FORBIDDEN_VARIABLE_OPTIONS = ["query", "method", "url"]; var GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/; -function graphql(request22, query2, options) { +function graphql(request2, query2, options) { if (options) { if (typeof query2 === "string" && "query" in options) { return Promise.reject( @@ -27300,11 +32437,11 @@ function graphql(request22, query2, options) { result.variables[key] = parsedOptions[key]; return result; }, {}); - const baseUrl = parsedOptions.baseUrl || request22.endpoint.DEFAULTS.baseUrl; + const baseUrl = parsedOptions.baseUrl || request2.endpoint.DEFAULTS.baseUrl; if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) { requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql"); } - return request22(requestOptions).then((response) => { + return request2(requestOptions).then((response) => { if (response.data.errors) { const headers = {}; for (const key of Object.keys(response.headers)) { @@ -27319,25 +32456,25 @@ function graphql(request22, query2, options) { return response.data.data; }); } -function withDefaults5(request22, newDefaults) { - const newRequest = request22.defaults(newDefaults); +function withDefaults3(request2, newDefaults) { + const newRequest = request2.defaults(newDefaults); const newApi = (query2, options) => { return graphql(newRequest, query2, options); }; return Object.assign(newApi, { - defaults: withDefaults5.bind(null, newRequest), + defaults: withDefaults3.bind(null, newRequest), endpoint: newRequest.endpoint }); } -var graphql2 = withDefaults5(request2, { +var graphql2 = withDefaults3(request, { headers: { - "user-agent": `octokit-graphql.js/${VERSION5} ${getUserAgent2()}` + "user-agent": `octokit-graphql.js/${VERSION3} ${getUserAgent()}` }, method: "POST", url: "/graphql" }); function withCustomRequest(customRequest) { - return withDefaults5(customRequest, { + return withDefaults3(customRequest, { method: "POST", url: "/graphql" }); @@ -27365,13 +32502,13 @@ function withAuthorizationPrefix(token) { } return `token ${token}`; } -async function hook(token, request3, route, parameters) { - const endpoint3 = request3.endpoint.merge( +async function hook(token, request2, route, parameters) { + const endpoint2 = request2.endpoint.merge( route, parameters ); - endpoint3.headers.authorization = withAuthorizationPrefix(token); - return request3(endpoint3); + endpoint2.headers.authorization = withAuthorizationPrefix(token); + return request2(endpoint2); } var createTokenAuth = function createTokenAuth2(token) { if (!token) { @@ -27389,15 +32526,31 @@ var createTokenAuth = function createTokenAuth2(token) { }; // -var VERSION6 = "6.1.5"; +var VERSION4 = "7.0.6"; // -var noop = () => { +var noop2 = () => { }; var consoleWarn = console.warn.bind(console); var consoleError = console.error.bind(console); -var userAgentTrail = `octokit-core.js/${VERSION6} ${getUserAgent()}`; +function createLogger(logger = {}) { + if (typeof logger.debug !== "function") { + logger.debug = noop2; + } + if (typeof logger.info !== "function") { + logger.info = noop2; + } + if (typeof logger.warn !== "function") { + logger.warn = consoleWarn; + } + if (typeof logger.error !== "function") { + logger.error = consoleError; + } + return logger; +} +var userAgentTrail = `octokit-core.js/${VERSION4} ${getUserAgent()}`; var Octokit = class { + static VERSION = VERSION4; static defaults(defaults) { const OctokitWithDefaults = class extends this { constructor(...args) { @@ -27420,6 +32573,13 @@ var Octokit = class { }; return OctokitWithDefaults; } + static plugins = []; + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ static plugin(...newPlugins) { const currentPlugins = this.plugins; const NewOctokit = class extends this { @@ -27435,6 +32595,7 @@ var Octokit = class { baseUrl: request.endpoint.DEFAULTS.baseUrl, headers: {}, request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type hook: hook2.bind(null, "request") }), mediaType: { @@ -27454,15 +32615,7 @@ var Octokit = class { } this.request = request.defaults(requestDefaults); this.graphql = withCustomRequest(this.request).defaults(requestDefaults); - this.log = Object.assign( - { - debug: noop, - info: noop, - warn: consoleWarn, - error: consoleError - }, - options.log - ); + this.log = createLogger(options.log); this.hook = hook2; if (!options.authStrategy) { if (!options.auth) { @@ -27481,6 +32634,11 @@ var Octokit = class { { request: this.request, log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. octokit: this, octokitOptions: otherOptions }, @@ -27495,26 +32653,26 @@ var Octokit = class { Object.assign(this, classConstructor.plugins[i](this, options)); } } + // assigned during constructor request; graphql; log; hook; + // TODO: type `octokit.auth` based on passed options.authStrategy auth; }; -__publicField(Octokit, "VERSION", VERSION6); -__publicField(Octokit, "plugins", []); // -var VERSION7 = "5.3.1"; +var VERSION5 = "6.0.0"; // function requestLog(octokit) { - octokit.hook.wrap("request", (request3, options) => { + octokit.hook.wrap("request", (request2, options) => { octokit.log.debug("request", options); const start = Date.now(); const requestOptions = octokit.request.endpoint.parse(options); const path = requestOptions.url.replace(options.baseUrl, ""); - return request3(options).then((response) => { + return request2(options).then((response) => { const requestId = response.headers["x-github-request-id"]; octokit.log.info( `${requestOptions.method} ${path} - ${response.status} with id ${requestId} in ${Date.now() - start}ms` @@ -27529,10 +32687,10 @@ function requestLog(octokit) { }); }); } -requestLog.VERSION = VERSION7; +requestLog.VERSION = VERSION5; // -var VERSION8 = "0.0.0-development"; +var VERSION6 = "0.0.0-development"; function normalizePaginatedListResponse(response) { if (!response.data) { return { @@ -27540,15 +32698,17 @@ function normalizePaginatedListResponse(response) { data: [] }; } - const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data); + const responseNeedsNormalization = ("total_count" in response.data || "total_commits" in response.data) && !("url" in response.data); if (!responseNeedsNormalization) return response; const incompleteResults = response.data.incomplete_results; const repositorySelection = response.data.repository_selection; const totalCount = response.data.total_count; + const totalCommits = response.data.total_commits; delete response.data.incomplete_results; delete response.data.repository_selection; delete response.data.total_count; + delete response.data.total_commits; const namespaceKey = Object.keys(response.data)[0]; const data = response.data[namespaceKey]; response.data = data; @@ -27559,6 +32719,7 @@ function normalizePaginatedListResponse(response) { response.data.repository_selection = repositorySelection; } response.data.total_count = totalCount; + response.data.total_commits = totalCommits; return response; } function iterator(octokit, route, parameters) { @@ -27578,6 +32739,16 @@ function iterator(octokit, route, parameters) { url = ((normalizedResponse.headers.link || "").match( /<([^<>]+)>;\s*rel="next"/ ) || [])[1]; + if (!url && "total_commits" in normalizedResponse.data) { + const parsedUrl = new URL(normalizedResponse.url); + const params2 = parsedUrl.searchParams; + const page = parseInt(params2.get("page") || "1", 10); + const per_page = parseInt(params2.get("per_page") || "250", 10); + if (page * per_page < normalizedResponse.data.total_commits) { + params2.set("page", String(page + 1)); + url = parsedUrl.toString(); + } + } return { value: normalizedResponse }; } catch (error) { if (error.status !== 409) @@ -27635,10 +32806,10 @@ function paginateRest(octokit) { }) }; } -paginateRest.VERSION = VERSION8; +paginateRest.VERSION = VERSION6; // -var VERSION9 = "13.5.0"; +var VERSION7 = "17.0.0"; // var Endpoints = { @@ -27699,6 +32870,12 @@ var Endpoints = { deleteArtifact: [ "DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}" ], + deleteCustomImageFromOrg: [ + "DELETE /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}" + ], + deleteCustomImageVersionFromOrg: [ + "DELETE /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions/{version}" + ], deleteEnvironmentSecret: [ "DELETE /repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}" ], @@ -27772,6 +32949,12 @@ var Endpoints = { "GET /repos/{owner}/{repo}/actions/permissions/selected-actions" ], getArtifact: ["GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}"], + getCustomImageForOrg: [ + "GET /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}" + ], + getCustomImageVersionForOrg: [ + "GET /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions/{version}" + ], getCustomOidcSubClaimForRepo: [ "GET /repos/{owner}/{repo}/actions/oidc/customization/sub" ], @@ -27851,6 +33034,12 @@ var Endpoints = { "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing" ], listArtifactsForRepo: ["GET /repos/{owner}/{repo}/actions/artifacts"], + listCustomImageVersionsForOrg: [ + "GET /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions" + ], + listCustomImagesForOrg: [ + "GET /orgs/{org}/actions/hosted-runners/images/custom" + ], listEnvironmentSecrets: [ "GET /repos/{owner}/{repo}/environments/{environment_name}/secrets" ], @@ -28109,9 +33298,18 @@ var Endpoints = { getGithubActionsBillingUser: [ "GET /users/{username}/settings/billing/actions" ], + getGithubBillingPremiumRequestUsageReportOrg: [ + "GET /organizations/{org}/settings/billing/premium_request/usage" + ], + getGithubBillingPremiumRequestUsageReportUser: [ + "GET /users/{username}/settings/billing/premium_request/usage" + ], getGithubBillingUsageReportOrg: [ "GET /organizations/{org}/settings/billing/usage" ], + getGithubBillingUsageReportUser: [ + "GET /users/{username}/settings/billing/usage" + ], getGithubPackagesBillingOrg: ["GET /orgs/{org}/settings/billing/packages"], getGithubPackagesBillingUser: [ "GET /users/{username}/settings/billing/packages" @@ -28123,6 +33321,13 @@ var Endpoints = { "GET /users/{username}/settings/billing/shared-storage" ] }, + campaigns: { + createCampaign: ["POST /orgs/{org}/campaigns"], + deleteCampaign: ["DELETE /orgs/{org}/campaigns/{campaign_number}"], + getCampaignSummary: ["GET /orgs/{org}/campaigns/{campaign_number}"], + listOrgCampaigns: ["GET /orgs/{org}/campaigns"], + updateCampaign: ["PATCH /orgs/{org}/campaigns/{campaign_number}"] + }, checks: { create: ["POST /repos/{owner}/{repo}/check-runs"], createSuite: ["POST /repos/{owner}/{repo}/check-suites"], @@ -28401,10 +33606,9 @@ var Endpoints = { getCopilotSeatDetailsForUser: [ "GET /orgs/{org}/members/{username}/copilot" ], - listCopilotSeats: ["GET /orgs/{org}/copilot/billing/seats"], - usageMetricsForOrg: ["GET /orgs/{org}/copilot/usage"], - usageMetricsForTeam: ["GET /orgs/{org}/team/{team_slug}/copilot/usage"] + listCopilotSeats: ["GET /orgs/{org}/copilot/billing/seats"] }, + credentials: { revoke: ["POST /credentials/revoke"] }, dependabot: { addSelectedRepoToOrgSecret: [ "PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}" @@ -28441,11 +33645,20 @@ var Endpoints = { removeSelectedRepoFromOrgSecret: [ "DELETE /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}" ], + repositoryAccessForOrg: [ + "GET /organizations/{org}/dependabot/repository-access" + ], + setRepositoryAccessDefaultLevel: [ + "PUT /organizations/{org}/dependabot/repository-access/default-level" + ], setSelectedReposForOrgSecret: [ "PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories" ], updateAlert: [ "PATCH /repos/{owner}/{repo}/dependabot/alerts/{alert_number}" + ], + updateRepositoryAccessForOrg: [ + "PATCH /organizations/{org}/dependabot/repository-access" ] }, dependencyGraph: { @@ -28458,6 +33671,51 @@ var Endpoints = { exportSbom: ["GET /repos/{owner}/{repo}/dependency-graph/sbom"] }, emojis: { get: ["GET /emojis"] }, + enterpriseTeamMemberships: { + add: [ + "PUT /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}" + ], + bulkAdd: [ + "POST /enterprises/{enterprise}/teams/{enterprise-team}/memberships/add" + ], + bulkRemove: [ + "POST /enterprises/{enterprise}/teams/{enterprise-team}/memberships/remove" + ], + get: [ + "GET /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}" + ], + list: ["GET /enterprises/{enterprise}/teams/{enterprise-team}/memberships"], + remove: [ + "DELETE /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}" + ] + }, + enterpriseTeamOrganizations: { + add: [ + "PUT /enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}" + ], + bulkAdd: [ + "POST /enterprises/{enterprise}/teams/{enterprise-team}/organizations/add" + ], + bulkRemove: [ + "POST /enterprises/{enterprise}/teams/{enterprise-team}/organizations/remove" + ], + delete: [ + "DELETE /enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}" + ], + getAssignment: [ + "GET /enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}" + ], + getAssignments: [ + "GET /enterprises/{enterprise}/teams/{enterprise-team}/organizations" + ] + }, + enterpriseTeams: { + create: ["POST /enterprises/{enterprise}/teams"], + delete: ["DELETE /enterprises/{enterprise}/teams/{team_slug}"], + get: ["GET /enterprises/{enterprise}/teams/{team_slug}"], + list: ["GET /enterprises/{enterprise}/teams"], + update: ["PATCH /enterprises/{enterprise}/teams/{team_slug}"] + }, gists: { checkIsStarred: ["GET /gists/{gist_id}/star"], create: ["POST /gists"], @@ -28551,6 +33809,9 @@ var Endpoints = { addAssignees: [ "POST /repos/{owner}/{repo}/issues/{issue_number}/assignees" ], + addBlockedByDependency: [ + "POST /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by" + ], addLabels: ["POST /repos/{owner}/{repo}/issues/{issue_number}/labels"], addSubIssue: [ "POST /repos/{owner}/{repo}/issues/{issue_number}/sub_issues" @@ -28577,10 +33838,17 @@ var Endpoints = { getEvent: ["GET /repos/{owner}/{repo}/issues/events/{event_id}"], getLabel: ["GET /repos/{owner}/{repo}/labels/{name}"], getMilestone: ["GET /repos/{owner}/{repo}/milestones/{milestone_number}"], + getParent: ["GET /repos/{owner}/{repo}/issues/{issue_number}/parent"], list: ["GET /issues"], listAssignees: ["GET /repos/{owner}/{repo}/assignees"], listComments: ["GET /repos/{owner}/{repo}/issues/{issue_number}/comments"], listCommentsForRepo: ["GET /repos/{owner}/{repo}/issues/comments"], + listDependenciesBlockedBy: [ + "GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by" + ], + listDependenciesBlocking: [ + "GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocking" + ], listEvents: ["GET /repos/{owner}/{repo}/issues/{issue_number}/events"], listEventsForRepo: ["GET /repos/{owner}/{repo}/issues/events"], listEventsForTimeline: [ @@ -28607,6 +33875,9 @@ var Endpoints = { removeAssignees: [ "DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees" ], + removeDependencyBlockedBy: [ + "DELETE /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by/{issue_id}" + ], removeLabel: [ "DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}" ], @@ -28709,30 +33980,61 @@ var Endpoints = { convertMemberToOutsideCollaborator: [ "PUT /orgs/{org}/outside_collaborators/{username}" ], + createArtifactStorageRecord: [ + "POST /orgs/{org}/artifacts/metadata/storage-record" + ], createInvitation: ["POST /orgs/{org}/invitations"], createIssueType: ["POST /orgs/{org}/issue-types"], - createOrUpdateCustomProperties: ["PATCH /orgs/{org}/properties/schema"], - createOrUpdateCustomPropertiesValuesForRepos: [ - "PATCH /orgs/{org}/properties/values" + createWebhook: ["POST /orgs/{org}/hooks"], + customPropertiesForOrgsCreateOrUpdateOrganizationValues: [ + "PATCH /organizations/{org}/org-properties/values" ], - createOrUpdateCustomProperty: [ + customPropertiesForOrgsGetOrganizationValues: [ + "GET /organizations/{org}/org-properties/values" + ], + customPropertiesForReposCreateOrUpdateOrganizationDefinition: [ "PUT /orgs/{org}/properties/schema/{custom_property_name}" ], - createWebhook: ["POST /orgs/{org}/hooks"], + customPropertiesForReposCreateOrUpdateOrganizationDefinitions: [ + "PATCH /orgs/{org}/properties/schema" + ], + customPropertiesForReposCreateOrUpdateOrganizationValues: [ + "PATCH /orgs/{org}/properties/values" + ], + customPropertiesForReposDeleteOrganizationDefinition: [ + "DELETE /orgs/{org}/properties/schema/{custom_property_name}" + ], + customPropertiesForReposGetOrganizationDefinition: [ + "GET /orgs/{org}/properties/schema/{custom_property_name}" + ], + customPropertiesForReposGetOrganizationDefinitions: [ + "GET /orgs/{org}/properties/schema" + ], + customPropertiesForReposGetOrganizationValues: [ + "GET /orgs/{org}/properties/values" + ], delete: ["DELETE /orgs/{org}"], + deleteAttestationsBulk: ["POST /orgs/{org}/attestations/delete-request"], + deleteAttestationsById: [ + "DELETE /orgs/{org}/attestations/{attestation_id}" + ], + deleteAttestationsBySubjectDigest: [ + "DELETE /orgs/{org}/attestations/digest/{subject_digest}" + ], deleteIssueType: ["DELETE /orgs/{org}/issue-types/{issue_type_id}"], deleteWebhook: ["DELETE /orgs/{org}/hooks/{hook_id}"], - enableOrDisableSecurityProductOnAllOrgRepos: [ - "POST /orgs/{org}/{security_product}/{enablement}", - {}, - { - deprecated: "octokit.rest.orgs.enableOrDisableSecurityProductOnAllOrgRepos() is deprecated, see https://docs.github.com/rest/orgs/orgs#enable-or-disable-a-security-feature-for-an-organization" - } + disableSelectedRepositoryImmutableReleasesOrganization: [ + "DELETE /orgs/{org}/settings/immutable-releases/repositories/{repository_id}" + ], + enableSelectedRepositoryImmutableReleasesOrganization: [ + "PUT /orgs/{org}/settings/immutable-releases/repositories/{repository_id}" ], get: ["GET /orgs/{org}"], - getAllCustomProperties: ["GET /orgs/{org}/properties/schema"], - getCustomProperty: [ - "GET /orgs/{org}/properties/schema/{custom_property_name}" + getImmutableReleasesSettings: [ + "GET /orgs/{org}/settings/immutable-releases" + ], + getImmutableReleasesSettingsRepositories: [ + "GET /orgs/{org}/settings/immutable-releases/repositories" ], getMembershipForAuthenticatedUser: ["GET /user/memberships/orgs/{org}"], getMembershipForUser: ["GET /orgs/{org}/memberships/{username}"], @@ -28748,9 +34050,15 @@ var Endpoints = { ], list: ["GET /organizations"], listAppInstallations: ["GET /orgs/{org}/installations"], + listArtifactStorageRecords: [ + "GET /orgs/{org}/artifacts/{subject_digest}/metadata/storage-records" + ], + listAttestationRepositories: ["GET /orgs/{org}/attestations/repositories"], listAttestations: ["GET /orgs/{org}/attestations/{subject_digest}"], + listAttestationsBulk: [ + "POST /orgs/{org}/attestations/bulk-list{?per_page,before,after}" + ], listBlockedUsers: ["GET /orgs/{org}/blocks"], - listCustomPropertiesValuesForRepos: ["GET /orgs/{org}/properties/values"], listFailedInvitations: ["GET /orgs/{org}/failed_invitations"], listForAuthenticatedUser: ["GET /user/orgs"], listForUser: ["GET /users/{username}/orgs"], @@ -28788,9 +34096,6 @@ var Endpoints = { redeliverWebhookDelivery: [ "POST /orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}/attempts" ], - removeCustomProperty: [ - "DELETE /orgs/{org}/properties/schema/{custom_property_name}" - ], removeMember: ["DELETE /orgs/{org}/members/{username}"], removeMembershipForUser: ["DELETE /orgs/{org}/memberships/{username}"], removeOutsideCollaborator: [ @@ -28824,6 +34129,12 @@ var Endpoints = { revokeOrgRoleUser: [ "DELETE /orgs/{org}/organization-roles/users/{username}/{role_id}" ], + setImmutableReleasesSettings: [ + "PUT /orgs/{org}/settings/immutable-releases" + ], + setImmutableReleasesSettingsRepositories: [ + "PUT /orgs/{org}/settings/immutable-releases/repositories" + ], setMembershipForUser: ["PUT /orgs/{org}/memberships/{username}"], setPublicMembershipForAuthenticatedUser: [ "PUT /orgs/{org}/public_members/{username}" @@ -28944,180 +34255,43 @@ var Endpoints = { ] }, projects: { - addCollaborator: [ - "PUT /projects/{project_id}/collaborators/{username}", - {}, - { - deprecated: "octokit.rest.projects.addCollaborator() is deprecated, see https://docs.github.com/rest/projects/collaborators#add-project-collaborator" - } - ], - createCard: [ - "POST /projects/columns/{column_id}/cards", - {}, - { - deprecated: "octokit.rest.projects.createCard() is deprecated, see https://docs.github.com/rest/projects/cards#create-a-project-card" - } - ], - createColumn: [ - "POST /projects/{project_id}/columns", - {}, - { - deprecated: "octokit.rest.projects.createColumn() is deprecated, see https://docs.github.com/rest/projects/columns#create-a-project-column" - } - ], - createForAuthenticatedUser: [ - "POST /user/projects", - {}, - { - deprecated: "octokit.rest.projects.createForAuthenticatedUser() is deprecated, see https://docs.github.com/rest/projects/projects#create-a-user-project" - } - ], - createForOrg: [ - "POST /orgs/{org}/projects", - {}, - { - deprecated: "octokit.rest.projects.createForOrg() is deprecated, see https://docs.github.com/rest/projects/projects#create-an-organization-project" - } - ], - createForRepo: [ - "POST /repos/{owner}/{repo}/projects", - {}, - { - deprecated: "octokit.rest.projects.createForRepo() is deprecated, see https://docs.github.com/rest/projects/projects#create-a-repository-project" - } - ], - delete: [ - "DELETE /projects/{project_id}", - {}, - { - deprecated: "octokit.rest.projects.delete() is deprecated, see https://docs.github.com/rest/projects/projects#delete-a-project" - } - ], - deleteCard: [ - "DELETE /projects/columns/cards/{card_id}", - {}, - { - deprecated: "octokit.rest.projects.deleteCard() is deprecated, see https://docs.github.com/rest/projects/cards#delete-a-project-card" - } - ], - deleteColumn: [ - "DELETE /projects/columns/{column_id}", - {}, - { - deprecated: "octokit.rest.projects.deleteColumn() is deprecated, see https://docs.github.com/rest/projects/columns#delete-a-project-column" - } - ], - get: [ - "GET /projects/{project_id}", - {}, - { - deprecated: "octokit.rest.projects.get() is deprecated, see https://docs.github.com/rest/projects/projects#get-a-project" - } + addItemForOrg: ["POST /orgs/{org}/projectsV2/{project_number}/items"], + addItemForUser: [ + "POST /users/{username}/projectsV2/{project_number}/items" ], - getCard: [ - "GET /projects/columns/cards/{card_id}", - {}, - { - deprecated: "octokit.rest.projects.getCard() is deprecated, see https://docs.github.com/rest/projects/cards#get-a-project-card" - } - ], - getColumn: [ - "GET /projects/columns/{column_id}", - {}, - { - deprecated: "octokit.rest.projects.getColumn() is deprecated, see https://docs.github.com/rest/projects/columns#get-a-project-column" - } - ], - getPermissionForUser: [ - "GET /projects/{project_id}/collaborators/{username}/permission", - {}, - { - deprecated: "octokit.rest.projects.getPermissionForUser() is deprecated, see https://docs.github.com/rest/projects/collaborators#get-project-permission-for-a-user" - } - ], - listCards: [ - "GET /projects/columns/{column_id}/cards", - {}, - { - deprecated: "octokit.rest.projects.listCards() is deprecated, see https://docs.github.com/rest/projects/cards#list-project-cards" - } + deleteItemForOrg: [ + "DELETE /orgs/{org}/projectsV2/{project_number}/items/{item_id}" ], - listCollaborators: [ - "GET /projects/{project_id}/collaborators", - {}, - { - deprecated: "octokit.rest.projects.listCollaborators() is deprecated, see https://docs.github.com/rest/projects/collaborators#list-project-collaborators" - } - ], - listColumns: [ - "GET /projects/{project_id}/columns", - {}, - { - deprecated: "octokit.rest.projects.listColumns() is deprecated, see https://docs.github.com/rest/projects/columns#list-project-columns" - } - ], - listForOrg: [ - "GET /orgs/{org}/projects", - {}, - { - deprecated: "octokit.rest.projects.listForOrg() is deprecated, see https://docs.github.com/rest/projects/projects#list-organization-projects" - } - ], - listForRepo: [ - "GET /repos/{owner}/{repo}/projects", - {}, - { - deprecated: "octokit.rest.projects.listForRepo() is deprecated, see https://docs.github.com/rest/projects/projects#list-repository-projects" - } + deleteItemForUser: [ + "DELETE /users/{username}/projectsV2/{project_number}/items/{item_id}" ], - listForUser: [ - "GET /users/{username}/projects", - {}, - { - deprecated: "octokit.rest.projects.listForUser() is deprecated, see https://docs.github.com/rest/projects/projects#list-user-projects" - } + getFieldForOrg: [ + "GET /orgs/{org}/projectsV2/{project_number}/fields/{field_id}" ], - moveCard: [ - "POST /projects/columns/cards/{card_id}/moves", - {}, - { - deprecated: "octokit.rest.projects.moveCard() is deprecated, see https://docs.github.com/rest/projects/cards#move-a-project-card" - } + getFieldForUser: [ + "GET /users/{username}/projectsV2/{project_number}/fields/{field_id}" ], - moveColumn: [ - "POST /projects/columns/{column_id}/moves", - {}, - { - deprecated: "octokit.rest.projects.moveColumn() is deprecated, see https://docs.github.com/rest/projects/columns#move-a-project-column" - } + getForOrg: ["GET /orgs/{org}/projectsV2/{project_number}"], + getForUser: ["GET /users/{username}/projectsV2/{project_number}"], + getOrgItem: ["GET /orgs/{org}/projectsV2/{project_number}/items/{item_id}"], + getUserItem: [ + "GET /users/{username}/projectsV2/{project_number}/items/{item_id}" ], - removeCollaborator: [ - "DELETE /projects/{project_id}/collaborators/{username}", - {}, - { - deprecated: "octokit.rest.projects.removeCollaborator() is deprecated, see https://docs.github.com/rest/projects/collaborators#remove-user-as-a-collaborator" - } + listFieldsForOrg: ["GET /orgs/{org}/projectsV2/{project_number}/fields"], + listFieldsForUser: [ + "GET /users/{username}/projectsV2/{project_number}/fields" ], - update: [ - "PATCH /projects/{project_id}", - {}, - { - deprecated: "octokit.rest.projects.update() is deprecated, see https://docs.github.com/rest/projects/projects#update-a-project" - } + listForOrg: ["GET /orgs/{org}/projectsV2"], + listForUser: ["GET /users/{username}/projectsV2"], + listItemsForOrg: ["GET /orgs/{org}/projectsV2/{project_number}/items"], + listItemsForUser: [ + "GET /users/{username}/projectsV2/{project_number}/items" ], - updateCard: [ - "PATCH /projects/columns/cards/{card_id}", - {}, - { - deprecated: "octokit.rest.projects.updateCard() is deprecated, see https://docs.github.com/rest/projects/cards#update-an-existing-project-card" - } + updateItemForOrg: [ + "PATCH /orgs/{org}/projectsV2/{project_number}/items/{item_id}" ], - updateColumn: [ - "PATCH /projects/columns/{column_id}", - {}, - { - deprecated: "octokit.rest.projects.updateColumn() is deprecated, see https://docs.github.com/rest/projects/columns#update-an-existing-project-column" - } + updateItemForUser: [ + "PATCH /users/{username}/projectsV2/{project_number}/items/{item_id}" ] }, pulls: { @@ -29280,6 +34454,7 @@ var Endpoints = { "GET /repos/{owner}/{repo}/automated-security-fixes" ], checkCollaborator: ["GET /repos/{owner}/{repo}/collaborators/{username}"], + checkImmutableReleases: ["GET /repos/{owner}/{repo}/immutable-releases"], checkPrivateVulnerabilityReporting: [ "GET /repos/{owner}/{repo}/private-vulnerability-reporting" ], @@ -29315,9 +34490,6 @@ var Endpoints = { createForAuthenticatedUser: ["POST /user/repos"], createFork: ["POST /repos/{owner}/{repo}/forks"], createInOrg: ["POST /orgs/{org}/repos"], - createOrUpdateCustomPropertiesValues: [ - "PATCH /repos/{owner}/{repo}/properties/values" - ], createOrUpdateEnvironment: [ "PUT /repos/{owner}/{repo}/environments/{environment_name}" ], @@ -29331,6 +34503,12 @@ var Endpoints = { "POST /repos/{template_owner}/{template_repo}/generate" ], createWebhook: ["POST /repos/{owner}/{repo}/hooks"], + customPropertiesForReposCreateOrUpdateRepositoryValues: [ + "PATCH /repos/{owner}/{repo}/properties/values" + ], + customPropertiesForReposGetRepositoryValues: [ + "GET /repos/{owner}/{repo}/properties/values" + ], declineInvitation: [ "DELETE /user/repository_invitations/{invitation_id}", {}, @@ -29385,6 +34563,9 @@ var Endpoints = { disableDeploymentProtectionRule: [ "DELETE /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}" ], + disableImmutableReleases: [ + "DELETE /repos/{owner}/{repo}/immutable-releases" + ], disablePrivateVulnerabilityReporting: [ "DELETE /repos/{owner}/{repo}/private-vulnerability-reporting" ], @@ -29401,6 +34582,7 @@ var Endpoints = { enableAutomatedSecurityFixes: [ "PUT /repos/{owner}/{repo}/automated-security-fixes" ], + enableImmutableReleases: ["PUT /repos/{owner}/{repo}/immutable-releases"], enablePrivateVulnerabilityReporting: [ "PUT /repos/{owner}/{repo}/private-vulnerability-reporting" ], @@ -29452,7 +34634,6 @@ var Endpoints = { getCustomDeploymentProtectionRule: [ "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}" ], - getCustomPropertiesValues: ["GET /repos/{owner}/{repo}/properties/values"], getDeployKey: ["GET /repos/{owner}/{repo}/keys/{key_id}"], getDeployment: ["GET /repos/{owner}/{repo}/deployments/{deployment_id}"], getDeploymentBranchPolicy: [ @@ -29670,13 +34851,7 @@ var Endpoints = { search: { code: ["GET /search/code"], commits: ["GET /search/commits"], - issuesAndPullRequests: [ - "GET /search/issues", - {}, - { - deprecated: "octokit.rest.search.issuesAndPullRequests() is deprecated, see https://docs.github.com/rest/search/search#search-issues-and-pull-requests" - } - ], + issuesAndPullRequests: ["GET /search/issues"], labels: ["GET /search/labels"], repos: ["GET /search/repositories"], topics: ["GET /search/topics"], @@ -29690,16 +34865,19 @@ var Endpoints = { "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}" ], getScanHistory: ["GET /repos/{owner}/{repo}/secret-scanning/scan-history"], - listAlertsForEnterprise: [ - "GET /enterprises/{enterprise}/secret-scanning/alerts" - ], listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], listLocationsForAlert: [ "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations" ], + listOrgPatternConfigs: [ + "GET /orgs/{org}/secret-scanning/pattern-configurations" + ], updateAlert: [ "PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}" + ], + updateOrgPatternConfigs: [ + "PATCH /orgs/{org}/secret-scanning/pattern-configurations" ] }, securityAdvisories: { @@ -29730,37 +34908,9 @@ var Endpoints = { addOrUpdateMembershipForUserInOrg: [ "PUT /orgs/{org}/teams/{team_slug}/memberships/{username}" ], - addOrUpdateProjectPermissionsInOrg: [ - "PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}", - {}, - { - deprecated: "octokit.rest.teams.addOrUpdateProjectPermissionsInOrg() is deprecated, see https://docs.github.com/rest/teams/teams#add-or-update-team-project-permissions" - } - ], - addOrUpdateProjectPermissionsLegacy: [ - "PUT /teams/{team_id}/projects/{project_id}", - {}, - { - deprecated: "octokit.rest.teams.addOrUpdateProjectPermissionsLegacy() is deprecated, see https://docs.github.com/rest/teams/teams#add-or-update-team-project-permissions-legacy" - } - ], addOrUpdateRepoPermissionsInOrg: [ "PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}" ], - checkPermissionsForProjectInOrg: [ - "GET /orgs/{org}/teams/{team_slug}/projects/{project_id}", - {}, - { - deprecated: "octokit.rest.teams.checkPermissionsForProjectInOrg() is deprecated, see https://docs.github.com/rest/teams/teams#check-team-permissions-for-a-project" - } - ], - checkPermissionsForProjectLegacy: [ - "GET /teams/{team_id}/projects/{project_id}", - {}, - { - deprecated: "octokit.rest.teams.checkPermissionsForProjectLegacy() is deprecated, see https://docs.github.com/rest/teams/teams#check-team-permissions-for-a-project-legacy" - } - ], checkPermissionsForRepoInOrg: [ "GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}" ], @@ -29797,38 +34947,10 @@ var Endpoints = { listPendingInvitationsInOrg: [ "GET /orgs/{org}/teams/{team_slug}/invitations" ], - listProjectsInOrg: [ - "GET /orgs/{org}/teams/{team_slug}/projects", - {}, - { - deprecated: "octokit.rest.teams.listProjectsInOrg() is deprecated, see https://docs.github.com/rest/teams/teams#list-team-projects" - } - ], - listProjectsLegacy: [ - "GET /teams/{team_id}/projects", - {}, - { - deprecated: "octokit.rest.teams.listProjectsLegacy() is deprecated, see https://docs.github.com/rest/teams/teams#list-team-projects-legacy" - } - ], listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], removeMembershipForUserInOrg: [ "DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}" ], - removeProjectInOrg: [ - "DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}", - {}, - { - deprecated: "octokit.rest.teams.removeProjectInOrg() is deprecated, see https://docs.github.com/rest/teams/teams#remove-a-project-from-a-team" - } - ], - removeProjectLegacy: [ - "DELETE /teams/{team_id}/projects/{project_id}", - {}, - { - deprecated: "octokit.rest.teams.removeProjectLegacy() is deprecated, see https://docs.github.com/rest/teams/teams#remove-a-project-from-a-team-legacy" - } - ], removeRepoInOrg: [ "DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}" ], @@ -29865,6 +34987,15 @@ var Endpoints = { ], createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], createSshSigningKeyForAuthenticatedUser: ["POST /user/ssh_signing_keys"], + deleteAttestationsBulk: [ + "POST /users/{username}/attestations/delete-request" + ], + deleteAttestationsById: [ + "DELETE /users/{username}/attestations/{attestation_id}" + ], + deleteAttestationsBySubjectDigest: [ + "DELETE /users/{username}/attestations/digest/{subject_digest}" + ], deleteEmailForAuthenticated: [ "DELETE /user/emails", {}, @@ -29909,6 +35040,9 @@ var Endpoints = { ], list: ["GET /users"], listAttestations: ["GET /users/{username}/attestations/{subject_digest}"], + listAttestationsBulk: [ + "POST /users/{username}/attestations/bulk-list{?per_page,before,after}" + ], listBlockedByAuthenticated: [ "GET /user/blocks", {}, @@ -29972,8 +35106,8 @@ var endpoints_default = Endpoints; // var endpointMethodsMap = /* @__PURE__ */ new Map(); for (const [scope, endpoints] of Object.entries(endpoints_default)) { - for (const [methodName, endpoint3] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint3; + for (const [methodName, endpoint2] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint2; const [method, url] = route.split(/ /); const endpointDefaults = Object.assign( { @@ -30000,6 +35134,7 @@ var handler = { getOwnPropertyDescriptor(target, methodName) { return { value: this.get(target, methodName), + // ensures method is in the cache configurable: true, writable: true, enumerable: true @@ -30098,7 +35233,7 @@ function restEndpointMethods(octokit) { rest: api }; } -restEndpointMethods.VERSION = VERSION9; +restEndpointMethods.VERSION = VERSION7; function legacyRestEndpointMethods(octokit) { const api = endpointsToMethods(octokit); return { @@ -30106,20 +35241,20 @@ function legacyRestEndpointMethods(octokit) { rest: api }; } -legacyRestEndpointMethods.VERSION = VERSION9; +legacyRestEndpointMethods.VERSION = VERSION7; // -var VERSION10 = "21.1.1"; +var VERSION8 = "22.0.1"; // var Octokit2 = Octokit.plugin(requestLog, legacyRestEndpointMethods, paginateRest).defaults( { - userAgent: `octokit-rest.js/${VERSION10}` + userAgent: `octokit-rest.js/${VERSION8}` } ); // -var import_typed_graphqlify2 = __toESM(require_dist(), 1); +var import_typed_graphqlify2 = __toESM(require_dist()); var GithubClient = class { constructor(_octokitOptions) { this._octokitOptions = _octokitOptions; @@ -30177,7 +35312,7 @@ var GitCommandError = class extends Error { super(`Command failed: git ${client.sanitizeConsoleOutput(unsanitizedArgs.join(" "))}`); } }; -var GitClient = class { +var GitClient = class _GitClient { constructor(config, baseDir = determineRepoBaseDirFromCwd()) { this.baseDir = baseDir; this.github = new GithubClient(); @@ -30265,12 +35400,12 @@ var GitClient = class { return value; } static async get() { - if (GitClient._unauthenticatedInstance === null) { - GitClient._unauthenticatedInstance = (async () => { - return new GitClient(await getConfig([assertValidGithubConfig])); + if (_GitClient._unauthenticatedInstance === null) { + _GitClient._unauthenticatedInstance = (async () => { + return new _GitClient(await getConfig([assertValidGithubConfig])); })(); } - return GitClient._unauthenticatedInstance; + return _GitClient._unauthenticatedInstance; } }; GitClient._unauthenticatedInstance = null; @@ -30279,7 +35414,7 @@ function gitOutputAsArray(gitCommandResult) { } // -var AuthenticatedGitClient = class extends GitClient { +var AuthenticatedGitClient = class _AuthenticatedGitClient extends GitClient { constructor(githubToken, userType, config, baseDir) { super(config, baseDir); this.githubToken = githubToken; @@ -30345,33 +35480,33 @@ Alternatively, a new token can be created at: ${GITHUB_TOKEN_GENERATE_URL} }); } static async get() { - if (AuthenticatedGitClient._token === null) { + if (_AuthenticatedGitClient._token === null) { throw new Error("No instance of `AuthenticatedGitClient` has been configured."); } - if (AuthenticatedGitClient._authenticatedInstance === null) { - AuthenticatedGitClient._authenticatedInstance = (async (token, userType) => { - return new AuthenticatedGitClient(token, userType, await getConfig([assertValidGithubConfig])); - })(AuthenticatedGitClient._token, AuthenticatedGitClient._userType); + if (_AuthenticatedGitClient._authenticatedInstance === null) { + _AuthenticatedGitClient._authenticatedInstance = (async (token, userType) => { + return new _AuthenticatedGitClient(token, userType, await getConfig([assertValidGithubConfig])); + })(_AuthenticatedGitClient._token, _AuthenticatedGitClient._userType); } - return AuthenticatedGitClient._authenticatedInstance; + return _AuthenticatedGitClient._authenticatedInstance; } static configure(token, userType = "user") { - if (AuthenticatedGitClient._token) { + if (_AuthenticatedGitClient._token) { throw Error("Unable to configure `AuthenticatedGitClient` as it has been configured already."); } - AuthenticatedGitClient._token = token; - AuthenticatedGitClient._userType = userType; + _AuthenticatedGitClient._token = token; + _AuthenticatedGitClient._userType = userType; } }; AuthenticatedGitClient._token = null; AuthenticatedGitClient._authenticatedInstance = null; // -var import_which = __toESM(require_lib2(), 1); -var import_lockfile = __toESM(require_lockfile(), 1); -var import_yaml = __toESM(require_dist2(), 1); +var import_which = __toESM(require_lib2()); +var import_lockfile = __toESM(require_lockfile()); +var import_yaml = __toESM(require_dist2()); -// +// .github/actions/deploy-docs-site/lib/deployments.mjs async function getDeployments() { const { github } = await AuthenticatedGitClient.get(); const releaseTrains = await ActiveReleaseTrains.fetch({ @@ -30387,7 +35522,8 @@ async function getDeployments() { [...ltsBranches.active, ...ltsBranches.inactive].forEach((branch) => { docSites.set(branch.name, { branch: branch.name, - destination: `v${branch.version.major}-angular-dev` + destination: `v${branch.version.major}-angular-dev`, + servingUrl: `https://v${branch.version.major}.angular.dev/` }); }); docSites.set(releaseTrains.latest.branchName, { @@ -30396,11 +35532,13 @@ async function getDeployments() { from: `v${releaseTrains.latest.version.major}-angular-dev`, to: "https://angular.dev" }, + servingUrl: "https://angular.dev/", destination: "angular-dev-site" }); if (releaseTrains.releaseCandidate) { docSites.set(releaseTrains.next.branchName, { - branch: releaseTrains.next.branchName + branch: releaseTrains.next.branchName, + servingUrl: "https://next.angular.dev/" }); docSites.set(releaseTrains.releaseCandidate.branchName, { branch: releaseTrains.releaseCandidate.branchName, @@ -30408,18 +35546,49 @@ async function getDeployments() { redirect: { from: `v${releaseTrains.releaseCandidate.version.major}-angular-dev`, to: "https://next.angular.dev" - } + }, + servingUrl: "https://next.angular.dev/" }); } else { docSites.set(releaseTrains.next.branchName, { branch: releaseTrains.next.branchName, - destination: "next-angular-dev" + destination: "next-angular-dev", + servingUrl: "https://next.angular.dev/" }); } return docSites; } -// +// .github/actions/deploy-docs-site/lib/sitemap.mjs +import { join as join4 } from "path"; +import { readFileSync as readFileSync4, writeFileSync } from "fs"; +async function generateSitemap(deployment, distDir) { + const servingUrlWithoutEndingSlash = deployment.servingUrl.endsWith("/") ? deployment.servingUrl.slice(0, -1) : deployment.servingUrl; + const lastModifiedTimestamp = (/* @__PURE__ */ new Date()).toISOString(); + const routes = JSON.parse(readFileSync4(join4(distDir, "prerendered-routes.json"), "utf-8")); + const sitemap = ` + + ${Object.keys(routes.routes).map((route) => { + const routeWithoutLeadingSlash = route.startsWith("/") ? route.slice(1) : route; + return ` + + ${servingUrlWithoutEndingSlash}/${routeWithoutLeadingSlash} + ${lastModifiedTimestamp} + daily + 1.0 + + `; + }).join("")} + `; + writeFileSync(join4(distDir, "browser", "sitemap.xml"), sitemap, "utf-8"); + console.log(`Generated sitemap with ${Object.keys(routes.routes).length} entries.`); +} + +// .github/actions/deploy-docs-site/lib/main.mts +import { spawnSync as spawnSync3 } from "child_process"; +import { cp, mkdtemp as mkdtemp2 } from "fs/promises"; +import { tmpdir as tmpdir2 } from "os"; +import { join as join5 } from "path"; var refMatcher = /refs\/heads\/(.*)/; async function deployDocs() { setConfig({ @@ -30439,7 +35608,9 @@ async function deployDocs() { } const currentBranch = matchedRef[1]; const configPath = (0, import_core3.getInput)("configPath"); - const distDir = (0, import_core3.getInput)("distDir"); + const stagingDir = await mkdtemp2(join5(tmpdir2(), "deploy-directory")); + await cp((0, import_core3.getInput)("distDir"), stagingDir, { recursive: true }); + spawnSync3(`chmod 777 -R ${stagingDir}`, { encoding: "utf-8", shell: true }); const deployment = (await getDeployments()).get(currentBranch); if (deployment === void 0) { console.log(`Current branch (${currentBranch}) does not deploy a documentation site.`); @@ -30465,7 +35636,8 @@ async function deployDocs() { console.log(` From: ${deployment.redirect.from}`); console.log(` To: ${deployment.redirect.to}`); } - await deployToFirebase(deployment, configPath, distDir); + await generateSitemap(deployment, stagingDir); + await deployToFirebase(deployment, configPath, stagingDir); await setupRedirect(deployment); } if (import_github3.context.repo.owner === "angular") { @@ -30474,19 +35646,62 @@ if (import_github3.context.repo.owner === "angular") { console.error(e); }); } else { - console.warn("The action was skipped as this action is only meant to run in repos belonging to the Angular organization."); + console.warn( + "The action was skipped as this action is only meant to run in repos belonging to the Angular organization." + ); } -/*! - * Tmp - * - * Copyright (c) 2011-2017 KARASZI Istvan - * - * MIT Licensed - */ -/** - * @license - * Copyright Google LLC - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ +/*! Bundled license information: + +tmp/lib/tmp.js: + (*! + * Tmp + * + * Copyright (c) 2011-2017 KARASZI Istvan + * + * MIT Licensed + *) + +yargs-parser/build/lib/string-utils.js: + (** + * @license + * Copyright (c) 2016, Contributors + * SPDX-License-Identifier: ISC + *) + +yargs-parser/build/lib/tokenize-arg-string.js: + (** + * @license + * Copyright (c) 2016, Contributors + * SPDX-License-Identifier: ISC + *) + +yargs-parser/build/lib/yargs-parser-types.js: + (** + * @license + * Copyright (c) 2016, Contributors + * SPDX-License-Identifier: ISC + *) + +yargs-parser/build/lib/yargs-parser.js: + (** + * @license + * Copyright (c) 2016, Contributors + * SPDX-License-Identifier: ISC + *) + +yargs-parser/build/lib/index.js: + (** + * @fileoverview Main entrypoint for libraries using yargs-parser in Node.js + * + * @license + * Copyright (c) 2016, Contributors + * SPDX-License-Identifier: ISC + *) + +@octokit/request-error/dist-src/index.js: + (* v8 ignore else -- @preserve -- Bug with vitest coverage where it sees an else branch that doesn't exist *) + +@octokit/request/dist-bundle/index.js: + (* v8 ignore next -- @preserve *) + (* v8 ignore else -- @preserve *) +*/ diff --git a/.github/actions/deploy-docs-site/tsconfig.json b/.github/actions/deploy-docs-site/tsconfig.json index 839b2e57c4f0..ddabad392d77 100644 --- a/.github/actions/deploy-docs-site/tsconfig.json +++ b/.github/actions/deploy-docs-site/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "module": "NodeNext", "target": "ES2021", + "types": ["node"], "lib": ["es2021"], "experimentalDecorators": true, "strict": true, @@ -11,6 +12,5 @@ "noImplicitReturns": true, "declaration": true, "sourceMap": true - } } \ No newline at end of file diff --git a/.github/actions/saucelabs-legacy/action.yml b/.github/actions/saucelabs-legacy/action.yml index 51bd3b99d5e2..e592789951d6 100644 --- a/.github/actions/saucelabs-legacy/action.yml +++ b/.github/actions/saucelabs-legacy/action.yml @@ -5,9 +5,9 @@ runs: using: 'composite' steps: - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Saucelabs Variables - uses: angular/dev-infra/github-actions/saucelabs@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/saucelabs@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Starting Saucelabs tunnel service shell: bash run: ./tools/saucelabs/sauce-service.sh run & @@ -19,11 +19,6 @@ runs: - name: Preparing Bazel-generated fixtures required in legacy tests shell: bash run: | - yarn bazel build //packages/core/test:downleveled_es5_fixture //packages/common/locales - # Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`. - mkdir -p dist/legacy-test-out/core/test/reflection/ - cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \ - dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js # Locale files are needed for i18n tests running within Saucelabs. These are added # directly as sources so that the TypeScript compilation of `/packages/tsconfig.json` # can succeed. Note that the base locale and currencies files are checked-in, so @@ -39,7 +34,7 @@ runs: run: ./tools/saucelabs/sauce-service.sh ready-wait - name: Running tests on Saucelabs. shell: bash - run: KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run + run: KARMA_WEB_TEST_MODE=SL_REQUIRED pnpm karma start ./karma-js.conf.js --single-run - name: Stop Saucelabs tunnel service shell: bash run: ./tools/saucelabs/sauce-service.sh stop diff --git a/.github/actions/yarn-install/action.yml b/.github/actions/yarn-install/action.yml deleted file mode 100644 index 7e08f9125666..000000000000 --- a/.github/actions/yarn-install/action.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: 'Installing Yarn dependencies' -description: 'Installs the dependencies using Yarn' - -runs: - using: 'composite' - steps: - - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 - with: - path: | - ./node_modules/ - # If just `WORKSPACE` or `yarn.lock` is changed, the most recent cache can be restored. - # See: https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action. - key: v1-angular-main-deps-${{hashFiles('WORKSPACE')}}-${{hashFiles('yarn.lock')}} - restore-keys: v1-angular-main-deps- - - - run: yarn install --frozen-lockfile --non-interactive - shell: bash diff --git a/.github/workflows/adev-preview-build.yml b/.github/workflows/adev-preview-build.yml index 5f9f479ec511..388618bd04f7 100644 --- a/.github/workflows/adev-preview-build.yml +++ b/.github/workflows/adev-preview-build.yml @@ -15,24 +15,25 @@ permissions: read-all jobs: adev-build: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8core if: | (github.event.action == 'labeled' && github.event.label.name == 'adev: preview') || (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview')) steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile - - name: Build adev to ensure it continues to work - run: yarn bazel build //adev:build --full_build_adev --config=release - - uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@1685f0afc967fb7de4b46ccb22f22d779ee3086c + run: pnpm install --frozen-lockfile + - name: Build adev + # `snapshot-build` config is used to stamp the exact version with sha in the footer. + run: pnpm bazel build //adev:build.production --config=snapshot-build + - uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: workflow-artifact-name: 'adev-preview' pull-number: '${{github.event.pull_request.number}}' artifact-build-revision: '${{github.event.pull_request.head.sha}}' - deploy-directory: './dist/bin/adev/build/browser' + deploy-directory: './dist/bin/adev/dist/browser' diff --git a/.github/workflows/adev-preview-deploy.yml b/.github/workflows/adev-preview-deploy.yml index 9e50b4e8e90b..d705103088d5 100644 --- a/.github/workflows/adev-preview-deploy.yml +++ b/.github/workflows/adev-preview-deploy.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 with: token: '${{secrets.GITHUB_TOKEN}}' @@ -40,7 +40,7 @@ jobs: npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}} - - uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@1685f0afc967fb7de4b46ccb22f22d779ee3086c + - uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: github-token: '${{secrets.GITHUB_TOKEN}}' workflow-artifact-name: 'adev-preview' diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 87ef4e7e6a20..43f71577f113 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -13,9 +13,9 @@ jobs: assistant_to_the_branch_manager: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@1685f0afc967fb7de4b46ccb22f22d779ee3086c + - uses: angular/dev-infra/github-actions/branch-manager@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/benchmark-compare.yml b/.github/workflows/benchmark-compare.yml index 54621a00c1e8..3ad7cd61a755 100644 --- a/.github/workflows/benchmark-compare.yml +++ b/.github/workflows/benchmark-compare.yml @@ -19,7 +19,7 @@ jobs: exit: true # Indicate that the benchmark command was received. - - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 + - uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: comment-id: ${{github.event.comment.id}} token: '${{secrets.BENCHMARK_POST_RESULTS_GITHUB_TOKEN}}' @@ -28,7 +28,7 @@ jobs: - uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1 id: comment-branch - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: # Specify repository as the PR branch might be from a fork. repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}} @@ -36,9 +36,9 @@ jobs: # that the action was triggered by a team member. ref: ${{steps.comment-branch.outputs.head_ref}} - - uses: ./.github/actions/yarn-install + - run: pnpm install --frozen-lockfile - - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + - uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: bazelrc: ./.bazelrc.user @@ -47,13 +47,13 @@ jobs: env: # Untrusted input used in an executable code, must be wrapped as an env var to prevent injections COMMENT_BODY: ${{ github.event.comment.body }} - run: yarn benchmarks prepare-for-github-action "$COMMENT_BODY" + run: pnpm benchmarks prepare-for-github-action "$COMMENT_BODY" - - run: yarn benchmarks run-compare ${{steps.info.outputs.compareSha}} ${{steps.info.outputs.benchmarkTarget}} + - run: pnpm benchmarks run-compare ${{steps.info.outputs.compareSha}} ${{steps.info.outputs.benchmarkTarget}} id: benchmark name: Running benchmark - - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 + - uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5 with: issue-number: ${{github.event.issue.number}} token: '${{secrets.BENCHMARK_POST_RESULTS_GITHUB_TOKEN}}' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4661f81b86f..55dcb0bb5078 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,140 +21,151 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Check code lint - run: yarn -s tslint + run: pnpm tslint - name: Check for circular dependencies - run: yarn -s ts-circular-deps:check + run: pnpm ts-circular-deps:check - name: Validate pull approve configuration - run: yarn -s ng-dev pullapprove verify + run: pnpm ng-dev pullapprove verify - name: Validate angular robot configuration - run: yarn -s ng-dev ngbot verify + run: pnpm ng-dev ngbot verify - name: Confirm code builds with typescript as expected - run: yarn -s check-tooling-setup + run: pnpm check-tooling-setup devtools: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: - cache-node-modules: true + disable-package-manager-cache: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Run unit tests - run: yarn devtools:test + run: pnpm devtools:test - name: Test build - run: yarn devtools:build:chrome + run: pnpm devtools:build:chrome + - name: Cypress run + uses: cypress-io/github-action@7ef72e250a9e564efb4ed4c2433971ada4cc38b4 # v6.10.4 + with: + command: pnpm devtools:test:e2e + start: pnpm bazel run //devtools/src:devserver + wait-on: 'http://localhost:4200' + wait-on-timeout: 300 + install: false test: - runs-on: ubuntu-latest-4core + runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel Remote Caching - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules - run: yarn install --frozen-lockfile --network-timeout 100000 + run: pnpm install --frozen-lockfile - name: Run CI tests for framework - run: yarn test:ci + run: pnpm test:ci integration-tests: - runs-on: ubuntu-latest-4core + runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel Remote Caching - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules - run: yarn install --frozen-lockfile --network-timeout 100000 + run: pnpm install --frozen-lockfile - name: Run integration CI tests for framework - run: yarn integration-tests:ci + run: pnpm integration-tests:ci adev: runs-on: - labels: ubuntu-latest-4core + labels: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Run tests - run: yarn bazel test //adev/... + run: pnpm bazel test //adev/... - name: Build adev in fast mode to ensure it continues to work - run: yarn bazel build //adev:build --config=release + run: pnpm bazel build //adev:build - publish-snapshots: + vscode-ng-language-service: runs-on: labels: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae + - name: Setup Bazel + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae + - name: Setup Bazel RBE + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: - cache-node-modules: true + google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} + - name: Install node modules + run: pnpm install --frozen-lockfile + - name: Run tests + run: pnpm bazel test //vscode-ng-language-service/... + + publish-snapshots: + runs-on: + labels: ubuntu-latest + steps: + - name: Initialize environment + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials - - run: yarn build - - run: ./scripts/ci/publish-build-artifacts.sh + - run: pnpm build + - run: ./scripts/ci/publish-snapshot-build-artifacts.sh zone-js: runs-on: - labels: ubuntu-latest-4core + labels: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true - node-module-directories: | - ./node_modules - ./packages/zone.js/node_modules - ./packages/zone.js/test/typings/node_modules + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - run: | - yarn bazel build \ + pnpm bazel build \ //packages/zone.js/bundles:zone.umd.js \ //packages/zone.js:npm_package \ - //packages/zone.js/test/closure:closure_js \ + //packages/zone.js/test/closure:closure - run: | rm -Rf packages/zone.js/build @@ -166,50 +177,53 @@ jobs: cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ - cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs + cp dist/bin/packages/zone.js/test/closure/zone.closure.js ./packages/zone.js/build/test/zone.closure.mjs # Install - - run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive + - run: pnpm -C packages/zone.js install --frozen-lockfile # Run zone.js tools tests - - run: yarn --cwd packages/zone.js promisefinallytest - - run: yarn --cwd packages/zone.js jest:test - - run: yarn --cwd packages/zone.js jest:nodetest - - run: yarn --cwd packages/zone.js electrontest - - run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive - - run: yarn --cwd packages/zone.js/test/typings test - - saucelabs: - runs-on: ubuntu-latest-4core - env: - SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }} - steps: - - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true - - name: Install node modules - run: yarn install --frozen-lockfile - - uses: ./.github/actions/saucelabs-legacy + - run: pnpm -C packages/zone.js promisefinallytest + - run: pnpm -C packages/zone.js jest:test + - run: pnpm -C packages/zone.js jest:nodetest + - run: pnpm -C packages/zone.js vitest:test + - run: pnpm -C packages/zone.js electrontest + - run: pnpm -C packages/zone.js/test/typings test + + # saucelabs: + # runs-on: ubuntu-latest + # env: + # SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }} + # steps: + # - name: Initialize environment + # uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b5a3609f89c06eb4037dce22a93641213a5d1508 + # - name: Install node modules + # run: pnpm install --frozen-lockfile + # - uses: ./.github/actions/saucelabs-legacy adev-deploy: needs: [adev] if: needs.adev.result == 'success' - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8core steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile - - name: Build adev to ensure it continues to work - run: yarn bazel build //adev:build --full_build_adev --config=release + run: pnpm install --frozen-lockfile + - name: Build adev + # `snapshot-build` config is used to stamp the exact version with sha in the footer. + run: pnpm bazel build //adev:build.production --config=snapshot-build - name: Deploy to firebase uses: ./.github/actions/deploy-docs-site with: serviceKey: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }} githubReleaseTrainReadToken: ${{ secrets.DOCS_DEPLOY_GITHUB_RELEASE_TRAIN_TOKEN }} configPath: 'adev/firebase.json' - distDir: 'dist/bin/adev/build/browser' + distDir: 'dist/bin/adev/dist' + - name: Update Algolia synonym record + run: pnpm tsx adev/scripts/synonyms/update-synonyms.mts + env: + ALGOLIA_KEY: ${{ secrets.ALGOLIA_SYNONYM_MANAGER }} diff --git a/.github/workflows/cross-repo-adev-docs.yml b/.github/workflows/cross-repo-adev-docs.yml new file mode 100644 index 000000000000..67f96d9a3c82 --- /dev/null +++ b/.github/workflows/cross-repo-adev-docs.yml @@ -0,0 +1,59 @@ +name: Update ADEV Cross Repo Docs + +on: + workflow_dispatch: + inputs: {} + push: + branches: + - 'main' + - '[0-9]+.[0-9]+.x' + +# Declare default permissions as read only. +permissions: + contents: read + +jobs: + update_adev_cross_repo_docs: + name: Update Cross Repo ADEV Docs + if: github.repository == 'angular/angular' + runs-on: ubuntu-latest + # Prevents multiple concurrent runs of this workflow for the same branch + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + steps: + - name: Checkout the repository + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + # Setting `persist-credentials: false` prevents the github-action account from being the + # account that is attempted to be used for authentication, instead the remote is set to + # an authenticated URL. + persist-credentials: false + + - name: Generate Docs + run: node adev/scripts/update-cross-repo-docs/index.mjs + env: + ANGULAR_READONLY_GITHUB_TOKEN: ${{ secrets.READONLY_GITHUB_TOKEN }} + + - name: Create a PR (if necessary) + uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 + with: + token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }} + push-to-fork: 'angular-robot/angular' + delete-branch: true + maintainer-can-modify: false + branch: docs-cross-repo-update-${{github.ref_name}} + committer: Angular Robot + author: Angular Robot + title: 'docs: update cross-repo adev docs [${{github.ref_name}}]' + body: | + Updated Angular adev cross repo docs files. + labels: | + action: merge + area: docs + target: automation + commit-message: | + docs: update cross-repo adev docs + + Updated Angular adev cross repo docs files. diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 93849f2b9113..2fa680b35016 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -12,14 +12,14 @@ jobs: labels: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: angular/dev-infra/github-actions/commit-message-based-labels@1685f0afc967fb7de4b46ccb22f22d779ee3086c + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: angular/dev-infra/github-actions/pull-request-labeling@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: angular/dev-infra/github-actions/post-approval-changes@1685f0afc967fb7de4b46ccb22f22d779ee3086c + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: angular/dev-infra/github-actions/post-approval-changes@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/google-internal-tests.yml b/.github/workflows/google-internal-tests.yml index 21939b75ef4b..32990de791ea 100644 --- a/.github/workflows/google-internal-tests.yml +++ b/.github/workflows/google-internal-tests.yml @@ -13,8 +13,8 @@ jobs: statuses: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: angular/dev-infra/github-actions/google-internal-tests@1685f0afc967fb7de4b46ccb22f22d779ee3086c + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: angular/dev-infra/github-actions/google-internal-tests@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: run-tests-guide-url: http://go/angular-g3sync-start github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 2d05c59ec597..879ce602a691 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -8,27 +8,25 @@ jobs: # Bazel saucelabs job resides in `manual.yml` because it's currently unstable, but # kept as "runnable" for debugging/stabilization effort purposes. bazel-saucelabs: - runs-on: ubuntu-latest-4core + runs-on: ubuntu-latest env: JOBS: 2 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel Remote Caching - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Saucelabs Variables - uses: angular/dev-infra/github-actions/saucelabs@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/saucelabs@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Set up Sauce Tunnel Daemon - run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS & + run: pnpm bazel run //tools/saucelabs-daemon/background-service -- $JOBS & env: SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }} - name: Run all saucelabs bazel tests run: | TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "fixme-saucelabs", ...)') - yarn bazel test --config=saucelabs --jobs=$JOBS ${TESTS} + pnpm bazel test --config=saucelabs --jobs=$JOBS ${TESTS} diff --git a/.github/workflows/merge-ready-status.yml b/.github/workflows/merge-ready-status.yml index d1415d879258..c1c743178ef0 100644 --- a/.github/workflows/merge-ready-status.yml +++ b/.github/workflows/merge-ready-status.yml @@ -9,6 +9,6 @@ jobs: status: runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/unified-status-check@1685f0afc967fb7de4b46ccb22f22d779ee3086c + - uses: angular/dev-infra/github-actions/unified-status-check@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 008e9ce7a480..cb20b81b1dd7 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -21,11 +21,11 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn -s install --frozen-lockfile + run: pnpm install --frozen-lockfile - id: workflows - run: echo "workflows=$(yarn -s ng-dev perf workflows --list)" >> "$GITHUB_OUTPUT" + run: echo "workflows=$(pnpm --silent ng-dev perf workflows --list)" >> "$GITHUB_OUTPUT" workflow: timeout-minutes: 30 @@ -36,18 +36,18 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn -s install --frozen-lockfile + run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow # identity federation. This allows us to request short lived credentials on demand, rather than storing # credentials in secrets long term. More information can be found at: # https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform - - uses: 'google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f' # v2 + - uses: 'google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093' # v3 with: project_id: 'internal-200822' workload_identity_provider: 'projects/823469418460/locations/global/workloadIdentityPools/measurables-tracking/providers/angular' service_account: 'measures-uploader@internal-200822.iam.gserviceaccount.com' - - run: yarn ng-dev perf workflows --name ${{ matrix.workflow }} --commit-sha ${{github.sha}} + - run: pnpm ng-dev perf workflows --name ${{ matrix.workflow }} --commit-sha ${{github.sha}} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index f2b5a9261201..552aec3e3175 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -19,27 +19,25 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Check code lint - run: yarn -s tslint + run: pnpm tslint - name: Check for circular dependencies - run: yarn -s ts-circular-deps:check + run: pnpm ts-circular-deps:check - name: Validate pull approve configuration - run: yarn -s ng-dev pullapprove verify + run: pnpm ng-dev pullapprove verify - name: Validate angular robot configuration - run: yarn -s ng-dev ngbot verify + run: pnpm ng-dev ngbot verify - name: Confirm code builds with typescript as expected - run: yarn -s check-tooling-setup + run: pnpm check-tooling-setup - name: Check commit message - run: yarn ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} + run: pnpm ng-dev commit-message validate-range ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} - name: Check code format - run: yarn ng-dev format changed --check ${{ github.event.pull_request.base.sha }} + run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/linting/licenses@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: allow-dependencies-licenses: 'pkg:npm/google-protobuf@' @@ -47,125 +45,115 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: - cache-node-modules: true + disable-package-manager-cache: true - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Run unit tests - run: yarn devtools:test + run: pnpm devtools:test - name: Test build - run: yarn devtools:build:chrome + run: pnpm devtools:build:chrome + - name: Cypress run + uses: cypress-io/github-action@7ef72e250a9e564efb4ed4c2433971ada4cc38b4 # v6.10.4 + with: + command: pnpm devtools:test:e2e + start: pnpm bazel run //devtools/src:devserver + wait-on: 'http://localhost:4200' + wait-on-timeout: 300 + install: false test: - runs-on: ubuntu-latest-4core + runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel Remote Caching - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile --network-timeout 100000 + run: pnpm install --frozen-lockfile - name: Run CI tests for framework - run: yarn test:ci + run: pnpm test:ci env: # Ensures Aspect lock files are up-to-date. - # TODO(devversion): Remove when removing yarn. + # TODO(devversion): Remove when removing pnpm. ASPECT_RULES_JS_FROZEN_PNPM_LOCK: '1' - name: Upload GRPC logs (for debugging of RBE issues) if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: path: /tmp/rbe-grpc.log retention-days: 1 integration-tests: - runs-on: ubuntu-latest-4core + runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel Remote Caching - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile --network-timeout 100000 + run: pnpm install --frozen-lockfile - name: Run integration CI tests for framework - run: yarn integration-tests:ci + run: pnpm integration-tests:ci - artifacts: - needs: [test] - if: needs.test.result == 'success' - runs-on: ubuntu-latest + adev: + runs-on: + labels: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c - - name: Setup Bazel Remote Caching - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae + - name: Setup Bazel RBE + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile --network-timeout 100000 - - name: Build artifacts - run: yarn tsx ./scripts/build/build-packages-dist.mts - - name: Archive build artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: pr-artifacts-${{ github.event.number }} - path: dist/packages-dist/ + run: pnpm install --frozen-lockfile + - name: Run tests + run: pnpm bazel test //adev/... + - name: Build adev in fast mode to ensure it continues to work + run: pnpm bazel build //adev:build - adev: + vscode-ng-language-service: runs-on: - labels: ubuntu-latest-4core + labels: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Run tests - run: yarn bazel test //adev/... - - name: Build adev in fast mode to ensure it continues to work - run: yarn bazel build //adev:build --config=release + run: pnpm bazel test //vscode-ng-language-service/... zone-js: runs-on: - labels: ubuntu-latest-4core + labels: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true - node-module-directories: | - ./node_modules - ./packages/zone.js/node_modules - ./packages/zone.js/test/typings/node_modules + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@1685f0afc967fb7de4b46ccb22f22d779ee3086c + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - run: | - yarn bazel build \ + pnpm bazel build \ //packages/zone.js/bundles:zone.umd.js \ //packages/zone.js:npm_package \ - //packages/zone.js/test/closure:closure_js \ + //packages/zone.js/test/closure:closure - run: | rm -Rf packages/zone.js/build @@ -177,27 +165,23 @@ jobs: cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ - cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs + cp dist/bin/packages/zone.js/test/closure/zone.closure.js ./packages/zone.js/build/test/zone.closure.mjs - # Install - - run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive # Run zone.js tools tests - - run: yarn --cwd packages/zone.js promisefinallytest - - run: yarn --cwd packages/zone.js jest:test - - run: yarn --cwd packages/zone.js jest:nodetest - - run: yarn --cwd packages/zone.js electrontest - - run: yarn --cwd packages/zone.js/test/typings install --frozen-lockfile --non-interactive - - run: yarn --cwd packages/zone.js/test/typings test - - saucelabs: - runs-on: ubuntu-latest-4core - env: - SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }} - steps: - - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - cache-node-modules: true - - name: Install node modules - run: yarn install --frozen-lockfile - - uses: ./.github/actions/saucelabs-legacy + - run: pnpm -C packages/zone.js promisefinallytest + - run: pnpm -C packages/zone.js jest:test + - run: pnpm -C packages/zone.js jest:nodetest + - run: pnpm -C packages/zone.js vitest:test + - run: pnpm -C packages/zone.js electrontest + - run: pnpm -C packages/zone.js/test/typings test + + # saucelabs: + # runs-on: ubuntu-latest + # env: + # SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }} + # steps: + # - name: Initialize environment + # uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b5a3609f89c06eb4037dce22a93641213a5d1508 + # - name: Install node modules + # run: pnpm install --frozen-lockfile + # - uses: ./.github/actions/saucelabs-legacy diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index eac59abecc87..9de992de9d8f 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -25,12 +25,12 @@ jobs: steps: - name: 'Checkout code' - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false - name: 'Run analysis' - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif @@ -39,7 +39,7 @@ jobs: # Upload the results as artifacts. - name: 'Upload artifact' - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: SARIF file path: results.sarif @@ -47,6 +47,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: sarif_file: results.sarif diff --git a/.github/workflows/sync-angular-robot-forked-repo.yml b/.github/workflows/sync-angular-robot-forked-repo.yml deleted file mode 100644 index f117b5945688..000000000000 --- a/.github/workflows/sync-angular-robot-forked-repo.yml +++ /dev/null @@ -1,46 +0,0 @@ -# This workflow addresses a limitation with Renovate's behavior in fork mode. -# Renovate does not automatically sync non-default branches in forked repositories. - -name: Sync angular-robot Forked Repository -on: - workflow_dispatch: - inputs: {} - push: - branches: - # We do no run this on the default branch (main), as this is done by Renovate. - - '[0-9]+.[0-9]+.x' - -permissions: - contents: read - -jobs: - sync_to_upstream: - runs-on: ubuntu-latest - # Prevents multiple concurrent runs of this workflow for the same branch - concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - steps: - - name: Checkout the repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - ref: ${{ github.ref }} # Checks out the branch that triggered the push - fetch-depth: 100 - persist-credentials: false - - - name: Push to angular-robot upstream remote - run: | - CURRENT_BRANCH="${{ github.ref_name }}" - UPSTREAM_TOKEN="${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }}" - UPSTREAM_OWNER="angular-robot" - UPSTREAM_REPO="angular" - UPSTREAM_URL="https://x-access-token:${UPSTREAM_TOKEN}@github.com/${UPSTREAM_OWNER}/${UPSTREAM_REPO}.git" - - # The UPSTREAM_TOKEN is automatically masked by GitHub Actions for security. - echo "Adding upstream remote: $UPSTREAM_URL" - git remote add upstream "$UPSTREAM_URL" - git remote -v - - echo "Pushing $CURRENT_BRANCH from origin to $UPSTREAM_OWNER upstream..." - git push upstream "$CURRENT_BRANCH" diff --git a/.github/workflows/update-cdk-apis.yml b/.github/workflows/update-cdk-apis.yml deleted file mode 100644 index efdab9f87b63..000000000000 --- a/.github/workflows/update-cdk-apis.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Update ADEV Angular CDK apis - -on: - workflow_dispatch: - inputs: {} - push: - branches: - - 'main' - - '[0-9]+.[0-9]+.x' - -# Declare default permissions as read only. -permissions: - contents: read - -jobs: - update_cdk_apis: - name: Update Angular CDK apis (if necessary) - if: github.repository == 'angular/angular' - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - # Setting `persist-credentials: false` prevents the github-action account from being the - # account that is attempted to be used for authentication, instead the remote is set to - # an authenticated URL. - persist-credentials: false - # This is needed as otherwise the PR creation will fail with `shallow update not allowed` when the forked branch is not in sync. - fetch-depth: 0 - - name: Generate CDK apis - run: node adev/scripts/update-cdk-apis/index.mjs - env: - ANGULAR_CDK_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CDK_BUILDS_READONLY_GITHUB_TOKEN }} - - name: Create a PR (if necessary) - uses: angular/dev-infra/github-actions/create-pr-for-changes@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - branch-prefix: update-cdk-apis - pr-title: 'docs: update Angular CDK apis [${{github.ref_name}}]' - pr-description: | - Updated Angular CDK api files. - pr-labels: | - action: merge - area: docs - angular-robot-token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }} diff --git a/.github/workflows/update-cli-help.yml b/.github/workflows/update-cli-help.yml deleted file mode 100644 index 7df64d8e3d87..000000000000 --- a/.github/workflows/update-cli-help.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Update ADEV Angular CLI help - -on: - workflow_dispatch: - inputs: {} - push: - branches: - - 'main' - - '[0-9]+.[0-9]+.x' - -# Declare default permissions as read only. -permissions: - contents: read - -jobs: - update_cli_help: - name: Update Angular CLI help (if necessary) - if: github.repository == 'angular/angular' - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - # Setting `persist-credentials: false` prevents the github-action account from being the - # account that is attempted to be used for authentication, instead the remote is set to - # an authenticated URL. - persist-credentials: false - # This is needed as otherwise the PR creation will fail with `shallow update not allowed` when the forked branch is not in sync. - fetch-depth: 0 - - name: Generate CLI help - run: node adev/scripts/update-cli-help/index.mjs - env: - ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN }} - - name: Create a PR (if necessary) - uses: angular/dev-infra/github-actions/create-pr-for-changes@1685f0afc967fb7de4b46ccb22f22d779ee3086c - with: - branch-prefix: update-cli-help - pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]' - pr-description: | - Updated Angular CLI help contents. - pr-labels: | - action: review - area: docs - angular-robot-token: ${{ secrets.ANGULAR_ROBOT_ACCESS_TOKEN }} diff --git a/.gitignore b/.gitignore index 8c124604a98f..3a7c650d9a1e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,9 +16,7 @@ pubspec.lock !.devcontainer/recommended-devcontainer.json !.devcontainer/recommended-Dockerfile .settings/ -.vscode/launch.json .vscode/settings.json -.vscode/tasks.json *.swo *.swp modules/.settings diff --git a/.husky/commit-msg b/.husky/commit-msg index 722ef5a097aa..70f42fbe6cb2 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,6 +1,6 @@ set +e -yarn -s ng-dev commit-message pre-commit-validate --file $1 2>/dev/null +pnpm --silent ng-dev commit-message pre-commit-validate --file $1 2>/dev/null if [ $? -ne 0 ]; then echo "WARNING: failed to run commit message validation (ng-dev commit-mesage pre-commit-validate)" fi diff --git a/.husky/pre-commit b/.husky/pre-commit index 858fdf5d9da7..68912c3fb110 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,6 +1,6 @@ set +e -yarn -s ng-dev format staged 2>/dev/null +pnpm --silent ng-dev format staged 2>/dev/null if [ $? -ne 0 ]; then echo "WARNING: failed to run file formatting (ng-dev format staged)" fi diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg index 44b7a18accc2..75e7adc6192a 100755 --- a/.husky/prepare-commit-msg +++ b/.husky/prepare-commit-msg @@ -1,6 +1,6 @@ set +e -yarn -s ng-dev commit-message restore-commit-message-draft $1 $2 2>/dev/null +pnpm --silent ng-dev commit-message restore-commit-message-draft $1 $2 2>/dev/null if [ $? -ne 0 ]; then echo "WARNING: failed to attempt to restore commit message draft (ng-dev commit-message restore-commit-message-draft)" fi diff --git a/.ng-dev/caretaker.mjs b/.ng-dev/caretaker.mjs new file mode 100644 index 000000000000..3f925d278a7b --- /dev/null +++ b/.ng-dev/caretaker.mjs @@ -0,0 +1,23 @@ +/** + * The configuration for `ng-dev caretaker` commands. + * + * @type { import("@angular/ng-dev").CaretakerConfig } + */ +export const caretaker = { + g3SyncConfigPath: './.ng-dev/google-sync-config.json', + githubQueries: [ + { + name: 'Merge Queue', + query: `is:pr is:open label:"action: merge"`, + }, + { + name: 'Merge Assistance Queue', + query: `is:pr is:open label:"merge: caretaker note" label:"action: merge"`, + }, + { + name: 'Initial Triage Queue', + query: `is:open no:milestone -draft:true`, + }, + ], + hasEmeaCaretaker: true, +}; diff --git a/.ng-dev/caretaker.mts b/.ng-dev/caretaker.mts deleted file mode 100644 index f4404dd93563..000000000000 --- a/.ng-dev/caretaker.mts +++ /dev/null @@ -1,21 +0,0 @@ -import {CaretakerConfig} from '@angular/ng-dev'; - -/** The configuration for `ng-dev caretaker` commands. */ -export const caretaker: CaretakerConfig = { - g3SyncConfigPath: './.ng-dev/google-sync-config.json', - githubQueries: [ - { - name: 'Merge Queue', - query: `is:pr is:open label:"action: merge"`, - }, - { - name: 'Merge Assistance Queue', - query: `is:pr is:open label:"merge: caretaker note" label:"action: merge"`, - }, - { - name: 'Initial Triage Queue', - query: `is:open no:milestone -draft:true`, - }, - ], - caretakerGroup: 'angular-caretaker', -}; diff --git a/.ng-dev/commit-message.mjs b/.ng-dev/commit-message.mjs new file mode 100644 index 000000000000..71f349e2b077 --- /dev/null +++ b/.ng-dev/commit-message.mjs @@ -0,0 +1,38 @@ +/** + * The configuration for `ng-dev commit-message` commands. + * + * @type { import("@angular/ng-dev").CommitMessageConfig } + */ +export const commitMessage = { + maxLineLength: Infinity, + minBodyLength: 20, + minBodyLengthTypeExcludes: ['docs'], + // If you update this, also update the docs. + // https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md#scope + scopes: [ + 'animations', + 'benchpress', + 'common', + 'compiler', + 'compiler-cli', + 'core', + 'dev-infra', + 'devtools', + 'docs-infra', + 'elements', + 'forms', + 'http', + 'language-service', + 'language-server', + 'localize', + 'migrations', + 'platform-browser', + 'platform-browser-dynamic', + 'platform-server', + 'router', + 'service-worker', + 'upgrade', + 'vscode-extension', + 'zone.js', + ], +}; diff --git a/.ng-dev/commit-message.mts b/.ng-dev/commit-message.mts deleted file mode 100644 index 524b37608acc..000000000000 --- a/.ng-dev/commit-message.mts +++ /dev/null @@ -1,39 +0,0 @@ -import {CommitMessageConfig} from '@angular/ng-dev'; - -/** - * The configuration for `ng-dev commit-message` commands. - */ -export const commitMessage: CommitMessageConfig = { - maxLineLength: Infinity, - minBodyLength: 20, - minBodyLengthTypeExcludes: ['docs'], - // If you update this, also update the docs. - // https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md#scope - scopes: [ - 'animations', - 'bazel', - 'benchpress', - 'changelog', - 'common', - 'compiler', - 'compiler-cli', - 'core', - 'dev-infra', - 'devtools', - 'docs-infra', - 'elements', - 'forms', - 'http', - 'language-service', - 'localize', - 'migrations', - 'packaging', - 'platform-browser', - 'platform-browser-dynamic', - 'platform-server', - 'router', - 'service-worker', - 'upgrade', - 'zone.js', - ], -}; diff --git a/.ng-dev/config.mjs b/.ng-dev/config.mjs new file mode 100644 index 000000000000..2199c8134c71 --- /dev/null +++ b/.ng-dev/config.mjs @@ -0,0 +1,8 @@ +import {caretaker} from './caretaker.mjs'; +import {commitMessage} from './commit-message.mjs'; +import {format} from './format.mjs'; +import {github} from './github.mjs'; +import {pullRequest} from './pull-request.mjs'; +import {release} from './release.mjs'; + +export {commitMessage, format, github, pullRequest, caretaker, release}; diff --git a/.ng-dev/config.mts b/.ng-dev/config.mts deleted file mode 100644 index c94eca1dd624..000000000000 --- a/.ng-dev/config.mts +++ /dev/null @@ -1,15 +0,0 @@ -import {caretaker} from './caretaker.mjs'; -import {commitMessage} from './commit-message.mjs'; -import {format} from './format.mjs'; -import {github} from './github.mjs'; -import {pullRequest} from './pull-request.mjs'; -import {release} from './release.mjs'; - -export { - commitMessage, - format, - github, - pullRequest, - caretaker, - release, -}; diff --git a/.ng-dev/format.mjs b/.ng-dev/format.mjs new file mode 100644 index 000000000000..53074fadc2ac --- /dev/null +++ b/.ng-dev/format.mjs @@ -0,0 +1,38 @@ +/** + * Configuration for the `ng-dev format` command. + * + * @type { import("@angular/ng-dev").FormatConfig } + */ +export const format = { + 'prettier': { + 'matchers': [ + '**/*.md', + '**/*.{yaml,yml}', + '**/*.{js,ts,mjs,mts,cjs,cts,tsx}', + 'devtools/**/*.{js,ts,mjs,mts,cjs,cts,html,scss}', + 'integration/**/size.json', + // Do not format d.ts files as they are generated + '!**/*.d.ts', + // Both third_party and .yarn are directories containing copied code which should + // not be modified. + '!third_party/**', + // Do not format the locale files which are checked-in for Google3, but generated using + // the `generate-locales-tool` from `packages/common/locales`. + '!packages/core/src/i18n/locale_en.ts', + '!packages/common/locales/closure-locale.ts', + '!packages/common/src/i18n/currencies.ts', + // Test cases contain non valid code. + '!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts,mjs,mts,cjs,cts}', + + // Ignore generated javascript file(s) + '!.github/actions/deploy-docs-site/main.js', + + // Ignore testing data files for language service + '!vscode-ng-language-service/syntaxes/test/data/*.ts', + + // Ignore goldens MD files + '!/goldens/**/*.api.md', + ], + }, + 'buildifier': true, +}; diff --git a/.ng-dev/format.mts b/.ng-dev/format.mts deleted file mode 100644 index 99a938486a07..000000000000 --- a/.ng-dev/format.mts +++ /dev/null @@ -1,32 +0,0 @@ -import {FormatConfig} from '@angular/ng-dev'; - -/** - * Configuration for the `ng-dev format` command. - */ -export const format: FormatConfig = { - 'prettier': { - 'matchers': [ - '**/*.{yaml,yml}', - '**/*.{js,ts,mjs,mts,cjs,cts}', - 'devtools/**/*.{js,ts,mjs,mts,cjs,cts,html,scss}', - - // Do not format d.ts files as they are generated - '!**/*.d.ts', - // Both third_party and .yarn are directories containing copied code which should - // not be modified. - '!third_party/**', - '!.yarn/**', - // Do not format the locale files which are checked-in for Google3, but generated using - // the `generate-locales-tool` from `packages/common/locales`. - '!packages/core/src/i18n/locale_en.ts', - '!packages/common/locales/closure-locale.ts', - '!packages/common/src/i18n/currencies.ts', - // Test cases contain non valid code. - '!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts,mjs,mts,cjs,cts}', - - // Ignore generated javascript file(s) - '!.github/actions/deploy-docs-site/main.js', - ], - }, - 'buildifier': true, -}; diff --git a/.ng-dev/github.mjs b/.ng-dev/github.mjs new file mode 100644 index 000000000000..c1403ae90a33 --- /dev/null +++ b/.ng-dev/github.mjs @@ -0,0 +1,12 @@ +/** + * Github configuration for the `ng-dev` command. This repository is used as + * remote for the merge script and other utilities like `ng-dev pr rebase`. + * + * @type { import("@angular/ng-dev").GithubConfig } + */ +export const github = { + owner: 'angular', + name: 'angular', + mainBranchName: 'main', + useNgDevAuthService: true, +}; diff --git a/.ng-dev/github.mts b/.ng-dev/github.mts deleted file mode 100644 index d77ca110bb3c..000000000000 --- a/.ng-dev/github.mts +++ /dev/null @@ -1,12 +0,0 @@ -import {GithubConfig} from '@angular/ng-dev'; - -/** - * Github configuration for the `ng-dev` command. This repository is used as - * remote for the merge script and other utilities like `ng-dev pr rebase`. - */ -export const github: GithubConfig = { - owner: 'angular', - name: 'angular', - mainBranchName: 'main', - useNgDevAuthService: true, -}; diff --git a/.ng-dev/pull-request.mjs b/.ng-dev/pull-request.mjs new file mode 100644 index 000000000000..44167fdd3e90 --- /dev/null +++ b/.ng-dev/pull-request.mjs @@ -0,0 +1,34 @@ +/** + * Configuration for the merge tool in `ng-dev`. This sets up the labels which + * are respected by the merge script (e.g. the target labels). + * + * @type { import("@angular/ng-dev").PullRequestConfig } + */ +export const pullRequest = { + githubApiMerge: { + default: 'auto', + labels: [{pattern: 'merge: squash commits', method: 'squash'}], + }, + requiredBaseCommits: { + // PRs that target either `main` or the patch branch, need to be rebased + // on top of the latest commit message validation fix. + // These SHAs are the commits that update the required license text in the header. + 'main': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a', + '10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24', + }, + // `docs-infra` are not affecting the public NPM packages. + targetLabelExemptScopes: ['docs-infra'], + // enables specific validations during the pull request merge process + validators: { + assertEnforceTested: true, + assertIsolatedSeparateFiles: true, + }, + + requiredStatuses: [ + {type: 'check', name: 'test'}, + {type: 'check', name: 'lint'}, + {type: 'check', name: 'adev'}, + {type: 'check', name: 'zone-js'}, + {type: 'status', name: 'google-internal-tests'}, + ], +}; diff --git a/.ng-dev/pull-request.mts b/.ng-dev/pull-request.mts deleted file mode 100644 index 237ea813ec9b..000000000000 --- a/.ng-dev/pull-request.mts +++ /dev/null @@ -1,33 +0,0 @@ -import {PullRequestConfig} from '@angular/ng-dev'; - -/** - * Configuration for the merge tool in `ng-dev`. This sets up the labels which - * are respected by the merge script (e.g. the target labels). - */ -export const pullRequest: PullRequestConfig = { - githubApiMerge: false, - requiredBaseCommits: { - // PRs that target either `main` or the patch branch, need to be rebased - // on top of the latest commit message validation fix. - // These SHAs are the commits that update the required license text in the header. - 'main': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a', - '10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24', - }, - // `dev-infra` and `docs-infra` are not affecting the public NPM packages. Similarly, - // the `bazel` package is not considered part of the public API so that features - // can land in patch branches. - targetLabelExemptScopes: ['dev-infra', 'docs-infra', 'bazel'], - // enables specific validations during the pull request merge process - validators: { - assertEnforceTested: true, - assertIsolatedSeparateFiles: true, - }, - - requiredStatuses: [ - {type: 'check', name: 'test'}, - {type: 'check', name: 'lint'}, - {type: 'check', name: 'adev'}, - {type: 'check', name: 'zone-js'}, - {type: 'status', name: 'google-internal-tests'}, - ], -}; diff --git a/.ng-dev/release.mjs b/.ng-dev/release.mjs new file mode 100644 index 000000000000..974cc5df8fcb --- /dev/null +++ b/.ng-dev/release.mjs @@ -0,0 +1,44 @@ +/** + * Configuration for the `ng-dev release` command. + * + * @type { import("@angular/ng-dev").ReleaseConfig } + */ +export const release = { + publishRegistry: 'https://wombat-dressing-room.appspot.com', + representativeNpmPackage: '@angular/core', + npmPackages: [ + {name: '@angular/animations'}, + {name: '@angular/common'}, + {name: '@angular/compiler-cli'}, + {name: '@angular/compiler'}, + {name: '@angular/core'}, + {name: '@angular/elements'}, + {name: '@angular/forms'}, + {name: '@angular/language-server'}, + {name: '@angular/language-service'}, + {name: '@angular/localize'}, + {name: '@angular/platform-browser-dynamic'}, + {name: '@angular/platform-browser'}, + {name: '@angular/platform-server'}, + {name: '@angular/router'}, + {name: '@angular/service-worker'}, + {name: '@angular/upgrade'}, + ], + buildPackages: async () => { + // The buildTargetPackages function is loaded at runtime as the loading the script + // causes an invocation of Bazel. + const {performNpmReleaseBuild} = await import('../scripts/build/package-builder.mjs'); + return performNpmReleaseBuild(); + }, + releaseNotes: { + hiddenScopes: [ + 'dev-infra', + 'docs-infra', + 'zone.js', + 'devtools', + 'vscode-extension', + 'benchpress', + ], + }, + releasePrLabels: ['area: build & ci', 'action: merge', 'PullApprove: disable'], +}; diff --git a/.ng-dev/release.mts b/.ng-dev/release.mts deleted file mode 100644 index dff95e9e6f2a..000000000000 --- a/.ng-dev/release.mts +++ /dev/null @@ -1,35 +0,0 @@ -import {ReleaseConfig} from '@angular/ng-dev'; - -/** Configuration for the `ng-dev release` command. */ -export const release: ReleaseConfig = { - rulesJsInteropMode: true, - publishRegistry: 'https://wombat-dressing-room.appspot.com', - representativeNpmPackage: '@angular/core', - npmPackages: [ - {name: '@angular/animations'}, - {name: '@angular/common'}, - {name: '@angular/compiler'}, - {name: '@angular/compiler-cli'}, - {name: '@angular/core'}, - {name: '@angular/elements'}, - {name: '@angular/forms'}, - {name: '@angular/language-service'}, - {name: '@angular/localize'}, - {name: '@angular/platform-browser'}, - {name: '@angular/platform-browser-dynamic'}, - {name: '@angular/platform-server'}, - {name: '@angular/router'}, - {name: '@angular/service-worker'}, - {name: '@angular/upgrade'}, - ], - buildPackages: async () => { - // The buildTargetPackages function is loaded at runtime as the loading the script - // causes an invocation of Bazel. - const {performNpmReleaseBuild} = await import('../scripts/build/package-builder.mjs'); - return performNpmReleaseBuild(); - }, - releaseNotes: { - hiddenScopes: ['bazel', 'dev-infra', 'docs-infra', 'zone.js', 'devtools'], - }, - releasePrLabels: ['area: build & ci', 'action: merge', 'PullApprove: disable'], -}; diff --git a/.ng-dev/tsconfig.json b/.ng-dev/tsconfig.json index 839312ba78b0..755e28d9d8d9 100644 --- a/.ng-dev/tsconfig.json +++ b/.ng-dev/tsconfig.json @@ -5,6 +5,6 @@ "module": "Node16", "noEmit": true, "skipLibCheck": true, - "types": [] + "types": ["node"] } } diff --git a/.nvmrc b/.nvmrc index b8ffd70759fb..5767036af0e2 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.15.0 +22.21.1 diff --git a/.pnpmfile.cjs b/.pnpmfile.cjs new file mode 100644 index 000000000000..9fbb50301f0c --- /dev/null +++ b/.pnpmfile.cjs @@ -0,0 +1,70 @@ +// TODO: Define these packages in a single common location. +const localAngularPackages = new Set([ + '@angular/animations', + '@angular/common', + '@angular/compiler', + '@angular/compiler-cli', + '@angular/core', + '@angular/elements', + '@angular/forms', + '@angular/language-service', + '@angular/localize', + '@angular/platform-browser', + '@angular/platform-browser-dynamic', + '@angular/platform-server', + '@angular/router', + '@angular/service-worker', + '@angular/upgrade', +]); + +const peerDepsToChange = new Set(['zone.js', 'rxjs']); + +function readPackage(pkg, context) { + // TODO(devversion): This allows us to make compiler/TS a production dependency of compiler-cli + // because `rules_js` doesn't otherwise include the dependency in the `npm_package_store`. + // See: https://github.com/aspect-build/rules_js/issues/2226 + if (pkg.name === '@angular/compiler-cli') { + pkg.dependencies = { + ...pkg.dependencies, + '@angular/compiler': 'workspace:*', + 'typescript': pkg.devDependencies['typescript'], + }; + + delete pkg.devDependencies['typescript']; + } + + for (const [key, version] of Object.entries(pkg.peerDependencies)) { + // Any package that has a peerDependency on rxjs or zone.js, should instead treat the peerDependency as a + // regular dependency. + if (peerDepsToChange.has(key)) { + pkg.dependencies = { + ...pkg.dependencies, + [key]: pkg.devDependencies[key] ?? version, + }; + + delete pkg.devDependencies[key]; + + continue; + } + + // Change all locally generated packages to directly depend on the other local packages, instead + // of expecting them as peerDependencies automatically as we do not auto install peer deps. The + // package is also removed from peerDependencies as it was moved over and will just cause errors. + if (pkg.version === '0.0.0-PLACEHOLDER' && localAngularPackages.has(key)) { + pkg.dependencies = { + ...pkg.dependencies, + [key]: 'workspace: *', + }; + + delete pkg.peerDependencies[key]; + } + } + + return pkg; +} + +module.exports = { + hooks: { + readPackage, + }, +}; diff --git a/.pullapprove.yml b/.pullapprove.yml index a87d5a339ee4..9ef09733b88f 100644 --- a/.pullapprove.yml +++ b/.pullapprove.yml @@ -15,9 +15,6 @@ # - We trust that people do the right thing and won't approve changes they don't feel confident reviewing # - We enforce that only approved PRs are merged ensuring that unreviewed code isn't accidentally merged # - We distribute approval rights as much as possible to help us scale better -# - Groups have one or two global approvers groups as fallbacks: -# - @angular/fw-global-approvers: for approving minor changes, large-scale refactorings, and emergency situations. -# - @angular/fw-global-approvers-for-docs-only-changes: for approving minor documentation-only changes that don't require engineering review # - A small number of file groups have very limited number of reviewers because incorrect changes to the files they guard would have serious consequences (e.g. security, public api) # # Configuration nuances: @@ -37,27 +34,10 @@ # See reviewer list under `required-minimum-review` group. Team member names and # usernames are managed there. -#################################################################################### -# Approval Groups -#################################################################################### -# ========================================================= -# @angular/framework-global-approvers -# ========================================================= -# Used for approving minor changes, large-scale refactorings, and in emergency situations. -# -# alxhub -# jelbourn -# josephperrott -# -# ========================================================= -# @angular/framework-global-approvers-for-docs-only-changes -# ========================================================= -# Used for approving minor documentation-only changes that don't require engineering review. - version: 3 -# availability: -# users_unavailable: ['atscott'] +#availability: +# users_unavailable: [] # Meta field that goes unused by PullApprove to allow for defining aliases to be # used throughout the config. @@ -97,14 +77,6 @@ overrides: - if: len(groups.active.exclude("required-minimum-review").exclude("global-*")) == 0 and len(groups.approved.include("global-*")) == 0 status: failure explanation: 'At least one group must match this PR. Please update an existing review group, or create a new group.' - # If any global dev-infra approval is given the status should be passing. - - if: len(groups.approved.include("global-dev-infra-approvers")) == 1 - status: success - explanation: 'Passing as globally approved by dev-infra' - # If any global docs approval is given the status should be passing. - - if: len(groups.approved.include("global-docs-approvers")) == 1 - status: success - explanation: 'Passing as globally approved by docs' # If any global approval is given the status should be passing. - if: len(groups.approved.include("global-approvers")) == 1 status: success @@ -126,14 +98,19 @@ groups: ]) reviewers: users: - - alxhub + - ~alxhub - AndrewKushnir - atscott - crisbeto - devversion + - thePunderWoman - kirjs - JoostK - mmalerba + - ~amishne + - ~leonsenft + - ~mattrbeck + - ~JeanMeche # ========================================================= # Framework: General (most code in our packages) @@ -163,10 +140,11 @@ groups: 'packages/router/**/{*,.*}', 'packages/service-worker/**/{*,.*}', 'packages/upgrade/**/{*,.*}', + 'vscode-ng-language-service/**/{*,.*}', ]) reviewers: users: - - alxhub + - ~alxhub - AndrewKushnir - atscott - crisbeto @@ -174,8 +152,12 @@ groups: - kirjs - ~jelbourn - thePunderWoman - - pkozlowski-opensource + - ~pkozlowski-opensource - mmalerba + - JeanMeche + - ~amishne + - ~leonsenft + - ~mattrbeck # ========================================================= # Framework: Security-sensitive files which require extra review @@ -197,30 +179,15 @@ groups: ]) reviewers: users: - - alxhub + - ~alxhub - jelbourn - josephperrott - - pkozlowski-opensource + - ~pkozlowski-opensource reviews: request: -1 # request reviews from everyone required: 2 # require at least 2 approvals reviewed_for: required - # ========================================================= - # Bazel - # ========================================================= - bazel: - <<: *defaults - conditions: - - > - contains_any_globs(files, [ - 'packages/bazel/**/{*,.*}', - ]) - reviewers: - users: - - devversion - - josephperrott - # ========================================================= # zone.js # ========================================================= @@ -233,7 +200,20 @@ groups: ]) reviewers: users: - - JiaLiPassion + - ~JiaLiPassion + - ~jelbourn + - ~alxhub + - AndrewKushnir + - atscott + - crisbeto + - devversion + - kirjs + - thePunderWoman + - ~pkozlowski-opensource + - mmalerba + - ~amishne + - ~leonsenft + - ~mattrbeck # ========================================================= # Tooling: Compiler API shared with Angular CLI @@ -271,23 +251,25 @@ groups: reviewers: users: - alan-agius4 - - alxhub + - ~alxhub - AndrewKushnir - atscott - bencodezen - crisbeto - kirjs - - ~JeanMeche + - JeanMeche - jelbourn - thePunderWoman - devversion - josephperrott - - pkozlowski-opensource - - mgechev + - ~pkozlowski-opensource + - ~mgechev - MarkTechson - - kirjs - mmalerba - ~hawkgs + - ~amishne + - ~leonsenft + - ~mattrbeck # ========================================================= # Angular DevTools @@ -302,12 +284,13 @@ groups: reviewers: users: - AleksanderBodurri - - devversion + - ~devversion - dgp1130 - - josephperrott - - mgechev - - MarkTechson - - ~JeanMeche + - hawkgs + - hybrist + - ~josephperrott + - JeanMeche + - milomg # ========================================================= # Dev-infra @@ -321,9 +304,9 @@ groups: '.devcontainer/**/{*,.*}', '.github/**/{*,.*}', '.husky/**/{*,.*}', + '.gemini/**/{*,.*}', '.ng-dev/**/{*,.*}', '.vscode/**/{*,.*}', - '.yarn/**/{*,.*}', 'contributing-docs/*.md', 'contributing-docs/images/**/{*,.*}', 'goldens/{*,.*}', @@ -335,13 +318,11 @@ groups: 'packages/examples/{*,.*}', 'scripts/**/{*,.*}', 'third_party/**/{*,.*}', - 'tools/bazel-repo-patches/**/{*,.*}', 'tools/contributing-stats/**/{*,.*}', - 'tools/esm-interop/**/{*,.*}', 'tools/gulp-tasks/**/{*,.*}', 'tools/legacy-saucelabs/**/{*,.*}', 'tools/manual_api_docs/**/{*,.*}', - 'tools/npm-patches/**/{*,.*}', + 'tools/pnpm-patches/**/{*,.*}', 'tools/rxjs/**/{*,.*}', 'tools/saucelabs-daemon/**/{*,.*}', 'tools/saucelabs/**/{*,.*}', @@ -370,6 +351,7 @@ groups: users: - ~alan-agius4 teams: + - angular-caretaker - framework-team # ========================================================= @@ -387,21 +369,26 @@ groups: reviewers: users: - AndrewKushnir - - alxhub + - ~alxhub - atscott - ~jelbourn - thePunderWoman - - pkozlowski-opensource + - ~pkozlowski-opensource - kirjs - mmalerba - crisbeto - devversion + - JeanMeche + - ~hybrist - ~iteriani - ~tbondwilkinson - ~rahatarmanahmed + - ~amishne + - ~leonsenft + - ~mattrbeck reviews: - request: 3 # Request reviews from 3 people - required: 2 # Require that 2 people approve + request: 2 + required: 1 reviewed_for: required # ================================================ @@ -414,18 +401,21 @@ groups: - *no-groups-above-this-rejected - > contains_any_globs(files, [ - 'goldens/size-tracking/**/{*,.*}' + 'integration/**/size.json' ]) reviewers: users: - - alxhub + - ~alxhub - AndrewKushnir - atscott - kirjs - ~jelbourn - thePunderWoman - - pkozlowski-opensource + - ~pkozlowski-opensource - mmalerba + - ~amishne + - ~leonsenft + - ~mattrbeck reviews: request: 2 # Request reviews from 2 people required: 1 # Require that 1 person approve @@ -447,7 +437,7 @@ groups: ]) reviewers: users: - - alxhub + - ~alxhub - AndrewKushnir - andrewseguin - dgp1130 @@ -469,8 +459,8 @@ groups: ]) reviewers: users: - - pkozlowski-opensource # Pawel Kozlowski - - alxhub # Alex Rickabaugh + - ~pkozlowski-opensource # Pawel Kozlowski + - ~alxhub # Alex Rickabaugh - thePunderWoman # Jessica Janiuk - AndrewKushnir # Andrew Kushnir - atscott # Andrew Scott @@ -519,44 +509,10 @@ groups: global-approvers: type: optional reviewers: - teams: - - framework-global-approvers - reviews: - request: 0 - required: 1 - reviewed_for: required - - # ========================================================= - # Global Approvers For Docs - # - # All reviews performed for global docs approvals require - # using the `Reviewed-for:` specifier to set the approval - # specificity as documented at: - # https://docs.pullapprove.com/reviewed-for/ - # ========================================================= - global-docs-approvers: - type: optional - reviewers: - teams: - - framework-global-approvers-for-docs-only-changes - reviews: - request: 0 - required: 1 - reviewed_for: required - - # ========================================================= - # Global Approvers For Dev-Infra changes - # - # All reviews performed for global dev-infra approvals - # require using the `Reviewed-for:` specifier to set the - # approval specificity as documented at: - # https://docs.pullapprove.com/reviewed-for/ - # ========================================================= - global-dev-infra-approvers: - type: optional - reviewers: - teams: - - dev-infra-framework + users: + - alxhub + - jelbourn + - josephperrott reviews: request: 0 required: 1 diff --git a/.vscode/README.md b/.vscode/README.md index e20581db2bf4..873910d9b3a4 100644 --- a/.vscode/README.md +++ b/.vscode/README.md @@ -8,8 +8,6 @@ To use the recommended configurations follow the steps below: - install the recommended extensions in `.vscode/extensions.json` - copy (or link) `.vscode/recommended-settings.json` to `.vscode/settings.json` -- copy (or link) `.vscode/recommended-launch.json` to `.vscode/launch.json` -- copy (or link) `.vscode/recommended-tasks.json` to `.vscode/tasks.json` - restart the editor If you already have your custom workspace settings, you should instead manually merge the file contents. diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000000..49d3780bb4e4 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,84 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +{ + "version": "0.2.0", + "configurations": [ + { + "type": "extensionHost", + "request": "launch", + "name": "VSCE: Launch Dev Client", + "runtimeExecutable": "${execPath}", + "args": [ + "--disable-extensions", + "--extensionDevelopmentPath=${workspaceFolder}/vscode-ng-language-service" + ], + "preLaunchTask": "VSCE: watch bundles" + }, + { + "type": "extensionHost", + "request": "launch", + "name": "VSCE: Launch Prod Client", + "runtimeExecutable": "${execPath}", + "args": [ + "--disable-extensions", + "--extensionDevelopmentPath=${workspaceFolder}/dist/bin/vscode-ng-language-service/development_package" + ], + "preLaunchTask": "VSCE: package" + }, + { + "name": "VSCE: Attach to Server", + "type": "node", + "request": "attach", + "port": 6009, + "restart": true, + "sourceMaps": true, + "skipFiles": ["/**"], + "sourceMapPathOverrides": { + "?:*/bin/*": "${workspaceFolder}/*" + }, + "resolveSourceMapLocations": ["!**/node_modules/**"] + }, + { + "name": "DEBUG: Attach to bazel test", + "type": "node", + "request": "attach", + "port": 9229, + "restart": true, + "timeout": 600000, + "sourceMaps": true, + "skipFiles": ["/**"], + "sourceMapPathOverrides": { + "?:*/bin/*": "${workspaceFolder}/*" + }, + "resolveSourceMapLocations": ["!**/node_modules/**"] + }, + { + "name": "DEBUG: Run bazel test (Custom Target)", + "type": "node", + "request": "launch", + "restart": true, + "timeout": 600000, + "runtimeExecutable": "pnpm", + "runtimeArgs": ["bazel", "test", "${input:bazelTarget}", "--config=debug"], + "console": "integratedTerminal", + "cwd": "${workspaceFolder}" + } + ], + "compounds": [ + { + "name": "VSCE: Dev Client + Attach to Server", + "configurations": ["VSCE: Launch Dev Client", "VSCE: Attach to Server"] + }, + { + "name": "DEBUG: Run bazel test (Custom Target) + Attach", + "configurations": ["DEBUG: Attach to bazel test", "DEBUG: Run bazel test (Custom Target)"] + } + ], + "inputs": [ + { + "id": "bazelTarget", + "type": "promptString", + "description": "Enter the Bazel test target (e.g., //path/to/my:unit_test)", + "default": "//packages/..." + } + ] +} diff --git a/.vscode/recommended-launch.json b/.vscode/recommended-launch.json deleted file mode 100644 index 2b4439b9e1de..000000000000 --- a/.vscode/recommended-launch.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Attach to bazel test ... --config=debug", - "type": "node", - "request": "attach", - "port": 9229, - "address": "localhost", - "restart": false, - "sourceMaps": true, - "localRoot": "${workspaceRoot}", - "remoteRoot": "${workspaceRoot}", - "stopOnEntry": false, - "timeout": 600000, - "outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"] - }, - { - "name": "Attach to bazel test ... --config=debug (no source maps)", - "type": "node", - "request": "attach", - "port": 9229, - "address": "localhost", - "restart": false, - "sourceMaps": false, - "localRoot": "${workspaceRoot}", - "remoteRoot": "${workspaceRoot}", - "stopOnEntry": false, - "timeout": 600000, - "outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"] - }, - { - "name": "IVY:packages/core/test/acceptance", - "type": "node", - "request": "launch", - "program": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": ["test", "packages/core/test/acceptance", "--config=debug"], - "port": 9229, - "address": "localhost", - "restart": true, - "sourceMaps": true, - "timeout": 600000, - "outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"] - }, - { - "name": "IVY:packages/core/test/render3", - "type": "node", - "request": "launch", - "program": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": ["test", "packages/core/test/render3", "--config=debug"], - "port": 9229, - "address": "localhost", - "restart": true, - "sourceMaps": true, - "timeout": 600000, - "outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"] - }, - { - "name": "IVY:packages/core/test", - "type": "node", - "request": "launch", - "program": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": ["test", "packages/core/test", "--config=debug"], - "port": 9229, - "address": "localhost", - "restart": true, - "sourceMaps": true, - "timeout": 600000, - "outFiles": ["${workspaceFolder}/dist/out/**/packages/**/*.js"] - } - ] -} diff --git a/.vscode/recommended-settings.json b/.vscode/recommended-settings.json index 37139416e2a4..b683f2711722 100644 --- a/.vscode/recommended-settings.json +++ b/.vscode/recommended-settings.json @@ -21,7 +21,5 @@ ".history": true }, "git.ignoreLimitWarning": true, - "gitlens.advanced.blame.customArguments": [ - "--ignore-revs-file .git-blame-ignore-revs" - ] + "gitlens.advanced.blame.customArguments": ["--ignore-revs-file .git-blame-ignore-revs"] } diff --git a/.vscode/recommended-tasks.json b/.vscode/recommended-tasks.json deleted file mode 100644 index 5f33ac12f981..000000000000 --- a/.vscode/recommended-tasks.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "IVY:packages/core/test/...", - "type": "shell", - "command": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": [ - "test", - "packages/core/test", - "packages/core/test/acceptance", - "packages/core/test/render3", - ], - "group": "test", - "presentation": { - "reveal": "always", - "panel": "dedicated", - }, - }, - { - "label": "VE:packages/core/test/...", - "type": "shell", - "command": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": [ - "test", - "packages/core/test", - "packages/core/test/acceptance", - "packages/core/test/render3", - ], - "group": "test", - "presentation": { - "reveal": "always", - "panel": "dedicated", - }, - }, - { - "label": "IVY:packages/core/test/acceptance", - "type": "shell", - "command": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": [ - "test", - "packages/core/test/acceptance", - ], - "group": "test", - "presentation": { - "reveal": "always", - "panel": "dedicated", - }, - }, - { - "label": "VE:packages/core/test/acceptance", - "type": "shell", - "command": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": [ - "test", - "packages/core/test/acceptance", - ], - "group": "test", - "presentation": { - "reveal": "always", - "panel": "dedicated", - }, - }, - { - "label": "IVY:packages/core/test", - "type": "shell", - "command": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": [ - "test", - "packages/core/test", - ], - "group": "test", - "presentation": { - "reveal": "always", - "panel": "dedicated", - }, - }, - { - "label": "VE:packages/core/test", - "type": "shell", - "command": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": [ - "test", - "packages/core/test", - ], - "group": "test", - "presentation": { - "reveal": "always", - "panel": "dedicated", - }, - }, - { - "label": "IVY:packages/core/test/render3", - "type": "shell", - "command": "${workspaceFolder}/node_modules/.bin/bazelisk", - "args": [ - "test", - "packages/core/test/render3", - ], - "group": "test", - "presentation": { - "reveal": "always", - "panel": "dedicated", - }, - }, - ], -} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000000..5520fa6f29a5 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,32 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "shell", + "label": "VSCE: watch bundles", + "command": "pnpm --filter=ng-template run watch", + "isBackground": true, + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "panel": "dedicated", + "reveal": "never" + }, + "problemMatcher": { + "base": "$tsc-watch", + "background": { + "activeOnStart": true, + "beginsPattern": "^iBazel \\[\\d{1,2}:\\d{1,2}(?:AM|PM)\\]: Querying for files to watch.*", + "endsPattern": "^INFO: Build completed successfully, \\d+ total action(s)?" + } + } + }, + { + "type": "shell", + "label": "VSCE: package", + "command": "pnpm --filter=ng-template run package" + } + ] +} diff --git a/.yarn/README.md b/.yarn/README.md deleted file mode 100644 index de1653b9dea0..000000000000 --- a/.yarn/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Yarn Vendoring -We utilize Yarn's `yarn-path` configuration in a shared `.yarnrc` file to enforce -everyone using the same version of Yarn. Yarn checks the `.yarnrc` file to -determine if yarn should delegate the command to a vendored version at the -provided path. - -## How to update -To update to the latest version of Yarn as our vendored version: -- Run this command -```sh -yarn policies set-version latest -``` -- Remove the previous version diff --git a/.yarn/releases/yarn-1.22.22.cjs b/.yarn/releases/yarn-1.22.22.cjs deleted file mode 100755 index ad51d93a8c9c..000000000000 --- a/.yarn/releases/yarn-1.22.22.cjs +++ /dev/null @@ -1,148049 +0,0 @@ -#!/usr/bin/env node -module.exports = -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 517); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -module.exports = require("path"); - -/***/ }), -/* 1 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony export (immutable) */ __webpack_exports__["a"] = __extends; -/* unused harmony export __assign */ -/* unused harmony export __rest */ -/* unused harmony export __decorate */ -/* unused harmony export __param */ -/* unused harmony export __metadata */ -/* unused harmony export __awaiter */ -/* unused harmony export __generator */ -/* unused harmony export __exportStar */ -/* unused harmony export __values */ -/* unused harmony export __read */ -/* unused harmony export __spread */ -/* unused harmony export __await */ -/* unused harmony export __asyncGenerator */ -/* unused harmony export __asyncDelegator */ -/* unused harmony export __asyncValues */ -/* unused harmony export __makeTemplateObject */ -/* unused harmony export __importStar */ -/* unused harmony export __importDefault */ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -function __extends(d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -var __assign = function() { - __assign = Object.assign || function __assign(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; - } - return t; - } - return __assign.apply(this, arguments); -} - -function __rest(s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) - t[p[i]] = s[p[i]]; - return t; -} - -function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -} - -function __param(paramIndex, decorator) { - return function (target, key) { decorator(target, key, paramIndex); } -} - -function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); -} - -function __awaiter(thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -function __exportStar(m, exports) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} - -function __values(o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; - if (m) return m.call(o); - return { - next: function () { - if (o && i >= o.length) o = void 0; - return { value: o && o[i++], done: !o }; - } - }; -} - -function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -} - -function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; -} - -function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); -} - -function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; - function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } - function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } - function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } - function fulfill(value) { resume("next", value); } - function reject(value) { resume("throw", value); } - function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } -} - -function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; - function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } -} - -function __asyncValues(o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); - function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } - function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } -} - -function __makeTemplateObject(cooked, raw) { - if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } - return cooked; -}; - -function __importStar(mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result.default = mod; - return result; -} - -function __importDefault(mod) { - return (mod && mod.__esModule) ? mod : { default: mod }; -} - - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _promise = __webpack_require__(224); - -var _promise2 = _interopRequireDefault(_promise); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = function (fn) { - return function () { - var gen = fn.apply(this, arguments); - return new _promise2.default(function (resolve, reject) { - function step(key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } - - if (info.done) { - resolve(value); - } else { - return _promise2.default.resolve(value).then(function (value) { - step("next", value); - }, function (err) { - step("throw", err); - }); - } - } - - return step("next"); - }); - }; -}; - -/***/ }), -/* 3 */ -/***/ (function(module, exports) { - -module.exports = require("util"); - -/***/ }), -/* 4 */ -/***/ (function(module, exports) { - -module.exports = require("fs"); - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getFirstSuitableFolder = exports.readFirstAvailableStream = exports.makeTempDir = exports.hardlinksWork = exports.writeFilePreservingEol = exports.getFileSizeOnDisk = exports.walk = exports.symlink = exports.find = exports.readJsonAndFile = exports.readJson = exports.readFileAny = exports.hardlinkBulk = exports.copyBulk = exports.unlink = exports.glob = exports.link = exports.chmod = exports.lstat = exports.exists = exports.mkdirp = exports.stat = exports.access = exports.rename = exports.readdir = exports.realpath = exports.readlink = exports.writeFile = exports.open = exports.readFileBuffer = exports.lockQueue = exports.constants = undefined; - -var _asyncToGenerator2; - -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(2)); -} - -let buildActionsForCopy = (() => { - var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { - - // - let build = (() => { - var _ref5 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - const src = data.src, - dest = data.dest, - type = data.type; - - const onFresh = data.onFresh || noop; - const onDone = data.onDone || noop; - - // TODO https://github.com/yarnpkg/yarn/issues/3751 - // related to bundled dependencies handling - if (files.has(dest.toLowerCase())) { - reporter.verbose(`The case-insensitive file ${dest} shouldn't be copied twice in one bulk copy`); - } else { - files.add(dest.toLowerCase()); - } - - if (type === 'symlink') { - yield mkdirp((_path || _load_path()).default.dirname(dest)); - onFresh(); - actions.symlink.push({ - dest, - linkname: src - }); - onDone(); - return; - } - - if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { - // ignored file - return; - } - - const srcStat = yield lstat(src); - let srcFiles; - - if (srcStat.isDirectory()) { - srcFiles = yield readdir(src); - } - - let destStat; - try { - // try accessing the destination - destStat = yield lstat(dest); - } catch (e) { - // proceed if destination doesn't exist, otherwise error - if (e.code !== 'ENOENT') { - throw e; - } - } - - // if destination exists - if (destStat) { - const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); - const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); - const bothFiles = srcStat.isFile() && destStat.isFile(); - - // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving - // us modes that aren't valid. investigate this, it's generally safe to proceed. - - /* if (srcStat.mode !== destStat.mode) { - try { - await access(dest, srcStat.mode); - } catch (err) {} - } */ - - if (bothFiles && artifactFiles.has(dest)) { - // this file gets changed during build, likely by a custom install script. Don't bother checking it. - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); - return; - } - - if (bothFiles && srcStat.size === destStat.size && (0, (_fsNormalized || _load_fsNormalized()).fileDatesEqual)(srcStat.mtime, destStat.mtime)) { - // we can safely assume this is the same file - onDone(); - reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.size, +srcStat.mtime)); - return; - } - - if (bothSymlinks) { - const srcReallink = yield readlink(src); - if (srcReallink === (yield readlink(dest))) { - // if both symlinks are the same then we can continue on - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); - return; - } - } - - if (bothFolders) { - // mark files that aren't in this folder as possibly extraneous - const destFiles = yield readdir(dest); - invariant(srcFiles, 'src files not initialised'); - - for (var _iterator4 = destFiles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { - var _ref6; - - if (_isArray4) { - if (_i4 >= _iterator4.length) break; - _ref6 = _iterator4[_i4++]; - } else { - _i4 = _iterator4.next(); - if (_i4.done) break; - _ref6 = _i4.value; - } - - const file = _ref6; - - if (srcFiles.indexOf(file) < 0) { - const loc = (_path || _load_path()).default.join(dest, file); - possibleExtraneous.add(loc); - - if ((yield lstat(loc)).isDirectory()) { - for (var _iterator5 = yield readdir(loc), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { - var _ref7; - - if (_isArray5) { - if (_i5 >= _iterator5.length) break; - _ref7 = _iterator5[_i5++]; - } else { - _i5 = _iterator5.next(); - if (_i5.done) break; - _ref7 = _i5.value; - } - - const file = _ref7; - - possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); - } - } - } - } - } - } - - if (destStat && destStat.isSymbolicLink()) { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); - destStat = null; - } - - if (srcStat.isSymbolicLink()) { - onFresh(); - const linkname = yield readlink(src); - actions.symlink.push({ - dest, - linkname - }); - onDone(); - } else if (srcStat.isDirectory()) { - if (!destStat) { - reporter.verbose(reporter.lang('verboseFileFolder', dest)); - yield mkdirp(dest); - } - - const destParts = dest.split((_path || _load_path()).default.sep); - while (destParts.length) { - files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); - destParts.pop(); - } - - // push all files to queue - invariant(srcFiles, 'src files not initialised'); - let remaining = srcFiles.length; - if (!remaining) { - onDone(); - } - for (var _iterator6 = srcFiles, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { - var _ref8; - - if (_isArray6) { - if (_i6 >= _iterator6.length) break; - _ref8 = _iterator6[_i6++]; - } else { - _i6 = _iterator6.next(); - if (_i6.done) break; - _ref8 = _i6.value; - } - - const file = _ref8; - - queue.push({ - dest: (_path || _load_path()).default.join(dest, file), - onFresh, - onDone: function (_onDone) { - function onDone() { - return _onDone.apply(this, arguments); - } - - onDone.toString = function () { - return _onDone.toString(); - }; - - return onDone; - }(function () { - if (--remaining === 0) { - onDone(); - } - }), - src: (_path || _load_path()).default.join(src, file) - }); - } - } else if (srcStat.isFile()) { - onFresh(); - actions.file.push({ - src, - dest, - atime: srcStat.atime, - mtime: srcStat.mtime, - mode: srcStat.mode - }); - onDone(); - } else { - throw new Error(`unsure how to copy this: ${src}`); - } - }); - - return function build(_x5) { - return _ref5.apply(this, arguments); - }; - })(); - - const artifactFiles = new Set(events.artifactFiles || []); - const files = new Set(); - - // initialise events - for (var _iterator = queue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref2; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref2 = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref2 = _i.value; - } - - const item = _ref2; - - const onDone = item.onDone; - item.onDone = function () { - events.onProgress(item.dest); - if (onDone) { - onDone(); - } - }; - } - events.onStart(queue.length); - - // start building actions - const actions = { - file: [], - symlink: [], - link: [] - }; - - // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items - // at a time due to the requirement to push items onto the queue - while (queue.length) { - const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); - yield Promise.all(items.map(build)); - } - - // simulate the existence of some files to prevent considering them extraneous - for (var _iterator2 = artifactFiles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref3; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref3 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref3 = _i2.value; - } - - const file = _ref3; - - if (possibleExtraneous.has(file)) { - reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); - possibleExtraneous.delete(file); - } - } - - for (var _iterator3 = possibleExtraneous, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { - var _ref4; - - if (_isArray3) { - if (_i3 >= _iterator3.length) break; - _ref4 = _iterator3[_i3++]; - } else { - _i3 = _iterator3.next(); - if (_i3.done) break; - _ref4 = _i3.value; - } - - const loc = _ref4; - - if (files.has(loc.toLowerCase())) { - possibleExtraneous.delete(loc); - } - } - - return actions; - }); - - return function buildActionsForCopy(_x, _x2, _x3, _x4) { - return _ref.apply(this, arguments); - }; -})(); - -let buildActionsForHardlink = (() => { - var _ref9 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { - - // - let build = (() => { - var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - const src = data.src, - dest = data.dest; - - const onFresh = data.onFresh || noop; - const onDone = data.onDone || noop; - if (files.has(dest.toLowerCase())) { - // Fixes issue https://github.com/yarnpkg/yarn/issues/2734 - // When bulk hardlinking we have A -> B structure that we want to hardlink to A1 -> B1, - // package-linker passes that modules A1 and B1 need to be hardlinked, - // the recursive linking algorithm of A1 ends up scheduling files in B1 to be linked twice which will case - // an exception. - onDone(); - return; - } - files.add(dest.toLowerCase()); - - if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { - // ignored file - return; - } - - const srcStat = yield lstat(src); - let srcFiles; - - if (srcStat.isDirectory()) { - srcFiles = yield readdir(src); - } - - const destExists = yield exists(dest); - if (destExists) { - const destStat = yield lstat(dest); - - const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); - const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); - const bothFiles = srcStat.isFile() && destStat.isFile(); - - if (srcStat.mode !== destStat.mode) { - try { - yield access(dest, srcStat.mode); - } catch (err) { - // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving - // us modes that aren't valid. investigate this, it's generally safe to proceed. - reporter.verbose(err); - } - } - - if (bothFiles && artifactFiles.has(dest)) { - // this file gets changed during build, likely by a custom install script. Don't bother checking it. - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); - return; - } - - // correct hardlink - if (bothFiles && srcStat.ino !== null && srcStat.ino === destStat.ino) { - onDone(); - reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.ino)); - return; - } - - if (bothSymlinks) { - const srcReallink = yield readlink(src); - if (srcReallink === (yield readlink(dest))) { - // if both symlinks are the same then we can continue on - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); - return; - } - } - - if (bothFolders) { - // mark files that aren't in this folder as possibly extraneous - const destFiles = yield readdir(dest); - invariant(srcFiles, 'src files not initialised'); - - for (var _iterator10 = destFiles, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { - var _ref14; - - if (_isArray10) { - if (_i10 >= _iterator10.length) break; - _ref14 = _iterator10[_i10++]; - } else { - _i10 = _iterator10.next(); - if (_i10.done) break; - _ref14 = _i10.value; - } - - const file = _ref14; - - if (srcFiles.indexOf(file) < 0) { - const loc = (_path || _load_path()).default.join(dest, file); - possibleExtraneous.add(loc); - - if ((yield lstat(loc)).isDirectory()) { - for (var _iterator11 = yield readdir(loc), _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { - var _ref15; - - if (_isArray11) { - if (_i11 >= _iterator11.length) break; - _ref15 = _iterator11[_i11++]; - } else { - _i11 = _iterator11.next(); - if (_i11.done) break; - _ref15 = _i11.value; - } - - const file = _ref15; - - possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); - } - } - } - } - } - } - - if (srcStat.isSymbolicLink()) { - onFresh(); - const linkname = yield readlink(src); - actions.symlink.push({ - dest, - linkname - }); - onDone(); - } else if (srcStat.isDirectory()) { - reporter.verbose(reporter.lang('verboseFileFolder', dest)); - yield mkdirp(dest); - - const destParts = dest.split((_path || _load_path()).default.sep); - while (destParts.length) { - files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); - destParts.pop(); - } - - // push all files to queue - invariant(srcFiles, 'src files not initialised'); - let remaining = srcFiles.length; - if (!remaining) { - onDone(); - } - for (var _iterator12 = srcFiles, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) { - var _ref16; - - if (_isArray12) { - if (_i12 >= _iterator12.length) break; - _ref16 = _iterator12[_i12++]; - } else { - _i12 = _iterator12.next(); - if (_i12.done) break; - _ref16 = _i12.value; - } - - const file = _ref16; - - queue.push({ - onFresh, - src: (_path || _load_path()).default.join(src, file), - dest: (_path || _load_path()).default.join(dest, file), - onDone: function (_onDone2) { - function onDone() { - return _onDone2.apply(this, arguments); - } - - onDone.toString = function () { - return _onDone2.toString(); - }; - - return onDone; - }(function () { - if (--remaining === 0) { - onDone(); - } - }) - }); - } - } else if (srcStat.isFile()) { - onFresh(); - actions.link.push({ - src, - dest, - removeDest: destExists - }); - onDone(); - } else { - throw new Error(`unsure how to copy this: ${src}`); - } - }); - - return function build(_x10) { - return _ref13.apply(this, arguments); - }; - })(); - - const artifactFiles = new Set(events.artifactFiles || []); - const files = new Set(); - - // initialise events - for (var _iterator7 = queue, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { - var _ref10; - - if (_isArray7) { - if (_i7 >= _iterator7.length) break; - _ref10 = _iterator7[_i7++]; - } else { - _i7 = _iterator7.next(); - if (_i7.done) break; - _ref10 = _i7.value; - } - - const item = _ref10; - - const onDone = item.onDone || noop; - item.onDone = function () { - events.onProgress(item.dest); - onDone(); - }; - } - events.onStart(queue.length); - - // start building actions - const actions = { - file: [], - symlink: [], - link: [] - }; - - // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items - // at a time due to the requirement to push items onto the queue - while (queue.length) { - const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); - yield Promise.all(items.map(build)); - } - - // simulate the existence of some files to prevent considering them extraneous - for (var _iterator8 = artifactFiles, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { - var _ref11; - - if (_isArray8) { - if (_i8 >= _iterator8.length) break; - _ref11 = _iterator8[_i8++]; - } else { - _i8 = _iterator8.next(); - if (_i8.done) break; - _ref11 = _i8.value; - } - - const file = _ref11; - - if (possibleExtraneous.has(file)) { - reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); - possibleExtraneous.delete(file); - } - } - - for (var _iterator9 = possibleExtraneous, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { - var _ref12; - - if (_isArray9) { - if (_i9 >= _iterator9.length) break; - _ref12 = _iterator9[_i9++]; - } else { - _i9 = _iterator9.next(); - if (_i9.done) break; - _ref12 = _i9.value; - } - - const loc = _ref12; - - if (files.has(loc.toLowerCase())) { - possibleExtraneous.delete(loc); - } - } - - return actions; - }); - - return function buildActionsForHardlink(_x6, _x7, _x8, _x9) { - return _ref9.apply(this, arguments); - }; -})(); - -let copyBulk = exports.copyBulk = (() => { - var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { - const events = { - onStart: _events && _events.onStart || noop, - onProgress: _events && _events.onProgress || noop, - possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), - ignoreBasenames: _events && _events.ignoreBasenames || [], - artifactFiles: _events && _events.artifactFiles || [] - }; - - const actions = yield buildActionsForCopy(queue, events, events.possibleExtraneous, reporter); - events.onStart(actions.file.length + actions.symlink.length + actions.link.length); - - const fileActions = actions.file; - - const currentlyWriting = new Map(); - - yield (_promise || _load_promise()).queue(fileActions, (() => { - var _ref18 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - let writePromise; - while (writePromise = currentlyWriting.get(data.dest)) { - yield writePromise; - } - - reporter.verbose(reporter.lang('verboseFileCopy', data.src, data.dest)); - const copier = (0, (_fsNormalized || _load_fsNormalized()).copyFile)(data, function () { - return currentlyWriting.delete(data.dest); - }); - currentlyWriting.set(data.dest, copier); - events.onProgress(data.dest); - return copier; - }); - - return function (_x14) { - return _ref18.apply(this, arguments); - }; - })(), CONCURRENT_QUEUE_ITEMS); - - // we need to copy symlinks last as they could reference files we were copying - const symlinkActions = actions.symlink; - yield (_promise || _load_promise()).queue(symlinkActions, function (data) { - const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); - reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); - return symlink(linkname, data.dest); - }); - }); - - return function copyBulk(_x11, _x12, _x13) { - return _ref17.apply(this, arguments); - }; -})(); - -let hardlinkBulk = exports.hardlinkBulk = (() => { - var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { - const events = { - onStart: _events && _events.onStart || noop, - onProgress: _events && _events.onProgress || noop, - possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), - artifactFiles: _events && _events.artifactFiles || [], - ignoreBasenames: [] - }; - - const actions = yield buildActionsForHardlink(queue, events, events.possibleExtraneous, reporter); - events.onStart(actions.file.length + actions.symlink.length + actions.link.length); - - const fileActions = actions.link; - - yield (_promise || _load_promise()).queue(fileActions, (() => { - var _ref20 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - reporter.verbose(reporter.lang('verboseFileLink', data.src, data.dest)); - if (data.removeDest) { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(data.dest); - } - yield link(data.src, data.dest); - }); - - return function (_x18) { - return _ref20.apply(this, arguments); - }; - })(), CONCURRENT_QUEUE_ITEMS); - - // we need to copy symlinks last as they could reference files we were copying - const symlinkActions = actions.symlink; - yield (_promise || _load_promise()).queue(symlinkActions, function (data) { - const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); - reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); - return symlink(linkname, data.dest); - }); - }); - - return function hardlinkBulk(_x15, _x16, _x17) { - return _ref19.apply(this, arguments); - }; -})(); - -let readFileAny = exports.readFileAny = (() => { - var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (files) { - for (var _iterator13 = files, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) { - var _ref22; - - if (_isArray13) { - if (_i13 >= _iterator13.length) break; - _ref22 = _iterator13[_i13++]; - } else { - _i13 = _iterator13.next(); - if (_i13.done) break; - _ref22 = _i13.value; - } - - const file = _ref22; - - if (yield exists(file)) { - return readFile(file); - } - } - return null; - }); - - return function readFileAny(_x19) { - return _ref21.apply(this, arguments); - }; -})(); - -let readJson = exports.readJson = (() => { - var _ref23 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - return (yield readJsonAndFile(loc)).object; - }); - - return function readJson(_x20) { - return _ref23.apply(this, arguments); - }; -})(); - -let readJsonAndFile = exports.readJsonAndFile = (() => { - var _ref24 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - const file = yield readFile(loc); - try { - return { - object: (0, (_map || _load_map()).default)(JSON.parse(stripBOM(file))), - content: file - }; - } catch (err) { - err.message = `${loc}: ${err.message}`; - throw err; - } - }); - - return function readJsonAndFile(_x21) { - return _ref24.apply(this, arguments); - }; -})(); - -let find = exports.find = (() => { - var _ref25 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (filename, dir) { - const parts = dir.split((_path || _load_path()).default.sep); - - while (parts.length) { - const loc = parts.concat(filename).join((_path || _load_path()).default.sep); - - if (yield exists(loc)) { - return loc; - } else { - parts.pop(); - } - } - - return false; - }); - - return function find(_x22, _x23) { - return _ref25.apply(this, arguments); - }; -})(); - -let symlink = exports.symlink = (() => { - var _ref26 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest) { - if (process.platform !== 'win32') { - // use relative paths otherwise which will be retained if the directory is moved - src = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(dest), src); - // When path.relative returns an empty string for the current directory, we should instead use - // '.', which is a valid fs.symlink target. - src = src || '.'; - } - - try { - const stats = yield lstat(dest); - if (stats.isSymbolicLink()) { - const resolved = dest; - if (resolved === src) { - return; - } - } - } catch (err) { - if (err.code !== 'ENOENT') { - throw err; - } - } - - // We use rimraf for unlink which never throws an ENOENT on missing target - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); - - if (process.platform === 'win32') { - // use directory junctions if possible on win32, this requires absolute paths - yield fsSymlink(src, dest, 'junction'); - } else { - yield fsSymlink(src, dest); - } - }); - - return function symlink(_x24, _x25) { - return _ref26.apply(this, arguments); - }; -})(); - -let walk = exports.walk = (() => { - var _ref27 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir, relativeDir, ignoreBasenames = new Set()) { - let files = []; - - let filenames = yield readdir(dir); - if (ignoreBasenames.size) { - filenames = filenames.filter(function (name) { - return !ignoreBasenames.has(name); - }); - } - - for (var _iterator14 = filenames, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) { - var _ref28; - - if (_isArray14) { - if (_i14 >= _iterator14.length) break; - _ref28 = _iterator14[_i14++]; - } else { - _i14 = _iterator14.next(); - if (_i14.done) break; - _ref28 = _i14.value; - } - - const name = _ref28; - - const relative = relativeDir ? (_path || _load_path()).default.join(relativeDir, name) : name; - const loc = (_path || _load_path()).default.join(dir, name); - const stat = yield lstat(loc); - - files.push({ - relative, - basename: name, - absolute: loc, - mtime: +stat.mtime - }); - - if (stat.isDirectory()) { - files = files.concat((yield walk(loc, relative, ignoreBasenames))); - } - } - - return files; - }); - - return function walk(_x26, _x27) { - return _ref27.apply(this, arguments); - }; -})(); - -let getFileSizeOnDisk = exports.getFileSizeOnDisk = (() => { - var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - const stat = yield lstat(loc); - const size = stat.size, - blockSize = stat.blksize; - - - return Math.ceil(size / blockSize) * blockSize; - }); - - return function getFileSizeOnDisk(_x28) { - return _ref29.apply(this, arguments); - }; -})(); - -let getEolFromFile = (() => { - var _ref30 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path) { - if (!(yield exists(path))) { - return undefined; - } - - const buffer = yield readFileBuffer(path); - - for (let i = 0; i < buffer.length; ++i) { - if (buffer[i] === cr) { - return '\r\n'; - } - if (buffer[i] === lf) { - return '\n'; - } - } - return undefined; - }); - - return function getEolFromFile(_x29) { - return _ref30.apply(this, arguments); - }; -})(); - -let writeFilePreservingEol = exports.writeFilePreservingEol = (() => { - var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path, data) { - const eol = (yield getEolFromFile(path)) || (_os || _load_os()).default.EOL; - if (eol !== '\n') { - data = data.replace(/\n/g, eol); - } - yield writeFile(path, data); - }); - - return function writeFilePreservingEol(_x30, _x31) { - return _ref31.apply(this, arguments); - }; -})(); - -let hardlinksWork = exports.hardlinksWork = (() => { - var _ref32 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir) { - const filename = 'test-file' + Math.random(); - const file = (_path || _load_path()).default.join(dir, filename); - const fileLink = (_path || _load_path()).default.join(dir, filename + '-link'); - try { - yield writeFile(file, 'test'); - yield link(file, fileLink); - } catch (err) { - return false; - } finally { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(file); - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(fileLink); - } - return true; - }); - - return function hardlinksWork(_x32) { - return _ref32.apply(this, arguments); - }; -})(); - -// not a strict polyfill for Node's fs.mkdtemp - - -let makeTempDir = exports.makeTempDir = (() => { - var _ref33 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (prefix) { - const dir = (_path || _load_path()).default.join((_os || _load_os()).default.tmpdir(), `yarn-${prefix || ''}-${Date.now()}-${Math.random()}`); - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dir); - yield mkdirp(dir); - return dir; - }); - - return function makeTempDir(_x33) { - return _ref33.apply(this, arguments); - }; -})(); - -let readFirstAvailableStream = exports.readFirstAvailableStream = (() => { - var _ref34 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths) { - for (var _iterator15 = paths, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { - var _ref35; - - if (_isArray15) { - if (_i15 >= _iterator15.length) break; - _ref35 = _iterator15[_i15++]; - } else { - _i15 = _iterator15.next(); - if (_i15.done) break; - _ref35 = _i15.value; - } - - const path = _ref35; - - try { - const fd = yield open(path, 'r'); - return (_fs || _load_fs()).default.createReadStream(path, { fd }); - } catch (err) { - // Try the next one - } - } - return null; - }); - - return function readFirstAvailableStream(_x34) { - return _ref34.apply(this, arguments); - }; -})(); - -let getFirstSuitableFolder = exports.getFirstSuitableFolder = (() => { - var _ref36 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths, mode = constants.W_OK | constants.X_OK) { - const result = { - skipped: [], - folder: null - }; - - for (var _iterator16 = paths, _isArray16 = Array.isArray(_iterator16), _i16 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) { - var _ref37; - - if (_isArray16) { - if (_i16 >= _iterator16.length) break; - _ref37 = _iterator16[_i16++]; - } else { - _i16 = _iterator16.next(); - if (_i16.done) break; - _ref37 = _i16.value; - } - - const folder = _ref37; - - try { - yield mkdirp(folder); - yield access(folder, mode); - - result.folder = folder; - - return result; - } catch (error) { - result.skipped.push({ - error, - folder - }); - } - } - return result; - }); - - return function getFirstSuitableFolder(_x35) { - return _ref36.apply(this, arguments); - }; -})(); - -exports.copy = copy; -exports.readFile = readFile; -exports.readFileRaw = readFileRaw; -exports.normalizeOS = normalizeOS; - -var _fs; - -function _load_fs() { - return _fs = _interopRequireDefault(__webpack_require__(4)); -} - -var _glob; - -function _load_glob() { - return _glob = _interopRequireDefault(__webpack_require__(99)); -} - -var _os; - -function _load_os() { - return _os = _interopRequireDefault(__webpack_require__(42)); -} - -var _path; - -function _load_path() { - return _path = _interopRequireDefault(__webpack_require__(0)); -} - -var _blockingQueue; - -function _load_blockingQueue() { - return _blockingQueue = _interopRequireDefault(__webpack_require__(110)); -} - -var _promise; - -function _load_promise() { - return _promise = _interopRequireWildcard(__webpack_require__(51)); -} - -var _promise2; - -function _load_promise2() { - return _promise2 = __webpack_require__(51); -} - -var _map; - -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(30)); -} - -var _fsNormalized; - -function _load_fsNormalized() { - return _fsNormalized = __webpack_require__(216); -} - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const constants = exports.constants = typeof (_fs || _load_fs()).default.constants !== 'undefined' ? (_fs || _load_fs()).default.constants : { - R_OK: (_fs || _load_fs()).default.R_OK, - W_OK: (_fs || _load_fs()).default.W_OK, - X_OK: (_fs || _load_fs()).default.X_OK -}; - -const lockQueue = exports.lockQueue = new (_blockingQueue || _load_blockingQueue()).default('fs lock'); - -const readFileBuffer = exports.readFileBuffer = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readFile); -const open = exports.open = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.open); -const writeFile = exports.writeFile = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.writeFile); -const readlink = exports.readlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readlink); -const realpath = exports.realpath = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.realpath); -const readdir = exports.readdir = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readdir); -const rename = exports.rename = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.rename); -const access = exports.access = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.access); -const stat = exports.stat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.stat); -const mkdirp = exports.mkdirp = (0, (_promise2 || _load_promise2()).promisify)(__webpack_require__(146)); -const exists = exports.exists = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.exists, true); -const lstat = exports.lstat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.lstat); -const chmod = exports.chmod = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.chmod); -const link = exports.link = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.link); -const glob = exports.glob = (0, (_promise2 || _load_promise2()).promisify)((_glob || _load_glob()).default); -exports.unlink = (_fsNormalized || _load_fsNormalized()).unlink; - -// fs.copyFile uses the native file copying instructions on the system, performing much better -// than any JS-based solution and consumes fewer resources. Repeated testing to fine tune the -// concurrency level revealed 128 as the sweet spot on a quad-core, 16 CPU Intel system with SSD. - -const CONCURRENT_QUEUE_ITEMS = (_fs || _load_fs()).default.copyFile ? 128 : 4; - -const fsSymlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.symlink); -const invariant = __webpack_require__(9); -const stripBOM = __webpack_require__(161); - -const noop = () => {}; - -function copy(src, dest, reporter) { - return copyBulk([{ src, dest }], reporter); -} - -function _readFile(loc, encoding) { - return new Promise((resolve, reject) => { - (_fs || _load_fs()).default.readFile(loc, encoding, function (err, content) { - if (err) { - reject(err); - } else { - resolve(content); - } - }); - }); -} - -function readFile(loc) { - return _readFile(loc, 'utf8').then(normalizeOS); -} - -function readFileRaw(loc) { - return _readFile(loc, 'binary'); -} - -function normalizeOS(body) { - return body.replace(/\r\n/g, '\n'); -} - -const cr = '\r'.charCodeAt(0); -const lf = '\n'.charCodeAt(0); - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -class MessageError extends Error { - constructor(msg, code) { - super(msg); - this.code = code; - } - -} - -exports.MessageError = MessageError; -class ProcessSpawnError extends MessageError { - constructor(msg, code, process) { - super(msg, code); - this.process = process; - } - -} - -exports.ProcessSpawnError = ProcessSpawnError; -class SecurityError extends MessageError {} - -exports.SecurityError = SecurityError; -class ProcessTermError extends MessageError {} - -exports.ProcessTermError = ProcessTermError; -class ResponseError extends Error { - constructor(msg, responseCode) { - super(msg); - this.responseCode = responseCode; - } - -} - -exports.ResponseError = ResponseError; -class OneTimePasswordError extends Error { - constructor(notice) { - super(); - this.notice = notice; - } - -} -exports.OneTimePasswordError = OneTimePasswordError; - -/***/ }), -/* 7 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Subscriber; }); -/* unused harmony export SafeSubscriber */ -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_tslib__ = __webpack_require__(1); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_isFunction__ = __webpack_require__(155); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Observer__ = __webpack_require__(420); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Subscription__ = __webpack_require__(25); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__internal_symbol_rxSubscriber__ = __webpack_require__(322); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__config__ = __webpack_require__(186); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_hostReportError__ = __webpack_require__(324); -/** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ - - - - - - - -var Subscriber = /*@__PURE__*/ (function (_super) { - __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](Subscriber, _super); - function Subscriber(destinationOrNext, error, complete) { - var _this = _super.call(this) || this; - _this.syncErrorValue = null; - _this.syncErrorThrown = false; - _this.syncErrorThrowable = false; - _this.isStopped = false; - _this._parentSubscription = null; - switch (arguments.length) { - case 0: - _this.destination = __WEBPACK_IMPORTED_MODULE_2__Observer__["a" /* empty */]; - break; - case 1: - if (!destinationOrNext) { - _this.destination = __WEBPACK_IMPORTED_MODULE_2__Observer__["a" /* empty */]; - break; - } - if (typeof destinationOrNext === 'object') { - if (destinationOrNext instanceof Subscriber) { - _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; - _this.destination = destinationOrNext; - destinationOrNext.add(_this); - } - else { - _this.syncErrorThrowable = true; - _this.destination = new SafeSubscriber(_this, destinationOrNext); - } - break; - } - default: - _this.syncErrorThrowable = true; - _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); - break; - } - return _this; - } - Subscriber.prototype[__WEBPACK_IMPORTED_MODULE_4__internal_symbol_rxSubscriber__["a" /* rxSubscriber */]] = function () { return this; }; - Subscriber.create = function (next, error, complete) { - var subscriber = new Subscriber(next, error, complete); - subscriber.syncErrorThrowable = false; - return subscriber; - }; - Subscriber.prototype.next = function (value) { - if (!this.isStopped) { - this._next(value); - } - }; - Subscriber.prototype.error = function (err) { - if (!this.isStopped) { - this.isStopped = true; - this._error(err); - } - }; - Subscriber.prototype.complete = function () { - if (!this.isStopped) { - this.isStopped = true; - this._complete(); - } - }; - Subscriber.prototype.unsubscribe = function () { - if (this.closed) { - return; - } - this.isStopped = true; - _super.prototype.unsubscribe.call(this); - }; - Subscriber.prototype._next = function (value) { - this.destination.next(value); - }; - Subscriber.prototype._error = function (err) { - this.destination.error(err); - this.unsubscribe(); - }; - Subscriber.prototype._complete = function () { - this.destination.complete(); - this.unsubscribe(); - }; - Subscriber.prototype._unsubscribeAndRecycle = function () { - var _a = this, _parent = _a._parent, _parents = _a._parents; - this._parent = null; - this._parents = null; - this.unsubscribe(); - this.closed = false; - this.isStopped = false; - this._parent = _parent; - this._parents = _parents; - this._parentSubscription = null; - return this; - }; - return Subscriber; -}(__WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */])); - -var SafeSubscriber = /*@__PURE__*/ (function (_super) { - __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](SafeSubscriber, _super); - function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { - var _this = _super.call(this) || this; - _this._parentSubscriber = _parentSubscriber; - var next; - var context = _this; - if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_isFunction__["a" /* isFunction */])(observerOrNext)) { - next = observerOrNext; - } - else if (observerOrNext) { - next = observerOrNext.next; - error = observerOrNext.error; - complete = observerOrNext.complete; - if (observerOrNext !== __WEBPACK_IMPORTED_MODULE_2__Observer__["a" /* empty */]) { - context = Object.create(observerOrNext); - if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_isFunction__["a" /* isFunction */])(context.unsubscribe)) { - _this.add(context.unsubscribe.bind(context)); - } - context.unsubscribe = _this.unsubscribe.bind(_this); - } - } - _this._context = context; - _this._next = next; - _this._error = error; - _this._complete = complete; - return _this; - } - SafeSubscriber.prototype.next = function (value) { - if (!this.isStopped && this._next) { - var _parentSubscriber = this._parentSubscriber; - if (!__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(this._next, value); - } - else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var _parentSubscriber = this._parentSubscriber; - var useDeprecatedSynchronousErrorHandling = __WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling; - if (this._error) { - if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(this._error, err); - this.unsubscribe(); - } - else { - this.__tryOrSetError(_parentSubscriber, this._error, err); - this.unsubscribe(); - } - } - else if (!_parentSubscriber.syncErrorThrowable) { - this.unsubscribe(); - if (useDeprecatedSynchronousErrorHandling) { - throw err; - } - __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); - } - else { - if (useDeprecatedSynchronousErrorHandling) { - _parentSubscriber.syncErrorValue = err; - _parentSubscriber.syncErrorThrown = true; - } - else { - __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); - } - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.complete = function () { - var _this = this; - if (!this.isStopped) { - var _parentSubscriber = this._parentSubscriber; - if (this._complete) { - var wrappedComplete = function () { return _this._complete.call(_this._context); }; - if (!__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(wrappedComplete); - this.unsubscribe(); - } - else { - this.__tryOrSetError(_parentSubscriber, wrappedComplete); - this.unsubscribe(); - } - } - else { - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { - try { - fn.call(this._context, value); - } - catch (err) { - this.unsubscribe(); - if (__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { - throw err; - } - else { - __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); - } - } - }; - SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { - if (!__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { - throw new Error('bad call'); - } - try { - fn.call(this._context, value); - } - catch (err) { - if (__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { - parent.syncErrorValue = err; - parent.syncErrorThrown = true; - return true; - } - else { - __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); - return true; - } - } - return false; - }; - SafeSubscriber.prototype._unsubscribe = function () { - var _parentSubscriber = this._parentSubscriber; - this._context = null; - this._parentSubscriber = null; - _parentSubscriber.unsubscribe(); - }; - return SafeSubscriber; -}(Subscriber)); - -//# sourceMappingURL=Subscriber.js.map - - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getPathKey = getPathKey; -const os = __webpack_require__(42); -const path = __webpack_require__(0); -const userHome = __webpack_require__(67).default; - -var _require = __webpack_require__(222); - -const getCacheDir = _require.getCacheDir, - getConfigDir = _require.getConfigDir, - getDataDir = _require.getDataDir; - -const isWebpackBundle = __webpack_require__(278); - -const DEPENDENCY_TYPES = exports.DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies', 'peerDependencies']; -const OWNED_DEPENDENCY_TYPES = exports.OWNED_DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies']; - -const RESOLUTIONS = exports.RESOLUTIONS = 'resolutions'; -const MANIFEST_FIELDS = exports.MANIFEST_FIELDS = [RESOLUTIONS, ...DEPENDENCY_TYPES]; - -const SUPPORTED_NODE_VERSIONS = exports.SUPPORTED_NODE_VERSIONS = '^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0'; - -const YARN_REGISTRY = exports.YARN_REGISTRY = 'https://registry.yarnpkg.com'; -const NPM_REGISTRY_RE = exports.NPM_REGISTRY_RE = /https?:\/\/registry\.npmjs\.org/g; - -const YARN_DOCS = exports.YARN_DOCS = 'https://yarnpkg.com/en/docs/cli/'; -const YARN_INSTALLER_SH = exports.YARN_INSTALLER_SH = 'https://yarnpkg.com/install.sh'; -const YARN_INSTALLER_MSI = exports.YARN_INSTALLER_MSI = 'https://yarnpkg.com/latest.msi'; - -const SELF_UPDATE_VERSION_URL = exports.SELF_UPDATE_VERSION_URL = 'https://yarnpkg.com/latest-version'; - -// cache version, bump whenever we make backwards incompatible changes -const CACHE_VERSION = exports.CACHE_VERSION = 6; - -// lockfile version, bump whenever we make backwards incompatible changes -const LOCKFILE_VERSION = exports.LOCKFILE_VERSION = 1; - -// max amount of network requests to perform concurrently -const NETWORK_CONCURRENCY = exports.NETWORK_CONCURRENCY = 8; - -// HTTP timeout used when downloading packages -const NETWORK_TIMEOUT = exports.NETWORK_TIMEOUT = 30 * 1000; // in milliseconds - -// max amount of child processes to execute concurrently -const CHILD_CONCURRENCY = exports.CHILD_CONCURRENCY = 5; - -const REQUIRED_PACKAGE_KEYS = exports.REQUIRED_PACKAGE_KEYS = ['name', 'version', '_uid']; - -function getPreferredCacheDirectories() { - const preferredCacheDirectories = [getCacheDir()]; - - if (process.getuid) { - // $FlowFixMe: process.getuid exists, dammit - preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache-${process.getuid()}`)); - } - - preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache`)); - - return preferredCacheDirectories; -} - -const PREFERRED_MODULE_CACHE_DIRECTORIES = exports.PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories(); -const CONFIG_DIRECTORY = exports.CONFIG_DIRECTORY = getConfigDir(); -const DATA_DIRECTORY = exports.DATA_DIRECTORY = getDataDir(); -const LINK_REGISTRY_DIRECTORY = exports.LINK_REGISTRY_DIRECTORY = path.join(DATA_DIRECTORY, 'link'); -const GLOBAL_MODULE_DIRECTORY = exports.GLOBAL_MODULE_DIRECTORY = path.join(DATA_DIRECTORY, 'global'); - -const NODE_BIN_PATH = exports.NODE_BIN_PATH = process.execPath; -const YARN_BIN_PATH = exports.YARN_BIN_PATH = getYarnBinPath(); - -// Webpack needs to be configured with node.__dirname/__filename = false -function getYarnBinPath() { - if (isWebpackBundle) { - return __filename; - } else { - return path.join(__dirname, '..', 'bin', 'yarn.js'); - } -} - -const NODE_MODULES_FOLDER = exports.NODE_MODULES_FOLDER = 'node_modules'; -const NODE_PACKAGE_JSON = exports.NODE_PACKAGE_JSON = 'package.json'; - -const PNP_FILENAME = exports.PNP_FILENAME = '.pnp.js'; - -const POSIX_GLOBAL_PREFIX = exports.POSIX_GLOBAL_PREFIX = `${process.env.DESTDIR || ''}/usr/local`; -const FALLBACK_GLOBAL_PREFIX = exports.FALLBACK_GLOBAL_PREFIX = path.join(userHome, '.yarn'); - -const META_FOLDER = exports.META_FOLDER = '.yarn-meta'; -const INTEGRITY_FILENAME = exports.INTEGRITY_FILENAME = '.yarn-integrity'; -const LOCKFILE_FILENAME = exports.LOCKFILE_FILENAME = 'yarn.lock'; -const METADATA_FILENAME = exports.METADATA_FILENAME = '.yarn-metadata.json'; -const TARBALL_FILENAME = exports.TARBALL_FILENAME = '.yarn-tarball.tgz'; -const CLEAN_FILENAME = exports.CLEAN_FILENAME = '.yarnclean'; - -const NPM_LOCK_FILENAME = exports.NPM_LOCK_FILENAME = 'package-lock.json'; -const NPM_SHRINKWRAP_FILENAME = exports.NPM_SHRINKWRAP_FILENAME = 'npm-shrinkwrap.json'; - -const DEFAULT_INDENT = exports.DEFAULT_INDENT = ' '; -const SINGLE_INSTANCE_PORT = exports.SINGLE_INSTANCE_PORT = 31997; -const SINGLE_INSTANCE_FILENAME = exports.SINGLE_INSTANCE_FILENAME = '.yarn-single-instance'; - -const ENV_PATH_KEY = exports.ENV_PATH_KEY = getPathKey(process.platform, process.env); - -function getPathKey(platform, env) { - let pathKey = 'PATH'; - - // windows calls its path "Path" usually, but this is not guaranteed. - if (platform === 'win32') { - pathKey = 'Path'; - - for (const key in env) { - if (key.toLowerCase() === 'path') { - pathKey = key; - } - } - } - - return pathKey; -} - -const VERSION_COLOR_SCHEME = exports.VERSION_COLOR_SCHEME = { - major: 'red', - premajor: 'red', - minor: 'yellow', - preminor: 'yellow', - patch: 'green', - prepatch: 'green', - prerelease: 'red', - unchanged: 'white', - unknown: 'red' -}; - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - - - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var NODE_ENV = process.env.NODE_ENV; - -var invariant = function(condition, format, a, b, c, d, e, f) { - if (NODE_ENV !== 'production') { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - error.name = 'Invariant Violation'; - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - - -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var YAMLException = __webpack_require__(55); - -var TYPE_CONSTRUCTOR_OPTIONS = [ - 'kind', - 'resolve', - 'construct', - 'instanceOf', - 'predicate', - 'represent', - 'defaultStyle', - 'styleAliases' -]; - -var YAML_NODE_KINDS = [ - 'scalar', - 'sequence', - 'mapping' -]; - -function compileStyleAliases(map) { - var result = {}; - - if (map !== null) { - Object.keys(map).forEach(function (style) { - map[style].forEach(function (alias) { - result[String(alias)] = style; - }); - }); - } - - return result; -} - -function Type(tag, options) { - options = options || {}; - - Object.keys(options).forEach(function (name) { - if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { - throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); - } - }); - - // TODO: Add tag format check. - this.tag = tag; - this.kind = options['kind'] || null; - this.resolve = options['resolve'] || function () { return true; }; - this.construct = options['construct'] || function (data) { return data; }; - this.instanceOf = options['instanceOf'] || null; - this.predicate = options['predicate'] || null; - this.represent = options['represent'] || null; - this.defaultStyle = options['defaultStyle'] || null; - this.styleAliases = compileStyleAliases(options['styleAliases'] || null); - - if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { - throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); - } -} - -module.exports = Type; - - -/***/ }), -/* 11 */ -/***/ (function(module, exports) { - -module.exports = require("crypto"); - -/***/ }), -/* 12 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Observable; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_canReportError__ = __webpack_require__(323); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_toSubscriber__ = __webpack_require__(932); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__internal_symbol_observable__ = __webpack_require__(118); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_pipe__ = __webpack_require__(325); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__config__ = __webpack_require__(186); -/** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_internal_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ - - - - - -var Observable = /*@__PURE__*/ (function () { - function Observable(subscribe) { - this._isScalar = false; - if (subscribe) { - this._subscribe = subscribe; - } - } - Observable.prototype.lift = function (operator) { - var observable = new Observable(); - observable.source = this; - observable.operator = operator; - return observable; - }; - Observable.prototype.subscribe = function (observerOrNext, error, complete) { - var operator = this.operator; - var sink = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_toSubscriber__["a" /* toSubscriber */])(observerOrNext, error, complete); - if (operator) { - operator.call(sink, this.source); - } - else { - sink.add(this.source || (__WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? - this._subscribe(sink) : - this._trySubscribe(sink)); - } - if (__WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { - if (sink.syncErrorThrowable) { - sink.syncErrorThrowable = false; - if (sink.syncErrorThrown) { - throw sink.syncErrorValue; - } - } - } - return sink; - }; - Observable.prototype._trySubscribe = function (sink) { - try { - return this._subscribe(sink); - } - catch (err) { - if (__WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { - sink.syncErrorThrown = true; - sink.syncErrorValue = err; - } - if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__util_canReportError__["a" /* canReportError */])(sink)) { - sink.error(err); - } - else { - console.warn(err); - } - } - }; - Observable.prototype.forEach = function (next, promiseCtor) { - var _this = this; - promiseCtor = getPromiseCtor(promiseCtor); - return new promiseCtor(function (resolve, reject) { - var subscription; - subscription = _this.subscribe(function (value) { - try { - next(value); - } - catch (err) { - reject(err); - if (subscription) { - subscription.unsubscribe(); - } - } - }, reject, resolve); - }); - }; - Observable.prototype._subscribe = function (subscriber) { - var source = this.source; - return source && source.subscribe(subscriber); - }; - Observable.prototype[__WEBPACK_IMPORTED_MODULE_2__internal_symbol_observable__["a" /* observable */]] = function () { - return this; - }; - Observable.prototype.pipe = function () { - var operations = []; - for (var _i = 0; _i < arguments.length; _i++) { - operations[_i] = arguments[_i]; - } - if (operations.length === 0) { - return this; - } - return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util_pipe__["b" /* pipeFromArray */])(operations)(this); - }; - Observable.prototype.toPromise = function (promiseCtor) { - var _this = this; - promiseCtor = getPromiseCtor(promiseCtor); - return new promiseCtor(function (resolve, reject) { - var value; - _this.subscribe(function (x) { return value = x; }, function (err) { return reject(err); }, function () { return resolve(value); }); - }); - }; - Observable.create = function (subscribe) { - return new Observable(subscribe); - }; - return Observable; -}()); - -function getPromiseCtor(promiseCtor) { - if (!promiseCtor) { - promiseCtor = __WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].Promise || Promise; - } - if (!promiseCtor) { - throw new Error('no Promise impl found'); - } - return promiseCtor; -} -//# sourceMappingURL=Observable.js.map - - -/***/ }), -/* 13 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return OuterSubscriber; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_tslib__ = __webpack_require__(1); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Subscriber__ = __webpack_require__(7); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - - -var OuterSubscriber = /*@__PURE__*/ (function (_super) { - __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](OuterSubscriber, _super); - function OuterSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; - } - OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); - }; - OuterSubscriber.prototype.notifyError = function (error, innerSub) { - this.destination.error(error); - }; - OuterSubscriber.prototype.notifyComplete = function (innerSub) { - this.destination.complete(); - }; - return OuterSubscriber; -}(__WEBPACK_IMPORTED_MODULE_1__Subscriber__["a" /* Subscriber */])); - -//# sourceMappingURL=OuterSubscriber.js.map - - -/***/ }), -/* 14 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony export (immutable) */ __webpack_exports__["a"] = subscribeToResult; -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__InnerSubscriber__ = __webpack_require__(84); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__subscribeTo__ = __webpack_require__(446); -/** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo PURE_IMPORTS_END */ - - -function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, destination) { - if (destination === void 0) { - destination = new __WEBPACK_IMPORTED_MODULE_0__InnerSubscriber__["a" /* InnerSubscriber */](outerSubscriber, outerValue, outerIndex); - } - if (destination.closed) { - return; - } - return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__subscribeTo__["a" /* subscribeTo */])(result)(destination); -} -//# sourceMappingURL=subscribeToResult.js.map - - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* eslint-disable node/no-deprecated-api */ - - - -var buffer = __webpack_require__(64) -var Buffer = buffer.Buffer - -var safer = {} - -var key - -for (key in buffer) { - if (!buffer.hasOwnProperty(key)) continue - if (key === 'SlowBuffer' || key === 'Buffer') continue - safer[key] = buffer[key] -} - -var Safer = safer.Buffer = {} -for (key in Buffer) { - if (!Buffer.hasOwnProperty(key)) continue - if (key === 'allocUnsafe' || key === 'allocUnsafeSlow') continue - Safer[key] = Buffer[key] -} - -safer.Buffer.prototype = Buffer.prototype - -if (!Safer.from || Safer.from === Uint8Array.from) { - Safer.from = function (value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('The "value" argument must not be of type number. Received type ' + typeof value) - } - if (value && typeof value.length === 'undefined') { - throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + typeof value) - } - return Buffer(value, encodingOrOffset, length) - } -} - -if (!Safer.alloc) { - Safer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size) - } - if (size < 0 || size >= 2 * (1 << 30)) { - throw new RangeError('The value "' + size + '" is invalid for option "size"') - } - var buf = Buffer(size) - if (!fill || fill.length === 0) { - buf.fill(0) - } else if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) - } - return buf - } -} - -if (!safer.kStringMaxLength) { - try { - safer.kStringMaxLength = process.binding('buffer').kStringMaxLength - } catch (e) { - // we can't determine kStringMaxLength in environments where process.binding - // is unsupported, so let's not set it - } -} - -if (!safer.constants) { - safer.constants = { - MAX_LENGTH: safer.kMaxLength - } - if (safer.kStringMaxLength) { - safer.constants.MAX_STRING_LENGTH = safer.kStringMaxLength - } -} - -module.exports = safer - - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright (c) 2012, Mark Cavage. All rights reserved. -// Copyright 2015 Joyent, Inc. - -var assert = __webpack_require__(29); -var Stream = __webpack_require__(23).Stream; -var util = __webpack_require__(3); - - -///--- Globals - -/* JSSTYLED */ -var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; - - -///--- Internal - -function _capitalize(str) { - return (str.charAt(0).toUpperCase() + str.slice(1)); -} - -function _toss(name, expected, oper, arg, actual) { - throw new assert.AssertionError({ - message: util.format('%s (%s) is required', name, expected), - actual: (actual === undefined) ? typeof (arg) : actual(arg), - expected: expected, - operator: oper || '===', - stackStartFunction: _toss.caller - }); -} - -function _getClass(arg) { - return (Object.prototype.toString.call(arg).slice(8, -1)); -} - -function noop() { - // Why even bother with asserts? -} - - -///--- Exports - -var types = { - bool: { - check: function (arg) { return typeof (arg) === 'boolean'; } - }, - func: { - check: function (arg) { return typeof (arg) === 'function'; } - }, - string: { - check: function (arg) { return typeof (arg) === 'string'; } - }, - object: { - check: function (arg) { - return typeof (arg) === 'object' && arg !== null; - } - }, - number: { - check: function (arg) { - return typeof (arg) === 'number' && !isNaN(arg); - } - }, - finite: { - check: function (arg) { - return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); - } - }, - buffer: { - check: function (arg) { return Buffer.isBuffer(arg); }, - operator: 'Buffer.isBuffer' - }, - array: { - check: function (arg) { return Array.isArray(arg); }, - operator: 'Array.isArray' - }, - stream: { - check: function (arg) { return arg instanceof Stream; }, - operator: 'instanceof', - actual: _getClass - }, - date: { - check: function (arg) { return arg instanceof Date; }, - operator: 'instanceof', - actual: _getClass - }, - regexp: { - check: function (arg) { return arg instanceof RegExp; }, - operator: 'instanceof', - actual: _getClass - }, - uuid: { - check: function (arg) { - return typeof (arg) === 'string' && UUID_REGEXP.test(arg); - }, - operator: 'isUUID' - } -}; - -function _setExports(ndebug) { - var keys = Object.keys(types); - var out; - - /* re-export standard assert */ - if (process.env.NODE_NDEBUG) { - out = noop; - } else { - out = function (arg, msg) { - if (!arg) { - _toss(msg, 'true', arg); - } - }; - } - - /* standard checks */ - keys.forEach(function (k) { - if (ndebug) { - out[k] = noop; - return; - } - var type = types[k]; - out[k] = function (arg, msg) { - if (!type.check(arg)) { - _toss(msg, k, type.operator, arg, type.actual); - } - }; - }); - - /* optional checks */ - keys.forEach(function (k) { - var name = 'optional' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - out[name] = function (arg, msg) { - if (arg === undefined || arg === null) { - return; - } - if (!type.check(arg)) { - _toss(msg, k, type.operator, arg, type.actual); - } - }; - }); - - /* arrayOf checks */ - keys.forEach(function (k) { - var name = 'arrayOf' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - var expected = '[' + k + ']'; - out[name] = function (arg, msg) { - if (!Array.isArray(arg)) { - _toss(msg, expected, type.operator, arg, type.actual); - } - var i; - for (i = 0; i < arg.length; i++) { - if (!type.check(arg[i])) { - _toss(msg, expected, type.operator, arg, type.actual); - } - } - }; - }); - - /* optionalArrayOf checks */ - keys.forEach(function (k) { - var name = 'optionalArrayOf' + _capitalize(k); - if (ndebug) { - out[name] = noop; - return; - } - var type = types[k]; - var expected = '[' + k + ']'; - out[name] = function (arg, msg) { - if (arg === undefined || arg === null) { - return; - } - if (!Array.isArray(arg)) { - _toss(msg, expected, type.operator, arg, type.actual); - } - var i; - for (i = 0; i < arg.length; i++) { - if (!type.check(arg[i])) { - _toss(msg, expected, type.operator, arg, type.actual); - } - } - }; - }); - - /* re-export built-in assertions */ - Object.keys(assert).forEach(function (k) { - if (k === 'AssertionError') { - out[k] = assert[k]; - return; - } - if (ndebug) { - out[k] = noop; - return; - } - out[k] = assert[k]; - }); - - /* export ourselves (for unit tests _only_) */ - out._setExports = _setExports; - - return out; -} - -module.exports = _setExports(process.env.NODE_NDEBUG); - - -/***/ }), -/* 17 */ -/***/ (function(module, exports) { - -// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 -var global = module.exports = typeof window != 'undefined' && window.Math == Math - ? window : typeof self != 'undefined' && self.Math == Math ? self - // eslint-disable-next-line no-new-func - : Function('return this')(); -if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.sortAlpha = sortAlpha; -exports.sortOptionsByFlags = sortOptionsByFlags; -exports.entries = entries; -exports.removePrefix = removePrefix; -exports.removeSuffix = removeSuffix; -exports.addSuffix = addSuffix; -exports.hyphenate = hyphenate; -exports.camelCase = camelCase; -exports.compareSortedArrays = compareSortedArrays; -exports.sleep = sleep; -const _camelCase = __webpack_require__(227); - -function sortAlpha(a, b) { - // sort alphabetically in a deterministic way - const shortLen = Math.min(a.length, b.length); - for (let i = 0; i < shortLen; i++) { - const aChar = a.charCodeAt(i); - const bChar = b.charCodeAt(i); - if (aChar !== bChar) { - return aChar - bChar; - } - } - return a.length - b.length; -} - -function sortOptionsByFlags(a, b) { - const aOpt = a.flags.replace(/-/g, ''); - const bOpt = b.flags.replace(/-/g, ''); - return sortAlpha(aOpt, bOpt); -} - -function entries(obj) { - const entries = []; - if (obj) { - for (const key in obj) { - entries.push([key, obj[key]]); - } - } - return entries; -} - -function removePrefix(pattern, prefix) { - if (pattern.startsWith(prefix)) { - pattern = pattern.slice(prefix.length); - } - - return pattern; -} - -function removeSuffix(pattern, suffix) { - if (pattern.endsWith(suffix)) { - return pattern.slice(0, -suffix.length); - } - - return pattern; -} - -function addSuffix(pattern, suffix) { - if (!pattern.endsWith(suffix)) { - return pattern + suffix; - } - - return pattern; -} - -function hyphenate(str) { - return str.replace(/[A-Z]/g, match => { - return '-' + match.charAt(0).toLowerCase(); - }); -} - -function camelCase(str) { - if (/[A-Z]/.test(str)) { - return null; - } else { - return _camelCase(str); - } -} - -function compareSortedArrays(array1, array2) { - if (array1.length !== array2.length) { - return false; - } - for (let i = 0, len = array1.length; i < len; i++) { - if (array1[i] !== array2[i]) { - return false; - } - } - return true; -} - -function sleep(ms) { - return new Promise(resolve => { - setTimeout(resolve, ms); - }); -} - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.stringify = exports.parse = undefined; - -var _asyncToGenerator2; - -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(2)); -} - -var _parse; - -function _load_parse() { - return _parse = __webpack_require__(106); -} - -Object.defineProperty(exports, 'parse', { - enumerable: true, - get: function get() { - return _interopRequireDefault(_parse || _load_parse()).default; - } -}); - -var _stringify; - -function _load_stringify() { - return _stringify = __webpack_require__(200); -} - -Object.defineProperty(exports, 'stringify', { - enumerable: true, - get: function get() { - return _interopRequireDefault(_stringify || _load_stringify()).default; - } -}); -exports.implodeEntry = implodeEntry; -exports.explodeEntry = explodeEntry; - -var _misc; - -function _load_misc() { - return _misc = __webpack_require__(18); -} - -var _normalizePattern; - -function _load_normalizePattern() { - return _normalizePattern = __webpack_require__(37); -} - -var _parse2; - -function _load_parse2() { - return _parse2 = _interopRequireDefault(__webpack_require__(106)); -} - -var _constants; - -function _load_constants() { - return _constants = __webpack_require__(8); -} - -var _fs; - -function _load_fs() { - return _fs = _interopRequireWildcard(__webpack_require__(5)); -} - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const invariant = __webpack_require__(9); - -const path = __webpack_require__(0); -const ssri = __webpack_require__(65); - -function getName(pattern) { - return (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(pattern).name; -} - -function blankObjectUndefined(obj) { - return obj && Object.keys(obj).length ? obj : undefined; -} - -function keyForRemote(remote) { - return remote.resolved || (remote.reference && remote.hash ? `${remote.reference}#${remote.hash}` : null); -} - -function serializeIntegrity(integrity) { - // We need this because `Integrity.toString()` does not use sorting to ensure a stable string output - // See https://git.io/vx2Hy - return integrity.toString().split(' ').sort().join(' '); -} - -function implodeEntry(pattern, obj) { - const inferredName = getName(pattern); - const integrity = obj.integrity ? serializeIntegrity(obj.integrity) : ''; - const imploded = { - name: inferredName === obj.name ? undefined : obj.name, - version: obj.version, - uid: obj.uid === obj.version ? undefined : obj.uid, - resolved: obj.resolved, - registry: obj.registry === 'npm' ? undefined : obj.registry, - dependencies: blankObjectUndefined(obj.dependencies), - optionalDependencies: blankObjectUndefined(obj.optionalDependencies), - permissions: blankObjectUndefined(obj.permissions), - prebuiltVariants: blankObjectUndefined(obj.prebuiltVariants) - }; - if (integrity) { - imploded.integrity = integrity; - } - return imploded; -} - -function explodeEntry(pattern, obj) { - obj.optionalDependencies = obj.optionalDependencies || {}; - obj.dependencies = obj.dependencies || {}; - obj.uid = obj.uid || obj.version; - obj.permissions = obj.permissions || {}; - obj.registry = obj.registry || 'npm'; - obj.name = obj.name || getName(pattern); - const integrity = obj.integrity; - if (integrity && integrity.isIntegrity) { - obj.integrity = ssri.parse(integrity); - } - return obj; -} - -class Lockfile { - constructor({ cache, source, parseResultType } = {}) { - this.source = source || ''; - this.cache = cache; - this.parseResultType = parseResultType; - } - - // source string if the `cache` was parsed - - - // if true, we're parsing an old yarn file and need to update integrity fields - hasEntriesExistWithoutIntegrity() { - if (!this.cache) { - return false; - } - - for (const key in this.cache) { - // $FlowFixMe - `this.cache` is clearly defined at this point - if (!/^.*@(file:|http)/.test(key) && this.cache[key] && !this.cache[key].integrity) { - return true; - } - } - - return false; - } - - static fromDirectory(dir, reporter) { - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - // read the manifest in this directory - const lockfileLoc = path.join(dir, (_constants || _load_constants()).LOCKFILE_FILENAME); - - let lockfile; - let rawLockfile = ''; - let parseResult; - - if (yield (_fs || _load_fs()).exists(lockfileLoc)) { - rawLockfile = yield (_fs || _load_fs()).readFile(lockfileLoc); - parseResult = (0, (_parse2 || _load_parse2()).default)(rawLockfile, lockfileLoc); - - if (reporter) { - if (parseResult.type === 'merge') { - reporter.info(reporter.lang('lockfileMerged')); - } else if (parseResult.type === 'conflict') { - reporter.warn(reporter.lang('lockfileConflict')); - } - } - - lockfile = parseResult.object; - } else if (reporter) { - reporter.info(reporter.lang('noLockfileFound')); - } - - if (lockfile && lockfile.__metadata) { - const lockfilev2 = lockfile; - lockfile = {}; - } - - return new Lockfile({ cache: lockfile, source: rawLockfile, parseResultType: parseResult && parseResult.type }); - })(); - } - - getLocked(pattern) { - const cache = this.cache; - if (!cache) { - return undefined; - } - - const shrunk = pattern in cache && cache[pattern]; - - if (typeof shrunk === 'string') { - return this.getLocked(shrunk); - } else if (shrunk) { - explodeEntry(pattern, shrunk); - return shrunk; - } - - return undefined; - } - - removePattern(pattern) { - const cache = this.cache; - if (!cache) { - return; - } - delete cache[pattern]; - } - - getLockfile(patterns) { - const lockfile = {}; - const seen = new Map(); - - // order by name so that lockfile manifest is assigned to the first dependency with this manifest - // the others that have the same remoteKey will just refer to the first - // ordering allows for consistency in lockfile when it is serialized - const sortedPatternsKeys = Object.keys(patterns).sort((_misc || _load_misc()).sortAlpha); - - for (var _iterator = sortedPatternsKeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - const pattern = _ref; - - const pkg = patterns[pattern]; - const remote = pkg._remote, - ref = pkg._reference; - - invariant(ref, 'Package is missing a reference'); - invariant(remote, 'Package is missing a remote'); - - const remoteKey = keyForRemote(remote); - const pkgName = getName(pattern); - - const seenKey = remoteKey ? `${remoteKey}#${pkgName}` : null; - const seenPattern = seenKey ? seen.get(seenKey) : null; - - if (seenPattern) { - // no point in duplicating it - lockfile[pattern] = seenPattern; - continue; - } - - const obj = implodeEntry(pattern, { - name: pkgName, - version: pkg.version, - uid: pkg._uid, - resolved: remote.resolved, - integrity: remote.integrity, - registry: remote.registry, - dependencies: pkg.dependencies, - peerDependencies: pkg.peerDependencies, - optionalDependencies: pkg.optionalDependencies, - permissions: ref.permissions, - prebuiltVariants: pkg.prebuiltVariants - }); - - lockfile[pattern] = obj; - - if (seenKey) { - seen.set(seenKey, obj); - } - } - - return lockfile; - } -} -exports.default = Lockfile; - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; - -var _assign = __webpack_require__(559); - -var _assign2 = _interopRequireDefault(_assign); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = _assign2.default || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target; -}; - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -var store = __webpack_require__(134)('wks'); -var uid = __webpack_require__(138); -var Symbol = __webpack_require__(17).Symbol; -var USE_SYMBOL = typeof Symbol == 'function'; - -var $exports = module.exports = function (name) { - return store[name] || (store[name] = - USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); -}; - -$exports.store = store; - - -/***/ }), -/* 22 */ -/***/ (function(module, exports) { - -exports = module.exports = SemVer; - -// The debug function is excluded entirely from the minified version. -/* nomin */ var debug; -/* nomin */ if (typeof process === 'object' && - /* nomin */ process.env && - /* nomin */ process.env.NODE_DEBUG && - /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) - /* nomin */ debug = function() { - /* nomin */ var args = Array.prototype.slice.call(arguments, 0); - /* nomin */ args.unshift('SEMVER'); - /* nomin */ console.log.apply(console, args); - /* nomin */ }; -/* nomin */ else - /* nomin */ debug = function() {}; - -// Note: this is the semver.org version of the spec that it implements -// Not necessarily the package version of this code. -exports.SEMVER_SPEC_VERSION = '2.0.0'; - -var MAX_LENGTH = 256; -var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; - -// Max safe segment length for coercion. -var MAX_SAFE_COMPONENT_LENGTH = 16; - -// The actual regexps go on exports.re -var re = exports.re = []; -var src = exports.src = []; -var R = 0; - -// The following Regular Expressions can be used for tokenizing, -// validating, and parsing SemVer version strings. - -// ## Numeric Identifier -// A single `0`, or a non-zero digit followed by zero or more digits. - -var NUMERICIDENTIFIER = R++; -src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; -var NUMERICIDENTIFIERLOOSE = R++; -src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; - - -// ## Non-numeric Identifier -// Zero or more digits, followed by a letter or hyphen, and then zero or -// more letters, digits, or hyphens. - -var NONNUMERICIDENTIFIER = R++; -src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; - - -// ## Main Version -// Three dot-separated numeric identifiers. - -var MAINVERSION = R++; -src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + - '(' + src[NUMERICIDENTIFIER] + ')\\.' + - '(' + src[NUMERICIDENTIFIER] + ')'; - -var MAINVERSIONLOOSE = R++; -src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; - -// ## Pre-release Version Identifier -// A numeric identifier, or a non-numeric identifier. - -var PRERELEASEIDENTIFIER = R++; -src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + - '|' + src[NONNUMERICIDENTIFIER] + ')'; - -var PRERELEASEIDENTIFIERLOOSE = R++; -src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + - '|' + src[NONNUMERICIDENTIFIER] + ')'; - - -// ## Pre-release Version -// Hyphen, followed by one or more dot-separated pre-release version -// identifiers. - -var PRERELEASE = R++; -src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + - '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; - -var PRERELEASELOOSE = R++; -src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + - '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; - -// ## Build Metadata Identifier -// Any combination of digits, letters, or hyphens. - -var BUILDIDENTIFIER = R++; -src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; - -// ## Build Metadata -// Plus sign, followed by one or more period-separated build metadata -// identifiers. - -var BUILD = R++; -src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + - '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; - - -// ## Full Version String -// A main version, followed optionally by a pre-release version and -// build metadata. - -// Note that the only major, minor, patch, and pre-release sections of -// the version string are capturing groups. The build metadata is not a -// capturing group, because it should not ever be used in version -// comparison. - -var FULL = R++; -var FULLPLAIN = 'v?' + src[MAINVERSION] + - src[PRERELEASE] + '?' + - src[BUILD] + '?'; - -src[FULL] = '^' + FULLPLAIN + '$'; - -// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. -// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty -// common in the npm registry. -var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + - src[PRERELEASELOOSE] + '?' + - src[BUILD] + '?'; - -var LOOSE = R++; -src[LOOSE] = '^' + LOOSEPLAIN + '$'; - -var GTLT = R++; -src[GTLT] = '((?:<|>)?=?)'; - -// Something like "2.*" or "1.2.x". -// Note that "x.x" is a valid xRange identifer, meaning "any version" -// Only the first item is strictly required. -var XRANGEIDENTIFIERLOOSE = R++; -src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; -var XRANGEIDENTIFIER = R++; -src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; - -var XRANGEPLAIN = R++; -src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + - '(?:' + src[PRERELEASE] + ')?' + - src[BUILD] + '?' + - ')?)?'; - -var XRANGEPLAINLOOSE = R++; -src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:' + src[PRERELEASELOOSE] + ')?' + - src[BUILD] + '?' + - ')?)?'; - -var XRANGE = R++; -src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; -var XRANGELOOSE = R++; -src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; - -// Coercion. -// Extract anything that could conceivably be a part of a valid semver -var COERCE = R++; -src[COERCE] = '(?:^|[^\\d])' + - '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:$|[^\\d])'; - -// Tilde ranges. -// Meaning is "reasonably at or greater than" -var LONETILDE = R++; -src[LONETILDE] = '(?:~>?)'; - -var TILDETRIM = R++; -src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; -re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); -var tildeTrimReplace = '$1~'; - -var TILDE = R++; -src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; -var TILDELOOSE = R++; -src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; - -// Caret ranges. -// Meaning is "at least and backwards compatible with" -var LONECARET = R++; -src[LONECARET] = '(?:\\^)'; - -var CARETTRIM = R++; -src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; -re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); -var caretTrimReplace = '$1^'; - -var CARET = R++; -src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; -var CARETLOOSE = R++; -src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; - -// A simple gt/lt/eq thing, or just "" to indicate "any version" -var COMPARATORLOOSE = R++; -src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; -var COMPARATOR = R++; -src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; - - -// An expression to strip any whitespace between the gtlt and the thing -// it modifies, so that `> 1.2.3` ==> `>1.2.3` -var COMPARATORTRIM = R++; -src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + - '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; - -// this one has to use the /g flag -re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); -var comparatorTrimReplace = '$1$2$3'; - - -// Something like `1.2.3 - 1.2.4` -// Note that these all use the loose form, because they'll be -// checked against either the strict or loose comparator form -// later. -var HYPHENRANGE = R++; -src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + - '\\s+-\\s+' + - '(' + src[XRANGEPLAIN] + ')' + - '\\s*$'; - -var HYPHENRANGELOOSE = R++; -src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + - '\\s+-\\s+' + - '(' + src[XRANGEPLAINLOOSE] + ')' + - '\\s*$'; - -// Star ranges basically just allow anything at all. -var STAR = R++; -src[STAR] = '(<|>)?=?\\s*\\*'; - -// Compile to actual regexp objects. -// All are flag-free, unless they were created above with a flag. -for (var i = 0; i < R; i++) { - debug(i, src[i]); - if (!re[i]) - re[i] = new RegExp(src[i]); -} - -exports.parse = parse; -function parse(version, loose) { - if (version instanceof SemVer) - return version; - - if (typeof version !== 'string') - return null; - - if (version.length > MAX_LENGTH) - return null; - - var r = loose ? re[LOOSE] : re[FULL]; - if (!r.test(version)) - return null; - - try { - return new SemVer(version, loose); - } catch (er) { - return null; - } -} - -exports.valid = valid; -function valid(version, loose) { - var v = parse(version, loose); - return v ? v.version : null; -} - - -exports.clean = clean; -function clean(version, loose) { - var s = parse(version.trim().replace(/^[=v]+/, ''), loose); - return s ? s.version : null; -} - -exports.SemVer = SemVer; - -function SemVer(version, loose) { - if (version instanceof SemVer) { - if (version.loose === loose) - return version; - else - version = version.version; - } else if (typeof version !== 'string') { - throw new TypeError('Invalid Version: ' + version); - } - - if (version.length > MAX_LENGTH) - throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') - - if (!(this instanceof SemVer)) - return new SemVer(version, loose); - - debug('SemVer', version, loose); - this.loose = loose; - var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); - - if (!m) - throw new TypeError('Invalid Version: ' + version); - - this.raw = version; - - // these are actually numbers - this.major = +m[1]; - this.minor = +m[2]; - this.patch = +m[3]; - - if (this.major > MAX_SAFE_INTEGER || this.major < 0) - throw new TypeError('Invalid major version') - - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) - throw new TypeError('Invalid minor version') - - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) - throw new TypeError('Invalid patch version') - - // numberify any prerelease numeric ids - if (!m[4]) - this.prerelease = []; - else - this.prerelease = m[4].split('.').map(function(id) { - if (/^[0-9]+$/.test(id)) { - var num = +id; - if (num >= 0 && num < MAX_SAFE_INTEGER) - return num; - } - return id; - }); - - this.build = m[5] ? m[5].split('.') : []; - this.format(); -} - -SemVer.prototype.format = function() { - this.version = this.major + '.' + this.minor + '.' + this.patch; - if (this.prerelease.length) - this.version += '-' + this.prerelease.join('.'); - return this.version; -}; - -SemVer.prototype.toString = function() { - return this.version; -}; - -SemVer.prototype.compare = function(other) { - debug('SemVer.compare', this.version, this.loose, other); - if (!(other instanceof SemVer)) - other = new SemVer(other, this.loose); - - return this.compareMain(other) || this.comparePre(other); -}; - -SemVer.prototype.compareMain = function(other) { - if (!(other instanceof SemVer)) - other = new SemVer(other, this.loose); - - return compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch); -}; - -SemVer.prototype.comparePre = function(other) { - if (!(other instanceof SemVer)) - other = new SemVer(other, this.loose); - - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) - return -1; - else if (!this.prerelease.length && other.prerelease.length) - return 1; - else if (!this.prerelease.length && !other.prerelease.length) - return 0; - - var i = 0; - do { - var a = this.prerelease[i]; - var b = other.prerelease[i]; - debug('prerelease compare', i, a, b); - if (a === undefined && b === undefined) - return 0; - else if (b === undefined) - return 1; - else if (a === undefined) - return -1; - else if (a === b) - continue; - else - return compareIdentifiers(a, b); - } while (++i); -}; - -// preminor will bump the version up to the next minor release, and immediately -// down to pre-release. premajor and prepatch work the same way. -SemVer.prototype.inc = function(release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0; - this.patch = 0; - this.minor = 0; - this.major++; - this.inc('pre', identifier); - break; - case 'preminor': - this.prerelease.length = 0; - this.patch = 0; - this.minor++; - this.inc('pre', identifier); - break; - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0; - this.inc('patch', identifier); - this.inc('pre', identifier); - break; - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) - this.inc('patch', identifier); - this.inc('pre', identifier); - break; - - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) - this.major++; - this.minor = 0; - this.patch = 0; - this.prerelease = []; - break; - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) - this.minor++; - this.patch = 0; - this.prerelease = []; - break; - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) - this.patch++; - this.prerelease = []; - break; - // This probably shouldn't be used publicly. - // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) - this.prerelease = [0]; - else { - var i = this.prerelease.length; - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++; - i = -2; - } - } - if (i === -1) // didn't increment anything - this.prerelease.push(0); - } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) - this.prerelease = [identifier, 0]; - } else - this.prerelease = [identifier, 0]; - } - break; - - default: - throw new Error('invalid increment argument: ' + release); - } - this.format(); - this.raw = this.version; - return this; -}; - -exports.inc = inc; -function inc(version, release, loose, identifier) { - if (typeof(loose) === 'string') { - identifier = loose; - loose = undefined; - } - - try { - return new SemVer(version, loose).inc(release, identifier).version; - } catch (er) { - return null; - } -} - -exports.diff = diff; -function diff(version1, version2) { - if (eq(version1, version2)) { - return null; - } else { - var v1 = parse(version1); - var v2 = parse(version2); - if (v1.prerelease.length || v2.prerelease.length) { - for (var key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return 'pre'+key; - } - } - } - return 'prerelease'; - } - for (var key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return key; - } - } - } - } -} - -exports.compareIdentifiers = compareIdentifiers; - -var numeric = /^[0-9]+$/; -function compareIdentifiers(a, b) { - var anum = numeric.test(a); - var bnum = numeric.test(b); - - if (anum && bnum) { - a = +a; - b = +b; - } - - return (anum && !bnum) ? -1 : - (bnum && !anum) ? 1 : - a < b ? -1 : - a > b ? 1 : - 0; -} - -exports.rcompareIdentifiers = rcompareIdentifiers; -function rcompareIdentifiers(a, b) { - return compareIdentifiers(b, a); -} - -exports.major = major; -function major(a, loose) { - return new SemVer(a, loose).major; -} - -exports.minor = minor; -function minor(a, loose) { - return new SemVer(a, loose).minor; -} - -exports.patch = patch; -function patch(a, loose) { - return new SemVer(a, loose).patch; -} - -exports.compare = compare; -function compare(a, b, loose) { - return new SemVer(a, loose).compare(new SemVer(b, loose)); -} - -exports.compareLoose = compareLoose; -function compareLoose(a, b) { - return compare(a, b, true); -} - -exports.rcompare = rcompare; -function rcompare(a, b, loose) { - return compare(b, a, loose); -} - -exports.sort = sort; -function sort(list, loose) { - return list.sort(function(a, b) { - return exports.compare(a, b, loose); - }); -} - -exports.rsort = rsort; -function rsort(list, loose) { - return list.sort(function(a, b) { - return exports.rcompare(a, b, loose); - }); -} - -exports.gt = gt; -function gt(a, b, loose) { - return compare(a, b, loose) > 0; -} - -exports.lt = lt; -function lt(a, b, loose) { - return compare(a, b, loose) < 0; -} - -exports.eq = eq; -function eq(a, b, loose) { - return compare(a, b, loose) === 0; -} - -exports.neq = neq; -function neq(a, b, loose) { - return compare(a, b, loose) !== 0; -} - -exports.gte = gte; -function gte(a, b, loose) { - return compare(a, b, loose) >= 0; -} - -exports.lte = lte; -function lte(a, b, loose) { - return compare(a, b, loose) <= 0; -} - -exports.cmp = cmp; -function cmp(a, op, b, loose) { - var ret; - switch (op) { - case '===': - if (typeof a === 'object') a = a.version; - if (typeof b === 'object') b = b.version; - ret = a === b; - break; - case '!==': - if (typeof a === 'object') a = a.version; - if (typeof b === 'object') b = b.version; - ret = a !== b; - break; - case '': case '=': case '==': ret = eq(a, b, loose); break; - case '!=': ret = neq(a, b, loose); break; - case '>': ret = gt(a, b, loose); break; - case '>=': ret = gte(a, b, loose); break; - case '<': ret = lt(a, b, loose); break; - case '<=': ret = lte(a, b, loose); break; - default: throw new TypeError('Invalid operator: ' + op); - } - return ret; -} - -exports.Comparator = Comparator; -function Comparator(comp, loose) { - if (comp instanceof Comparator) { - if (comp.loose === loose) - return comp; - else - comp = comp.value; - } - - if (!(this instanceof Comparator)) - return new Comparator(comp, loose); - - debug('comparator', comp, loose); - this.loose = loose; - this.parse(comp); - - if (this.semver === ANY) - this.value = ''; - else - this.value = this.operator + this.semver.version; - - debug('comp', this); -} - -var ANY = {}; -Comparator.prototype.parse = function(comp) { - var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; - var m = comp.match(r); - - if (!m) - throw new TypeError('Invalid comparator: ' + comp); - - this.operator = m[1]; - if (this.operator === '=') - this.operator = ''; - - // if it literally is just '>' or '' then allow anything. - if (!m[2]) - this.semver = ANY; - else - this.semver = new SemVer(m[2], this.loose); -}; - -Comparator.prototype.toString = function() { - return this.value; -}; - -Comparator.prototype.test = function(version) { - debug('Comparator.test', version, this.loose); - - if (this.semver === ANY) - return true; - - if (typeof version === 'string') - version = new SemVer(version, this.loose); - - return cmp(version, this.operator, this.semver, this.loose); -}; - -Comparator.prototype.intersects = function(comp, loose) { - if (!(comp instanceof Comparator)) { - throw new TypeError('a Comparator is required'); - } - - var rangeTmp; - - if (this.operator === '') { - rangeTmp = new Range(comp.value, loose); - return satisfies(this.value, rangeTmp, loose); - } else if (comp.operator === '') { - rangeTmp = new Range(this.value, loose); - return satisfies(comp.semver, rangeTmp, loose); - } - - var sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>'); - var sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<'); - var sameSemVer = this.semver.version === comp.semver.version; - var differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<='); - var oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, loose) && - ((this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<')); - var oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, loose) && - ((this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>')); - - return sameDirectionIncreasing || sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || oppositeDirectionsGreaterThan; -}; - - -exports.Range = Range; -function Range(range, loose) { - if (range instanceof Range) { - if (range.loose === loose) { - return range; - } else { - return new Range(range.raw, loose); - } - } - - if (range instanceof Comparator) { - return new Range(range.value, loose); - } - - if (!(this instanceof Range)) - return new Range(range, loose); - - this.loose = loose; - - // First, split based on boolean or || - this.raw = range; - this.set = range.split(/\s*\|\|\s*/).map(function(range) { - return this.parseRange(range.trim()); - }, this).filter(function(c) { - // throw out any that are not relevant for whatever reason - return c.length; - }); - - if (!this.set.length) { - throw new TypeError('Invalid SemVer Range: ' + range); - } - - this.format(); -} - -Range.prototype.format = function() { - this.range = this.set.map(function(comps) { - return comps.join(' ').trim(); - }).join('||').trim(); - return this.range; -}; - -Range.prototype.toString = function() { - return this.range; -}; - -Range.prototype.parseRange = function(range) { - var loose = this.loose; - range = range.trim(); - debug('range', range, loose); - // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; - range = range.replace(hr, hyphenReplace); - debug('hyphen replace', range); - // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); - debug('comparator trim', range, re[COMPARATORTRIM]); - - // `~ 1.2.3` => `~1.2.3` - range = range.replace(re[TILDETRIM], tildeTrimReplace); - - // `^ 1.2.3` => `^1.2.3` - range = range.replace(re[CARETTRIM], caretTrimReplace); - - // normalize spaces - range = range.split(/\s+/).join(' '); - - // At this point, the range is completely trimmed and - // ready to be split into comparators. - - var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; - var set = range.split(' ').map(function(comp) { - return parseComparator(comp, loose); - }).join(' ').split(/\s+/); - if (this.loose) { - // in loose mode, throw out any that are not valid comparators - set = set.filter(function(comp) { - return !!comp.match(compRe); - }); - } - set = set.map(function(comp) { - return new Comparator(comp, loose); - }); - - return set; -}; - -Range.prototype.intersects = function(range, loose) { - if (!(range instanceof Range)) { - throw new TypeError('a Range is required'); - } - - return this.set.some(function(thisComparators) { - return thisComparators.every(function(thisComparator) { - return range.set.some(function(rangeComparators) { - return rangeComparators.every(function(rangeComparator) { - return thisComparator.intersects(rangeComparator, loose); - }); - }); - }); - }); -}; - -// Mostly just for testing and legacy API reasons -exports.toComparators = toComparators; -function toComparators(range, loose) { - return new Range(range, loose).set.map(function(comp) { - return comp.map(function(c) { - return c.value; - }).join(' ').trim().split(' '); - }); -} - -// comprised of xranges, tildes, stars, and gtlt's at this point. -// already replaced the hyphen ranges -// turn into a set of JUST comparators. -function parseComparator(comp, loose) { - debug('comp', comp); - comp = replaceCarets(comp, loose); - debug('caret', comp); - comp = replaceTildes(comp, loose); - debug('tildes', comp); - comp = replaceXRanges(comp, loose); - debug('xrange', comp); - comp = replaceStars(comp, loose); - debug('stars', comp); - return comp; -} - -function isX(id) { - return !id || id.toLowerCase() === 'x' || id === '*'; -} - -// ~, ~> --> * (any, kinda silly) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 -function replaceTildes(comp, loose) { - return comp.trim().split(/\s+/).map(function(comp) { - return replaceTilde(comp, loose); - }).join(' '); -} - -function replaceTilde(comp, loose) { - var r = loose ? re[TILDELOOSE] : re[TILDE]; - return comp.replace(r, function(_, M, m, p, pr) { - debug('tilde', comp, _, M, m, p, pr); - var ret; - - if (isX(M)) - ret = ''; - else if (isX(m)) - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; - else if (isX(p)) - // ~1.2 == >=1.2.0 <1.3.0 - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; - else if (pr) { - debug('replaceTilde pr', pr); - if (pr.charAt(0) !== '-') - pr = '-' + pr; - ret = '>=' + M + '.' + m + '.' + p + pr + - ' <' + M + '.' + (+m + 1) + '.0'; - } else - // ~1.2.3 == >=1.2.3 <1.3.0 - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0'; - - debug('tilde return', ret); - return ret; - }); -} - -// ^ --> * (any, kinda silly) -// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 -// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 -// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 -// ^1.2.3 --> >=1.2.3 <2.0.0 -// ^1.2.0 --> >=1.2.0 <2.0.0 -function replaceCarets(comp, loose) { - return comp.trim().split(/\s+/).map(function(comp) { - return replaceCaret(comp, loose); - }).join(' '); -} - -function replaceCaret(comp, loose) { - debug('caret', comp, loose); - var r = loose ? re[CARETLOOSE] : re[CARET]; - return comp.replace(r, function(_, M, m, p, pr) { - debug('caret', comp, _, M, m, p, pr); - var ret; - - if (isX(M)) - ret = ''; - else if (isX(m)) - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; - else if (isX(p)) { - if (M === '0') - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; - else - ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; - } else if (pr) { - debug('replaceCaret pr', pr); - if (pr.charAt(0) !== '-') - pr = '-' + pr; - if (M === '0') { - if (m === '0') - ret = '>=' + M + '.' + m + '.' + p + pr + - ' <' + M + '.' + m + '.' + (+p + 1); - else - ret = '>=' + M + '.' + m + '.' + p + pr + - ' <' + M + '.' + (+m + 1) + '.0'; - } else - ret = '>=' + M + '.' + m + '.' + p + pr + - ' <' + (+M + 1) + '.0.0'; - } else { - debug('no pr'); - if (M === '0') { - if (m === '0') - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + m + '.' + (+p + 1); - else - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0'; - } else - ret = '>=' + M + '.' + m + '.' + p + - ' <' + (+M + 1) + '.0.0'; - } - - debug('caret return', ret); - return ret; - }); -} - -function replaceXRanges(comp, loose) { - debug('replaceXRanges', comp, loose); - return comp.split(/\s+/).map(function(comp) { - return replaceXRange(comp, loose); - }).join(' '); -} - -function replaceXRange(comp, loose) { - comp = comp.trim(); - var r = loose ? re[XRANGELOOSE] : re[XRANGE]; - return comp.replace(r, function(ret, gtlt, M, m, p, pr) { - debug('xRange', comp, ret, gtlt, M, m, p, pr); - var xM = isX(M); - var xm = xM || isX(m); - var xp = xm || isX(p); - var anyX = xp; - - if (gtlt === '=' && anyX) - gtlt = ''; - - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<0.0.0'; - } else { - // nothing is forbidden - ret = '*'; - } - } else if (gtlt && anyX) { - // replace X with 0 - if (xm) - m = 0; - if (xp) - p = 0; - - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - // >1.2.3 => >= 1.2.4 - gtlt = '>='; - if (xm) { - M = +M + 1; - m = 0; - p = 0; - } else if (xp) { - m = +m + 1; - p = 0; - } - } else if (gtlt === '<=') { - // <=0.7.x is actually <0.8.0, since any 0.7.x should - // pass. Similarly, <=7.x is actually <8.0.0, etc. - gtlt = '<'; - if (xm) - M = +M + 1; - else - m = +m + 1; - } - - ret = gtlt + M + '.' + m + '.' + p; - } else if (xm) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; - } else if (xp) { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; - } - - debug('xRange return', ret); - - return ret; - }); -} - -// Because * is AND-ed with everything else in the comparator, -// and '' means "any version", just remove the *s entirely. -function replaceStars(comp, loose) { - debug('replaceStars', comp, loose); - // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re[STAR], ''); -} - -// This function is passed to string.replace(re[HYPHENRANGE]) -// M, m, patch, prerelease, build -// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 -// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do -// 1.2 - 3.4 => >=1.2.0 <3.5.0 -function hyphenReplace($0, - from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) { - - if (isX(fM)) - from = ''; - else if (isX(fm)) - from = '>=' + fM + '.0.0'; - else if (isX(fp)) - from = '>=' + fM + '.' + fm + '.0'; - else - from = '>=' + from; - - if (isX(tM)) - to = ''; - else if (isX(tm)) - to = '<' + (+tM + 1) + '.0.0'; - else if (isX(tp)) - to = '<' + tM + '.' + (+tm + 1) + '.0'; - else if (tpr) - to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; - else - to = '<=' + to; - - return (from + ' ' + to).trim(); -} - - -// if ANY of the sets match ALL of its comparators, then pass -Range.prototype.test = function(version) { - if (!version) - return false; - - if (typeof version === 'string') - version = new SemVer(version, this.loose); - - for (var i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version)) - return true; - } - return false; -}; - -function testSet(set, version) { - for (var i = 0; i < set.length; i++) { - if (!set[i].test(version)) - return false; - } - - if (version.prerelease.length) { - // Find the set of versions that are allowed to have prereleases - // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 - // That should allow `1.2.3-pr.2` to pass. - // However, `1.2.4-alpha.notready` should NOT be allowed, - // even though it's within the range set by the comparators. - for (var i = 0; i < set.length; i++) { - debug(set[i].semver); - if (set[i].semver === ANY) - continue; - - if (set[i].semver.prerelease.length > 0) { - var allowed = set[i].semver; - if (allowed.major === version.major && - allowed.minor === version.minor && - allowed.patch === version.patch) - return true; - } - } - - // Version has a -pre, but it's not one of the ones we like. - return false; - } - - return true; -} - -exports.satisfies = satisfies; -function satisfies(version, range, loose) { - try { - range = new Range(range, loose); - } catch (er) { - return false; - } - return range.test(version); -} - -exports.maxSatisfying = maxSatisfying; -function maxSatisfying(versions, range, loose) { - var max = null; - var maxSV = null; - try { - var rangeObj = new Range(range, loose); - } catch (er) { - return null; - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { // satisfies(v, range, loose) - if (!max || maxSV.compare(v) === -1) { // compare(max, v, true) - max = v; - maxSV = new SemVer(max, loose); - } - } - }) - return max; -} - -exports.minSatisfying = minSatisfying; -function minSatisfying(versions, range, loose) { - var min = null; - var minSV = null; - try { - var rangeObj = new Range(range, loose); - } catch (er) { - return null; - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { // satisfies(v, range, loose) - if (!min || minSV.compare(v) === 1) { // compare(min, v, true) - min = v; - minSV = new SemVer(min, loose); - } - } - }) - return min; -} - -exports.validRange = validRange; -function validRange(range, loose) { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range(range, loose).range || '*'; - } catch (er) { - return null; - } -} - -// Determine if version is less than all the versions possible in the range -exports.ltr = ltr; -function ltr(version, range, loose) { - return outside(version, range, '<', loose); -} - -// Determine if version is greater than all the versions possible in the range. -exports.gtr = gtr; -function gtr(version, range, loose) { - return outside(version, range, '>', loose); -} - -exports.outside = outside; -function outside(version, range, hilo, loose) { - version = new SemVer(version, loose); - range = new Range(range, loose); - - var gtfn, ltefn, ltfn, comp, ecomp; - switch (hilo) { - case '>': - gtfn = gt; - ltefn = lte; - ltfn = lt; - comp = '>'; - ecomp = '>='; - break; - case '<': - gtfn = lt; - ltefn = gte; - ltfn = gt; - comp = '<'; - ecomp = '<='; - break; - default: - throw new TypeError('Must provide a hilo val of "<" or ">"'); - } - - // If it satisifes the range it is not outside - if (satisfies(version, range, loose)) { - return false; - } - - // From now on, variable terms are as if we're in "gtr" mode. - // but note that everything is flipped for the "ltr" function. - - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i]; - - var high = null; - var low = null; - - comparators.forEach(function(comparator) { - if (comparator.semver === ANY) { - comparator = new Comparator('>=0.0.0') - } - high = high || comparator; - low = low || comparator; - if (gtfn(comparator.semver, high.semver, loose)) { - high = comparator; - } else if (ltfn(comparator.semver, low.semver, loose)) { - low = comparator; - } - }); - - // If the edge version comparator has a operator then our version - // isn't outside it - if (high.operator === comp || high.operator === ecomp) { - return false; - } - - // If the lowest version comparator has an operator and our version - // is less than it then it isn't higher than the range - if ((!low.operator || low.operator === comp) && - ltefn(version, low.semver)) { - return false; - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false; - } - } - return true; -} - -exports.prerelease = prerelease; -function prerelease(version, loose) { - var parsed = parse(version, loose); - return (parsed && parsed.prerelease.length) ? parsed.prerelease : null; -} - -exports.intersects = intersects; -function intersects(r1, r2, loose) { - r1 = new Range(r1, loose) - r2 = new Range(r2, loose) - return r1.intersects(r2) -} - -exports.coerce = coerce; -function coerce(version) { - if (version instanceof SemVer) - return version; - - if (typeof version !== 'string') - return null; - - var match = version.match(re[COERCE]); - - if (match == null) - return null; - - return parse((match[1] || '0') + '.' + (match[2] || '0') + '.' + (match[3] || '0')); -} - - -/***/ }), -/* 23 */ -/***/ (function(module, exports) { - -module.exports = require("stream"); - -/***/ }), -/* 24 */ -/***/ (function(module, exports) { - -module.exports = require("url"); - -/***/ }), -/* 25 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Subscription; }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_isArray__ = __webpack_require__(41); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_isObject__ = __webpack_require__(444); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_isFunction__ = __webpack_require__(155); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_tryCatch__ = __webpack_require__(57); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_errorObject__ = __webpack_require__(48); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__ = __webpack_require__(441); -/** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_tryCatch,_util_errorObject,_util_UnsubscriptionError PURE_IMPORTS_END */ - - - - - - -var Subscription = /*@__PURE__*/ (function () { - function Subscription(unsubscribe) { - this.closed = false; - this._parent = null; - this._parents = null; - this._subscriptions = null; - if (unsubscribe) { - this._unsubscribe = unsubscribe; - } - } - Subscription.prototype.unsubscribe = function () { - var hasErrors = false; - var errors; - if (this.closed) { - return; - } - var _a = this, _parent = _a._parent, _parents = _a._parents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; - this.closed = true; - this._parent = null; - this._parents = null; - this._subscriptions = null; - var index = -1; - var len = _parents ? _parents.length : 0; - while (_parent) { - _parent.remove(this); - _parent = ++index < len && _parents[index] || null; - } - if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__util_isFunction__["a" /* isFunction */])(_unsubscribe)) { - var trial = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util_tryCatch__["a" /* tryCatch */])(_unsubscribe).call(this); - if (trial === __WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */]) { - hasErrors = true; - errors = errors || (__WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e instanceof __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */] ? - flattenUnsubscriptionErrors(__WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e.errors) : [__WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e]); - } - } - if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__util_isArray__["a" /* isArray */])(_subscriptions)) { - index = -1; - len = _subscriptions.length; - while (++index < len) { - var sub = _subscriptions[index]; - if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_isObject__["a" /* isObject */])(sub)) { - var trial = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util_tryCatch__["a" /* tryCatch */])(sub.unsubscribe).call(sub); - if (trial === __WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */]) { - hasErrors = true; - errors = errors || []; - var err = __WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e; - if (err instanceof __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */]) { - errors = errors.concat(flattenUnsubscriptionErrors(err.errors)); - } - else { - errors.push(err); - } - } - } - } - } - if (hasErrors) { - throw new __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */](errors); - } - }; - Subscription.prototype.add = function (teardown) { - if (!teardown || (teardown === Subscription.EMPTY)) { - return Subscription.EMPTY; - } - if (teardown === this) { - return this; - } - var subscription = teardown; - switch (typeof teardown) { - case 'function': - subscription = new Subscription(teardown); - case 'object': - if (subscription.closed || typeof subscription.unsubscribe !== 'function') { - return subscription; - } - else if (this.closed) { - subscription.unsubscribe(); - return subscription; - } - else if (typeof subscription._addParent !== 'function') { - var tmp = subscription; - subscription = new Subscription(); - subscription._subscriptions = [tmp]; - } - break; - default: - throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); - } - var subscriptions = this._subscriptions || (this._subscriptions = []); - subscriptions.push(subscription); - subscription._addParent(this); - return subscription; - }; - Subscription.prototype.remove = function (subscription) { - var subscriptions = this._subscriptions; - if (subscriptions) { - var subscriptionIndex = subscriptions.indexOf(subscription); - if (subscriptionIndex !== -1) { - subscriptions.splice(subscriptionIndex, 1); - } - } - }; - Subscription.prototype._addParent = function (parent) { - var _a = this, _parent = _a._parent, _parents = _a._parents; - if (!_parent || _parent === parent) { - this._parent = parent; - } - else if (!_parents) { - this._parents = [parent]; - } - else if (_parents.indexOf(parent) === -1) { - _parents.push(parent); - } - }; - Subscription.EMPTY = (function (empty) { - empty.closed = true; - return empty; - }(new Subscription())); - return Subscription; -}()); - -function flattenUnsubscriptionErrors(errors) { - return errors.reduce(function (errs, err) { return errs.concat((err instanceof __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */]) ? err.errors : err); }, []); -} -//# sourceMappingURL=Subscription.js.map - - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright 2015 Joyent, Inc. - -module.exports = { - bufferSplit: bufferSplit, - addRSAMissing: addRSAMissing, - calculateDSAPublic: calculateDSAPublic, - calculateED25519Public: calculateED25519Public, - calculateX25519Public: calculateX25519Public, - mpNormalize: mpNormalize, - mpDenormalize: mpDenormalize, - ecNormalize: ecNormalize, - countZeros: countZeros, - assertCompatible: assertCompatible, - isCompatible: isCompatible, - opensslKeyDeriv: opensslKeyDeriv, - opensshCipherInfo: opensshCipherInfo, - publicFromPrivateECDSA: publicFromPrivateECDSA, - zeroPadToLength: zeroPadToLength, - writeBitString: writeBitString, - readBitString: readBitString -}; - -var assert = __webpack_require__(16); -var Buffer = __webpack_require__(15).Buffer; -var PrivateKey = __webpack_require__(33); -var Key = __webpack_require__(28); -var crypto = __webpack_require__(11); -var algs = __webpack_require__(32); -var asn1 = __webpack_require__(66); - -var ec, jsbn; -var nacl; - -var MAX_CLASS_DEPTH = 3; - -function isCompatible(obj, klass, needVer) { - if (obj === null || typeof (obj) !== 'object') - return (false); - if (needVer === undefined) - needVer = klass.prototype._sshpkApiVersion; - if (obj instanceof klass && - klass.prototype._sshpkApiVersion[0] == needVer[0]) - return (true); - var proto = Object.getPrototypeOf(obj); - var depth = 0; - while (proto.constructor.name !== klass.name) { - proto = Object.getPrototypeOf(proto); - if (!proto || ++depth > MAX_CLASS_DEPTH) - return (false); - } - if (proto.constructor.name !== klass.name) - return (false); - var ver = proto._sshpkApiVersion; - if (ver === undefined) - ver = klass._oldVersionDetect(obj); - if (ver[0] != needVer[0] || ver[1] < needVer[1]) - return (false); - return (true); -} - -function assertCompatible(obj, klass, needVer, name) { - if (name === undefined) - name = 'object'; - assert.ok(obj, name + ' must not be null'); - assert.object(obj, name + ' must be an object'); - if (needVer === undefined) - needVer = klass.prototype._sshpkApiVersion; - if (obj instanceof klass && - klass.prototype._sshpkApiVersion[0] == needVer[0]) - return; - var proto = Object.getPrototypeOf(obj); - var depth = 0; - while (proto.constructor.name !== klass.name) { - proto = Object.getPrototypeOf(proto); - assert.ok(proto && ++depth <= MAX_CLASS_DEPTH, - name + ' must be a ' + klass.name + ' instance'); - } - assert.strictEqual(proto.constructor.name, klass.name, - name + ' must be a ' + klass.name + ' instance'); - var ver = proto._sshpkApiVersion; - if (ver === undefined) - ver = klass._oldVersionDetect(obj); - assert.ok(ver[0] == needVer[0] && ver[1] >= needVer[1], - name + ' must be compatible with ' + klass.name + ' klass ' + - 'version ' + needVer[0] + '.' + needVer[1]); -} - -var CIPHER_LEN = { - 'des-ede3-cbc': { key: 7, iv: 8 }, - 'aes-128-cbc': { key: 16, iv: 16 } -}; -var PKCS5_SALT_LEN = 8; - -function opensslKeyDeriv(cipher, salt, passphrase, count) { - assert.buffer(salt, 'salt'); - assert.buffer(passphrase, 'passphrase'); - assert.number(count, 'iteration count'); - - var clen = CIPHER_LEN[cipher]; - assert.object(clen, 'supported cipher'); - - salt = salt.slice(0, PKCS5_SALT_LEN); - - var D, D_prev, bufs; - var material = Buffer.alloc(0); - while (material.length < clen.key + clen.iv) { - bufs = []; - if (D_prev) - bufs.push(D_prev); - bufs.push(passphrase); - bufs.push(salt); - D = Buffer.concat(bufs); - for (var j = 0; j < count; ++j) - D = crypto.createHash('md5').update(D).digest(); - material = Buffer.concat([material, D]); - D_prev = D; - } - - return ({ - key: material.slice(0, clen.key), - iv: material.slice(clen.key, clen.key + clen.iv) - }); -} - -/* Count leading zero bits on a buffer */ -function countZeros(buf) { - var o = 0, obit = 8; - while (o < buf.length) { - var mask = (1 << obit); - if ((buf[o] & mask) === mask) - break; - obit--; - if (obit < 0) { - o++; - obit = 8; - } - } - return (o*8 + (8 - obit) - 1); -} - -function bufferSplit(buf, chr) { - assert.buffer(buf); - assert.string(chr); - - var parts = []; - var lastPart = 0; - var matches = 0; - for (var i = 0; i < buf.length; ++i) { - if (buf[i] === chr.charCodeAt(matches)) - ++matches; - else if (buf[i] === chr.charCodeAt(0)) - matches = 1; - else - matches = 0; - - if (matches >= chr.length) { - var newPart = i + 1; - parts.push(buf.slice(lastPart, newPart - matches)); - lastPart = newPart; - matches = 0; - } - } - if (lastPart <= buf.length) - parts.push(buf.slice(lastPart, buf.length)); - - return (parts); -} - -function ecNormalize(buf, addZero) { - assert.buffer(buf); - if (buf[0] === 0x00 && buf[1] === 0x04) { - if (addZero) - return (buf); - return (buf.slice(1)); - } else if (buf[0] === 0x04) { - if (!addZero) - return (buf); - } else { - while (buf[0] === 0x00) - buf = buf.slice(1); - if (buf[0] === 0x02 || buf[0] === 0x03) - throw (new Error('Compressed elliptic curve points ' + - 'are not supported')); - if (buf[0] !== 0x04) - throw (new Error('Not a valid elliptic curve point')); - if (!addZero) - return (buf); - } - var b = Buffer.alloc(buf.length + 1); - b[0] = 0x0; - buf.copy(b, 1); - return (b); -} - -function readBitString(der, tag) { - if (tag === undefined) - tag = asn1.Ber.BitString; - var buf = der.readString(tag, true); - assert.strictEqual(buf[0], 0x00, 'bit strings with unused bits are ' + - 'not supported (0x' + buf[0].toString(16) + ')'); - return (buf.slice(1)); -} - -function writeBitString(der, buf, tag) { - if (tag === undefined) - tag = asn1.Ber.BitString; - var b = Buffer.alloc(buf.length + 1); - b[0] = 0x00; - buf.copy(b, 1); - der.writeBuffer(b, tag); -} - -function mpNormalize(buf) { - assert.buffer(buf); - while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00) - buf = buf.slice(1); - if ((buf[0] & 0x80) === 0x80) { - var b = Buffer.alloc(buf.length + 1); - b[0] = 0x00; - buf.copy(b, 1); - buf = b; - } - return (buf); -} - -function mpDenormalize(buf) { - assert.buffer(buf); - while (buf.length > 1 && buf[0] === 0x00) - buf = buf.slice(1); - return (buf); -} - -function zeroPadToLength(buf, len) { - assert.buffer(buf); - assert.number(len); - while (buf.length > len) { - assert.equal(buf[0], 0x00); - buf = buf.slice(1); - } - while (buf.length < len) { - var b = Buffer.alloc(buf.length + 1); - b[0] = 0x00; - buf.copy(b, 1); - buf = b; - } - return (buf); -} - -function bigintToMpBuf(bigint) { - var buf = Buffer.from(bigint.toByteArray()); - buf = mpNormalize(buf); - return (buf); -} - -function calculateDSAPublic(g, p, x) { - assert.buffer(g); - assert.buffer(p); - assert.buffer(x); - try { - var bigInt = __webpack_require__(81).BigInteger; - } catch (e) { - throw (new Error('To load a PKCS#8 format DSA private key, ' + - 'the node jsbn library is required.')); - } - g = new bigInt(g); - p = new bigInt(p); - x = new bigInt(x); - var y = g.modPow(x, p); - var ybuf = bigintToMpBuf(y); - return (ybuf); -} - -function calculateED25519Public(k) { - assert.buffer(k); - - if (nacl === undefined) - nacl = __webpack_require__(76); - - var kp = nacl.sign.keyPair.fromSeed(new Uint8Array(k)); - return (Buffer.from(kp.publicKey)); -} - -function calculateX25519Public(k) { - assert.buffer(k); - - if (nacl === undefined) - nacl = __webpack_require__(76); - - var kp = nacl.box.keyPair.fromSeed(new Uint8Array(k)); - return (Buffer.from(kp.publicKey)); -} - -function addRSAMissing(key) { - assert.object(key); - assertCompatible(key, PrivateKey, [1, 1]); - try { - var bigInt = __webpack_require__(81).BigInteger; - } catch (e) { - throw (new Error('To write a PEM private key from ' + - 'this source, the node jsbn lib is required.')); - } - - var d = new bigInt(key.part.d.data); - var buf; - - if (!key.part.dmodp) { - var p = new bigInt(key.part.p.data); - var dmodp = d.mod(p.subtract(1)); - - buf = bigintToMpBuf(dmodp); - key.part.dmodp = {name: 'dmodp', data: buf}; - key.parts.push(key.part.dmodp); - } - if (!key.part.dmodq) { - var q = new bigInt(key.part.q.data); - var dmodq = d.mod(q.subtract(1)); - - buf = bigintToMpBuf(dmodq); - key.part.dmodq = {name: 'dmodq', data: buf}; - key.parts.push(key.part.dmodq); - } -} - -function publicFromPrivateECDSA(curveName, priv) { - assert.string(curveName, 'curveName'); - assert.buffer(priv); - if (ec === undefined) - ec = __webpack_require__(140); - if (jsbn === undefined) - jsbn = __webpack_require__(81).BigInteger; - var params = algs.curves[curveName]; - var p = new jsbn(params.p); - var a = new jsbn(params.a); - var b = new jsbn(params.b); - var curve = new ec.ECCurveFp(p, a, b); - var G = curve.decodePointHex(params.G.toString('hex')); - - var d = new jsbn(mpNormalize(priv)); - var pub = G.multiply(d); - pub = Buffer.from(curve.encodePointHex(pub), 'hex'); - - var parts = []; - parts.push({name: 'curve', data: Buffer.from(curveName)}); - parts.push({name: 'Q', data: pub}); - - var key = new Key({type: 'ecdsa', curve: curve, parts: parts}); - return (key); -} - -function opensshCipherInfo(cipher) { - var inf = {}; - switch (cipher) { - case '3des-cbc': - inf.keySize = 24; - inf.blockSize = 8; - inf.opensslName = 'des-ede3-cbc'; - break; - case 'blowfish-cbc': - inf.keySize = 16; - inf.blockSize = 8; - inf.opensslName = 'bf-cbc'; - break; - case 'aes128-cbc': - case 'aes128-ctr': - case 'aes128-gcm@openssh.com': - inf.keySize = 16; - inf.blockSize = 16; - inf.opensslName = 'aes-128-' + cipher.slice(7, 10); - break; - case 'aes192-cbc': - case 'aes192-ctr': - case 'aes192-gcm@openssh.com': - inf.keySize = 24; - inf.blockSize = 16; - inf.opensslName = 'aes-192-' + cipher.slice(7, 10); - break; - case 'aes256-cbc': - case 'aes256-ctr': - case 'aes256-gcm@openssh.com': - inf.keySize = 32; - inf.blockSize = 16; - inf.opensslName = 'aes-256-' + cipher.slice(7, 10); - break; - default: - throw (new Error( - 'Unsupported openssl cipher "' + cipher + '"')); - } - return (inf); -} - - -/***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const escapeStringRegexp = __webpack_require__(382); -const ansiStyles = __webpack_require__(474); -const stdoutColor = __webpack_require__(566).stdout; - -const template = __webpack_require__(567); - -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); - -const styles = Object.create(null); - -function applyOptions(obj, options) { - options = options || {}; - - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} - -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); - - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = Chalk; - - return chalk.template; - } - - applyOptions(this, options); -} - -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} - -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} - -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; - -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } - - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } - - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -const proto = Object.defineProperties(() => {}, styles); - -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder._empty = _empty; - - const self = this; - - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); - - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); - - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; - - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto - - return builder; -} - -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); - - if (argsLen === 0) { - return ''; - } - - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } - - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } - - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } - - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; - - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } - - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; - - return str; -} - -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } - - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; - - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } - - return template(chalk, parts.join('')); -} - -Object.defineProperties(Chalk.prototype, styles); - -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript - - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright 2017 Joyent, Inc. - -module.exports = Key; - -var assert = __webpack_require__(16); -var algs = __webpack_require__(32); -var crypto = __webpack_require__(11); -var Fingerprint = __webpack_require__(157); -var Signature = __webpack_require__(75); -var DiffieHellman = __webpack_require__(326).DiffieHellman; -var errs = __webpack_require__(74); -var utils = __webpack_require__(26); -var PrivateKey = __webpack_require__(33); -var edCompat; - -try { - edCompat = __webpack_require__(454); -} catch (e) { - /* Just continue through, and bail out if we try to use it. */ -} - -var InvalidAlgorithmError = errs.InvalidAlgorithmError; -var KeyParseError = errs.KeyParseError; - -var formats = {}; -formats['auto'] = __webpack_require__(455); -formats['pem'] = __webpack_require__(86); -formats['pkcs1'] = __webpack_require__(328); -formats['pkcs8'] = __webpack_require__(158); -formats['rfc4253'] = __webpack_require__(103); -formats['ssh'] = __webpack_require__(456); -formats['ssh-private'] = __webpack_require__(193); -formats['openssh'] = formats['ssh-private']; -formats['dnssec'] = __webpack_require__(327); - -function Key(opts) { - assert.object(opts, 'options'); - assert.arrayOfObject(opts.parts, 'options.parts'); - assert.string(opts.type, 'options.type'); - assert.optionalString(opts.comment, 'options.comment'); - - var algInfo = algs.info[opts.type]; - if (typeof (algInfo) !== 'object') - throw (new InvalidAlgorithmError(opts.type)); - - var partLookup = {}; - for (var i = 0; i < opts.parts.length; ++i) { - var part = opts.parts[i]; - partLookup[part.name] = part; - } - - this.type = opts.type; - this.parts = opts.parts; - this.part = partLookup; - this.comment = undefined; - this.source = opts.source; - - /* for speeding up hashing/fingerprint operations */ - this._rfc4253Cache = opts._rfc4253Cache; - this._hashCache = {}; - - var sz; - this.curve = undefined; - if (this.type === 'ecdsa') { - var curve = this.part.curve.data.toString(); - this.curve = curve; - sz = algs.curves[curve].size; - } else if (this.type === 'ed25519' || this.type === 'curve25519') { - sz = 256; - this.curve = 'curve25519'; - } else { - var szPart = this.part[algInfo.sizePart]; - sz = szPart.data.length; - sz = sz * 8 - utils.countZeros(szPart.data); - } - this.size = sz; -} - -Key.formats = formats; - -Key.prototype.toBuffer = function (format, options) { - if (format === undefined) - format = 'ssh'; - assert.string(format, 'format'); - assert.object(formats[format], 'formats[format]'); - assert.optionalObject(options, 'options'); - - if (format === 'rfc4253') { - if (this._rfc4253Cache === undefined) - this._rfc4253Cache = formats['rfc4253'].write(this); - return (this._rfc4253Cache); - } - - return (formats[format].write(this, options)); -}; - -Key.prototype.toString = function (format, options) { - return (this.toBuffer(format, options).toString()); -}; - -Key.prototype.hash = function (algo) { - assert.string(algo, 'algorithm'); - algo = algo.toLowerCase(); - if (algs.hashAlgs[algo] === undefined) - throw (new InvalidAlgorithmError(algo)); - - if (this._hashCache[algo]) - return (this._hashCache[algo]); - var hash = crypto.createHash(algo). - update(this.toBuffer('rfc4253')).digest(); - this._hashCache[algo] = hash; - return (hash); -}; - -Key.prototype.fingerprint = function (algo) { - if (algo === undefined) - algo = 'sha256'; - assert.string(algo, 'algorithm'); - var opts = { - type: 'key', - hash: this.hash(algo), - algorithm: algo - }; - return (new Fingerprint(opts)); -}; - -Key.prototype.defaultHashAlgorithm = function () { - var hashAlgo = 'sha1'; - if (this.type === 'rsa') - hashAlgo = 'sha256'; - if (this.type === 'dsa' && this.size > 1024) - hashAlgo = 'sha256'; - if (this.type === 'ed25519') - hashAlgo = 'sha512'; - if (this.type === 'ecdsa') { - if (this.size <= 256) - hashAlgo = 'sha256'; - else if (this.size <= 384) - hashAlgo = 'sha384'; - else - hashAlgo = 'sha512'; - } - return (hashAlgo); -}; - -Key.prototype.createVerify = function (hashAlgo) { - if (hashAlgo === undefined) - hashAlgo = this.defaultHashAlgorithm(); - assert.string(hashAlgo, 'hash algorithm'); - - /* ED25519 is not supported by OpenSSL, use a javascript impl. */ - if (this.type === 'ed25519' && edCompat !== undefined) - return (new edCompat.Verifier(this, hashAlgo)); - if (this.type === 'curve25519') - throw (new Error('Curve25519 keys are not suitable for ' + - 'signing or verification')); - - var v, nm, err; - try { - nm = hashAlgo.toUpperCase(); - v = crypto.createVerify(nm); - } catch (e) { - err = e; - } - if (v === undefined || (err instanceof Error && - err.message.match(/Unknown message digest/))) { - nm = 'RSA-'; - nm += hashAlgo.toUpperCase(); - v = crypto.createVerify(nm); - } - assert.ok(v, 'failed to create verifier'); - var oldVerify = v.verify.bind(v); - var key = this.toBuffer('pkcs8'); - var curve = this.curve; - var self = this; - v.verify = function (signature, fmt) { - if (Signature.isSignature(signature, [2, 0])) { - if (signature.type !== self.type) - return (false); - if (signature.hashAlgorithm && - signature.hashAlgorithm !== hashAlgo) - return (false); - if (signature.curve && self.type === 'ecdsa' && - signature.curve !== curve) - return (false); - return (oldVerify(key, signature.toBuffer('asn1'))); - - } else if (typeof (signature) === 'string' || - Buffer.isBuffer(signature)) { - return (oldVerify(key, signature, fmt)); - - /* - * Avoid doing this on valid arguments, walking the prototype - * chain can be quite slow. - */ - } else if (Signature.isSignature(signature, [1, 0])) { - throw (new Error('signature was created by too old ' + - 'a version of sshpk and cannot be verified')); - - } else { - throw (new TypeError('signature must be a string, ' + - 'Buffer, or Signature object')); - } - }; - return (v); -}; - -Key.prototype.createDiffieHellman = function () { - if (this.type === 'rsa') - throw (new Error('RSA keys do not support Diffie-Hellman')); - - return (new DiffieHellman(this)); -}; -Key.prototype.createDH = Key.prototype.createDiffieHellman; - -Key.parse = function (data, format, options) { - if (typeof (data) !== 'string') - assert.buffer(data, 'data'); - if (format === undefined) - format = 'auto'; - assert.string(format, 'format'); - if (typeof (options) === 'string') - options = { filename: options }; - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - assert.optionalString(options.filename, 'options.filename'); - if (options.filename === undefined) - options.filename = '(unnamed)'; - - assert.object(formats[format], 'formats[format]'); - - try { - var k = formats[format].read(data, options); - if (k instanceof PrivateKey) - k = k.toPublic(); - if (!k.comment) - k.comment = options.filename; - return (k); - } catch (e) { - if (e.name === 'KeyEncryptedError') - throw (e); - throw (new KeyParseError(options.filename, format, e)); - } -}; - -Key.isKey = function (obj, ver) { - return (utils.isCompatible(obj, Key, ver)); -}; - -/* - * API versions for Key: - * [1,0] -- initial ver, may take Signature for createVerify or may not - * [1,1] -- added pkcs1, pkcs8 formats - * [1,2] -- added auto, ssh-private, openssh formats - * [1,3] -- added defaultHashAlgorithm - * [1,4] -- added ed support, createDH - * [1,5] -- first explicitly tagged version - * [1,6] -- changed ed25519 part names - */ -Key.prototype._sshpkApiVersion = [1, 6]; - -Key._oldVersionDetect = function (obj) { - assert.func(obj.toBuffer); - assert.func(obj.fingerprint); - if (obj.createDH) - return ([1, 4]); - if (obj.defaultHashAlgorithm) - return ([1, 3]); - if (obj.formats['auto']) - return ([1, 2]); - if (obj.formats['pkcs1']) - return ([1, 1]); - return ([1, 0]); -}; - - -/***/ }), -/* 29 */ -/***/ (function(module, exports) { - -module.exports = require("assert"); - -/***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = nullify; -function nullify(obj = {}) { - if (Array.isArray(obj)) { - for (var _iterator = obj, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - const item = _ref; - - nullify(item); - } - } else if (obj !== null && typeof obj === 'object' || typeof obj === 'function') { - Object.setPrototypeOf(obj, null); - - // for..in can only be applied to 'object', not 'function' - if (typeof obj === 'object') { - for (const key in obj) { - nullify(obj[key]); - } - } - } - - return obj; -} - -/***/ }), -/* 31 */ -/***/ (function(module, exports) { - -var core = module.exports = { version: '2.5.7' }; -if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef - - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright 2015 Joyent, Inc. - -var Buffer = __webpack_require__(15).Buffer; - -var algInfo = { - 'dsa': { - parts: ['p', 'q', 'g', 'y'], - sizePart: 'p' - }, - 'rsa': { - parts: ['e', 'n'], - sizePart: 'n' - }, - 'ecdsa': { - parts: ['curve', 'Q'], - sizePart: 'Q' - }, - 'ed25519': { - parts: ['A'], - sizePart: 'A' - } -}; -algInfo['curve25519'] = algInfo['ed25519']; - -var algPrivInfo = { - 'dsa': { - parts: ['p', 'q', 'g', 'y', 'x'] - }, - 'rsa': { - parts: ['n', 'e', 'd', 'iqmp', 'p', 'q'] - }, - 'ecdsa': { - parts: ['curve', 'Q', 'd'] - }, - 'ed25519': { - parts: ['A', 'k'] - } -}; -algPrivInfo['curve25519'] = algPrivInfo['ed25519']; - -var hashAlgs = { - 'md5': true, - 'sha1': true, - 'sha256': true, - 'sha384': true, - 'sha512': true -}; - -/* - * Taken from - * http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf - */ -var curves = { - 'nistp256': { - size: 256, - pkcs8oid: '1.2.840.10045.3.1.7', - p: Buffer.from(('00' + - 'ffffffff 00000001 00000000 00000000' + - '00000000 ffffffff ffffffff ffffffff'). - replace(/ /g, ''), 'hex'), - a: Buffer.from(('00' + - 'FFFFFFFF 00000001 00000000 00000000' + - '00000000 FFFFFFFF FFFFFFFF FFFFFFFC'). - replace(/ /g, ''), 'hex'), - b: Buffer.from(( - '5ac635d8 aa3a93e7 b3ebbd55 769886bc' + - '651d06b0 cc53b0f6 3bce3c3e 27d2604b'). - replace(/ /g, ''), 'hex'), - s: Buffer.from(('00' + - 'c49d3608 86e70493 6a6678e1 139d26b7' + - '819f7e90'). - replace(/ /g, ''), 'hex'), - n: Buffer.from(('00' + - 'ffffffff 00000000 ffffffff ffffffff' + - 'bce6faad a7179e84 f3b9cac2 fc632551'). - replace(/ /g, ''), 'hex'), - G: Buffer.from(('04' + - '6b17d1f2 e12c4247 f8bce6e5 63a440f2' + - '77037d81 2deb33a0 f4a13945 d898c296' + - '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16' + - '2bce3357 6b315ece cbb64068 37bf51f5'). - replace(/ /g, ''), 'hex') - }, - 'nistp384': { - size: 384, - pkcs8oid: '1.3.132.0.34', - p: Buffer.from(('00' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff fffffffe' + - 'ffffffff 00000000 00000000 ffffffff'). - replace(/ /g, ''), 'hex'), - a: Buffer.from(('00' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE' + - 'FFFFFFFF 00000000 00000000 FFFFFFFC'). - replace(/ /g, ''), 'hex'), - b: Buffer.from(( - 'b3312fa7 e23ee7e4 988e056b e3f82d19' + - '181d9c6e fe814112 0314088f 5013875a' + - 'c656398d 8a2ed19d 2a85c8ed d3ec2aef'). - replace(/ /g, ''), 'hex'), - s: Buffer.from(('00' + - 'a335926a a319a27a 1d00896a 6773a482' + - '7acdac73'). - replace(/ /g, ''), 'hex'), - n: Buffer.from(('00' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff c7634d81 f4372ddf' + - '581a0db2 48b0a77a ecec196a ccc52973'). - replace(/ /g, ''), 'hex'), - G: Buffer.from(('04' + - 'aa87ca22 be8b0537 8eb1c71e f320ad74' + - '6e1d3b62 8ba79b98 59f741e0 82542a38' + - '5502f25d bf55296c 3a545e38 72760ab7' + - '3617de4a 96262c6f 5d9e98bf 9292dc29' + - 'f8f41dbd 289a147c e9da3113 b5f0b8c0' + - '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'). - replace(/ /g, ''), 'hex') - }, - 'nistp521': { - size: 521, - pkcs8oid: '1.3.132.0.35', - p: Buffer.from(( - '01ffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffff').replace(/ /g, ''), 'hex'), - a: Buffer.from(('01FF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + - 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC'). - replace(/ /g, ''), 'hex'), - b: Buffer.from(('51' + - '953eb961 8e1c9a1f 929a21a0 b68540ee' + - 'a2da725b 99b315f3 b8b48991 8ef109e1' + - '56193951 ec7e937b 1652c0bd 3bb1bf07' + - '3573df88 3d2c34f1 ef451fd4 6b503f00'). - replace(/ /g, ''), 'hex'), - s: Buffer.from(('00' + - 'd09e8800 291cb853 96cc6717 393284aa' + - 'a0da64ba').replace(/ /g, ''), 'hex'), - n: Buffer.from(('01ff' + - 'ffffffff ffffffff ffffffff ffffffff' + - 'ffffffff ffffffff ffffffff fffffffa' + - '51868783 bf2f966b 7fcc0148 f709a5d0' + - '3bb5c9b8 899c47ae bb6fb71e 91386409'). - replace(/ /g, ''), 'hex'), - G: Buffer.from(('04' + - '00c6 858e06b7 0404e9cd 9e3ecb66 2395b442' + - '9c648139 053fb521 f828af60 6b4d3dba' + - 'a14b5e77 efe75928 fe1dc127 a2ffa8de' + - '3348b3c1 856a429b f97e7e31 c2e5bd66' + - '0118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9' + - '98f54449 579b4468 17afbd17 273e662c' + - '97ee7299 5ef42640 c550b901 3fad0761' + - '353c7086 a272c240 88be9476 9fd16650'). - replace(/ /g, ''), 'hex') - } -}; - -module.exports = { - info: algInfo, - privInfo: algPrivInfo, - hashAlgs: hashAlgs, - curves: curves -}; - - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright 2017 Joyent, Inc. - -module.exports = PrivateKey; - -var assert = __webpack_require__(16); -var Buffer = __webpack_require__(15).Buffer; -var algs = __webpack_require__(32); -var crypto = __webpack_require__(11); -var Fingerprint = __webpack_require__(157); -var Signature = __webpack_require__(75); -var errs = __webpack_require__(74); -var util = __webpack_require__(3); -var utils = __webpack_require__(26); -var dhe = __webpack_require__(326); -var generateECDSA = dhe.generateECDSA; -var generateED25519 = dhe.generateED25519; -var edCompat; -var nacl; - -try { - edCompat = __webpack_require__(454); -} catch (e) { - /* Just continue through, and bail out if we try to use it. */ -} - -var Key = __webpack_require__(28); - -var InvalidAlgorithmError = errs.InvalidAlgorithmError; -var KeyParseError = errs.KeyParseError; -var KeyEncryptedError = errs.KeyEncryptedError; - -var formats = {}; -formats['auto'] = __webpack_require__(455); -formats['pem'] = __webpack_require__(86); -formats['pkcs1'] = __webpack_require__(328); -formats['pkcs8'] = __webpack_require__(158); -formats['rfc4253'] = __webpack_require__(103); -formats['ssh-private'] = __webpack_require__(193); -formats['openssh'] = formats['ssh-private']; -formats['ssh'] = formats['ssh-private']; -formats['dnssec'] = __webpack_require__(327); - -function PrivateKey(opts) { - assert.object(opts, 'options'); - Key.call(this, opts); - - this._pubCache = undefined; -} -util.inherits(PrivateKey, Key); - -PrivateKey.formats = formats; - -PrivateKey.prototype.toBuffer = function (format, options) { - if (format === undefined) - format = 'pkcs1'; - assert.string(format, 'format'); - assert.object(formats[format], 'formats[format]'); - assert.optionalObject(options, 'options'); - - return (formats[format].write(this, options)); -}; - -PrivateKey.prototype.hash = function (algo) { - return (this.toPublic().hash(algo)); -}; - -PrivateKey.prototype.toPublic = function () { - if (this._pubCache) - return (this._pubCache); - - var algInfo = algs.info[this.type]; - var pubParts = []; - for (var i = 0; i < algInfo.parts.length; ++i) { - var p = algInfo.parts[i]; - pubParts.push(this.part[p]); - } - - this._pubCache = new Key({ - type: this.type, - source: this, - parts: pubParts - }); - if (this.comment) - this._pubCache.comment = this.comment; - return (this._pubCache); -}; - -PrivateKey.prototype.derive = function (newType) { - assert.string(newType, 'type'); - var priv, pub, pair; - - if (this.type === 'ed25519' && newType === 'curve25519') { - if (nacl === undefined) - nacl = __webpack_require__(76); - - priv = this.part.k.data; - if (priv[0] === 0x00) - priv = priv.slice(1); - - pair = nacl.box.keyPair.fromSecretKey(new Uint8Array(priv)); - pub = Buffer.from(pair.publicKey); - - return (new PrivateKey({ - type: 'curve25519', - parts: [ - { name: 'A', data: utils.mpNormalize(pub) }, - { name: 'k', data: utils.mpNormalize(priv) } - ] - })); - } else if (this.type === 'curve25519' && newType === 'ed25519') { - if (nacl === undefined) - nacl = __webpack_require__(76); - - priv = this.part.k.data; - if (priv[0] === 0x00) - priv = priv.slice(1); - - pair = nacl.sign.keyPair.fromSeed(new Uint8Array(priv)); - pub = Buffer.from(pair.publicKey); - - return (new PrivateKey({ - type: 'ed25519', - parts: [ - { name: 'A', data: utils.mpNormalize(pub) }, - { name: 'k', data: utils.mpNormalize(priv) } - ] - })); - } - throw (new Error('Key derivation not supported from ' + this.type + - ' to ' + newType)); -}; - -PrivateKey.prototype.createVerify = function (hashAlgo) { - return (this.toPublic().createVerify(hashAlgo)); -}; - -PrivateKey.prototype.createSign = function (hashAlgo) { - if (hashAlgo === undefined) - hashAlgo = this.defaultHashAlgorithm(); - assert.string(hashAlgo, 'hash algorithm'); - - /* ED25519 is not supported by OpenSSL, use a javascript impl. */ - if (this.type === 'ed25519' && edCompat !== undefined) - return (new edCompat.Signer(this, hashAlgo)); - if (this.type === 'curve25519') - throw (new Error('Curve25519 keys are not suitable for ' + - 'signing or verification')); - - var v, nm, err; - try { - nm = hashAlgo.toUpperCase(); - v = crypto.createSign(nm); - } catch (e) { - err = e; - } - if (v === undefined || (err instanceof Error && - err.message.match(/Unknown message digest/))) { - nm = 'RSA-'; - nm += hashAlgo.toUpperCase(); - v = crypto.createSign(nm); - } - assert.ok(v, 'failed to create verifier'); - var oldSign = v.sign.bind(v); - var key = this.toBuffer('pkcs1'); - var type = this.type; - var curve = this.curve; - v.sign = function () { - var sig = oldSign(key); - if (typeof (sig) === 'string') - sig = Buffer.from(sig, 'binary'); - sig = Signature.parse(sig, type, 'asn1'); - sig.hashAlgorithm = hashAlgo; - sig.curve = curve; - return (sig); - }; - return (v); -}; - -PrivateKey.parse = function (data, format, options) { - if (typeof (data) !== 'string') - assert.buffer(data, 'data'); - if (format === undefined) - format = 'auto'; - assert.string(format, 'format'); - if (typeof (options) === 'string') - options = { filename: options }; - assert.optionalObject(options, 'options'); - if (options === undefined) - options = {}; - assert.optionalString(options.filename, 'options.filename'); - if (options.filename === undefined) - options.filename = '(unnamed)'; - - assert.object(formats[format], 'formats[format]'); - - try { - var k = formats[format].read(data, options); - assert.ok(k instanceof PrivateKey, 'key is not a private key'); - if (!k.comment) - k.comment = options.filename; - return (k); - } catch (e) { - if (e.name === 'KeyEncryptedError') - throw (e); - throw (new KeyParseError(options.filename, format, e)); - } -}; - -PrivateKey.isPrivateKey = function (obj, ver) { - return (utils.isCompatible(obj, PrivateKey, ver)); -}; - -PrivateKey.generate = function (type, options) { - if (options === undefined) - options = {}; - assert.object(options, 'options'); - - switch (type) { - case 'ecdsa': - if (options.curve === undefined) - options.curve = 'nistp256'; - assert.string(options.curve, 'options.curve'); - return (generateECDSA(options.curve)); - case 'ed25519': - return (generateED25519()); - default: - throw (new Error('Key generation not supported with key ' + - 'type "' + type + '"')); - } -}; - -/* - * API versions for PrivateKey: - * [1,0] -- initial ver - * [1,1] -- added auto, pkcs[18], openssh/ssh-private formats - * [1,2] -- added defaultHashAlgorithm - * [1,3] -- added derive, ed, createDH - * [1,4] -- first tagged version - * [1,5] -- changed ed25519 part names and format - */ -PrivateKey.prototype._sshpkApiVersion = [1, 5]; - -PrivateKey._oldVersionDetect = function (obj) { - assert.func(obj.toPublic); - assert.func(obj.createSign); - if (obj.derive) - return ([1, 3]); - if (obj.defaultHashAlgorithm) - return ([1, 2]); - if (obj.formats['auto']) - return ([1, 1]); - return ([1, 0]); -}; - - -/***/ }), -/* 34 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.wrapLifecycle = exports.run = exports.install = exports.Install = undefined; - -var _extends2; - -function _load_extends() { - return _extends2 = _interopRequireDefault(__webpack_require__(20)); -} - -var _asyncToGenerator2; - -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(2)); -} - -let install = exports.install = (() => { - var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, reporter, flags, lockfile) { - yield wrapLifecycle(config, flags, (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - const install = new Install(flags, config, reporter, lockfile); - yield install.init(); - })); - }); - - return function install(_x7, _x8, _x9, _x10) { - return _ref29.apply(this, arguments); - }; -})(); - -let run = exports.run = (() => { - var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, reporter, flags, args) { - let lockfile; - let error = 'installCommandRenamed'; - if (flags.lockfile === false) { - lockfile = new (_lockfile || _load_lockfile()).default(); - } else { - lockfile = yield (_lockfile || _load_lockfile()).default.fromDirectory(config.lockfileFolder, reporter); - } - - if (args.length) { - const exampleArgs = args.slice(); - - if (flags.saveDev) { - exampleArgs.push('--dev'); - } - if (flags.savePeer) { - exampleArgs.push('--peer'); - } - if (flags.saveOptional) { - exampleArgs.push('--optional'); - } - if (flags.saveExact) { - exampleArgs.push('--exact'); - } - if (flags.saveTilde) { - exampleArgs.push('--tilde'); - } - let command = 'add'; - if (flags.global) { - error = 'globalFlagRemoved'; - command = 'global add'; - } - throw new (_errors || _load_errors()).MessageError(reporter.lang(error, `yarn ${command} ${exampleArgs.join(' ')}`)); - } - - yield install(config, reporter, flags, lockfile); - }); - - return function run(_x11, _x12, _x13, _x14) { - return _ref31.apply(this, arguments); - }; -})(); - -let wrapLifecycle = exports.wrapLifecycle = (() => { - var _ref32 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, flags, factory) { - yield config.executeLifecycleScript('preinstall'); - - yield factory(); - - // npm behaviour, seems kinda funky but yay compatibility - yield config.executeLifecycleScript('install'); - yield config.executeLifecycleScript('postinstall'); - - if (!config.production) { - if (!config.disablePrepublish) { - yield config.executeLifecycleScript('prepublish'); - } - yield config.executeLifecycleScript('prepare'); - } - }); - - return function wrapLifecycle(_x15, _x16, _x17) { - return _ref32.apply(this, arguments); - }; -})(); - -exports.hasWrapper = hasWrapper; -exports.setFlags = setFlags; - -var _objectPath; - -function _load_objectPath() { - return _objectPath = _interopRequireDefault(__webpack_require__(304)); -} - -var _hooks; - -function _load_hooks() { - return _hooks = __webpack_require__(368); -} - -var _index; - -function _load_index() { - return _index = _interopRequireDefault(__webpack_require__(218)); -} - -var _errors; - -function _load_errors() { - return _errors = __webpack_require__(6); -} - -var _integrityChecker; - -function _load_integrityChecker() { - return _integrityChecker = _interopRequireDefault(__webpack_require__(206)); -} - -var _lockfile; - -function _load_lockfile() { - return _lockfile = _interopRequireDefault(__webpack_require__(19)); -} - -var _lockfile2; - -function _load_lockfile2() { - return _lockfile2 = __webpack_require__(19); -} - -var _packageFetcher; - -function _load_packageFetcher() { - return _packageFetcher = _interopRequireWildcard(__webpack_require__(208)); -} - -var _packageInstallScripts; - -function _load_packageInstallScripts() { - return _packageInstallScripts = _interopRequireDefault(__webpack_require__(525)); -} - -var _packageCompatibility; - -function _load_packageCompatibility() { - return _packageCompatibility = _interopRequireWildcard(__webpack_require__(207)); -} - -var _packageResolver; - -function _load_packageResolver() { - return _packageResolver = _interopRequireDefault(__webpack_require__(360)); -} - -var _packageLinker; - -function _load_packageLinker() { - return _packageLinker = _interopRequireDefault(__webpack_require__(209)); -} - -var _index2; - -function _load_index2() { - return _index2 = __webpack_require__(58); -} - -var _index3; - -function _load_index3() { - return _index3 = __webpack_require__(78); -} - -var _autoclean; - -function _load_autoclean() { - return _autoclean = __webpack_require__(348); -} - -var _constants; - -function _load_constants() { - return _constants = _interopRequireWildcard(__webpack_require__(8)); -} - -var _normalizePattern; - -function _load_normalizePattern() { - return _normalizePattern = __webpack_require__(37); -} - -var _fs; - -function _load_fs() { - return _fs = _interopRequireWildcard(__webpack_require__(5)); -} - -var _map; - -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(30)); -} - -var _yarnVersion; - -function _load_yarnVersion() { - return _yarnVersion = __webpack_require__(105); -} - -var _generatePnpMap; - -function _load_generatePnpMap() { - return _generatePnpMap = __webpack_require__(547); -} - -var _workspaceLayout; - -function _load_workspaceLayout() { - return _workspaceLayout = _interopRequireDefault(__webpack_require__(90)); -} - -var _resolutionMap; - -function _load_resolutionMap() { - return _resolutionMap = _interopRequireDefault(__webpack_require__(212)); -} - -var _guessName; - -function _load_guessName() { - return _guessName = _interopRequireDefault(__webpack_require__(169)); -} - -var _audit; - -function _load_audit() { - return _audit = _interopRequireDefault(__webpack_require__(347)); -} - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const deepEqual = __webpack_require__(599); - -const emoji = __webpack_require__(302); -const invariant = __webpack_require__(9); -const path = __webpack_require__(0); -const semver = __webpack_require__(22); -const uuid = __webpack_require__(120); -const ssri = __webpack_require__(65); - -const ONE_DAY = 1000 * 60 * 60 * 24; - -/** - * Try and detect the installation method for Yarn and provide a command to update it with. - */ - -function getUpdateCommand(installationMethod) { - if (installationMethod === 'tar') { - return `curl --compressed -o- -L ${(_constants || _load_constants()).YARN_INSTALLER_SH} | bash`; - } - - if (installationMethod === 'homebrew') { - return 'brew upgrade yarn'; - } - - if (installationMethod === 'deb') { - return 'sudo apt-get update && sudo apt-get install yarn'; - } - - if (installationMethod === 'rpm') { - return 'sudo yum install yarn'; - } - - if (installationMethod === 'npm') { - return 'npm install --global yarn'; - } - - if (installationMethod === 'chocolatey') { - return 'choco upgrade yarn'; - } - - if (installationMethod === 'apk') { - return 'apk update && apk add -u yarn'; - } - - if (installationMethod === 'portage') { - return 'sudo emerge --sync && sudo emerge -au sys-apps/yarn'; - } - - return null; -} - -function getUpdateInstaller(installationMethod) { - // Windows - if (installationMethod === 'msi') { - return (_constants || _load_constants()).YARN_INSTALLER_MSI; - } - - return null; -} - -function normalizeFlags(config, rawFlags) { - const flags = { - // install - har: !!rawFlags.har, - ignorePlatform: !!rawFlags.ignorePlatform, - ignoreEngines: !!rawFlags.ignoreEngines, - ignoreScripts: !!rawFlags.ignoreScripts, - ignoreOptional: !!rawFlags.ignoreOptional, - force: !!rawFlags.force, - flat: !!rawFlags.flat, - lockfile: rawFlags.lockfile !== false, - pureLockfile: !!rawFlags.pureLockfile, - updateChecksums: !!rawFlags.updateChecksums, - skipIntegrityCheck: !!rawFlags.skipIntegrityCheck, - frozenLockfile: !!rawFlags.frozenLockfile, - linkDuplicates: !!rawFlags.linkDuplicates, - checkFiles: !!rawFlags.checkFiles, - audit: !!rawFlags.audit, - - // add - peer: !!rawFlags.peer, - dev: !!rawFlags.dev, - optional: !!rawFlags.optional, - exact: !!rawFlags.exact, - tilde: !!rawFlags.tilde, - ignoreWorkspaceRootCheck: !!rawFlags.ignoreWorkspaceRootCheck, - - // outdated, update-interactive - includeWorkspaceDeps: !!rawFlags.includeWorkspaceDeps, - - // add, remove, update - workspaceRootIsCwd: rawFlags.workspaceRootIsCwd !== false - }; - - if (config.getOption('ignore-scripts')) { - flags.ignoreScripts = true; - } - - if (config.getOption('ignore-platform')) { - flags.ignorePlatform = true; - } - - if (config.getOption('ignore-engines')) { - flags.ignoreEngines = true; - } - - if (config.getOption('ignore-optional')) { - flags.ignoreOptional = true; - } - - if (config.getOption('force')) { - flags.force = true; - } - - return flags; -} - -class Install { - constructor(flags, config, reporter, lockfile) { - this.rootManifestRegistries = []; - this.rootPatternsToOrigin = (0, (_map || _load_map()).default)(); - this.lockfile = lockfile; - this.reporter = reporter; - this.config = config; - this.flags = normalizeFlags(config, flags); - this.resolutions = (0, (_map || _load_map()).default)(); // Legacy resolutions field used for flat install mode - this.resolutionMap = new (_resolutionMap || _load_resolutionMap()).default(config); // Selective resolutions for nested dependencies - this.resolver = new (_packageResolver || _load_packageResolver()).default(config, lockfile, this.resolutionMap); - this.integrityChecker = new (_integrityChecker || _load_integrityChecker()).default(config); - this.linker = new (_packageLinker || _load_packageLinker()).default(config, this.resolver); - this.scripts = new (_packageInstallScripts || _load_packageInstallScripts()).default(config, this.resolver, this.flags.force); - } - - /** - * Create a list of dependency requests from the current directories manifests. - */ - - fetchRequestFromCwd(excludePatterns = [], ignoreUnusedPatterns = false) { - var _this = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - const patterns = []; - const deps = []; - let resolutionDeps = []; - const manifest = {}; - - const ignorePatterns = []; - const usedPatterns = []; - let workspaceLayout; - - // some commands should always run in the context of the entire workspace - const cwd = _this.flags.includeWorkspaceDeps || _this.flags.workspaceRootIsCwd ? _this.config.lockfileFolder : _this.config.cwd; - - // non-workspaces are always root, otherwise check for workspace root - const cwdIsRoot = !_this.config.workspaceRootFolder || _this.config.lockfileFolder === cwd; - - // exclude package names that are in install args - const excludeNames = []; - for (var _iterator = excludePatterns, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - const pattern = _ref; - - if ((0, (_index3 || _load_index3()).getExoticResolver)(pattern)) { - excludeNames.push((0, (_guessName || _load_guessName()).default)(pattern)); - } else { - // extract the name - const parts = (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(pattern); - excludeNames.push(parts.name); - } - } - - const stripExcluded = function stripExcluded(manifest) { - for (var _iterator2 = excludeNames, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - - const exclude = _ref2; - - if (manifest.dependencies && manifest.dependencies[exclude]) { - delete manifest.dependencies[exclude]; - } - if (manifest.devDependencies && manifest.devDependencies[exclude]) { - delete manifest.devDependencies[exclude]; - } - if (manifest.optionalDependencies && manifest.optionalDependencies[exclude]) { - delete manifest.optionalDependencies[exclude]; - } - } - }; - - for (var _iterator3 = Object.keys((_index2 || _load_index2()).registries), _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { - var _ref3; - - if (_isArray3) { - if (_i3 >= _iterator3.length) break; - _ref3 = _iterator3[_i3++]; - } else { - _i3 = _iterator3.next(); - if (_i3.done) break; - _ref3 = _i3.value; - } - - const registry = _ref3; - - const filename = (_index2 || _load_index2()).registries[registry].filename; - - const loc = path.join(cwd, filename); - if (!(yield (_fs || _load_fs()).exists(loc))) { - continue; - } - - _this.rootManifestRegistries.push(registry); - - const projectManifestJson = yield _this.config.readJson(loc); - yield (0, (_index || _load_index()).default)(projectManifestJson, cwd, _this.config, cwdIsRoot); - - Object.assign(_this.resolutions, projectManifestJson.resolutions); - Object.assign(manifest, projectManifestJson); - - _this.resolutionMap.init(_this.resolutions); - for (var _iterator4 = Object.keys(_this.resolutionMap.resolutionsByPackage), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { - var _ref4; - - if (_isArray4) { - if (_i4 >= _iterator4.length) break; - _ref4 = _iterator4[_i4++]; - } else { - _i4 = _iterator4.next(); - if (_i4.done) break; - _ref4 = _i4.value; - } - - const packageName = _ref4; - - const optional = (_objectPath || _load_objectPath()).default.has(manifest.optionalDependencies, packageName) && _this.flags.ignoreOptional; - for (var _iterator8 = _this.resolutionMap.resolutionsByPackage[packageName], _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { - var _ref9; - - if (_isArray8) { - if (_i8 >= _iterator8.length) break; - _ref9 = _iterator8[_i8++]; - } else { - _i8 = _iterator8.next(); - if (_i8.done) break; - _ref9 = _i8.value; - } - - const _ref8 = _ref9; - const pattern = _ref8.pattern; - - resolutionDeps = [...resolutionDeps, { registry, pattern, optional, hint: 'resolution' }]; - } - } - - const pushDeps = function pushDeps(depType, manifest, { hint, optional }, isUsed) { - if (ignoreUnusedPatterns && !isUsed) { - return; - } - // We only take unused dependencies into consideration to get deterministic hoisting. - // Since flat mode doesn't care about hoisting and everything is top level and specified then we can safely - // leave these out. - if (_this.flags.flat && !isUsed) { - return; - } - const depMap = manifest[depType]; - for (const name in depMap) { - if (excludeNames.indexOf(name) >= 0) { - continue; - } - - let pattern = name; - if (!_this.lockfile.getLocked(pattern)) { - // when we use --save we save the dependency to the lockfile with just the name rather than the - // version combo - pattern += '@' + depMap[name]; - } - - // normalization made sure packages are mentioned only once - if (isUsed) { - usedPatterns.push(pattern); - } else { - ignorePatterns.push(pattern); - } - - _this.rootPatternsToOrigin[pattern] = depType; - patterns.push(pattern); - deps.push({ pattern, registry, hint, optional, workspaceName: manifest.name, workspaceLoc: manifest._loc }); - } - }; - - if (cwdIsRoot) { - pushDeps('dependencies', projectManifestJson, { hint: null, optional: false }, true); - pushDeps('devDependencies', projectManifestJson, { hint: 'dev', optional: false }, !_this.config.production); - pushDeps('optionalDependencies', projectManifestJson, { hint: 'optional', optional: true }, true); - } - - if (_this.config.workspaceRootFolder) { - const workspaceLoc = cwdIsRoot ? loc : path.join(_this.config.lockfileFolder, filename); - const workspacesRoot = path.dirname(workspaceLoc); - - let workspaceManifestJson = projectManifestJson; - if (!cwdIsRoot) { - // the manifest we read before was a child workspace, so get the root - workspaceManifestJson = yield _this.config.readJson(workspaceLoc); - yield (0, (_index || _load_index()).default)(workspaceManifestJson, workspacesRoot, _this.config, true); - } - - const workspaces = yield _this.config.resolveWorkspaces(workspacesRoot, workspaceManifestJson); - workspaceLayout = new (_workspaceLayout || _load_workspaceLayout()).default(workspaces, _this.config); - - // add virtual manifest that depends on all workspaces, this way package hoisters and resolvers will work fine - const workspaceDependencies = (0, (_extends2 || _load_extends()).default)({}, workspaceManifestJson.dependencies); - for (var _iterator5 = Object.keys(workspaces), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { - var _ref5; - - if (_isArray5) { - if (_i5 >= _iterator5.length) break; - _ref5 = _iterator5[_i5++]; - } else { - _i5 = _iterator5.next(); - if (_i5.done) break; - _ref5 = _i5.value; - } - - const workspaceName = _ref5; - - const workspaceManifest = workspaces[workspaceName].manifest; - workspaceDependencies[workspaceName] = workspaceManifest.version; - - // include dependencies from all workspaces - if (_this.flags.includeWorkspaceDeps) { - pushDeps('dependencies', workspaceManifest, { hint: null, optional: false }, true); - pushDeps('devDependencies', workspaceManifest, { hint: 'dev', optional: false }, !_this.config.production); - pushDeps('optionalDependencies', workspaceManifest, { hint: 'optional', optional: true }, true); - } - } - const virtualDependencyManifest = { - _uid: '', - name: `workspace-aggregator-${uuid.v4()}`, - version: '1.0.0', - _registry: 'npm', - _loc: workspacesRoot, - dependencies: workspaceDependencies, - devDependencies: (0, (_extends2 || _load_extends()).default)({}, workspaceManifestJson.devDependencies), - optionalDependencies: (0, (_extends2 || _load_extends()).default)({}, workspaceManifestJson.optionalDependencies), - private: workspaceManifestJson.private, - workspaces: workspaceManifestJson.workspaces - }; - workspaceLayout.virtualManifestName = virtualDependencyManifest.name; - const virtualDep = {}; - virtualDep[virtualDependencyManifest.name] = virtualDependencyManifest.version; - workspaces[virtualDependencyManifest.name] = { loc: workspacesRoot, manifest: virtualDependencyManifest }; - - // ensure dependencies that should be excluded are stripped from the correct manifest - stripExcluded(cwdIsRoot ? virtualDependencyManifest : workspaces[projectManifestJson.name].manifest); - - pushDeps('workspaces', { workspaces: virtualDep }, { hint: 'workspaces', optional: false }, true); - - const implicitWorkspaceDependencies = (0, (_extends2 || _load_extends()).default)({}, workspaceDependencies); - - for (var _iterator6 = (_constants || _load_constants()).OWNED_DEPENDENCY_TYPES, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { - var _ref6; - - if (_isArray6) { - if (_i6 >= _iterator6.length) break; - _ref6 = _iterator6[_i6++]; - } else { - _i6 = _iterator6.next(); - if (_i6.done) break; - _ref6 = _i6.value; - } - - const type = _ref6; - - for (var _iterator7 = Object.keys(projectManifestJson[type] || {}), _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { - var _ref7; - - if (_isArray7) { - if (_i7 >= _iterator7.length) break; - _ref7 = _iterator7[_i7++]; - } else { - _i7 = _iterator7.next(); - if (_i7.done) break; - _ref7 = _i7.value; - } - - const dependencyName = _ref7; - - delete implicitWorkspaceDependencies[dependencyName]; - } - } - - pushDeps('dependencies', { dependencies: implicitWorkspaceDependencies }, { hint: 'workspaces', optional: false }, true); - } - - break; - } - - // inherit root flat flag - if (manifest.flat) { - _this.flags.flat = true; - } - - return { - requests: [...resolutionDeps, ...deps], - patterns, - manifest, - usedPatterns, - ignorePatterns, - workspaceLayout - }; - })(); - } - - /** - * TODO description - */ - - prepareRequests(requests) { - return requests; - } - - preparePatterns(patterns) { - return patterns; - } - preparePatternsForLinking(patterns, cwdManifest, cwdIsRoot) { - return patterns; - } - - prepareManifests() { - var _this2 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - const manifests = yield _this2.config.getRootManifests(); - return manifests; - })(); - } - - bailout(patterns, workspaceLayout) { - var _this3 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - // We don't want to skip the audit - it could yield important errors - if (_this3.flags.audit) { - return false; - } - // PNP is so fast that the integrity check isn't pertinent - if (_this3.config.plugnplayEnabled) { - return false; - } - if (_this3.flags.skipIntegrityCheck || _this3.flags.force) { - return false; - } - const lockfileCache = _this3.lockfile.cache; - if (!lockfileCache) { - return false; - } - const lockfileClean = _this3.lockfile.parseResultType === 'success'; - const match = yield _this3.integrityChecker.check(patterns, lockfileCache, _this3.flags, workspaceLayout); - if (_this3.flags.frozenLockfile && (!lockfileClean || match.missingPatterns.length > 0)) { - throw new (_errors || _load_errors()).MessageError(_this3.reporter.lang('frozenLockfileError')); - } - - const haveLockfile = yield (_fs || _load_fs()).exists(path.join(_this3.config.lockfileFolder, (_constants || _load_constants()).LOCKFILE_FILENAME)); - - const lockfileIntegrityPresent = !_this3.lockfile.hasEntriesExistWithoutIntegrity(); - const integrityBailout = lockfileIntegrityPresent || !_this3.config.autoAddIntegrity; - - if (match.integrityMatches && haveLockfile && lockfileClean && integrityBailout) { - _this3.reporter.success(_this3.reporter.lang('upToDate')); - return true; - } - - if (match.integrityFileMissing && haveLockfile) { - // Integrity file missing, force script installations - _this3.scripts.setForce(true); - return false; - } - - if (match.hardRefreshRequired) { - // e.g. node version doesn't match, force script installations - _this3.scripts.setForce(true); - return false; - } - - if (!patterns.length && !match.integrityFileMissing) { - _this3.reporter.success(_this3.reporter.lang('nothingToInstall')); - yield _this3.createEmptyManifestFolders(); - yield _this3.saveLockfileAndIntegrity(patterns, workspaceLayout); - return true; - } - - return false; - })(); - } - - /** - * Produce empty folders for all used root manifests. - */ - - createEmptyManifestFolders() { - var _this4 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - if (_this4.config.modulesFolder) { - // already created - return; - } - - for (var _iterator9 = _this4.rootManifestRegistries, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { - var _ref10; - - if (_isArray9) { - if (_i9 >= _iterator9.length) break; - _ref10 = _iterator9[_i9++]; - } else { - _i9 = _iterator9.next(); - if (_i9.done) break; - _ref10 = _i9.value; - } - - const registryName = _ref10; - const folder = _this4.config.registries[registryName].folder; - - yield (_fs || _load_fs()).mkdirp(path.join(_this4.config.lockfileFolder, folder)); - } - })(); - } - - /** - * TODO description - */ - - markIgnored(patterns) { - for (var _iterator10 = patterns, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { - var _ref11; - - if (_isArray10) { - if (_i10 >= _iterator10.length) break; - _ref11 = _iterator10[_i10++]; - } else { - _i10 = _iterator10.next(); - if (_i10.done) break; - _ref11 = _i10.value; - } - - const pattern = _ref11; - - const manifest = this.resolver.getStrictResolvedPattern(pattern); - const ref = manifest._reference; - invariant(ref, 'expected package reference'); - - // just mark the package as ignored. if the package is used by a required package, the hoister - // will take care of that. - ref.ignore = true; - } - } - - /** - * helper method that gets only recent manifests - * used by global.ls command - */ - getFlattenedDeps() { - var _this5 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - var _ref12 = yield _this5.fetchRequestFromCwd(); - - const depRequests = _ref12.requests, - rawPatterns = _ref12.patterns; - - - yield _this5.resolver.init(depRequests, {}); - - const manifests = yield (_packageFetcher || _load_packageFetcher()).fetch(_this5.resolver.getManifests(), _this5.config); - _this5.resolver.updateManifests(manifests); - - return _this5.flatten(rawPatterns); - })(); - } - - /** - * TODO description - */ - - init() { - var _this6 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - _this6.checkUpdate(); - - // warn if we have a shrinkwrap - if (yield (_fs || _load_fs()).exists(path.join(_this6.config.lockfileFolder, (_constants || _load_constants()).NPM_SHRINKWRAP_FILENAME))) { - _this6.reporter.warn(_this6.reporter.lang('shrinkwrapWarning')); - } - - // warn if we have an npm lockfile - if (yield (_fs || _load_fs()).exists(path.join(_this6.config.lockfileFolder, (_constants || _load_constants()).NPM_LOCK_FILENAME))) { - _this6.reporter.warn(_this6.reporter.lang('npmLockfileWarning')); - } - - if (_this6.config.plugnplayEnabled) { - _this6.reporter.info(_this6.reporter.lang('plugnplaySuggestV2L1')); - _this6.reporter.info(_this6.reporter.lang('plugnplaySuggestV2L2')); - } - - let flattenedTopLevelPatterns = []; - const steps = []; - - var _ref13 = yield _this6.fetchRequestFromCwd(); - - const depRequests = _ref13.requests, - rawPatterns = _ref13.patterns, - ignorePatterns = _ref13.ignorePatterns, - workspaceLayout = _ref13.workspaceLayout, - manifest = _ref13.manifest; - - let topLevelPatterns = []; - - const artifacts = yield _this6.integrityChecker.getArtifacts(); - if (artifacts) { - _this6.linker.setArtifacts(artifacts); - _this6.scripts.setArtifacts(artifacts); - } - - if ((_packageCompatibility || _load_packageCompatibility()).shouldCheck(manifest, _this6.flags)) { - steps.push((() => { - var _ref14 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (curr, total) { - _this6.reporter.step(curr, total, _this6.reporter.lang('checkingManifest'), emoji.get('mag')); - yield _this6.checkCompatibility(); - }); - - return function (_x, _x2) { - return _ref14.apply(this, arguments); - }; - })()); - } - - const audit = new (_audit || _load_audit()).default(_this6.config, _this6.reporter, { groups: (_constants || _load_constants()).OWNED_DEPENDENCY_TYPES }); - let auditFoundProblems = false; - - steps.push(function (curr, total) { - return (0, (_hooks || _load_hooks()).callThroughHook)('resolveStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - _this6.reporter.step(curr, total, _this6.reporter.lang('resolvingPackages'), emoji.get('mag')); - yield _this6.resolver.init(_this6.prepareRequests(depRequests), { - isFlat: _this6.flags.flat, - isFrozen: _this6.flags.frozenLockfile, - workspaceLayout - }); - topLevelPatterns = _this6.preparePatterns(rawPatterns); - flattenedTopLevelPatterns = yield _this6.flatten(topLevelPatterns); - return { bailout: !_this6.flags.audit && (yield _this6.bailout(topLevelPatterns, workspaceLayout)) }; - })); - }); - - if (_this6.flags.audit) { - steps.push(function (curr, total) { - return (0, (_hooks || _load_hooks()).callThroughHook)('auditStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - _this6.reporter.step(curr, total, _this6.reporter.lang('auditRunning'), emoji.get('mag')); - if (_this6.flags.offline) { - _this6.reporter.warn(_this6.reporter.lang('auditOffline')); - return { bailout: false }; - } - const preparedManifests = yield _this6.prepareManifests(); - // $FlowFixMe - Flow considers `m` in the map operation to be "mixed", so does not recognize `m.object` - const mergedManifest = Object.assign({}, ...Object.values(preparedManifests).map(function (m) { - return m.object; - })); - const auditVulnerabilityCounts = yield audit.performAudit(mergedManifest, _this6.lockfile, _this6.resolver, _this6.linker, topLevelPatterns); - auditFoundProblems = auditVulnerabilityCounts.info || auditVulnerabilityCounts.low || auditVulnerabilityCounts.moderate || auditVulnerabilityCounts.high || auditVulnerabilityCounts.critical; - return { bailout: yield _this6.bailout(topLevelPatterns, workspaceLayout) }; - })); - }); - } - - steps.push(function (curr, total) { - return (0, (_hooks || _load_hooks()).callThroughHook)('fetchStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - _this6.markIgnored(ignorePatterns); - _this6.reporter.step(curr, total, _this6.reporter.lang('fetchingPackages'), emoji.get('truck')); - const manifests = yield (_packageFetcher || _load_packageFetcher()).fetch(_this6.resolver.getManifests(), _this6.config); - _this6.resolver.updateManifests(manifests); - yield (_packageCompatibility || _load_packageCompatibility()).check(_this6.resolver.getManifests(), _this6.config, _this6.flags.ignoreEngines); - })); - }); - - steps.push(function (curr, total) { - return (0, (_hooks || _load_hooks()).callThroughHook)('linkStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - // remove integrity hash to make this operation atomic - yield _this6.integrityChecker.removeIntegrityFile(); - _this6.reporter.step(curr, total, _this6.reporter.lang('linkingDependencies'), emoji.get('link')); - flattenedTopLevelPatterns = _this6.preparePatternsForLinking(flattenedTopLevelPatterns, manifest, _this6.config.lockfileFolder === _this6.config.cwd); - yield _this6.linker.init(flattenedTopLevelPatterns, workspaceLayout, { - linkDuplicates: _this6.flags.linkDuplicates, - ignoreOptional: _this6.flags.ignoreOptional - }); - })); - }); - - if (_this6.config.plugnplayEnabled) { - steps.push(function (curr, total) { - return (0, (_hooks || _load_hooks()).callThroughHook)('pnpStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - const pnpPath = `${_this6.config.lockfileFolder}/${(_constants || _load_constants()).PNP_FILENAME}`; - - const code = yield (0, (_generatePnpMap || _load_generatePnpMap()).generatePnpMap)(_this6.config, flattenedTopLevelPatterns, { - resolver: _this6.resolver, - reporter: _this6.reporter, - targetPath: pnpPath, - workspaceLayout - }); - - try { - const file = yield (_fs || _load_fs()).readFile(pnpPath); - if (file === code) { - return; - } - } catch (error) {} - - yield (_fs || _load_fs()).writeFile(pnpPath, code); - yield (_fs || _load_fs()).chmod(pnpPath, 0o755); - })); - }); - } - - steps.push(function (curr, total) { - return (0, (_hooks || _load_hooks()).callThroughHook)('buildStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - _this6.reporter.step(curr, total, _this6.flags.force ? _this6.reporter.lang('rebuildingPackages') : _this6.reporter.lang('buildingFreshPackages'), emoji.get('hammer')); - - if (_this6.config.ignoreScripts) { - _this6.reporter.warn(_this6.reporter.lang('ignoredScripts')); - } else { - yield _this6.scripts.init(flattenedTopLevelPatterns); - } - })); - }); - - if (_this6.flags.har) { - steps.push((() => { - var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (curr, total) { - const formattedDate = new Date().toISOString().replace(/:/g, '-'); - const filename = `yarn-install_${formattedDate}.har`; - _this6.reporter.step(curr, total, _this6.reporter.lang('savingHar', filename), emoji.get('black_circle_for_record')); - yield _this6.config.requestManager.saveHar(filename); - }); - - return function (_x3, _x4) { - return _ref21.apply(this, arguments); - }; - })()); - } - - if (yield _this6.shouldClean()) { - steps.push((() => { - var _ref22 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (curr, total) { - _this6.reporter.step(curr, total, _this6.reporter.lang('cleaningModules'), emoji.get('recycle')); - yield (0, (_autoclean || _load_autoclean()).clean)(_this6.config, _this6.reporter); - }); - - return function (_x5, _x6) { - return _ref22.apply(this, arguments); - }; - })()); - } - - let currentStep = 0; - for (var _iterator11 = steps, _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { - var _ref23; - - if (_isArray11) { - if (_i11 >= _iterator11.length) break; - _ref23 = _iterator11[_i11++]; - } else { - _i11 = _iterator11.next(); - if (_i11.done) break; - _ref23 = _i11.value; - } - - const step = _ref23; - - const stepResult = yield step(++currentStep, steps.length); - if (stepResult && stepResult.bailout) { - if (_this6.flags.audit) { - audit.summary(); - } - if (auditFoundProblems) { - _this6.reporter.warn(_this6.reporter.lang('auditRunAuditForDetails')); - } - _this6.maybeOutputUpdate(); - return flattenedTopLevelPatterns; - } - } - - // fin! - if (_this6.flags.audit) { - audit.summary(); - } - if (auditFoundProblems) { - _this6.reporter.warn(_this6.reporter.lang('auditRunAuditForDetails')); - } - yield _this6.saveLockfileAndIntegrity(topLevelPatterns, workspaceLayout); - yield _this6.persistChanges(); - _this6.maybeOutputUpdate(); - _this6.config.requestManager.clearCache(); - return flattenedTopLevelPatterns; - })(); - } - - checkCompatibility() { - var _this7 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - var _ref24 = yield _this7.fetchRequestFromCwd(); - - const manifest = _ref24.manifest; - - yield (_packageCompatibility || _load_packageCompatibility()).checkOne(manifest, _this7.config, _this7.flags.ignoreEngines); - })(); - } - - persistChanges() { - var _this8 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - // get all the different registry manifests in this folder - const manifests = yield _this8.config.getRootManifests(); - - if (yield _this8.applyChanges(manifests)) { - yield _this8.config.saveRootManifests(manifests); - } - })(); - } - - applyChanges(manifests) { - let hasChanged = false; - - if (this.config.plugnplayPersist) { - const object = manifests.npm.object; - - - if (typeof object.installConfig !== 'object') { - object.installConfig = {}; - } - - if (this.config.plugnplayEnabled && object.installConfig.pnp !== true) { - object.installConfig.pnp = true; - hasChanged = true; - } else if (!this.config.plugnplayEnabled && typeof object.installConfig.pnp !== 'undefined') { - delete object.installConfig.pnp; - hasChanged = true; - } - - if (Object.keys(object.installConfig).length === 0) { - delete object.installConfig; - } - } - - return Promise.resolve(hasChanged); - } - - /** - * Check if we should run the cleaning step. - */ - - shouldClean() { - return (_fs || _load_fs()).exists(path.join(this.config.lockfileFolder, (_constants || _load_constants()).CLEAN_FILENAME)); - } - - /** - * TODO - */ - - flatten(patterns) { - var _this9 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - if (!_this9.flags.flat) { - return patterns; - } - - const flattenedPatterns = []; - - for (var _iterator12 = _this9.resolver.getAllDependencyNamesByLevelOrder(patterns), _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) { - var _ref25; - - if (_isArray12) { - if (_i12 >= _iterator12.length) break; - _ref25 = _iterator12[_i12++]; - } else { - _i12 = _iterator12.next(); - if (_i12.done) break; - _ref25 = _i12.value; - } - - const name = _ref25; - - const infos = _this9.resolver.getAllInfoForPackageName(name).filter(function (manifest) { - const ref = manifest._reference; - invariant(ref, 'expected package reference'); - return !ref.ignore; - }); - - if (infos.length === 0) { - continue; - } - - if (infos.length === 1) { - // single version of this package - // take out a single pattern as multiple patterns may have resolved to this package - flattenedPatterns.push(_this9.resolver.patternsByPackage[name][0]); - continue; - } - - const options = infos.map(function (info) { - const ref = info._reference; - invariant(ref, 'expected reference'); - return { - // TODO `and is required by {PARENT}`, - name: _this9.reporter.lang('manualVersionResolutionOption', ref.patterns.join(', '), info.version), - - value: info.version - }; - }); - const versions = infos.map(function (info) { - return info.version; - }); - let version; - - const resolutionVersion = _this9.resolutions[name]; - if (resolutionVersion && versions.indexOf(resolutionVersion) >= 0) { - // use json `resolution` version - version = resolutionVersion; - } else { - version = yield _this9.reporter.select(_this9.reporter.lang('manualVersionResolution', name), _this9.reporter.lang('answer'), options); - _this9.resolutions[name] = version; - } - - flattenedPatterns.push(_this9.resolver.collapseAllVersionsOfPackage(name, version)); - } - - // save resolutions to their appropriate root manifest - if (Object.keys(_this9.resolutions).length) { - const manifests = yield _this9.config.getRootManifests(); - - for (const name in _this9.resolutions) { - const version = _this9.resolutions[name]; - - const patterns = _this9.resolver.patternsByPackage[name]; - if (!patterns) { - continue; - } - - let manifest; - for (var _iterator13 = patterns, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) { - var _ref26; - - if (_isArray13) { - if (_i13 >= _iterator13.length) break; - _ref26 = _iterator13[_i13++]; - } else { - _i13 = _iterator13.next(); - if (_i13.done) break; - _ref26 = _i13.value; - } - - const pattern = _ref26; - - manifest = _this9.resolver.getResolvedPattern(pattern); - if (manifest) { - break; - } - } - invariant(manifest, 'expected manifest'); - - const ref = manifest._reference; - invariant(ref, 'expected reference'); - - const object = manifests[ref.registry].object; - object.resolutions = object.resolutions || {}; - object.resolutions[name] = version; - } - - yield _this9.config.saveRootManifests(manifests); - } - - return flattenedPatterns; - })(); - } - - /** - * Remove offline tarballs that are no longer required - */ - - pruneOfflineMirror(lockfile) { - var _this10 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - const mirror = _this10.config.getOfflineMirrorPath(); - if (!mirror) { - return; - } - - const requiredTarballs = new Set(); - for (const dependency in lockfile) { - const resolved = lockfile[dependency].resolved; - if (resolved) { - const basename = path.basename(resolved.split('#')[0]); - if (dependency[0] === '@' && basename[0] !== '@') { - requiredTarballs.add(`${dependency.split('/')[0]}-${basename}`); - } - requiredTarballs.add(basename); - } - } - - const mirrorFiles = yield (_fs || _load_fs()).walk(mirror); - for (var _iterator14 = mirrorFiles, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) { - var _ref27; - - if (_isArray14) { - if (_i14 >= _iterator14.length) break; - _ref27 = _iterator14[_i14++]; - } else { - _i14 = _iterator14.next(); - if (_i14.done) break; - _ref27 = _i14.value; - } - - const file = _ref27; - - const isTarball = path.extname(file.basename) === '.tgz'; - // if using experimental-pack-script-packages-in-mirror flag, don't unlink prebuilt packages - const hasPrebuiltPackage = file.relative.startsWith('prebuilt/'); - if (isTarball && !hasPrebuiltPackage && !requiredTarballs.has(file.basename)) { - yield (_fs || _load_fs()).unlink(file.absolute); - } - } - })(); - } - - /** - * Save updated integrity and lockfiles. - */ - - saveLockfileAndIntegrity(patterns, workspaceLayout) { - var _this11 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - const resolvedPatterns = {}; - Object.keys(_this11.resolver.patterns).forEach(function (pattern) { - if (!workspaceLayout || !workspaceLayout.getManifestByPattern(pattern)) { - resolvedPatterns[pattern] = _this11.resolver.patterns[pattern]; - } - }); - - // TODO this code is duplicated in a few places, need a common way to filter out workspace patterns from lockfile - patterns = patterns.filter(function (p) { - return !workspaceLayout || !workspaceLayout.getManifestByPattern(p); - }); - - const lockfileBasedOnResolver = _this11.lockfile.getLockfile(resolvedPatterns); - - if (_this11.config.pruneOfflineMirror) { - yield _this11.pruneOfflineMirror(lockfileBasedOnResolver); - } - - // write integrity hash - if (!_this11.config.plugnplayEnabled) { - yield _this11.integrityChecker.save(patterns, lockfileBasedOnResolver, _this11.flags, workspaceLayout, _this11.scripts.getArtifacts()); - } - - // --no-lockfile or --pure-lockfile or --frozen-lockfile - if (_this11.flags.lockfile === false || _this11.flags.pureLockfile || _this11.flags.frozenLockfile) { - return; - } - - const lockFileHasAllPatterns = patterns.every(function (p) { - return _this11.lockfile.getLocked(p); - }); - const lockfilePatternsMatch = Object.keys(_this11.lockfile.cache || {}).every(function (p) { - return lockfileBasedOnResolver[p]; - }); - const resolverPatternsAreSameAsInLockfile = Object.keys(lockfileBasedOnResolver).every(function (pattern) { - const manifest = _this11.lockfile.getLocked(pattern); - return manifest && manifest.resolved === lockfileBasedOnResolver[pattern].resolved && deepEqual(manifest.prebuiltVariants, lockfileBasedOnResolver[pattern].prebuiltVariants); - }); - const integrityPatternsAreSameAsInLockfile = Object.keys(lockfileBasedOnResolver).every(function (pattern) { - const existingIntegrityInfo = lockfileBasedOnResolver[pattern].integrity; - if (!existingIntegrityInfo) { - // if this entry does not have an integrity, no need to re-write the lockfile because of it - return true; - } - const manifest = _this11.lockfile.getLocked(pattern); - if (manifest && manifest.integrity) { - const manifestIntegrity = ssri.stringify(manifest.integrity); - return manifestIntegrity === existingIntegrityInfo; - } - return false; - }); - - // remove command is followed by install with force, lockfile will be rewritten in any case then - if (!_this11.flags.force && _this11.lockfile.parseResultType === 'success' && lockFileHasAllPatterns && lockfilePatternsMatch && resolverPatternsAreSameAsInLockfile && integrityPatternsAreSameAsInLockfile && patterns.length) { - return; - } - - // build lockfile location - const loc = path.join(_this11.config.lockfileFolder, (_constants || _load_constants()).LOCKFILE_FILENAME); - - // write lockfile - const lockSource = (0, (_lockfile2 || _load_lockfile2()).stringify)(lockfileBasedOnResolver, false, _this11.config.enableLockfileVersions); - yield (_fs || _load_fs()).writeFilePreservingEol(loc, lockSource); - - _this11._logSuccessSaveLockfile(); - })(); - } - - _logSuccessSaveLockfile() { - this.reporter.success(this.reporter.lang('savedLockfile')); - } - - /** - * Load the dependency graph of the current install. Only does package resolving and wont write to the cwd. - */ - hydrate(ignoreUnusedPatterns) { - var _this12 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - const request = yield _this12.fetchRequestFromCwd([], ignoreUnusedPatterns); - const depRequests = request.requests, - rawPatterns = request.patterns, - ignorePatterns = request.ignorePatterns, - workspaceLayout = request.workspaceLayout; - - - yield _this12.resolver.init(depRequests, { - isFlat: _this12.flags.flat, - isFrozen: _this12.flags.frozenLockfile, - workspaceLayout - }); - yield _this12.flatten(rawPatterns); - _this12.markIgnored(ignorePatterns); - - // fetch packages, should hit cache most of the time - const manifests = yield (_packageFetcher || _load_packageFetcher()).fetch(_this12.resolver.getManifests(), _this12.config); - _this12.resolver.updateManifests(manifests); - yield (_packageCompatibility || _load_packageCompatibility()).check(_this12.resolver.getManifests(), _this12.config, _this12.flags.ignoreEngines); - - // expand minimal manifests - for (var _iterator15 = _this12.resolver.getManifests(), _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { - var _ref28; - - if (_isArray15) { - if (_i15 >= _iterator15.length) break; - _ref28 = _iterator15[_i15++]; - } else { - _i15 = _iterator15.next(); - if (_i15.done) break; - _ref28 = _i15.value; - } - - const manifest = _ref28; - - const ref = manifest._reference; - invariant(ref, 'expected reference'); - const type = ref.remote.type; - // link specifier won't ever hit cache - - let loc = ''; - if (type === 'link') { - continue; - } else if (type === 'workspace') { - if (!ref.remote.reference) { - continue; - } - loc = ref.remote.reference; - } else { - loc = _this12.config.generateModuleCachePath(ref); - } - const newPkg = yield _this12.config.readManifest(loc); - yield _this12.resolver.updateManifest(ref, newPkg); - } - - return request; - })(); - } - - /** - * Check for updates every day and output a nag message if there's a newer version. - */ - - checkUpdate() { - if (this.config.nonInteractive) { - // don't show upgrade dialog on CI or non-TTY terminals - return; - } - - // don't check if disabled - if (this.config.getOption('disable-self-update-check')) { - return; - } - - // only check for updates once a day - const lastUpdateCheck = Number(this.config.getOption('lastUpdateCheck')) || 0; - if (lastUpdateCheck && Date.now() - lastUpdateCheck < ONE_DAY) { - return; - } - - // don't bug for updates on tagged releases - if ((_yarnVersion || _load_yarnVersion()).version.indexOf('-') >= 0) { - return; - } - - this._checkUpdate().catch(() => { - // swallow errors - }); - } - - _checkUpdate() { - var _this13 = this; - - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - let latestVersion = yield _this13.config.requestManager.request({ - url: (_constants || _load_constants()).SELF_UPDATE_VERSION_URL - }); - invariant(typeof latestVersion === 'string', 'expected string'); - latestVersion = latestVersion.trim(); - if (!semver.valid(latestVersion)) { - return; - } - - // ensure we only check for updates periodically - _this13.config.registries.yarn.saveHomeConfig({ - lastUpdateCheck: Date.now() - }); - - if (semver.gt(latestVersion, (_yarnVersion || _load_yarnVersion()).version)) { - const installationMethod = yield (0, (_yarnVersion || _load_yarnVersion()).getInstallationMethod)(); - _this13.maybeOutputUpdate = function () { - _this13.reporter.warn(_this13.reporter.lang('yarnOutdated', latestVersion, (_yarnVersion || _load_yarnVersion()).version)); - - const command = getUpdateCommand(installationMethod); - if (command) { - _this13.reporter.info(_this13.reporter.lang('yarnOutdatedCommand')); - _this13.reporter.command(command); - } else { - const installer = getUpdateInstaller(installationMethod); - if (installer) { - _this13.reporter.info(_this13.reporter.lang('yarnOutdatedInstaller', installer)); - } - } - }; - } - })(); - } - - /** - * Method to override with a possible upgrade message. - */ - - maybeOutputUpdate() {} -} - -exports.Install = Install; -function hasWrapper(commander, args) { - return true; -} - -function setFlags(commander) { - commander.description('Yarn install is used to install all dependencies for a project.'); - commander.usage('install [flags]'); - commander.option('-A, --audit', 'Run vulnerability audit on installed packages'); - commander.option('-g, --global', 'DEPRECATED'); - commander.option('-S, --save', 'DEPRECATED - save package to your `dependencies`'); - commander.option('-D, --save-dev', 'DEPRECATED - save package to your `devDependencies`'); - commander.option('-P, --save-peer', 'DEPRECATED - save package to your `peerDependencies`'); - commander.option('-O, --save-optional', 'DEPRECATED - save package to your `optionalDependencies`'); - commander.option('-E, --save-exact', 'DEPRECATED'); - commander.option('-T, --save-tilde', 'DEPRECATED'); -} - -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(53); -module.exports = function (it) { - if (!isObject(it)) throw TypeError(it + ' is not an object!'); - return it; -}; - - -/***/ }), -/* 36 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return SubjectSubscriber; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Subject; }); -/* unused harmony export AnonymousSubject */ -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_tslib__ = __webpack_require__(1); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Observable__ = __webpack_require__(12); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Subscriber__ = __webpack_require__(7); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Subscription__ = __webpack_require__(25); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__ = __webpack_require__(190); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__SubjectSubscription__ = __webpack_require__(422); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__internal_symbol_rxSubscriber__ = __webpack_require__(322); -/** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ - - - - - - - -var SubjectSubscriber = /*@__PURE__*/ (function (_super) { - __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](SubjectSubscriber, _super); - function SubjectSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - return _this; - } - return SubjectSubscriber; -}(__WEBPACK_IMPORTED_MODULE_2__Subscriber__["a" /* Subscriber */])); - -var Subject = /*@__PURE__*/ (function (_super) { - __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](Subject, _super); - function Subject() { - var _this = _super.call(this) || this; - _this.observers = []; - _this.closed = false; - _this.isStopped = false; - _this.hasError = false; - _this.thrownError = null; - return _this; - } - Subject.prototype[__WEBPACK_IMPORTED_MODULE_6__internal_symbol_rxSubscriber__["a" /* rxSubscriber */]] = function () { - return new SubjectSubscriber(this); - }; - Subject.prototype.lift = function (operator) { - var subject = new AnonymousSubject(this, this); - subject.operator = operator; - return subject; - }; - Subject.prototype.next = function (value) { - if (this.closed) { - throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); - } - if (!this.isStopped) { - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].next(value); - } - } - }; - Subject.prototype.error = function (err) { - if (this.closed) { - throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); - } - this.hasError = true; - this.thrownError = err; - this.isStopped = true; - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].error(err); - } - this.observers.length = 0; - }; - Subject.prototype.complete = function () { - if (this.closed) { - throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); - } - this.isStopped = true; - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].complete(); - } - this.observers.length = 0; - }; - Subject.prototype.unsubscribe = function () { - this.isStopped = true; - this.closed = true; - this.observers = null; - }; - Subject.prototype._trySubscribe = function (subscriber) { - if (this.closed) { - throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); - } - else { - return _super.prototype._trySubscribe.call(this, subscriber); - } - }; - Subject.prototype._subscribe = function (subscriber) { - if (this.closed) { - throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); - } - else if (this.hasError) { - subscriber.error(this.thrownError); - return __WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */].EMPTY; - } - else if (this.isStopped) { - subscriber.complete(); - return __WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */].EMPTY; - } - else { - this.observers.push(subscriber); - return new __WEBPACK_IMPORTED_MODULE_5__SubjectSubscription__["a" /* SubjectSubscription */](this, subscriber); - } - }; - Subject.prototype.asObservable = function () { - var observable = new __WEBPACK_IMPORTED_MODULE_1__Observable__["a" /* Observable */](); - observable.source = this; - return observable; - }; - Subject.create = function (destination, source) { - return new AnonymousSubject(destination, source); - }; - return Subject; -}(__WEBPACK_IMPORTED_MODULE_1__Observable__["a" /* Observable */])); - -var AnonymousSubject = /*@__PURE__*/ (function (_super) { - __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](AnonymousSubject, _super); - function AnonymousSubject(destination, source) { - var _this = _super.call(this) || this; - _this.destination = destination; - _this.source = source; - return _this; - } - AnonymousSubject.prototype.next = function (value) { - var destination = this.destination; - if (destination && destination.next) { - destination.next(value); - } - }; - AnonymousSubject.prototype.error = function (err) { - var destination = this.destination; - if (destination && destination.error) { - this.destination.error(err); - } - }; - AnonymousSubject.prototype.complete = function () { - var destination = this.destination; - if (destination && destination.complete) { - this.destination.complete(); - } - }; - AnonymousSubject.prototype._subscribe = function (subscriber) { - var source = this.source; - if (source) { - return this.source.subscribe(subscriber); - } - else { - return __WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */].EMPTY; - } - }; - return AnonymousSubject; -}(Subject)); - -//# sourceMappingURL=Subject.js.map - - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.normalizePattern = normalizePattern; - -/** - * Explode and normalize a pattern into its name and range. - */ - -function normalizePattern(pattern) { - let hasVersion = false; - let range = 'latest'; - let name = pattern; - - // if we're a scope then remove the @ and add it back later - let isScoped = false; - if (name[0] === '@') { - isScoped = true; - name = name.slice(1); - } - - // take first part as the name - const parts = name.split('@'); - if (parts.length > 1) { - name = parts.shift(); - range = parts.join('@'); - - if (range) { - hasVersion = true; - } else { - range = '*'; - } - } - - // add back @ scope suffix - if (isScoped) { - name = `@${name}`; - } - - return { name, range, hasVersion }; -} - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_RESULT__;/** - * @license - * Lodash - * Copyright JS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as the semantic version number. */ - var VERSION = '4.17.10'; - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** Error message constants. */ - var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', - FUNC_ERROR_TEXT = 'Expected a function'; - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED = '__lodash_hash_undefined__'; - - /** Used as the maximum memoize cache size. */ - var MAX_MEMOIZE_SIZE = 500; - - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; - - /** Used to compose bitmasks for cloning. */ - var CLONE_DEEP_FLAG = 1, - CLONE_FLAT_FLAG = 2, - CLONE_SYMBOLS_FLAG = 4; - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - - /** Used to compose bitmasks for function metadata. */ - var WRAP_BIND_FLAG = 1, - WRAP_BIND_KEY_FLAG = 2, - WRAP_CURRY_BOUND_FLAG = 4, - WRAP_CURRY_FLAG = 8, - WRAP_CURRY_RIGHT_FLAG = 16, - WRAP_PARTIAL_FLAG = 32, - WRAP_PARTIAL_RIGHT_FLAG = 64, - WRAP_ARY_FLAG = 128, - WRAP_REARG_FLAG = 256, - WRAP_FLIP_FLAG = 512; - - /** Used as default options for `_.truncate`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; - - /** Used to detect hot functions by number of calls within a span of milliseconds. */ - var HOT_COUNT = 800, - HOT_SPAN = 16; - - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2, - LAZY_WHILE_FLAG = 3; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0, - MAX_SAFE_INTEGER = 9007199254740991, - MAX_INTEGER = 1.7976931348623157e+308, - NAN = 0 / 0; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - - /** Used to associate wrap methods with their bit flags. */ - var wrapFlags = [ - ['ary', WRAP_ARY_FLAG], - ['bind', WRAP_BIND_FLAG], - ['bindKey', WRAP_BIND_KEY_FLAG], - ['curry', WRAP_CURRY_FLAG], - ['curryRight', WRAP_CURRY_RIGHT_FLAG], - ['flip', WRAP_FLIP_FLAG], - ['partial', WRAP_PARTIAL_FLAG], - ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], - ['rearg', WRAP_REARG_FLAG] - ]; - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - asyncTag = '[object AsyncFunction]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - domExcTag = '[object DOMException]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - nullTag = '[object Null]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - proxyTag = '[object Proxy]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - undefinedTag = '[object Undefined]', - weakMapTag = '[object WeakMap]', - weakSetTag = '[object WeakSet]'; - - var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to match empty string literals in compiled template source. */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, - reUnescapedHtml = /[&<>"']/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - - /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, - reHasRegExpChar = RegExp(reRegExpChar.source); - - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g, - reTrimStart = /^\s+/, - reTrimEnd = /\s+$/; - - /** Used to match wrap detail comments. */ - var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, - reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, - reSplitDetails = /,? & /; - - /** Used to match words composed of alphanumeric characters. */ - var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; - - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; - - /** - * Used to match - * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; - - /** Used to detect bad signed hexadecimal string values. */ - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - - /** Used to detect binary string values. */ - var reIsBinary = /^0b[01]+$/i; - - /** Used to detect host constructors (Safari). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used to detect octal string values. */ - var reIsOctal = /^0o[0-7]+$/i; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** Used to match Latin Unicode letters (excluding mathematical operators). */ - var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; - - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; - - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsDingbatRange = '\\u2700-\\u27bf', - rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', - rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', - rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', - rsPunctuationRange = '\\u2000-\\u206f', - rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', - rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', - rsVarRange = '\\ufe0e\\ufe0f', - rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; - - /** Used to compose unicode capture groups. */ - var rsApos = "['\u2019]", - rsAstral = '[' + rsAstralRange + ']', - rsBreak = '[' + rsBreakRange + ']', - rsCombo = '[' + rsComboRange + ']', - rsDigits = '\\d+', - rsDingbat = '[' + rsDingbatRange + ']', - rsLower = '[' + rsLowerRange + ']', - rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsUpper = '[' + rsUpperRange + ']', - rsZWJ = '\\u200d'; - - /** Used to compose unicode regexes. */ - var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', - rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', - rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', - rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', - reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', - rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match apostrophes. */ - var reApos = RegExp(rsApos, 'g'); - - /** - * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and - * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). - */ - var reComboMark = RegExp(rsCombo, 'g'); - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** Used to match complex or compound words. */ - var reUnicodeWord = RegExp([ - rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', - rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', - rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, - rsUpper + '+' + rsOptContrUpper, - rsOrdUpper, - rsOrdLower, - rsDigits, - rsEmoji - ].join('|'), 'g'); - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); - - /** Used to detect strings that need a more robust regexp to match words. */ - var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', - 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' - ]; - - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = - cloneableTags[boolTag] = cloneableTags[dateTag] = - cloneableTags[float32Tag] = cloneableTags[float64Tag] = - cloneableTags[int8Tag] = cloneableTags[int16Tag] = - cloneableTags[int32Tag] = cloneableTags[mapTag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[setTag] = - cloneableTags[stringTag] = cloneableTags[symbolTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[weakMapTag] = false; - - /** Used to map Latin Unicode letters to basic Latin letters. */ - var deburredLetters = { - // Latin-1 Supplement block. - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss', - // Latin Extended-A block. - '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', - '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', - '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', - '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', - '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', - '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', - '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', - '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', - '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', - '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', - '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', - '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', - '\u0134': 'J', '\u0135': 'j', - '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', - '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', - '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', - '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', - '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', - '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', - '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', - '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', - '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', - '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', - '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', - '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', - '\u0163': 't', '\u0165': 't', '\u0167': 't', - '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', - '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', - '\u0174': 'W', '\u0175': 'w', - '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', - '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', - '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', - '\u0132': 'IJ', '\u0133': 'ij', - '\u0152': 'Oe', '\u0153': 'oe', - '\u0149': "'n", '\u017f': 's' - }; - - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'" - }; - - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Built-in method references without a dependency on `root`. */ - var freeParseFloat = parseFloat, - freeParseInt = parseInt; - - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); - - /** Detect free variable `exports`. */ - var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; - - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports && freeGlobal.process; - - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; - - if (types) { - return types; - } - - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} - }()); - - /* Node.js helper references. */ - var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, - nodeIsDate = nodeUtil && nodeUtil.isDate, - nodeIsMap = nodeUtil && nodeUtil.isMap, - nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, - nodeIsSet = nodeUtil && nodeUtil.isSet, - nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - - /*--------------------------------------------------------------------------*/ - - /** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ - function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); - } - - /** - * A specialized version of `baseAggregator` for arrays. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function arrayAggregator(array, setter, iteratee, accumulator) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - var value = array[index]; - setter(accumulator, value, iteratee(value), array); - } - return accumulator; - } - - /** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.forEachRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array == null ? 0 : array.length; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludes(array, value) { - var length = array == null ? 0 : array.length; - return !!length && baseIndexOf(array, value, 0) > -1; - } - - /** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } - } - return false; - } - - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } - - /** - * A specialized version of `_.reduce` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the first element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initAccum) { - var index = -1, - length = array == null ? 0 : array.length; - - if (initAccum && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.reduceRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the last element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initAccum) { - var length = array == null ? 0 : array.length; - if (initAccum && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * Gets the size of an ASCII `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ - var asciiSize = baseProperty('length'); - - /** - * Converts an ASCII `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function asciiToArray(string) { - return string.split(''); - } - - /** - * Splits an ASCII `string` into an array of its words. - * - * @private - * @param {string} The string to inspect. - * @returns {Array} Returns the words of `string`. - */ - function asciiWords(string) { - return string.match(reAsciiWord) || []; - } - - /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; - } - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - return value === value - ? strictIndexOf(array, value, fromIndex) - : baseFindIndex(array, baseIsNaN, fromIndex); - } - - /** - * This function is like `baseIndexOf` except that it accepts a comparator. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @param {Function} comparator The comparator invoked per element. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOfWith(array, value, fromIndex, comparator) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (comparator(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } - - /** - * The base implementation of `_.mean` and `_.meanBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the mean. - */ - function baseMean(array, iteratee) { - var length = array == null ? 0 : array.length; - return length ? (baseSum(array, iteratee) / length) : NAN; - } - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.propertyOf` without support for deep paths. - * - * @private - * @param {Object} object The object to query. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyOf(object) { - return function(key) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.reduce` and `_.reduceRight`, without support - * for iteratee shorthands, which iterates over `collection` using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initAccum Specify using the first or last element of - * `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ - function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initAccum - ? (initAccum = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.sortBy` which uses `comparer` to define the - * sort order of `array` and replaces criteria objects with their corresponding - * values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } - - /** - * The base implementation of `_.sum` and `_.sumBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ - function baseSum(array, iteratee) { - var result, - index = -1, - length = array.length; - - while (++index < length) { - var current = iteratee(array[index]); - if (current !== undefined) { - result = result === undefined ? current : (result + current); - } - } - return result; - } - - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; - } - - /** - * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array - * of key-value pairs for `object` corresponding to the property names of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the key-value pairs. - */ - function baseToPairs(object, props) { - return arrayMap(props, function(key) { - return [key, object[key]]; - }); - } - - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function(value) { - return func(value); - }; - } - - /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ - function baseValues(object, props) { - return arrayMap(props, function(key) { - return object[key]; - }); - } - - /** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function cacheHas(cache, key) { - return cache.has(key); - } - - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; - - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Gets the number of `placeholder` occurrences in `array`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} placeholder The placeholder to search for. - * @returns {number} Returns the placeholder count. - */ - function countHolders(array, placeholder) { - var length = array.length, - result = 0; - - while (length--) { - if (array[length] === placeholder) { - ++result; - } - } - return result; - } - - /** - * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A - * letters to basic Latin letters. - * - * @private - * @param {string} letter The matched letter to deburr. - * @returns {string} Returns the deburred letter. - */ - var deburrLetter = basePropertyOf(deburredLetters); - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - var escapeHtmlChar = basePropertyOf(htmlEscapes); - - /** - * Used by `_.template` to escape characters for inclusion in compiled string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; - } - - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function getValue(object, key) { - return object == null ? undefined : object[key]; - } - - /** - * Checks if `string` contains Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. - */ - function hasUnicode(string) { - return reHasUnicode.test(string); - } - - /** - * Checks if `string` contains a word composed of Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a word is found, else `false`. - */ - function hasUnicodeWord(string) { - return reHasUnicodeWord.test(string); - } - - /** - * Converts `iterator` to an array. - * - * @private - * @param {Object} iterator The iterator to convert. - * @returns {Array} Returns the converted array. - */ - function iteratorToArray(iterator) { - var data, - result = []; - - while (!(data = iterator.next()).done) { - result.push(data.value); - } - return result; - } - - /** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ - function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; - } - - /** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } - - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value === placeholder || value === PLACEHOLDER) { - array[index] = PLACEHOLDER; - result[resIndex++] = index; - } - } - return result; - } - - /** - * Gets the value at `key`, unless `key` is "__proto__". - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function safeGet(object, key) { - return key == '__proto__' - ? undefined - : object[key]; - } - - /** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ - function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; - } - - /** - * Converts `set` to its value-value pairs. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the value-value pairs. - */ - function setToPairs(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = [value, value]; - }); - return result; - } - - /** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * A specialized version of `_.lastIndexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictLastIndexOf(array, value, fromIndex) { - var index = fromIndex + 1; - while (index--) { - if (array[index] === value) { - return index; - } - } - return index; - } - - /** - * Gets the number of symbols in `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. - */ - function stringSize(string) { - return hasUnicode(string) - ? unicodeSize(string) - : asciiSize(string); - } - - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return hasUnicode(string) - ? unicodeToArray(string) - : asciiToArray(string); - } - - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - var unescapeHtmlChar = basePropertyOf(htmlUnescapes); - - /** - * Gets the size of a Unicode `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ - function unicodeSize(string) { - var result = reUnicode.lastIndex = 0; - while (reUnicode.test(string)) { - ++result; - } - return result; - } - - /** - * Converts a Unicode `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function unicodeToArray(string) { - return string.match(reUnicode) || []; - } - - /** - * Splits a Unicode `string` into an array of its words. - * - * @private - * @param {string} The string to inspect. - * @returns {Array} Returns the words of `string`. - */ - function unicodeWords(string) { - return string.match(reUnicodeWord) || []; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new pristine `lodash` function using the `context` object. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Util - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `lodash` function. - * @example - * - * _.mixin({ 'foo': _.constant('foo') }); - * - * var lodash = _.runInContext(); - * lodash.mixin({ 'bar': lodash.constant('bar') }); - * - * _.isFunction(_.foo); - * // => true - * _.isFunction(_.bar); - * // => false - * - * lodash.isFunction(lodash.foo); - * // => false - * lodash.isFunction(lodash.bar); - * // => true - * - * // Create a suped-up `defer` in Node.js. - * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; - */ - var runInContext = (function runInContext(context) { - context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); - - /** Built-in constructor references. */ - var Array = context.Array, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** Used for built-in method references. */ - var arrayProto = Array.prototype, - funcProto = Function.prototype, - objectProto = Object.prototype; - - /** Used to detect overreaching core-js shims. */ - var coreJsData = context['__core-js_shared__']; - - /** Used to resolve the decompiled source of functions. */ - var funcToString = funcProto.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to generate unique IDs. */ - var idCounter = 0; - - /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; - }()); - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString = objectProto.toString; - - /** Used to infer the `Object` constructor. */ - var objectCtorString = funcToString.call(Object); - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = root._; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Built-in value references. */ - var Buffer = moduleExports ? context.Buffer : undefined, - Symbol = context.Symbol, - Uint8Array = context.Uint8Array, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, - getPrototype = overArg(Object.getPrototypeOf, Object), - objectCreate = Object.create, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice, - spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, - symIterator = Symbol ? Symbol.iterator : undefined, - symToStringTag = Symbol ? Symbol.toStringTag : undefined; - - var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} - }()); - - /** Mocked built-ins. */ - var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, - ctxNow = Date && Date.now !== root.Date.now && Date.now, - ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil, - nativeFloor = Math.floor, - nativeGetSymbols = Object.getOwnPropertySymbols, - nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, - nativeIsFinite = context.isFinite, - nativeJoin = arrayProto.join, - nativeKeys = overArg(Object.keys, Object), - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = Date.now, - nativeParseInt = context.parseInt, - nativeRandom = Math.random, - nativeReverse = arrayProto.reverse; - - /* Built-in method references that are verified to be native. */ - var DataView = getNative(context, 'DataView'), - Map = getNative(context, 'Map'), - Promise = getNative(context, 'Promise'), - Set = getNative(context, 'Set'), - WeakMap = getNative(context, 'WeakMap'), - nativeCreate = getNative(Object, 'create'); - - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; - - /** Used to lookup unminified function names. */ - var realNames = {}; - - /** Used to detect maps, sets, and weakmaps. */ - var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps `value` to enable implicit method - * chain sequences. Methods that operate on and return arrays, collections, - * and functions can be chained together. Methods that retrieve a single value - * or may return a primitive value will automatically end the chain sequence - * and return the unwrapped value. Otherwise, the value must be unwrapped - * with `_#value`. - * - * Explicit chain sequences, which must be unwrapped with `_#value`, may be - * enabled using `_.chain`. - * - * The execution of chained methods is lazy, that is, it's deferred until - * `_#value` is implicitly or explicitly called. - * - * Lazy evaluation allows several methods to support shortcut fusion. - * Shortcut fusion is an optimization to merge iteratee calls; this avoids - * the creation of intermediate arrays and can greatly reduce the number of - * iteratee executions. Sections of a chain sequence qualify for shortcut - * fusion if the section is applied to an array and iteratees accept only - * one argument. The heuristic for whether a section qualifies for shortcut - * fusion is subject to change. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, - * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, - * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, - * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, - * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, - * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, - * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, - * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, - * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, - * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, - * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, - * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, - * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, - * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, - * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, - * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, - * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, - * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, - * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, - * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, - * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, - * `zipObject`, `zipObjectDeep`, and `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, - * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, - * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, - * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, - * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, - * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, - * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, - * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, - * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, - * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, - * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, - * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, - * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, - * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, - * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, - * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, - * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, - * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, - * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, - * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, - * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, - * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, - * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, - * `upperFirst`, `value`, and `words` - * - * @name _ - * @constructor - * @category Seq - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2, 3]); - * - * // Returns an unwrapped value. - * wrapped.reduce(_.add); - * // => 6 - * - * // Returns a wrapped value. - * var squares = wrapped.map(square); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ - var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; - }()); - - /** - * The function whose prototype chain sequence wrappers inherit from. - * - * @private - */ - function baseLodash() { - // No operation performed. - } - - /** - * The base constructor for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable explicit method chain sequences. - */ - function LodashWrapper(value, chainAll) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__chain__ = !!chainAll; - this.__index__ = 0; - this.__values__ = undefined; - } - - /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB) as well as ES2015 template strings. Change the - * following template settings to use alternative delimiters. - * - * @static - * @memberOf _ - * @type {Object} - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'escape': reEscape, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'evaluate': reEvaluate, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type {string} - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type {Object} - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type {Function} - */ - '_': lodash - } - }; - - // Ensure wrappers are instances of `baseLodash`. - lodash.prototype = baseLodash.prototype; - lodash.prototype.constructor = lodash; - - LodashWrapper.prototype = baseCreate(baseLodash.prototype); - LodashWrapper.prototype.constructor = LodashWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @constructor - * @param {*} value The value to wrap. - */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = MAX_ARRAY_LENGTH; - this.__views__ = []; - } - - /** - * Creates a clone of the lazy wrapper object. - * - * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. - */ - function lazyClone() { - var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = copyArray(this.__actions__); - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = copyArray(this.__iteratees__); - result.__takeCount__ = this.__takeCount__; - result.__views__ = copyArray(this.__views__); - return result; - } - - /** - * Reverses the direction of lazy iteration. - * - * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. - */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; - } - return result; - } - - /** - * Extracts the unwrapped value from its lazy wrapper. - * - * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. - */ - function lazyValue() { - var array = this.__wrapped__.value(), - dir = this.__dir__, - isArr = isArray(array), - isRight = dir < 0, - arrLength = isArr ? array.length : 0, - view = getView(0, arrLength, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - iteratees = this.__iteratees__, - iterLength = iteratees.length, - resIndex = 0, - takeCount = nativeMin(length, this.__takeCount__); - - if (!isArr || (!isRight && arrLength == length && takeCount == length)) { - return baseWrapperValue(array, this.__actions__); - } - var result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type, - computed = iteratee(value); - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - result[resIndex++] = value; - } - return result; - } - - // Ensure `LazyWrapper` is an instance of `baseLodash`. - LazyWrapper.prototype = baseCreate(baseLodash.prototype); - LazyWrapper.prototype.constructor = LazyWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; - } - - /** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; - } - - /** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; - } - - /** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); - } - - /** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ - function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; - } - - // Add methods to `Hash`. - Hash.prototype.clear = hashClear; - Hash.prototype['delete'] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ - function listCacheClear() { - this.__data__ = []; - this.size = 0; - } - - /** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; - } - - /** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; - } - - /** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; - } - - /** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ - function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; - } - - // Add methods to `ListCache`. - ListCache.prototype.clear = listCacheClear; - ListCache.prototype['delete'] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ - function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; - } - - /** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; - } - - /** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function mapCacheGet(key) { - return getMapData(this, key).get(key); - } - - /** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapCacheHas(key) { - return getMapData(this, key).has(key); - } - - /** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ - function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; - } - - // Add methods to `MapCache`. - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype['delete'] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } - } - - /** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; - } - - /** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ - function setCacheHas(value) { - return this.__data__.has(value); - } - - // Add methods to `SetCache`. - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; - } - - /** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ - function stackClear() { - this.__data__ = new ListCache; - this.size = 0; - } - - /** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); - - this.size = data.size; - return result; - } - - /** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function stackGet(key) { - return this.__data__.get(key); - } - - /** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function stackHas(key) { - return this.__data__.has(key); - } - - /** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ - function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; - } - - // Add methods to `Stack`. - Stack.prototype.clear = stackClear; - Stack.prototype['delete'] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ - function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; - } - - /** - * A specialized version of `_.sample` for arrays. - * - * @private - * @param {Array} array The array to sample. - * @returns {*} Returns the random element. - */ - function arraySample(array) { - var length = array.length; - return length ? array[baseRandom(0, length - 1)] : undefined; - } - - /** - * A specialized version of `_.sampleSize` for arrays. - * - * @private - * @param {Array} array The array to sample. - * @param {number} n The number of elements to sample. - * @returns {Array} Returns the random elements. - */ - function arraySampleSize(array, n) { - return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); - } - - /** - * A specialized version of `_.shuffle` for arrays. - * - * @private - * @param {Array} array The array to shuffle. - * @returns {Array} Returns the new shuffled array. - */ - function arrayShuffle(array) { - return shuffleSelf(copyArray(array)); - } - - /** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; - } - - /** - * Aggregates elements of `collection` on `accumulator` with keys transformed - * by `iteratee` and values set by `setter`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function baseAggregator(collection, setter, iteratee, accumulator) { - baseEach(collection, function(value, key, collection) { - setter(accumulator, value, iteratee(value), collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); - } - - /** - * The base implementation of `_.assignIn` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssignIn(object, source) { - return object && copyObject(source, keysIn(source), object); - } - - /** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } - } - - /** - * The base implementation of `_.at` without support for individual paths. - * - * @private - * @param {Object} object The object to iterate over. - * @param {string[]} paths The property paths to pick. - * @returns {Array} Returns the picked elements. - */ - function baseAt(object, paths) { - var index = -1, - length = paths.length, - result = Array(length), - skip = object == null; - - while (++index < length) { - result[index] = skip ? undefined : get(object, paths[index]); - } - return result; - } - - /** - * The base implementation of `_.clamp` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - */ - function baseClamp(number, lower, upper) { - if (number === number) { - if (upper !== undefined) { - number = number <= upper ? number : upper; - } - if (lower !== undefined) { - number = number >= lower ? number : lower; - } - } - return number; - } - - /** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} bitmask The bitmask flags. - * 1 - Deep clone - * 2 - Flatten inherited properties - * 4 - Clone symbols - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, bitmask, customizer, key, object, stack) { - var result, - isDeep = bitmask & CLONE_DEEP_FLAG, - isFlat = bitmask & CLONE_FLAT_FLAG, - isFull = bitmask & CLONE_SYMBOLS_FLAG; - - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return copyArray(value, result); - } - } else { - var tag = getTag(value), - isFunc = tag == funcTag || tag == genTag; - - if (isBuffer(value)) { - return cloneBuffer(value, isDeep); - } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = (isFlat || isFunc) ? {} : initCloneObject(value); - if (!isDeep) { - return isFlat - ? copySymbolsIn(value, baseAssignIn(result, value)) - : copySymbols(value, baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; - } - result = initCloneByTag(value, tag, isDeep); - } - } - // Check for circular references and return its corresponding clone. - stack || (stack = new Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; - } - stack.set(value, result); - - if (isSet(value)) { - value.forEach(function(subValue) { - result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); - }); - - return result; - } - - if (isMap(value)) { - value.forEach(function(subValue, key) { - result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); - - return result; - } - - var keysFunc = isFull - ? (isFlat ? getAllKeysIn : getAllKeys) - : (isFlat ? keysIn : keys); - - var props = isArr ? undefined : keysFunc(value); - arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; - } - // Recursively populate clone (susceptible to call stack limits). - assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); - return result; - } - - /** - * The base implementation of `_.conforms` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property predicates to conform to. - * @returns {Function} Returns the new spec function. - */ - function baseConforms(source) { - var props = keys(source); - return function(object) { - return baseConformsTo(object, source, props); - }; - } - - /** - * The base implementation of `_.conformsTo` which accepts `props` to check. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - */ - function baseConformsTo(object, source, props) { - var length = props.length; - if (object == null) { - return !length; - } - object = Object(object); - while (length--) { - var key = props[length], - predicate = source[key], - value = object[key]; - - if ((value === undefined && !(key in object)) || !predicate(value)) { - return false; - } - } - return true; - } - - /** - * The base implementation of `_.delay` and `_.defer` which accepts `args` - * to provide to `func`. - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Array} args The arguments to provide to `func`. - * @returns {number|Object} Returns the timer id or timeout object. - */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * The base implementation of methods like `_.difference` without support - * for excluding multiple arrays or iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - */ - function baseDifference(array, values, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - isCommon = true, - length = array.length, - result = [], - valuesLength = values.length; - - if (!length) { - return result; - } - if (iteratee) { - values = arrayMap(values, baseUnary(iteratee)); - } - if (comparator) { - includes = arrayIncludesWith; - isCommon = false; - } - else if (values.length >= LARGE_ARRAY_SIZE) { - includes = cacheHas; - isCommon = false; - values = new SetCache(values); - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee == null ? value : iteratee(value); - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === computed) { - continue outer; - } - } - result.push(value); - } - else if (!includes(values, computed, comparator)) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEach = createBaseEach(baseForOwn); - - /** - * The base implementation of `_.forEachRight` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEachRight = createBaseEach(baseForOwnRight, true); - - /** - * The base implementation of `_.every` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` - */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; - } - - /** - * The base implementation of methods like `_.max` and `_.min` which accepts a - * `comparator` to determine the extremum value. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The iteratee invoked per iteration. - * @param {Function} comparator The comparator used to compare values. - * @returns {*} Returns the extremum value. - */ - function baseExtremum(array, iteratee, comparator) { - var index = -1, - length = array.length; - - while (++index < length) { - var value = array[index], - current = iteratee(value); - - if (current != null && (computed === undefined - ? (current === current && !isSymbol(current)) - : comparator(current, computed) - )) { - var computed = current, - result = value; - } - } - return result; - } - - /** - * The base implementation of `_.fill` without an iteratee call guard. - * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - */ - function baseFill(array, value, start, end) { - var length = array.length; - - start = toInteger(start); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : toInteger(end); - if (end < 0) { - end += length; - } - end = start > end ? 0 : toLength(end); - while (start < end) { - array[start++] = value; - } - return array; - } - - /** - * The base implementation of `_.filter` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } - - /** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ - function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; - } - - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * This function is like `baseFor` except that it iterates over properties - * in the opposite order. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseForRight = createBaseFor(true); - - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); - } - - /** - * The base implementation of `_.forOwnRight` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwnRight(object, iteratee) { - return object && baseForRight(object, iteratee, keys); - } - - /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from `props`. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the function names. - */ - function baseFunctions(object, props) { - return arrayFilter(props, function(key) { - return isFunction(object[key]); - }); - } - - /** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; - } - - /** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ - function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); - } - - /** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); - } - - /** - * The base implementation of `_.gt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - */ - function baseGt(value, other) { - return value > other; - } - - /** - * The base implementation of `_.has` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHas(object, key) { - return object != null && hasOwnProperty.call(object, key); - } - - /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHasIn(object, key) { - return object != null && key in Object(object); - } - - /** - * The base implementation of `_.inRange` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to check. - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - */ - function baseInRange(number, start, end) { - return number >= nativeMin(start, end) && number < nativeMax(start, end); - } - - /** - * The base implementation of methods like `_.intersection`, without support - * for iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of shared values. - */ - function baseIntersection(arrays, iteratee, comparator) { - var includes = comparator ? arrayIncludesWith : arrayIncludes, - length = arrays[0].length, - othLength = arrays.length, - othIndex = othLength, - caches = Array(othLength), - maxLength = Infinity, - result = []; - - while (othIndex--) { - var array = arrays[othIndex]; - if (othIndex && iteratee) { - array = arrayMap(array, baseUnary(iteratee)); - } - maxLength = nativeMin(array.length, maxLength); - caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) - ? new SetCache(othIndex && array) - : undefined; - } - array = arrays[0]; - - var index = -1, - seen = caches[0]; - - outer: - while (++index < length && result.length < maxLength) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (!(seen - ? cacheHas(seen, computed) - : includes(result, computed, comparator) - )) { - othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if (!(cache - ? cacheHas(cache, computed) - : includes(arrays[othIndex], computed, comparator)) - ) { - continue outer; - } - } - if (seen) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.invert` and `_.invertBy` which inverts - * `object` with values transformed by `iteratee` and set by `setter`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform values. - * @param {Object} accumulator The initial inverted object. - * @returns {Function} Returns `accumulator`. - */ - function baseInverter(object, setter, iteratee, accumulator) { - baseForOwn(object, function(value, key, object) { - setter(accumulator, iteratee(value), key, object); - }); - return accumulator; - } - - /** - * The base implementation of `_.invoke` without support for individual - * method arguments. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - */ - function baseInvoke(object, path, args) { - path = castPath(path, object); - object = parent(object, path); - var func = object == null ? object : object[toKey(last(path))]; - return func == null ? undefined : apply(func, object, args); - } - - /** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ - function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; - } - - /** - * The base implementation of `_.isArrayBuffer` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - */ - function baseIsArrayBuffer(value) { - return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; - } - - /** - * The base implementation of `_.isDate` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - */ - function baseIsDate(value) { - return isObjectLike(value) && baseGetTag(value) == dateTag; - } - - /** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); - } - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag : getTag(object), - othTag = othIsArr ? arrayTag : getTag(other); - - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; - - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); - } - - /** - * The base implementation of `_.isMap` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - */ - function baseIsMap(value) { - return isObjectLike(value) && getTag(value) == mapTag; - } - - /** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) - : result - )) { - return false; - } - } - } - return true; - } - - /** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ - function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); - } - - /** - * The base implementation of `_.isRegExp` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - */ - function baseIsRegExp(value) { - return isObjectLike(value) && baseGetTag(value) == regexpTag; - } - - /** - * The base implementation of `_.isSet` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - */ - function baseIsSet(value) { - return isObjectLike(value) && getTag(value) == setTag; - } - - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; - } - - /** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ - function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); - } - - /** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; - } - - /** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; - - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * The base implementation of `_.lt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - */ - function baseLt(value, other) { - return value < other; - } - - /** - * The base implementation of `_.map` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; - } - - /** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; - } - - /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); - }; - } - - /** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - baseFor(source, function(srcValue, key) { - if (isObject(srcValue)) { - stack || (stack = new Stack); - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }, keysIn); - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = safeGet(object, key), - srcValue = safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); - - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { - newValue = initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); - } - - /** - * The base implementation of `_.nth` which doesn't coerce arguments. - * - * @private - * @param {Array} array The array to query. - * @param {number} n The index of the element to return. - * @returns {*} Returns the nth element of `array`. - */ - function baseNth(array, n) { - var length = array.length; - if (!length) { - return; - } - n += n < 0 ? length : 0; - return isIndex(n, length) ? array[n] : undefined; - } - - /** - * The base implementation of `_.orderBy` without param guards. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {string[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ - function baseOrderBy(collection, iteratees, orders) { - var index = -1; - iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee())); - - var result = baseMap(collection, function(value, key, collection) { - var criteria = arrayMap(iteratees, function(iteratee) { - return iteratee(value); - }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); - - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); - } - - /** - * The base implementation of `_.pick` without support for individual - * property identifiers. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @returns {Object} Returns the new object. - */ - function basePick(object, paths) { - return basePickBy(object, paths, function(value, path) { - return hasIn(object, path); - }); - } - - /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @param {Function} predicate The function invoked per property. - * @returns {Object} Returns the new object. - */ - function basePickBy(object, paths, predicate) { - var index = -1, - length = paths.length, - result = {}; - - while (++index < length) { - var path = paths[index], - value = baseGet(object, path); - - if (predicate(value, path)) { - baseSet(result, castPath(path, object), value); - } - } - return result; - } - - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; - } - - /** - * The base implementation of `_.pullAllBy` without support for iteratee - * shorthands. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - */ - function basePullAll(array, values, iteratee, comparator) { - var indexOf = comparator ? baseIndexOfWith : baseIndexOf, - index = -1, - length = values.length, - seen = array; - - if (array === values) { - values = copyArray(values); - } - if (iteratee) { - seen = arrayMap(array, baseUnary(iteratee)); - } - while (++index < length) { - var fromIndex = 0, - value = values[index], - computed = iteratee ? iteratee(value) : value; - - while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { - if (seen !== array) { - splice.call(seen, fromIndex, 1); - } - splice.call(array, fromIndex, 1); - } - } - return array; - } - - /** - * The base implementation of `_.pullAt` without support for individual - * indexes or capturing the removed elements. - * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns `array`. - */ - function basePullAt(array, indexes) { - var length = array ? indexes.length : 0, - lastIndex = length - 1; - - while (length--) { - var index = indexes[length]; - if (length == lastIndex || index !== previous) { - var previous = index; - if (isIndex(index)) { - splice.call(array, index, 1); - } else { - baseUnset(array, index); - } - } - } - return array; - } - - /** - * The base implementation of `_.random` without support for returning - * floating-point numbers. - * - * @private - * @param {number} lower The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the random number. - */ - function baseRandom(lower, upper) { - return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); - } - - /** - * The base implementation of `_.range` and `_.rangeRight` which doesn't - * coerce arguments. - * - * @private - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @param {number} step The value to increment or decrement by. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the range of numbers. - */ - function baseRange(start, end, step, fromRight) { - var index = -1, - length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); - - while (length--) { - result[fromRight ? length : ++index] = start; - start += step; - } - return result; - } - - /** - * The base implementation of `_.repeat` which doesn't coerce arguments. - * - * @private - * @param {string} string The string to repeat. - * @param {number} n The number of times to repeat the string. - * @returns {string} Returns the repeated string. - */ - function baseRepeat(string, n) { - var result = ''; - if (!string || n < 1 || n > MAX_SAFE_INTEGER) { - return result; - } - // Leverage the exponentiation by squaring algorithm for a faster repeat. - // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - do { - if (n % 2) { - result += string; - } - n = nativeFloor(n / 2); - if (n) { - string += string; - } - } while (n); - - return result; - } - - /** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ - function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); - } - - /** - * The base implementation of `_.sample`. - * - * @private - * @param {Array|Object} collection The collection to sample. - * @returns {*} Returns the random element. - */ - function baseSample(collection) { - return arraySample(values(collection)); - } - - /** - * The base implementation of `_.sampleSize` without param guards. - * - * @private - * @param {Array|Object} collection The collection to sample. - * @param {number} n The number of elements to sample. - * @returns {Array} Returns the random elements. - */ - function baseSampleSize(collection, n) { - var array = values(collection); - return shuffleSelf(array, baseClamp(n, 0, array.length)); - } - - /** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } - path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; - } - - /** - * The base implementation of `setData` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; - - /** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); - }; - - /** - * The base implementation of `_.shuffle`. - * - * @private - * @param {Array|Object} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - */ - function baseShuffle(collection) { - return shuffleSelf(values(collection)); - } - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * The base implementation of `_.some` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function baseSome(collection, predicate) { - var result; - - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } - - /** - * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which - * performs a binary search of `array` to determine the index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndex(array, value, retHighest) { - var low = 0, - high = array == null ? low : array.length; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; - - if (computed !== null && !isSymbol(computed) && - (retHighest ? (computed <= value) : (computed < value))) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return baseSortedIndexBy(array, value, identity, retHighest); - } - - /** - * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` - * which invokes `iteratee` for `value` and each element of `array` to compute - * their sort ranking. The iteratee is invoked with one argument; (value). - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The iteratee invoked per element. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); - - var low = 0, - high = array == null ? 0 : array.length, - valIsNaN = value !== value, - valIsNull = value === null, - valIsSymbol = isSymbol(value), - valIsUndefined = value === undefined; - - while (low < high) { - var mid = nativeFloor((low + high) / 2), - computed = iteratee(array[mid]), - othIsDefined = computed !== undefined, - othIsNull = computed === null, - othIsReflexive = computed === computed, - othIsSymbol = isSymbol(computed); - - if (valIsNaN) { - var setLow = retHighest || othIsReflexive; - } else if (valIsUndefined) { - setLow = othIsReflexive && (retHighest || othIsDefined); - } else if (valIsNull) { - setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); - } else if (valIsSymbol) { - setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); - } else if (othIsNull || othIsSymbol) { - setLow = false; - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } - - /** - * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseSortedUniq(array, iteratee) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - if (!index || !eq(computed, seen)) { - var seen = computed; - result[resIndex++] = value === 0 ? 0 : value; - } - } - return result; - } - - /** - * The base implementation of `_.toNumber` which doesn't ensure correct - * conversions of binary, hexadecimal, or octal string values. - * - * @private - * @param {*} value The value to process. - * @returns {number} Returns the number. - */ - function baseToNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - return +value; - } - - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; - - if (comparator) { - isCommon = false; - includes = arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : createSet(array); - if (set) { - return setToArray(set); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.unset`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The property path to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - */ - function baseUnset(object, path) { - path = castPath(path, object); - object = parent(object, path); - return object == null || delete object[toKey(last(path))]; - } - - /** - * The base implementation of `_.update`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to update. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseUpdate(object, path, updater, customizer) { - return baseSet(object, path, updater(baseGet(object, path)), customizer); - } - - /** - * The base implementation of methods like `_.dropWhile` and `_.takeWhile` - * without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to query. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [isDrop] Specify dropping elements instead of taking them. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the slice of `array`. - */ - function baseWhile(array, predicate, isDrop, fromRight) { - var length = array.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length) && - predicate(array[index], index, array)) {} - - return isDrop - ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) - : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); - } - - /** - * The base implementation of `wrapperValue` which returns the result of - * performing a sequence of actions on the unwrapped `value`, where each - * successive action is supplied the return value of the previous. - * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to perform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. - */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - return arrayReduce(actions, function(result, action) { - return action.func.apply(action.thisArg, arrayPush([result], action.args)); - }, result); - } - - /** - * The base implementation of methods like `_.xor`, without support for - * iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of values. - */ - function baseXor(arrays, iteratee, comparator) { - var length = arrays.length; - if (length < 2) { - return length ? baseUniq(arrays[0]) : []; - } - var index = -1, - result = Array(length); - - while (++index < length) { - var array = arrays[index], - othIndex = -1; - - while (++othIndex < length) { - if (othIndex != index) { - result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); - } - } - } - return baseUniq(baseFlatten(result, 1), iteratee, comparator); - } - - /** - * This base implementation of `_.zipObject` which assigns values using `assignFunc`. - * - * @private - * @param {Array} props The property identifiers. - * @param {Array} values The property values. - * @param {Function} assignFunc The function to assign values. - * @returns {Object} Returns the new object. - */ - function baseZipObject(props, values, assignFunc) { - var index = -1, - length = props.length, - valsLength = values.length, - result = {}; - - while (++index < length) { - var value = index < valsLength ? values[index] : undefined; - assignFunc(result, props[index], value); - } - return result; - } - - /** - * Casts `value` to an empty array if it's not an array like object. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array|Object} Returns the cast array-like object. - */ - function castArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; - } - - /** - * Casts `value` to `identity` if it's not a function. - * - * @private - * @param {*} value The value to inspect. - * @returns {Function} Returns cast function. - */ - function castFunction(value) { - return typeof value == 'function' ? value : identity; - } - - /** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ - function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); - } - - /** - * A `baseRest` alias which can be replaced with `identity` by module - * replacement plugins. - * - * @private - * @type {Function} - * @param {Function} func The function to apply a rest parameter to. - * @returns {Function} Returns the new function. - */ - var castRest = baseRest; - - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } - - /** - * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). - * - * @private - * @param {number|Object} id The timer id or timeout object of the timer to clear. - */ - var clearTimeout = ctxClearTimeout || function(id) { - return root.clearTimeout(id); - }; - - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; - } - - /** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; - } - - /** - * Creates a clone of `dataView`. - * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. - */ - function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); - } - - /** - * Creates a clone of `regexp`. - * - * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. - */ - function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; - } - - /** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ - function cloneSymbol(symbol) { - return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; - } - - /** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ - function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); - } - - /** - * Compares values to sort them in ascending order. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ - function compareAscending(value, other) { - if (value !== other) { - var valIsDefined = value !== undefined, - valIsNull = value === null, - valIsReflexive = value === value, - valIsSymbol = isSymbol(value); - - var othIsDefined = other !== undefined, - othIsNull = other === null, - othIsReflexive = other === other, - othIsSymbol = isSymbol(other); - - if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || - (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || - (valIsNull && othIsDefined && othIsReflexive) || - (!valIsDefined && othIsReflexive) || - !valIsReflexive) { - return 1; - } - if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || - (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || - (othIsNull && valIsDefined && valIsReflexive) || - (!othIsDefined && valIsReflexive) || - !othIsReflexive) { - return -1; - } - } - return 0; - } - - /** - * Used by `_.orderBy` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, - * specify an order of "desc" for descending or "asc" for ascending sort order - * of corresponding values. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]|string[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; - - while (++index < length) { - var result = compareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; - } - var order = orders[index]; - return result * (order == 'desc' ? -1 : 1); - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - - /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgs(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersLength = holders.length, - leftIndex = -1, - leftLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(leftLength + rangeLength), - isUncurried = !isCurried; - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - } - while (rangeLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } - - /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersIndex = -1, - holdersLength = holders.length, - rightIndex = -1, - rightLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(rangeLength + rightLength), - isUncurried = !isCurried; - - while (++argsIndex < rangeLength) { - result[argsIndex] = args[argsIndex]; - } - var offset = argsIndex; - while (++rightIndex < rightLength) { - result[offset + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; - } - } - return result; - } - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ - function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; - } - - /** - * Copies own symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); - } - - /** - * Copies own and inherited symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbolsIn(source, object) { - return copyObject(source, getSymbolsIn(source), object); - } - - /** - * Creates a function like `_.groupBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} [initializer] The accumulator object initializer. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter, initializer) { - return function(collection, iteratee) { - var func = isArray(collection) ? arrayAggregator : baseAggregator, - accumulator = initializer ? initializer() : {}; - - return func(collection, setter, getIteratee(iteratee, 2), accumulator); - }; - } - - /** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); - } - - /** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - if (collection == null) { - return collection; - } - if (!isArrayLike(collection)) { - return eachFunc(collection, iteratee); - } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); - - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; - } - - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } - - /** - * Creates a function that wraps `func` to invoke it with the optional `this` - * binding of `thisArg`. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createBind(func, bitmask, thisArg) { - var isBind = bitmask & WRAP_BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, arguments); - } - return wrapper; - } - - /** - * Creates a function like `_.lowerFirst`. - * - * @private - * @param {string} methodName The name of the `String` case method to use. - * @returns {Function} Returns the new case function. - */ - function createCaseFirst(methodName) { - return function(string) { - string = toString(string); - - var strSymbols = hasUnicode(string) - ? stringToArray(string) - : undefined; - - var chr = strSymbols - ? strSymbols[0] - : string.charAt(0); - - var trailing = strSymbols - ? castSlice(strSymbols, 1).join('') - : string.slice(1); - - return chr[methodName]() + trailing; - }; - } - - /** - * Creates a function like `_.camelCase`. - * - * @private - * @param {Function} callback The function to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); - }; - } - - /** - * Creates a function that produces an instance of `Ctor` regardless of - * whether it was invoked as part of a `new` expression or by `call` or `apply`. - * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. - */ - function createCtor(Ctor) { - return function() { - // Use a `switch` statement to work with class constructors. See - // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist - // for more details. - var args = arguments; - switch (args.length) { - case 0: return new Ctor; - case 1: return new Ctor(args[0]); - case 2: return new Ctor(args[0], args[1]); - case 3: return new Ctor(args[0], args[1], args[2]); - case 4: return new Ctor(args[0], args[1], args[2], args[3]); - case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); - case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - } - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, args); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; - } - - /** - * Creates a function that wraps `func` to enable currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {number} arity The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createCurry(func, bitmask, arity) { - var Ctor = createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length, - placeholder = getHolder(wrapper); - - while (index--) { - args[index] = arguments[index]; - } - var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) - ? [] - : replaceHolders(args, placeholder); - - length -= holders.length; - if (length < arity) { - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, undefined, - args, holders, undefined, undefined, arity - length); - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return apply(fn, this, args); - } - return wrapper; - } - - /** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} findIndexFunc The function to find the collection index. - * @returns {Function} Returns the new find function. - */ - function createFind(findIndexFunc) { - return function(collection, predicate, fromIndex) { - var iterable = Object(collection); - if (!isArrayLike(collection)) { - var iteratee = getIteratee(predicate, 3); - collection = keys(collection); - predicate = function(key) { return iteratee(iterable[key], key, iterable); }; - } - var index = findIndexFunc(collection, predicate, fromIndex); - return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; - }; - } - - /** - * Creates a `_.flow` or `_.flowRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. - */ - function createFlow(fromRight) { - return flatRest(function(funcs) { - var length = funcs.length, - index = length, - prereq = LodashWrapper.prototype.thru; - - if (fromRight) { - funcs.reverse(); - } - while (index--) { - var func = funcs[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (prereq && !wrapper && getFuncName(func) == 'wrapper') { - var wrapper = new LodashWrapper([], true); - } - } - index = wrapper ? index : length; - while (++index < length) { - func = funcs[index]; - - var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : undefined; - - if (data && isLaziable(data[0]) && - data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && - !data[4].length && data[9] == 1 - ) { - wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); - } else { - wrapper = (func.length == 1 && isLaziable(func)) - ? wrapper[funcName]() - : wrapper.thru(func); - } - } - return function() { - var args = arguments, - value = args[0]; - - if (wrapper && args.length == 1 && isArray(value)) { - return wrapper.plant(value).value(); - } - var index = 0, - result = length ? funcs[index].apply(this, args) : value; - - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - }); - } - - /** - * Creates a function that wraps `func` to invoke it with optional `this` - * binding of `thisArg`, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [partialsRight] The arguments to append to those provided - * to the new function. - * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & WRAP_ARY_FLAG, - isBind = bitmask & WRAP_BIND_FLAG, - isBindKey = bitmask & WRAP_BIND_KEY_FLAG, - isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), - isFlip = bitmask & WRAP_FLIP_FLAG, - Ctor = isBindKey ? undefined : createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length; - - while (index--) { - args[index] = arguments[index]; - } - if (isCurried) { - var placeholder = getHolder(wrapper), - holdersCount = countHolders(args, placeholder); - } - if (partials) { - args = composeArgs(args, partials, holders, isCurried); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight, isCurried); - } - length -= holdersCount; - if (isCurried && length < arity) { - var newHolders = replaceHolders(args, placeholder); - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, thisArg, - args, newHolders, argPos, ary, arity - length - ); - } - var thisBinding = isBind ? thisArg : this, - fn = isBindKey ? thisBinding[func] : func; - - length = args.length; - if (argPos) { - args = reorder(args, argPos); - } else if (isFlip && length > 1) { - args.reverse(); - } - if (isAry && ary < length) { - args.length = ary; - } - if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtor(fn); - } - return fn.apply(thisBinding, args); - } - return wrapper; - } - - /** - * Creates a function like `_.invertBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} toIteratee The function to resolve iteratees. - * @returns {Function} Returns the new inverter function. - */ - function createInverter(setter, toIteratee) { - return function(object, iteratee) { - return baseInverter(object, setter, toIteratee(iteratee), {}); - }; - } - - /** - * Creates a function that performs a mathematical operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @param {number} [defaultValue] The value used for `undefined` arguments. - * @returns {Function} Returns the new mathematical operation function. - */ - function createMathOperation(operator, defaultValue) { - return function(value, other) { - var result; - if (value === undefined && other === undefined) { - return defaultValue; - } - if (value !== undefined) { - result = value; - } - if (other !== undefined) { - if (result === undefined) { - return other; - } - if (typeof value == 'string' || typeof other == 'string') { - value = baseToString(value); - other = baseToString(other); - } else { - value = baseToNumber(value); - other = baseToNumber(other); - } - result = operator(value, other); - } - return result; - }; - } - - /** - * Creates a function like `_.over`. - * - * @private - * @param {Function} arrayFunc The function to iterate over iteratees. - * @returns {Function} Returns the new over function. - */ - function createOver(arrayFunc) { - return flatRest(function(iteratees) { - iteratees = arrayMap(iteratees, baseUnary(getIteratee())); - return baseRest(function(args) { - var thisArg = this; - return arrayFunc(iteratees, function(iteratee) { - return apply(iteratee, thisArg, args); - }); - }); - }); - } - - /** - * Creates the padding for `string` based on `length`. The `chars` string - * is truncated if the number of characters exceeds `length`. - * - * @private - * @param {number} length The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padding for `string`. - */ - function createPadding(length, chars) { - chars = chars === undefined ? ' ' : baseToString(chars); - - var charsLength = chars.length; - if (charsLength < 2) { - return charsLength ? baseRepeat(chars, length) : chars; - } - var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); - return hasUnicode(chars) - ? castSlice(stringToArray(result), 0, length).join('') - : result.slice(0, length); - } - - /** - * Creates a function that wraps `func` to invoke it with the `this` binding - * of `thisArg` and `partials` prepended to the arguments it receives. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} partials The arguments to prepend to those provided to - * the new function. - * @returns {Function} Returns the new wrapped function. - */ - function createPartial(func, bitmask, thisArg, partials) { - var isBind = bitmask & WRAP_BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(leftLength + argsLength), - fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - return apply(fn, isBind ? thisArg : this, args); - } - return wrapper; - } - - /** - * Creates a `_.range` or `_.rangeRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new range function. - */ - function createRange(fromRight) { - return function(start, end, step) { - if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { - end = step = undefined; - } - // Ensure the sign of `-0` is preserved. - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); - return baseRange(start, end, step, fromRight); - }; - } - - /** - * Creates a function that performs a relational operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @returns {Function} Returns the new relational operation function. - */ - function createRelationalOperation(operator) { - return function(value, other) { - if (!(typeof value == 'string' && typeof other == 'string')) { - value = toNumber(value); - other = toNumber(other); - } - return operator(value, other); - }; - } - - /** - * Creates a function that wraps `func` to continue currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {Function} wrapFunc The function to create the `func` wrapper. - * @param {*} placeholder The placeholder value. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { - var isCurry = bitmask & WRAP_CURRY_FLAG, - newHolders = isCurry ? holders : undefined, - newHoldersRight = isCurry ? undefined : holders, - newPartials = isCurry ? partials : undefined, - newPartialsRight = isCurry ? undefined : partials; - - bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); - - if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { - bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); - } - var newData = [ - func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, - newHoldersRight, argPos, ary, arity - ]; - - var result = wrapFunc.apply(undefined, newData); - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return setWrapToString(result, func, bitmask); - } - - /** - * Creates a function like `_.round`. - * - * @private - * @param {string} methodName The name of the `Math` method to use when rounding. - * @returns {Function} Returns the new round function. - */ - function createRound(methodName) { - var func = Math[methodName]; - return function(number, precision) { - number = toNumber(number); - precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); - if (precision) { - // Shift with exponential notation to avoid floating-point issues. - // See [MDN](https://mdn.io/round#Examples) for more details. - var pair = (toString(number) + 'e').split('e'), - value = func(pair[0] + 'e' + (+pair[1] + precision)); - - pair = (toString(value) + 'e').split('e'); - return +(pair[0] + 'e' + (+pair[1] - precision)); - } - return func(number); - }; - } - - /** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ - var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { - return new Set(values); - }; - - /** - * Creates a `_.toPairs` or `_.toPairsIn` function. - * - * @private - * @param {Function} keysFunc The function to get the keys of a given object. - * @returns {Function} Returns the new pairs function. - */ - function createToPairs(keysFunc) { - return function(object) { - var tag = getTag(object); - if (tag == mapTag) { - return mapToArray(object); - } - if (tag == setTag) { - return setToPairs(object); - } - return baseToPairs(object, keysFunc(object)); - }; - } - - /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * 512 - `_.flip` - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to be partially applied. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); - partials = holders = undefined; - } - ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); - arity = arity === undefined ? arity : toInteger(arity); - length -= holders ? holders.length : 0; - - if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = undefined; - } - var data = isBindKey ? undefined : getData(func); - - var newData = [ - func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, - argPos, ary, arity - ]; - - if (data) { - mergeData(newData, data); - } - func = newData[0]; - bitmask = newData[1]; - thisArg = newData[2]; - partials = newData[3]; - holders = newData[4]; - arity = newData[9] = newData[9] === undefined - ? (isBindKey ? 0 : func.length) - : nativeMax(newData[9] - length, 0); - - if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { - bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); - } - if (!bitmask || bitmask == WRAP_BIND_FLAG) { - var result = createBind(func, bitmask, thisArg); - } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { - result = createCurry(func, bitmask, arity); - } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { - result = createPartial(func, bitmask, thisArg, partials); - } else { - result = createHybrid.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setWrapToString(setter(result, newData), func, bitmask); - } - - /** - * Used by `_.defaults` to customize its `_.assignIn` use to assign properties - * of source objects to the destination object for all destination properties - * that resolve to `undefined`. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to assign. - * @param {Object} object The parent object of `objValue`. - * @returns {*} Returns the value to assign. - */ - function customDefaultsAssignIn(objValue, srcValue, key, object) { - if (objValue === undefined || - (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { - return srcValue; - } - return objValue; - } - - /** - * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source - * objects into destination objects that are passed thru. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to merge. - * @param {Object} object The parent object of `objValue`. - * @param {Object} source The parent object of `srcValue`. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - * @returns {*} Returns the value to assign. - */ - function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { - if (isObject(objValue) && isObject(srcValue)) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); - stack['delete'](srcValue); - } - return objValue; - } - - /** - * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain - * objects. - * - * @private - * @param {*} value The value to inspect. - * @param {string} key The key of the property to inspect. - * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. - */ - function customOmitClone(value) { - return isPlainObject(value) ? undefined : value; - } - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; - } - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag: - var convert = mapToArray; - - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; - - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; - } - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; - } - - /** - * A specialized version of `baseRest` which flattens the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @returns {Function} Returns the new function. - */ - function flatRest(func) { - return setToString(overRest(func, undefined, flatten), func + ''); - } - - /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); - } - - /** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); - } - - /** - * Gets metadata for `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. - */ - var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); - }; - - /** - * Gets the name of `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. - */ - function getFuncName(func) { - var result = (func.name + ''), - array = realNames[result], - length = hasOwnProperty.call(realNames, result) ? array.length : 0; - - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; - } - - /** - * Gets the argument placeholder value for `func`. - * - * @private - * @param {Function} func The function to inspect. - * @returns {*} Returns the placeholder value. - */ - function getHolder(func) { - var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; - return object.placeholder; - } - - /** - * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, - * this function returns the custom method, otherwise it returns `baseIteratee`. - * If arguments are provided, the chosen function is invoked with them and - * its result is returned. - * - * @private - * @param {*} [value] The value to convert to an iteratee. - * @param {number} [arity] The arity of the created iteratee. - * @returns {Function} Returns the chosen function or its result. - */ - function getIteratee() { - var result = lodash.iteratee || iteratee; - result = result === iteratee ? baseIteratee : result; - return arguments.length ? result(arguments[0], arguments[1]) : result; - } - - /** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ - function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; - } - - /** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; - } - - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; - } - - /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ - function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; - } - - /** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); - }); - }; - - /** - * Creates an array of the own and inherited enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; - }; - - /** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - var getTag = baseGetTag; - - // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. - if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; - } - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. - * - * @private - * @param {number} start The start of the view. - * @param {number} end The end of the view. - * @param {Array} transforms The transformations to apply to the view. - * @returns {Object} Returns an object containing the `start` and `end` - * positions of the view. - */ - function getView(start, end, transforms) { - var index = -1, - length = transforms.length; - - while (++index < length) { - var data = transforms[index], - size = data.size; - - switch (data.type) { - case 'drop': start += size; break; - case 'dropRight': end -= size; break; - case 'take': end = nativeMin(end, start + size); break; - case 'takeRight': start = nativeMax(start, end - size); break; - } - } - return { 'start': start, 'end': end }; - } - - /** - * Extracts wrapper details from the `source` body comment. - * - * @private - * @param {string} source The source to inspect. - * @returns {Array} Returns the wrapper details. - */ - function getWrapDetails(source) { - var match = source.match(reWrapDetails); - return match ? match[1].split(reSplitDetails) : []; - } - - /** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ - function hasPath(object, path, hasFunc) { - path = castPath(path, object); - - var index = -1, - length = path.length, - result = false; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); - } - - /** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ - function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); - - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; - } - - /** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneByTag(object, tag, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return cloneArrayBuffer(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case dataViewTag: - return cloneDataView(object, isDeep); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - return cloneTypedArray(object, isDeep); - - case mapTag: - return new Ctor; - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - return cloneRegExp(object); - - case setTag: - return new Ctor; - - case symbolTag: - return cloneSymbol(object); - } - } - - /** - * Inserts wrapper `details` in a comment at the top of the `source` body. - * - * @private - * @param {string} source The source to modify. - * @returns {Array} details The details to insert. - * @returns {string} Returns the modified source. - */ - function insertWrapDetails(source, details) { - var length = details.length; - if (!length) { - return source; - } - var lastIndex = length - 1; - details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; - details = details.join(length > 2 ? ', ' : ' '); - return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); - } - - /** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ - function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); - } - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); - } - - /** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; - } - - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); - } - - /** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ - function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); - } - - /** - * Checks if `func` has a lazy counterpart. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, - * else `false`. - */ - function isLaziable(func) { - var funcName = getFuncName(func), - other = lodash[funcName]; - - if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { - return false; - } - if (func === other) { - return true; - } - var data = getData(other); - return !!data && func === data[0]; - } - - /** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ - function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); - } - - /** - * Checks if `func` is capable of being masked. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `func` is maskable, else `false`. - */ - var isMaskable = coreJsData ? isFunction : stubFalse; - - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); - } - - /** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; - } - - /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ - function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; - } - - /** - * Merges the function metadata of `source` into `data`. - * - * Merging metadata reduces the number of wrappers used to invoke a function. - * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` - * may be applied regardless of execution order. Methods like `_.ary` and - * `_.rearg` modify function arguments, making the order in which they are - * executed important, preventing the merging of metadata. However, we make - * an exception for a safe combined case where curried functions have `_.ary` - * and or `_.rearg` applied. - * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. - */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); - - var isCombo = - ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || - ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || - ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & WRAP_BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : value; - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = value; - } - // Use source `ary` if it's smaller. - if (srcBitmask & WRAP_ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; - } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; - - return data; - } - - /** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; - } - - /** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ - function objectToString(value) { - return nativeObjectToString.call(value); - } - - /** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ - function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; - } - - /** - * Gets the parent value at `path` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path to get the parent value of. - * @returns {*} Returns the parent value. - */ - function parent(object, path) { - return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); - } - - /** - * Reorder `array` according to the specified indexes where the element at - * the first index is assigned as the first element, the element at - * the second index is assigned as the second element, and so on. - * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. - */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = copyArray(array); - - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; - } - return array; - } - - /** - * Sets metadata for `func`. - * - * **Note:** If this function becomes hot, i.e. is invoked a lot in a short - * period of time, it will trip its breaker and transition to an identity - * function to avoid garbage collection pauses in V8. See - * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) - * for more details. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = shortOut(baseSetData); - - /** - * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @returns {number|Object} Returns the timer id or timeout object. - */ - var setTimeout = ctxSetTimeout || function(func, wait) { - return root.setTimeout(func, wait); - }; - - /** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var setToString = shortOut(baseSetToString); - - /** - * Sets the `toString` method of `wrapper` to mimic the source of `reference` - * with wrapper details in a comment at the top of the source body. - * - * @private - * @param {Function} wrapper The function to modify. - * @param {Function} reference The reference function. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Function} Returns `wrapper`. - */ - function setWrapToString(wrapper, reference, bitmask) { - var source = (reference + ''); - return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); - } - - /** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ - function shortOut(func) { - var count = 0, - lastCalled = 0; - - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; - } - - /** - * A specialized version of `_.shuffle` which mutates and sets the size of `array`. - * - * @private - * @param {Array} array The array to shuffle. - * @param {number} [size=array.length] The size of `array`. - * @returns {Array} Returns `array`. - */ - function shuffleSelf(array, size) { - var index = -1, - length = array.length, - lastIndex = length - 1; - - size = size === undefined ? length : size; - while (++index < size) { - var rand = baseRandom(index, lastIndex), - value = array[rand]; - - array[rand] = array[index]; - array[index] = value; - } - array.length = size; - return array; - } - - /** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ - var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - }); - - /** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ - function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ - function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; - } - - /** - * Updates wrapper `details` based on `bitmask` flags. - * - * @private - * @returns {Array} details The details to modify. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Array} Returns `details`. - */ - function updateWrapDetails(details, bitmask) { - arrayEach(wrapFlags, function(pair) { - var value = '_.' + pair[0]; - if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { - details.push(value); - } - }); - return details.sort(); - } - - /** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - if (wrapper instanceof LazyWrapper) { - return wrapper.clone(); - } - var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); - result.__actions__ = copyArray(wrapper.__actions__); - result.__index__ = wrapper.__index__; - result.__values__ = wrapper.__values__; - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements split into groups the length of `size`. - * If `array` can't be split evenly, the final chunk will be the remaining - * elements. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the new array of chunks. - * @example - * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] - * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] - */ - function chunk(array, size, guard) { - if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { - size = 1; - } else { - size = nativeMax(toInteger(size), 0); - } - var length = array == null ? 0 : array.length; - if (!length || size < 1) { - return []; - } - var index = 0, - resIndex = 0, - result = Array(nativeCeil(length / size)); - - while (index < length) { - result[resIndex++] = baseSlice(array, index, (index += size)); - } - return result; - } - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * Creates a new array concatenating `array` with any additional arrays - * and/or values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to concatenate. - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example - * - * var array = [1]; - * var other = _.concat(array, 2, [3], [[4]]); - * - * console.log(other); - * // => [1, 2, 3, [4]] - * - * console.log(array); - * // => [1] - */ - function concat() { - var length = arguments.length; - if (!length) { - return []; - } - var args = Array(length - 1), - array = arguments[0], - index = length; - - while (index--) { - args[index - 1] = arguments[index]; - } - return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); - } - - /** - * Creates an array of `array` values not included in the other given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * **Note:** Unlike `_.pullAll`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.without, _.xor - * @example - * - * _.difference([2, 1], [2, 3]); - * // => [1] - */ - var difference = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) - : []; - }); - - /** - * This method is like `_.difference` except that it accepts `iteratee` which - * is invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. The order and references of result values are - * determined by the first array. The iteratee is invoked with one argument: - * (value). - * - * **Note:** Unlike `_.pullAllBy`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2] - * - * // The `_.property` iteratee shorthand. - * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var differenceBy = baseRest(function(array, values) { - var iteratee = last(values); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) - : []; - }); - - /** - * This method is like `_.difference` except that it accepts `comparator` - * which is invoked to compare elements of `array` to `values`. The order and - * references of result values are determined by the first array. The comparator - * is invoked with two arguments: (arrVal, othVal). - * - * **Note:** Unlike `_.pullAllWith`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * - * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); - * // => [{ 'x': 2, 'y': 1 }] - */ - var differenceWith = baseRest(function(array, values) { - var comparator = last(values); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) - : []; - }); - - /** - * Creates a slice of `array` with `n` elements dropped from the beginning. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.drop([1, 2, 3]); - * // => [2, 3] - * - * _.drop([1, 2, 3], 2); - * // => [3] - * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * Creates a slice of `array` with `n` elements dropped from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRight([1, 2, 3]); - * // => [1, 2] - * - * _.dropRight([1, 2, 3], 2); - * // => [1] - * - * _.dropRight([1, 2, 3], 5); - * // => [] - * - * _.dropRight([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function dropRight(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` excluding elements dropped from the end. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.dropRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney'] - * - * // The `_.matches` iteratee shorthand. - * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropRightWhile(users, ['active', false]); - * // => objects for ['barney'] - * - * // The `_.property` iteratee shorthand. - * _.dropRightWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true, true) - : []; - } - - /** - * Creates a slice of `array` excluding elements dropped from the beginning. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.dropWhile(users, function(o) { return !o.active; }); - * // => objects for ['pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.dropWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropWhile(users, ['active', false]); - * // => objects for ['pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.dropWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true) - : []; - } - - /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. - * - * **Note:** This method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Array - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.fill(array, 'a'); - * console.log(array); - * // => ['a', 'a', 'a'] - * - * _.fill(Array(3), 2); - * // => [2, 2, 2] - * - * _.fill([4, 6, 8, 10], '*', 1, 3); - * // => [4, '*', '*', 10] - */ - function fill(array, value, start, end) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { - start = 0; - end = length; - } - return baseFill(array, value, start, end); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(o) { return o.user == 'barney'; }); - * // => 0 - * - * // The `_.matches` iteratee shorthand. - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findIndex(users, ['active', false]); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.findIndex(users, 'active'); - * // => 2 - */ - function findIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseFindIndex(array, getIteratee(predicate, 3), index); - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); - * // => 2 - * - * // The `_.matches` iteratee shorthand. - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastIndex(users, ['active', false]); - * // => 2 - * - * // The `_.property` iteratee shorthand. - * _.findLastIndex(users, 'active'); - * // => 0 - */ - function findLastIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = length - 1; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = fromIndex < 0 - ? nativeMax(length + index, 0) - : nativeMin(index, length - 1); - } - return baseFindIndex(array, getIteratee(predicate, 3), index, true); - } - - /** - * Flattens `array` a single level deep. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2, [3, [4]], 5]]); - * // => [1, 2, [3, [4]], 5] - */ - function flatten(array) { - var length = array == null ? 0 : array.length; - return length ? baseFlatten(array, 1) : []; - } - - /** - * Recursively flattens `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flattenDeep([1, [2, [3, [4]], 5]]); - * // => [1, 2, 3, 4, 5] - */ - function flattenDeep(array) { - var length = array == null ? 0 : array.length; - return length ? baseFlatten(array, INFINITY) : []; - } - - /** - * Recursively flatten `array` up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Array - * @param {Array} array The array to flatten. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * var array = [1, [2, [3, [4]], 5]]; - * - * _.flattenDepth(array, 1); - * // => [1, 2, [3, [4]], 5] - * - * _.flattenDepth(array, 2); - * // => [1, 2, 3, [4], 5] - */ - function flattenDepth(array, depth) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(array, depth); - } - - /** - * The inverse of `_.toPairs`; this method returns an object composed - * from key-value `pairs`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} pairs The key-value pairs. - * @returns {Object} Returns the new object. - * @example - * - * _.fromPairs([['a', 1], ['b', 2]]); - * // => { 'a': 1, 'b': 2 } - */ - function fromPairs(pairs) { - var index = -1, - length = pairs == null ? 0 : pairs.length, - result = {}; - - while (++index < length) { - var pair = pairs[index]; - result[pair[0]] = pair[1]; - } - return result; - } - - /** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias first - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.head([1, 2, 3]); - * // => 1 - * - * _.head([]); - * // => undefined - */ - function head(array) { - return (array && array.length) ? array[0] : undefined; - } - - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it's used as the - * offset from the end of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 - * - * // Search from the `fromIndex`. - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 - */ - function indexOf(array, value, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseIndexOf(array, value, index); - } - - /** - * Gets all but the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - */ - function initial(array) { - var length = array == null ? 0 : array.length; - return length ? baseSlice(array, 0, -1) : []; - } - - /** - * Creates an array of unique values that are included in all given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. The order and references of result values are - * determined by the first array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersection([2, 1], [2, 3]); - * // => [2] - */ - var intersection = baseRest(function(arrays) { - var mapped = arrayMap(arrays, castArrayLikeObject); - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped) - : []; - }); - - /** - * This method is like `_.intersection` except that it accepts `iteratee` - * which is invoked for each element of each `arrays` to generate the criterion - * by which they're compared. The order and references of result values are - * determined by the first array. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [2.1] - * - * // The `_.property` iteratee shorthand. - * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }] - */ - var intersectionBy = baseRest(function(arrays) { - var iteratee = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); - - if (iteratee === last(mapped)) { - iteratee = undefined; - } else { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, getIteratee(iteratee, 2)) - : []; - }); - - /** - * This method is like `_.intersection` except that it accepts `comparator` - * which is invoked to compare elements of `arrays`. The order and references - * of result values are determined by the first array. The comparator is - * invoked with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.intersectionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }] - */ - var intersectionWith = baseRest(function(arrays) { - var comparator = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); - - comparator = typeof comparator == 'function' ? comparator : undefined; - if (comparator) { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, undefined, comparator) - : []; - }); - - /** - * Converts all elements in `array` into a string separated by `separator`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to convert. - * @param {string} [separator=','] The element separator. - * @returns {string} Returns the joined string. - * @example - * - * _.join(['a', 'b', 'c'], '~'); - * // => 'a~b~c' - */ - function join(array, separator) { - return array == null ? '' : nativeJoin.call(array, separator); - } - - /** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ - function last(array) { - var length = array == null ? 0 : array.length; - return length ? array[length - 1] : undefined; - } - - /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.lastIndexOf([1, 2, 1, 2], 2); - * // => 3 - * - * // Search from the `fromIndex`. - * _.lastIndexOf([1, 2, 1, 2], 2, 2); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = length; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); - } - return value === value - ? strictLastIndexOf(array, value, index) - : baseFindIndex(array, baseIsNaN, index, true); - } - - /** - * Gets the element at index `n` of `array`. If `n` is negative, the nth - * element from the end is returned. - * - * @static - * @memberOf _ - * @since 4.11.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=0] The index of the element to return. - * @returns {*} Returns the nth element of `array`. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * - * _.nth(array, 1); - * // => 'b' - * - * _.nth(array, -2); - * // => 'c'; - */ - function nth(array, n) { - return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; - } - - /** - * Removes all given values from `array` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` - * to remove elements from an array by predicate. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pull(array, 'a', 'c'); - * console.log(array); - * // => ['b', 'b'] - */ - var pull = baseRest(pullAll); - - /** - * This method is like `_.pull` except that it accepts an array of values to remove. - * - * **Note:** Unlike `_.difference`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pullAll(array, ['a', 'c']); - * console.log(array); - * // => ['b', 'b'] - */ - function pullAll(array, values) { - return (array && array.length && values && values.length) - ? basePullAll(array, values) - : array; - } - - /** - * This method is like `_.pullAll` except that it accepts `iteratee` which is - * invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. The iteratee is invoked with one argument: (value). - * - * **Note:** Unlike `_.differenceBy`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; - * - * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); - * console.log(array); - * // => [{ 'x': 2 }] - */ - function pullAllBy(array, values, iteratee) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, getIteratee(iteratee, 2)) - : array; - } - - /** - * This method is like `_.pullAll` except that it accepts `comparator` which - * is invoked to compare elements of `array` to `values`. The comparator is - * invoked with two arguments: (arrVal, othVal). - * - * **Note:** Unlike `_.differenceWith`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; - * - * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); - * console.log(array); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] - */ - function pullAllWith(array, values, comparator) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, undefined, comparator) - : array; - } - - /** - * Removes elements from `array` corresponding to `indexes` and returns an - * array of removed elements. - * - * **Note:** Unlike `_.at`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...(number|number[])} [indexes] The indexes of elements to remove. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * var pulled = _.pullAt(array, [1, 3]); - * - * console.log(array); - * // => ['a', 'c'] - * - * console.log(pulled); - * // => ['b', 'd'] - */ - var pullAt = flatRest(function(array, indexes) { - var length = array == null ? 0 : array.length, - result = baseAt(array, indexes); - - basePullAt(array, arrayMap(indexes, function(index) { - return isIndex(index, length) ? +index : index; - }).sort(compareAscending)); - - return result; - }); - - /** - * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is invoked - * with three arguments: (value, index, array). - * - * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` - * to pull elements from an array by value. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { - * return n % 2 == 0; - * }); - * - * console.log(array); - * // => [1, 3] - * - * console.log(evens); - * // => [2, 4] - */ - function remove(array, predicate) { - var result = []; - if (!(array && array.length)) { - return result; - } - var index = -1, - indexes = [], - length = array.length; - - predicate = getIteratee(predicate, 3); - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - indexes.push(index); - } - } - basePullAt(array, indexes); - return result; - } - - /** - * Reverses `array` so that the first element becomes the last, the second - * element becomes the second to last, and so on. - * - * **Note:** This method mutates `array` and is based on - * [`Array#reverse`](https://mdn.io/Array/reverse). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.reverse(array); - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function reverse(array) { - return array == null ? array : nativeReverse.call(array); - } - - /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This method is used instead of - * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are - * returned. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - else { - start = start == null ? 0 : toInteger(start); - end = end === undefined ? length : toInteger(end); - } - return baseSlice(array, start, end); - } - - /** - * Uses a binary search to determine the lowest index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([30, 50], 40); - * // => 1 - */ - function sortedIndex(array, value) { - return baseSortedIndex(array, value); - } - - /** - * This method is like `_.sortedIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); - * // => 0 - */ - function sortedIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); - } - - /** - * This method is like `_.indexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedIndexOf([4, 5, 5, 5, 6], 5); - * // => 1 - */ - function sortedIndexOf(array, value) { - var length = array == null ? 0 : array.length; - if (length) { - var index = baseSortedIndex(array, value); - if (index < length && eq(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.sortedIndex` except that it returns the highest - * index at which `value` should be inserted into `array` in order to - * maintain its sort order. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedLastIndex([4, 5, 5, 5, 6], 5); - * // => 4 - */ - function sortedLastIndex(array, value) { - return baseSortedIndex(array, value, true); - } - - /** - * This method is like `_.sortedLastIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 1 - * - * // The `_.property` iteratee shorthand. - * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); - * // => 1 - */ - function sortedLastIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); - } - - /** - * This method is like `_.lastIndexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); - * // => 3 - */ - function sortedLastIndexOf(array, value) { - var length = array == null ? 0 : array.length; - if (length) { - var index = baseSortedIndex(array, value, true) - 1; - if (eq(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.uniq` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniq([1, 1, 2]); - * // => [1, 2] - */ - function sortedUniq(array) { - return (array && array.length) - ? baseSortedUniq(array) - : []; - } - - /** - * This method is like `_.uniqBy` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); - * // => [1.1, 2.3] - */ - function sortedUniqBy(array, iteratee) { - return (array && array.length) - ? baseSortedUniq(array, getIteratee(iteratee, 2)) - : []; - } - - /** - * Gets all but the first element of `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.tail([1, 2, 3]); - * // => [2, 3] - */ - function tail(array) { - var length = array == null ? 0 : array.length; - return length ? baseSlice(array, 1, length) : []; - } - - /** - * Creates a slice of `array` with `n` elements taken from the beginning. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.take([1, 2, 3], 0); - * // => [] - */ - function take(array, n, guard) { - if (!(array && array.length)) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements taken from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.takeRight([1, 2, 3], 0); - * // => [] - */ - function takeRight(array, n, guard) { - var length = array == null ? 0 : array.length; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.takeRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeRightWhile(users, ['active', false]); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.takeRightWhile(users, 'active'); - * // => [] - */ - function takeRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), false, true) - : []; - } - - /** - * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.takeWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matches` iteratee shorthand. - * _.takeWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeWhile(users, ['active', false]); - * // => objects for ['barney', 'fred'] - * - * // The `_.property` iteratee shorthand. - * _.takeWhile(users, 'active'); - * // => [] - */ - function takeWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3)) - : []; - } - - /** - * Creates an array of unique values, in order, from all given arrays using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([2], [1, 2]); - * // => [2, 1] - */ - var union = baseRest(function(arrays) { - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); - }); - - /** - * This method is like `_.union` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which uniqueness is computed. Result values are chosen from the first - * array in which the value occurs. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.unionBy([2.1], [1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - var unionBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); - }); - - /** - * This method is like `_.union` except that it accepts `comparator` which - * is invoked to compare elements of `arrays`. Result values are chosen from - * the first array in which the value occurs. The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.unionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var unionWith = baseRest(function(arrays) { - var comparator = last(arrays); - comparator = typeof comparator == 'function' ? comparator : undefined; - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); - }); - - /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurrence of each element - * is kept. The order of result values is determined by the order they occur - * in the array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniq([2, 1, 2]); - * // => [2, 1] - */ - function uniq(array) { - return (array && array.length) ? baseUniq(array) : []; - } - - /** - * This method is like `_.uniq` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * uniqueness is computed. The order of result values is determined by the - * order they occur in the array. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniqBy([2.1, 1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniqBy(array, iteratee) { - return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : []; - } - - /** - * This method is like `_.uniq` except that it accepts `comparator` which - * is invoked to compare elements of `array`. The order of result values is - * determined by the order they occur in the array.The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.uniqWith(objects, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] - */ - function uniqWith(array, comparator) { - comparator = typeof comparator == 'function' ? comparator : undefined; - return (array && array.length) ? baseUniq(array, undefined, comparator) : []; - } - - /** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-zip - * configuration. - * - * @static - * @memberOf _ - * @since 1.2.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - * - * _.unzip(zipped); - * // => [['a', 'b'], [1, 2], [true, false]] - */ - function unzip(array) { - if (!(array && array.length)) { - return []; - } - var length = 0; - array = arrayFilter(array, function(group) { - if (isArrayLikeObject(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - return baseTimes(length, function(index) { - return arrayMap(array, baseProperty(index)); - }); - } - - /** - * This method is like `_.unzip` except that it accepts `iteratee` to specify - * how regrouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee=_.identity] The function to combine - * regrouped values. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip([1, 2], [10, 20], [100, 200]); - * // => [[1, 10, 100], [2, 20, 200]] - * - * _.unzipWith(zipped, _.add); - * // => [3, 30, 300] - */ - function unzipWith(array, iteratee) { - if (!(array && array.length)) { - return []; - } - var result = unzip(array); - if (iteratee == null) { - return result; - } - return arrayMap(result, function(group) { - return apply(iteratee, undefined, group); - }); - } - - /** - * Creates an array excluding all given values using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.pull`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.xor - * @example - * - * _.without([2, 1, 2, 3], 1, 2); - * // => [3] - */ - var without = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, values) - : []; - }); - - /** - * Creates an array of unique values that is the - * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the given arrays. The order of result values is determined by the order - * they occur in the arrays. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.without - * @example - * - * _.xor([2, 1], [2, 3]); - * // => [1, 3] - */ - var xor = baseRest(function(arrays) { - return baseXor(arrayFilter(arrays, isArrayLikeObject)); - }); - - /** - * This method is like `_.xor` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which by which they're compared. The order of result values is determined - * by the order they occur in the arrays. The iteratee is invoked with one - * argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2, 3.4] - * - * // The `_.property` iteratee shorthand. - * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var xorBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); - }); - - /** - * This method is like `_.xor` except that it accepts `comparator` which is - * invoked to compare elements of `arrays`. The order of result values is - * determined by the order they occur in the arrays. The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.xorWith(objects, others, _.isEqual); - * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var xorWith = baseRest(function(arrays) { - var comparator = last(arrays); - comparator = typeof comparator == 'function' ? comparator : undefined; - return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); - }); - - /** - * Creates an array of grouped elements, the first of which contains the - * first elements of the given arrays, the second of which contains the - * second elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - */ - var zip = baseRest(unzip); - - /** - * This method is like `_.fromPairs` except that it accepts two arrays, - * one of property identifiers and one of corresponding values. - * - * @static - * @memberOf _ - * @since 0.4.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject(['a', 'b'], [1, 2]); - * // => { 'a': 1, 'b': 2 } - */ - function zipObject(props, values) { - return baseZipObject(props || [], values || [], assignValue); - } - - /** - * This method is like `_.zipObject` except that it supports property paths. - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); - * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } - */ - function zipObjectDeep(props, values) { - return baseZipObject(props || [], values || [], baseSet); - } - - /** - * This method is like `_.zip` except that it accepts `iteratee` to specify - * how grouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee=_.identity] The function to combine - * grouped values. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { - * return a + b + c; - * }); - * // => [111, 222] - */ - var zipWith = baseRest(function(arrays) { - var length = arrays.length, - iteratee = length > 1 ? arrays[length - 1] : undefined; - - iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; - return unzipWith(arrays, iteratee); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` wrapper instance that wraps `value` with explicit method - * chain sequences enabled. The result of such sequences must be unwrapped - * with `_#value`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Seq - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; - * - * var youngest = _ - * .chain(users) - * .sortBy('age') - * .map(function(o) { - * return o.user + ' is ' + o.age; - * }) - * .head() - * .value(); - * // => 'pebbles is 1' - */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } - - /** - * This method invokes `interceptor` and returns `value`. The interceptor - * is invoked with one argument; (value). The purpose of this method is to - * "tap into" a method chain sequence in order to modify intermediate results. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns `value`. - * @example - * - * _([1, 2, 3]) - * .tap(function(array) { - * // Mutate input array. - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] - */ - function tap(value, interceptor) { - interceptor(value); - return value; - } - - /** - * This method is like `_.tap` except that it returns the result of `interceptor`. - * The purpose of this method is to "pass thru" values replacing intermediate - * results in a method chain sequence. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns the result of `interceptor`. - * @example - * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] - */ - function thru(value, interceptor) { - return interceptor(value); - } - - /** - * This method is the wrapper version of `_.at`. - * - * @name at - * @memberOf _ - * @since 1.0.0 - * @category Seq - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _(object).at(['a[0].b.c', 'a[1]']).value(); - * // => [3, 4] - */ - var wrapperAt = flatRest(function(paths) { - var length = paths.length, - start = length ? paths[0] : 0, - value = this.__wrapped__, - interceptor = function(object) { return baseAt(object, paths); }; - - if (length > 1 || this.__actions__.length || - !(value instanceof LazyWrapper) || !isIndex(start)) { - return this.thru(interceptor); - } - value = value.slice(start, +start + (length ? 1 : 0)); - value.__actions__.push({ - 'func': thru, - 'args': [interceptor], - 'thisArg': undefined - }); - return new LodashWrapper(value, this.__chain__).thru(function(array) { - if (length && !array.length) { - array.push(undefined); - } - return array; - }); - }); - - /** - * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. - * - * @name chain - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * // A sequence without explicit chaining. - * _(users).head(); - * // => { 'user': 'barney', 'age': 36 } - * - * // A sequence with explicit chaining. - * _(users) - * .chain() - * .head() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } - */ - function wrapperChain() { - return chain(this); - } - - /** - * Executes the chain sequence and returns the wrapped result. - * - * @name commit - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapped = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapped = wrapped.commit(); - * console.log(array); - * // => [1, 2, 3] - * - * wrapped.last(); - * // => 3 - * - * console.log(array); - * // => [1, 2, 3] - */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } - - /** - * Gets the next value on a wrapped object following the - * [iterator protocol](https://mdn.io/iteration_protocols#iterator). - * - * @name next - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the next iterator value. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped.next(); - * // => { 'done': false, 'value': 1 } - * - * wrapped.next(); - * // => { 'done': false, 'value': 2 } - * - * wrapped.next(); - * // => { 'done': true, 'value': undefined } - */ - function wrapperNext() { - if (this.__values__ === undefined) { - this.__values__ = toArray(this.value()); - } - var done = this.__index__ >= this.__values__.length, - value = done ? undefined : this.__values__[this.__index__++]; - - return { 'done': done, 'value': value }; - } - - /** - * Enables the wrapper to be iterable. - * - * @name Symbol.iterator - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the wrapper object. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped[Symbol.iterator]() === wrapped; - * // => true - * - * Array.from(wrapped); - * // => [1, 2] - */ - function wrapperToIterator() { - return this; - } - - /** - * Creates a clone of the chain sequence planting `value` as the wrapped value. - * - * @name plant - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @param {*} value The value to plant. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2]).map(square); - * var other = wrapped.plant([3, 4]); - * - * other.value(); - * // => [9, 16] - * - * wrapped.value(); - * // => [1, 4] - */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof baseLodash) { - var clone = wrapperClone(parent); - clone.__index__ = 0; - clone.__values__ = undefined; - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; - } - previous.__wrapped__ = value; - return result; - } - - /** - * This method is the wrapper version of `_.reverse`. - * - * **Note:** This method mutates the wrapped array. - * - * @name reverse - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function wrapperReverse() { - var value = this.__wrapped__; - if (value instanceof LazyWrapper) { - var wrapped = value; - if (this.__actions__.length) { - wrapped = new LazyWrapper(this); - } - wrapped = wrapped.reverse(); - wrapped.__actions__.push({ - 'func': thru, - 'args': [reverse], - 'thisArg': undefined - }); - return new LodashWrapper(wrapped, this.__chain__); - } - return this.thru(reverse); - } - - /** - * Executes the chain sequence to resolve the unwrapped value. - * - * @name value - * @memberOf _ - * @since 0.1.0 - * @alias toJSON, valueOf - * @category Seq - * @returns {*} Returns the resolved unwrapped value. - * @example - * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] - */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the number of times the key was returned by `iteratee`. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': 1, '6': 2 } - * - * // The `_.property` iteratee shorthand. - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - ++result[key]; - } else { - baseAssignValue(result, key, 1); - } - }); - - /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * Iteration is stopped once `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * **Note:** This method returns `true` for - * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because - * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of - * elements of empty collections. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.every(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.every(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.every(users, 'active'); - * // => false - */ - function every(collection, predicate, guard) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * **Note:** Unlike `_.remove`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.reject - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.filter(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, { 'age': 36, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.filter(users, 'active'); - * // => objects for ['barney'] - */ - function filter(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.find(users, function(o) { return o.age < 40; }); - * // => object for 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.find(users, { 'age': 1, 'active': true }); - * // => object for 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.find(users, ['active', false]); - * // => object for 'fred' - * - * // The `_.property` iteratee shorthand. - * _.find(users, 'active'); - * // => object for 'barney' - */ - var find = createFind(findIndex); - - /** - * This method is like `_.find` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=collection.length-1] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(n) { - * return n % 2 == 1; - * }); - * // => 3 - */ - var findLast = createFind(findLastIndex); - - /** - * Creates a flattened array of values by running each element in `collection` - * thru `iteratee` and flattening the mapped results. The iteratee is invoked - * with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [n, n]; - * } - * - * _.flatMap([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMap(collection, iteratee) { - return baseFlatten(map(collection, iteratee), 1); - } - - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDeep([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMapDeep(collection, iteratee) { - return baseFlatten(map(collection, iteratee), INFINITY); - } - - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDepth([1, 2], duplicate, 2); - * // => [[1, 1], [2, 2]] - */ - function flatMapDepth(collection, iteratee, depth) { - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(map(collection, iteratee), depth); - } - - /** - * Iterates over elements of `collection` and invokes `iteratee` for each element. - * The iteratee is invoked with three arguments: (value, index|key, collection). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" - * property are iterated like arrays. To avoid this behavior use `_.forIn` - * or `_.forOwn` for object iteration. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias each - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEachRight - * @example - * - * _.forEach([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `1` then `2`. - * - * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forEach(collection, iteratee) { - var func = isArray(collection) ? arrayEach : baseEach; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.forEach` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @alias eachRight - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEach - * @example - * - * _.forEachRight([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `2` then `1`. - */ - function forEachRight(collection, iteratee) { - var func = isArray(collection) ? arrayEachRight : baseEachRight; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The order of grouped values - * is determined by the order they occur in `collection`. The corresponding - * value of each key is an array of elements responsible for generating the - * key. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': [4.2], '6': [6.1, 6.3] } - * - * // The `_.property` iteratee shorthand. - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - baseAssignValue(result, key, [value]); - } - }); - - /** - * Checks if `value` is in `collection`. If `collection` is a string, it's - * checked for a substring of `value`, otherwise - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * is used for equality comparisons. If `fromIndex` is negative, it's used as - * the offset from the end of `collection`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {boolean} Returns `true` if `value` is found, else `false`. - * @example - * - * _.includes([1, 2, 3], 1); - * // => true - * - * _.includes([1, 2, 3], 1, 2); - * // => false - * - * _.includes({ 'a': 1, 'b': 2 }, 1); - * // => true - * - * _.includes('abcd', 'bc'); - * // => true - */ - function includes(collection, value, fromIndex, guard) { - collection = isArrayLike(collection) ? collection : values(collection); - fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; - - var length = collection.length; - if (fromIndex < 0) { - fromIndex = nativeMax(length + fromIndex, 0); - } - return isString(collection) - ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) - : (!!length && baseIndexOf(collection, value, fromIndex) > -1); - } - - /** - * Invokes the method at `path` of each element in `collection`, returning - * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `path` is a function, it's invoked - * for, and `this` bound to, each element in `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array|Function|string} path The path of the method to invoke or - * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke each method with. - * @returns {Array} Returns the array of results. - * @example - * - * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invokeMap([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - var invokeMap = baseRest(function(collection, path, args) { - var index = -1, - isFunc = typeof path == 'function', - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value) { - result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); - }); - return result; - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the last element responsible for generating the key. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var array = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.keyBy(array, function(o) { - * return String.fromCharCode(o.code); - * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.keyBy(array, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - */ - var keyBy = createAggregator(function(result, value, key) { - baseAssignValue(result, key, value); - }); - - /** - * Creates an array of values by running each element in `collection` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, - * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, - * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, - * `template`, `trim`, `trimEnd`, `trimStart`, and `words` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - * @example - * - * function square(n) { - * return n * n; - * } - * - * _.map([4, 8], square); - * // => [16, 64] - * - * _.map({ 'a': 4, 'b': 8 }, square); - * // => [16, 64] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // The `_.property` iteratee shorthand. - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ - function map(collection, iteratee) { - var func = isArray(collection) ? arrayMap : baseMap; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.sortBy` except that it allows specifying the sort - * orders of the iteratees to sort by. If `orders` is unspecified, all values - * are sorted in ascending order. Otherwise, specify an order of "desc" for - * descending or "asc" for ascending sort order of corresponding values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] - * The iteratees to sort by. - * @param {string[]} [orders] The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 36 } - * ]; - * - * // Sort by `user` in ascending order and by `age` in descending order. - * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - */ - function orderBy(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; - } - orders = guard ? undefined : orders; - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; - } - return baseOrderBy(collection, iteratees, orders); - } - - /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, the second of which - * contains elements `predicate` returns falsey for. The predicate is - * invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the array of grouped elements. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * _.partition(users, function(o) { return o.active; }); - * // => objects for [['fred'], ['barney', 'pebbles']] - * - * // The `_.matches` iteratee shorthand. - * _.partition(users, { 'age': 1, 'active': false }); - * // => objects for [['pebbles'], ['barney', 'fred']] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.partition(users, ['active', false]); - * // => objects for [['barney', 'pebbles'], ['fred']] - * - * // The `_.property` iteratee shorthand. - * _.partition(users, 'active'); - * // => objects for [['fred'], ['barney', 'pebbles']] - */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); - - /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` thru `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not given, the first element of `collection` is used as the initial - * value. The iteratee is invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, - * and `sortBy` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduceRight - * @example - * - * _.reduce([1, 2], function(sum, n) { - * return sum + n; - * }, 0); - * // => 3 - * - * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * return result; - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) - */ - function reduce(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduce : baseReduce, - initAccum = arguments.length < 3; - - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); - } - - /** - * This method is like `_.reduce` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduce - * @example - * - * var array = [[0, 1], [2, 3], [4, 5]]; - * - * _.reduceRight(array, function(flattened, other) { - * return flattened.concat(other); - * }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduceRight : baseReduce, - initAccum = arguments.length < 3; - - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); - } - - /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.filter - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * _.reject(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.reject(users, { 'age': 40, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.reject(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.reject(users, 'active'); - * // => objects for ['barney'] - */ - function reject(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, negate(getIteratee(predicate, 3))); - } - - /** - * Gets a random element from `collection`. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @returns {*} Returns the random element. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - */ - function sample(collection) { - var func = isArray(collection) ? arraySample : baseSample; - return func(collection); - } - - /** - * Gets `n` random elements at unique keys from `collection` up to the - * size of `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @param {number} [n=1] The number of elements to sample. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the random elements. - * @example - * - * _.sampleSize([1, 2, 3], 2); - * // => [3, 1] - * - * _.sampleSize([1, 2, 3], 4); - * // => [2, 3, 1] - */ - function sampleSize(collection, n, guard) { - if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { - n = 1; - } else { - n = toInteger(n); - } - var func = isArray(collection) ? arraySampleSize : baseSampleSize; - return func(collection, n); - } - - /** - * Creates an array of shuffled values, using a version of the - * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - * @example - * - * _.shuffle([1, 2, 3, 4]); - * // => [4, 1, 3, 2] - */ - function shuffle(collection) { - var func = isArray(collection) ? arrayShuffle : baseShuffle; - return func(collection); - } - - /** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable string keyed properties for objects. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the collection size. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - if (collection == null) { - return 0; - } - if (isArrayLike(collection)) { - return isString(collection) ? stringSize(collection) : collection.length; - } - var tag = getTag(collection); - if (tag == mapTag || tag == setTag) { - return collection.size; - } - return baseKeys(collection).length; - } - - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * Iteration is stopped once `predicate` returns truthy. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.some(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.some(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.some(users, 'active'); - * // => true - */ - function some(collection, predicate, guard) { - var func = isArray(collection) ? arraySome : baseSome; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection thru each iteratee. This method - * performs a stable sort, that is, it preserves the original sort order of - * equal elements. The iteratees are invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {...(Function|Function[])} [iteratees=[_.identity]] - * The iteratees to sort by. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 34 } - * ]; - * - * _.sortBy(users, [function(o) { return o.user; }]); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - * - * _.sortBy(users, ['user', 'age']); - * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] - */ - var sortBy = baseRest(function(collection, iteratees) { - if (collection == null) { - return []; - } - var length = iteratees.length; - if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { - iteratees = []; - } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { - iteratees = [iteratees[0]]; - } - return baseOrderBy(collection, baseFlatten(iteratees, 1), []); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Gets the timestamp of the number of milliseconds that have elapsed since - * the Unix epoch (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Date - * @returns {number} Returns the timestamp. - * @example - * - * _.defer(function(stamp) { - * console.log(_.now() - stamp); - * }, _.now()); - * // => Logs the number of milliseconds it took for the deferred invocation. - */ - var now = ctxNow || function() { - return root.Date.now(); - }; - - /*------------------------------------------------------------------------*/ - - /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it's called `n` or more times. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {number} n The number of calls before `func` is invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => Logs 'done saving!' after the two async saves have completed. - */ - function after(n, func) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that invokes `func`, with up to `n` arguments, - * ignoring any additional arguments. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @param {number} [n=func.length] The arity cap. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.ary(parseInt, 1)); - * // => [6, 8, 10] - */ - function ary(func, n, guard) { - n = guard ? undefined : n; - n = (func && n == null) ? func.length : n; - return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); - } - - /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it's called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {number} n The number of calls at which `func` is no longer invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * jQuery(element).on('click', _.before(5, addContactToList)); - * // => Allows adding up to 4 contacts to the list. - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } - if (n <= 1) { - func = undefined; - } - return result; - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and `partials` prepended to the arguments it receives. - * - * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for partially applied arguments. - * - * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" - * property of bound functions. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * function greet(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // Bound with placeholders. - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - var bind = baseRest(function(func, thisArg, partials) { - var bitmask = WRAP_BIND_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bind)); - bitmask |= WRAP_PARTIAL_FLAG; - } - return createWrap(func, bitmask, thisArg, partials, holders); - }); - - /** - * Creates a function that invokes the method at `object[key]` with `partials` - * prepended to the arguments it receives. - * - * This method differs from `_.bind` by allowing bound functions to reference - * methods that may be redefined or don't yet exist. See - * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) - * for more details. - * - * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Function - * @param {Object} object The object to invoke the method on. - * @param {string} key The key of the method. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'user': 'fred', - * 'greet': function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * }; - * - * var bound = _.bindKey(object, 'greet', 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * object.greet = function(greeting, punctuation) { - * return greeting + 'ya ' + this.user + punctuation; - * }; - * - * bound('!'); - * // => 'hiya fred!' - * - * // Bound with placeholders. - * var bound = _.bindKey(object, 'greet', _, '!'); - * bound('hi'); - * // => 'hiya fred!' - */ - var bindKey = baseRest(function(object, key, partials) { - var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bindKey)); - bitmask |= WRAP_PARTIAL_FLAG; - } - return createWrap(key, bitmask, object, partials, holders); - }); - - /** - * Creates a function that accepts arguments of `func` and either invokes - * `func` returning its result, if at least `arity` number of arguments have - * been provided, or returns a function that accepts the remaining `func` - * arguments, and so on. The arity of `func` may be specified if `func.length` - * is not sufficient. - * - * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curry(abc); - * - * curried(1)(2)(3); - * // => [1, 2, 3] - * - * curried(1, 2)(3); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(1)(_, 3)(2); - * // => [1, 2, 3] - */ - function curry(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curry.placeholder; - return result; - } - - /** - * This method is like `_.curry` except that arguments are applied to `func` - * in the manner of `_.partialRight` instead of `_.partial`. - * - * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curryRight(abc); - * - * curried(3)(2)(1); - * // => [1, 2, 3] - * - * curried(2, 3)(1); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(3)(1, _)(2); - * // => [1, 2, 3] - */ - function curryRight(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curryRight.placeholder; - return result; - } - - /** - * Creates a debounced function that delays invoking `func` until after `wait` - * milliseconds have elapsed since the last time the debounced function was - * invoked. The debounced function comes with a `cancel` method to cancel - * delayed `func` invocations and a `flush` method to immediately invoke them. - * Provide `options` to indicate whether `func` should be invoked on the - * leading and/or trailing edge of the `wait` timeout. The `func` is invoked - * with the last arguments provided to the debounced function. Subsequent - * calls to the debounced function return the result of the last `func` - * invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the debounced function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to debounce. - * @param {number} [wait=0] The number of milliseconds to delay. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=false] - * Specify invoking on the leading edge of the timeout. - * @param {number} [options.maxWait] - * The maximum time `func` is allowed to be delayed before it's invoked. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // Avoid costly calculations while the window size is in flux. - * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); - * - * // Invoke `sendMail` when clicked, debouncing subsequent calls. - * jQuery(element).on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // Ensure `batchLog` is invoked once after 1 second of debounced calls. - * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); - * var source = new EventSource('/stream'); - * jQuery(source).on('message', debounced); - * - * // Cancel the trailing debounced invocation. - * jQuery(window).on('popstate', debounced.cancel); - */ - function debounce(func, wait, options) { - var lastArgs, - lastThis, - maxWait, - result, - timerId, - lastCallTime, - lastInvokeTime = 0, - leading = false, - maxing = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = toNumber(wait) || 0; - if (isObject(options)) { - leading = !!options.leading; - maxing = 'maxWait' in options; - maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - - function invokeFunc(time) { - var args = lastArgs, - thisArg = lastThis; - - lastArgs = lastThis = undefined; - lastInvokeTime = time; - result = func.apply(thisArg, args); - return result; - } - - function leadingEdge(time) { - // Reset any `maxWait` timer. - lastInvokeTime = time; - // Start the timer for the trailing edge. - timerId = setTimeout(timerExpired, wait); - // Invoke the leading edge. - return leading ? invokeFunc(time) : result; - } - - function remainingWait(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime, - timeWaiting = wait - timeSinceLastCall; - - return maxing - ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) - : timeWaiting; - } - - function shouldInvoke(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime; - - // Either this is the first call, activity has stopped and we're at the - // trailing edge, the system time has gone backwards and we're treating - // it as the trailing edge, or we've hit the `maxWait` limit. - return (lastCallTime === undefined || (timeSinceLastCall >= wait) || - (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); - } - - function timerExpired() { - var time = now(); - if (shouldInvoke(time)) { - return trailingEdge(time); - } - // Restart the timer. - timerId = setTimeout(timerExpired, remainingWait(time)); - } - - function trailingEdge(time) { - timerId = undefined; - - // Only invoke if we have `lastArgs` which means `func` has been - // debounced at least once. - if (trailing && lastArgs) { - return invokeFunc(time); - } - lastArgs = lastThis = undefined; - return result; - } - - function cancel() { - if (timerId !== undefined) { - clearTimeout(timerId); - } - lastInvokeTime = 0; - lastArgs = lastCallTime = lastThis = timerId = undefined; - } - - function flush() { - return timerId === undefined ? result : trailingEdge(now()); - } - - function debounced() { - var time = now(), - isInvoking = shouldInvoke(time); - - lastArgs = arguments; - lastThis = this; - lastCallTime = time; - - if (isInvoking) { - if (timerId === undefined) { - return leadingEdge(lastCallTime); - } - if (maxing) { - // Handle invocations in a tight loop. - timerId = setTimeout(timerExpired, wait); - return invokeFunc(lastCallTime); - } - } - if (timerId === undefined) { - timerId = setTimeout(timerExpired, wait); - } - return result; - } - debounced.cancel = cancel; - debounced.flush = flush; - return debounced; - } - - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { - * console.log(text); - * }, 'deferred'); - * // => Logs 'deferred' after one millisecond. - */ - var defer = baseRest(function(func, args) { - return baseDelay(func, 1, args); - }); - - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { - * console.log(text); - * }, 1000, 'later'); - * // => Logs 'later' after one second. - */ - var delay = baseRest(function(func, wait, args) { - return baseDelay(func, toNumber(wait) || 0, args); - }); - - /** - * Creates a function that invokes `func` with arguments reversed. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to flip arguments for. - * @returns {Function} Returns the new flipped function. - * @example - * - * var flipped = _.flip(function() { - * return _.toArray(arguments); - * }); - * - * flipped('a', 'b', 'c', 'd'); - * // => ['d', 'c', 'b', 'a'] - */ - function flip(func) { - return createWrap(func, WRAP_FLIP_FLAG); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; - } - - // Expose `MapCache`. - memoize.Cache = MapCache; - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new negated function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - var args = arguments; - switch (args.length) { - case 0: return !predicate.call(this); - case 1: return !predicate.call(this, args[0]); - case 2: return !predicate.call(this, args[0], args[1]); - case 3: return !predicate.call(this, args[0], args[1], args[2]); - } - return !predicate.apply(this, args); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first invocation. The `func` is - * invoked with the `this` binding and arguments of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // => `createApplication` is invoked once - */ - function once(func) { - return before(2, func); - } - - /** - * Creates a function that invokes `func` with its arguments transformed. - * - * @static - * @since 4.0.0 - * @memberOf _ - * @category Function - * @param {Function} func The function to wrap. - * @param {...(Function|Function[])} [transforms=[_.identity]] - * The argument transforms. - * @returns {Function} Returns the new function. - * @example - * - * function doubled(n) { - * return n * 2; - * } - * - * function square(n) { - * return n * n; - * } - * - * var func = _.overArgs(function(x, y) { - * return [x, y]; - * }, [square, doubled]); - * - * func(9, 3); - * // => [81, 6] - * - * func(10, 5); - * // => [100, 10] - */ - var overArgs = castRest(function(func, transforms) { - transforms = (transforms.length == 1 && isArray(transforms[0])) - ? arrayMap(transforms[0], baseUnary(getIteratee())) - : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); - - var funcsLength = transforms.length; - return baseRest(function(args) { - var index = -1, - length = nativeMin(args.length, funcsLength); - - while (++index < length) { - args[index] = transforms[index].call(this, args[index]); - } - return apply(func, this, args); - }); - }); - - /** - * Creates a function that invokes `func` with `partials` prepended to the - * arguments it receives. This method is like `_.bind` except it does **not** - * alter the `this` binding. - * - * The `_.partial.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 0.2.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var sayHelloTo = _.partial(greet, 'hello'); - * sayHelloTo('fred'); - * // => 'hello fred' - * - * // Partially applied with placeholders. - * var greetFred = _.partial(greet, _, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - */ - var partial = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partial)); - return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); - }); - - /** - * This method is like `_.partial` except that partially applied arguments - * are appended to the arguments it receives. - * - * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var greetFred = _.partialRight(greet, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - * - * // Partially applied with placeholders. - * var sayHelloTo = _.partialRight(greet, 'hello', _); - * sayHelloTo('fred'); - * // => 'hello fred' - */ - var partialRight = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partialRight)); - return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders); - }); - - /** - * Creates a function that invokes `func` with arguments arranged according - * to the specified `indexes` where the argument value at the first index is - * provided as the first argument, the argument value at the second index is - * provided as the second argument, and so on. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to rearrange arguments for. - * @param {...(number|number[])} indexes The arranged argument indexes. - * @returns {Function} Returns the new function. - * @example - * - * var rearged = _.rearg(function(a, b, c) { - * return [a, b, c]; - * }, [2, 0, 1]); - * - * rearged('b', 'c', 'a') - * // => ['a', 'b', 'c'] - */ - var rearg = flatRest(function(func, indexes) { - return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); - }); - - /** - * Creates a function that invokes `func` with the `this` binding of the - * created function and arguments from `start` and beyond provided as - * an array. - * - * **Note:** This method is based on the - * [rest parameter](https://mdn.io/rest_parameters). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.rest(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + - * (_.size(names) > 1 ? ', & ' : '') + _.last(names); - * }); - * - * say('hello', 'fred', 'barney', 'pebbles'); - * // => 'hello fred, barney, & pebbles' - */ - function rest(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start === undefined ? start : toInteger(start); - return baseRest(func, start); - } - - /** - * Creates a function that invokes `func` with the `this` binding of the - * create function and an array of arguments much like - * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). - * - * **Note:** This method is based on the - * [spread operator](https://mdn.io/spread_operator). - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Function - * @param {Function} func The function to spread arguments over. - * @param {number} [start=0] The start position of the spread. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.spread(function(who, what) { - * return who + ' says ' + what; - * }); - * - * say(['fred', 'hello']); - * // => 'fred says hello' - * - * var numbers = Promise.all([ - * Promise.resolve(40), - * Promise.resolve(36) - * ]); - * - * numbers.then(_.spread(function(x, y) { - * return x + y; - * })); - * // => a Promise of 76 - */ - function spread(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start == null ? 0 : nativeMax(toInteger(start), 0); - return baseRest(function(args) { - var array = args[start], - otherArgs = castSlice(args, 0, start); - - if (array) { - arrayPush(otherArgs, array); - } - return apply(func, this, otherArgs); - }); - } - - /** - * Creates a throttled function that only invokes `func` at most once per - * every `wait` milliseconds. The throttled function comes with a `cancel` - * method to cancel delayed `func` invocations and a `flush` method to - * immediately invoke them. Provide `options` to indicate whether `func` - * should be invoked on the leading and/or trailing edge of the `wait` - * timeout. The `func` is invoked with the last arguments provided to the - * throttled function. Subsequent calls to the throttled function return the - * result of the last `func` invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the throttled function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to throttle. - * @param {number} [wait=0] The number of milliseconds to throttle invocations to. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=true] - * Specify invoking on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // Avoid excessively updating the position while scrolling. - * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); - * - * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. - * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); - * jQuery(element).on('click', throttled); - * - * // Cancel the trailing throttled invocation. - * jQuery(window).on('popstate', throttled.cancel); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - return debounce(func, wait, { - 'leading': leading, - 'maxWait': wait, - 'trailing': trailing - }); - } - - /** - * Creates a function that accepts up to one argument, ignoring any - * additional arguments. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.unary(parseInt)); - * // => [6, 8, 10] - */ - function unary(func) { - return ary(func, 1); - } - - /** - * Creates a function that provides `value` to `wrapper` as its first - * argument. Any additional arguments provided to the function are appended - * to those provided to the `wrapper`. The wrapper is invoked with the `this` - * binding of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {*} value The value to wrap. - * @param {Function} [wrapper=identity] The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

' + func(text) + '

'; - * }); - * - * p('fred, barney, & pebbles'); - * // => '

fred, barney, & pebbles

' - */ - function wrap(value, wrapper) { - return partial(castFunction(wrapper), value); - } - - /*------------------------------------------------------------------------*/ - - /** - * Casts `value` as an array if it's not one. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Lang - * @param {*} value The value to inspect. - * @returns {Array} Returns the cast array. - * @example - * - * _.castArray(1); - * // => [1] - * - * _.castArray({ 'a': 1 }); - * // => [{ 'a': 1 }] - * - * _.castArray('abc'); - * // => ['abc'] - * - * _.castArray(null); - * // => [null] - * - * _.castArray(undefined); - * // => [undefined] - * - * _.castArray(); - * // => [] - * - * var array = [1, 2, 3]; - * console.log(_.castArray(array) === array); - * // => true - */ - function castArray() { - if (!arguments.length) { - return []; - } - var value = arguments[0]; - return isArray(value) ? value : [value]; - } - - /** - * Creates a shallow clone of `value`. - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) - * and supports cloning arrays, array buffers, booleans, date objects, maps, - * numbers, `Object` objects, regexes, sets, strings, symbols, and typed - * arrays. The own enumerable properties of `arguments` objects are cloned - * as plain objects. An empty object is returned for uncloneable values such - * as error objects, functions, DOM nodes, and WeakMaps. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to clone. - * @returns {*} Returns the cloned value. - * @see _.cloneDeep - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var shallow = _.clone(objects); - * console.log(shallow[0] === objects[0]); - * // => true - */ - function clone(value) { - return baseClone(value, CLONE_SYMBOLS_FLAG); - } - - /** - * This method is like `_.clone` except that it accepts `customizer` which - * is invoked to produce the cloned value. If `customizer` returns `undefined`, - * cloning is handled by the method instead. The `customizer` is invoked with - * up to four arguments; (value [, index|key, object, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the cloned value. - * @see _.cloneDeepWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(false); - * } - * } - * - * var el = _.cloneWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 0 - */ - function cloneWith(value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); - } - - /** - * This method is like `_.clone` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @returns {*} Returns the deep cloned value. - * @see _.clone - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var deep = _.cloneDeep(objects); - * console.log(deep[0] === objects[0]); - * // => false - */ - function cloneDeep(value) { - return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); - } - - /** - * This method is like `_.cloneWith` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the deep cloned value. - * @see _.cloneWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(true); - * } - * } - * - * var el = _.cloneDeepWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 20 - */ - function cloneDeepWith(value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); - } - - /** - * Checks if `object` conforms to `source` by invoking the predicate - * properties of `source` with the corresponding property values of `object`. - * - * **Note:** This method is equivalent to `_.conforms` when `source` is - * partially applied. - * - * @static - * @memberOf _ - * @since 4.14.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); - * // => true - * - * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); - * // => false - */ - function conformsTo(object, source) { - return source == null || baseConformsTo(object, source, keys(source)); - } - - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ - function eq(value, other) { - return value === other || (value !== value && other !== other); - } - - /** - * Checks if `value` is greater than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - * @see _.lt - * @example - * - * _.gt(3, 1); - * // => true - * - * _.gt(3, 3); - * // => false - * - * _.gt(1, 3); - * // => false - */ - var gt = createRelationalOperation(baseGt); - - /** - * Checks if `value` is greater than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than or equal to - * `other`, else `false`. - * @see _.lte - * @example - * - * _.gte(3, 1); - * // => true - * - * _.gte(3, 3); - * // => true - * - * _.gte(1, 3); - * // => false - */ - var gte = createRelationalOperation(function(value, other) { - return value >= other; - }); - - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); - }; - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; - - /** - * Checks if `value` is classified as an `ArrayBuffer` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - * @example - * - * _.isArrayBuffer(new ArrayBuffer(2)); - * // => true - * - * _.isArrayBuffer(new Array(2)); - * // => false - */ - var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; - - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } - - /** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ - function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); - } - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - (isObjectLike(value) && baseGetTag(value) == boolTag); - } - - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; - - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; - - /** - * Checks if `value` is likely a DOM element. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - * - * _.isElement(''); - * // => false - */ - function isElement(value) { - return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); - } - - /** - * Checks if `value` is an empty object, collection, map, or set. - * - * Objects are considered empty if they have no own enumerable string keyed - * properties. - * - * Array-like values such as `arguments` objects, arrays, buffers, strings, or - * jQuery-like collections are considered empty if they have a `length` of `0`. - * Similarly, maps and sets are considered empty if they have a `size` of `0`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ - function isEmpty(value) { - if (value == null) { - return true; - } - if (isArrayLike(value) && - (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || - isBuffer(value) || isTypedArray(value) || isArguments(value))) { - return !value.length; - } - var tag = getTag(value); - if (tag == mapTag || tag == setTag) { - return !value.size; - } - if (isPrototype(value)) { - return !baseKeys(value).length; - } - for (var key in value) { - if (hasOwnProperty.call(value, key)) { - return false; - } - } - return true; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. - * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are compared by strict equality, i.e. `===`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.isEqual(object, other); - * // => true - * - * object === other; - * // => false - */ - function isEqual(value, other) { - return baseIsEqual(value, other); - } - - /** - * This method is like `_.isEqual` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with up to - * six arguments: (objValue, othValue [, index|key, object, other, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, othValue) { - * if (isGreeting(objValue) && isGreeting(othValue)) { - * return true; - * } - * } - * - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqualWith(array, other, customizer); - * // => true - */ - function isEqualWith(value, other, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; - } - - /** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an error object, else `false`. - * @example - * - * _.isError(new Error); - * // => true - * - * _.isError(Error); - * // => false - */ - function isError(value) { - if (!isObjectLike(value)) { - return false; - } - var tag = baseGetTag(value); - return tag == errorTag || tag == domExcTag || - (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); - } - - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on - * [`Number.isFinite`](https://mdn.io/Number/isFinite). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. - * @example - * - * _.isFinite(3); - * // => true - * - * _.isFinite(Number.MIN_VALUE); - * // => true - * - * _.isFinite(Infinity); - * // => false - * - * _.isFinite('3'); - * // => false - */ - function isFinite(value) { - return typeof value == 'number' && nativeIsFinite(value); - } - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; - } - - /** - * Checks if `value` is an integer. - * - * **Note:** This method is based on - * [`Number.isInteger`](https://mdn.io/Number/isInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an integer, else `false`. - * @example - * - * _.isInteger(3); - * // => true - * - * _.isInteger(Number.MIN_VALUE); - * // => false - * - * _.isInteger(Infinity); - * // => false - * - * _.isInteger('3'); - * // => false - */ - function isInteger(value) { - return typeof value == 'number' && value == toInteger(value); - } - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); - } - - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return value != null && typeof value == 'object'; - } - - /** - * Checks if `value` is classified as a `Map` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - * @example - * - * _.isMap(new Map); - * // => true - * - * _.isMap(new WeakMap); - * // => false - */ - var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; - - /** - * Performs a partial deep comparison between `object` and `source` to - * determine if `object` contains equivalent property values. - * - * **Note:** This method is equivalent to `_.matches` when `source` is - * partially applied. - * - * Partial comparisons will match empty array and empty object `source` - * values against any array or object value, respectively. See `_.isEqual` - * for a list of supported value comparisons. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.isMatch(object, { 'b': 2 }); - * // => true - * - * _.isMatch(object, { 'b': 1 }); - * // => false - */ - function isMatch(object, source) { - return object === source || baseIsMatch(object, source, getMatchData(source)); - } - - /** - * This method is like `_.isMatch` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with five - * arguments: (objValue, srcValue, index|key, object, source). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, srcValue) { - * if (isGreeting(objValue) && isGreeting(srcValue)) { - * return true; - * } - * } - * - * var object = { 'greeting': 'hello' }; - * var source = { 'greeting': 'hi' }; - * - * _.isMatchWith(object, source, customizer); - * // => true - */ - function isMatchWith(object, source, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseIsMatch(object, source, getMatchData(source), customizer); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is a pristine native function. - * - * **Note:** This method can't reliably detect native functions in the presence - * of the core-js package because core-js circumvents this kind of detection. - * Despite multiple requests, the core-js maintainer has made it clear: any - * attempt to fix the detection will be obstructed. As a result, we're left - * with little choice but to throw an error. Unfortunately, this also affects - * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), - * which rely on core-js. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - * @example - * - * _.isNative(Array.prototype.push); - * // => true - * - * _.isNative(_); - * // => false - */ - function isNative(value) { - if (isMaskable(value)) { - throw new Error(CORE_ERROR_TEXT); - } - return baseIsNative(value); - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is `null` or `undefined`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is nullish, else `false`. - * @example - * - * _.isNil(null); - * // => true - * - * _.isNil(void 0); - * // => true - * - * _.isNil(NaN); - * // => false - */ - function isNil(value) { - return value == null; - } - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || - (isObjectLike(value) && baseGetTag(value) == numberTag); - } - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString.call(Ctor) == objectCtorString; - } - - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; - - /** - * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 - * double precision number which isn't the result of a rounded unsafe integer. - * - * **Note:** This method is based on - * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. - * @example - * - * _.isSafeInteger(3); - * // => true - * - * _.isSafeInteger(Number.MIN_VALUE); - * // => false - * - * _.isSafeInteger(Infinity); - * // => false - * - * _.isSafeInteger('3'); - * // => false - */ - function isSafeInteger(value) { - return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is classified as a `Set` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - * @example - * - * _.isSet(new Set); - * // => true - * - * _.isSet(new WeakSet); - * // => false - */ - var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || - (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); - } - - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); - } - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - - /** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * Checks if `value` is classified as a `WeakMap` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. - * @example - * - * _.isWeakMap(new WeakMap); - * // => true - * - * _.isWeakMap(new Map); - * // => false - */ - function isWeakMap(value) { - return isObjectLike(value) && getTag(value) == weakMapTag; - } - - /** - * Checks if `value` is classified as a `WeakSet` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. - * @example - * - * _.isWeakSet(new WeakSet); - * // => true - * - * _.isWeakSet(new Set); - * // => false - */ - function isWeakSet(value) { - return isObjectLike(value) && baseGetTag(value) == weakSetTag; - } - - /** - * Checks if `value` is less than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - * @see _.gt - * @example - * - * _.lt(1, 3); - * // => true - * - * _.lt(3, 3); - * // => false - * - * _.lt(3, 1); - * // => false - */ - var lt = createRelationalOperation(baseLt); - - /** - * Checks if `value` is less than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than or equal to - * `other`, else `false`. - * @see _.gte - * @example - * - * _.lte(1, 3); - * // => true - * - * _.lte(3, 3); - * // => true - * - * _.lte(3, 1); - * // => false - */ - var lte = createRelationalOperation(function(value, other) { - return value <= other; - }); - - /** - * Converts `value` to an array. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * _.toArray({ 'a': 1, 'b': 2 }); - * // => [1, 2] - * - * _.toArray('abc'); - * // => ['a', 'b', 'c'] - * - * _.toArray(1); - * // => [] - * - * _.toArray(null); - * // => [] - */ - function toArray(value) { - if (!value) { - return []; - } - if (isArrayLike(value)) { - return isString(value) ? stringToArray(value) : copyArray(value); - } - if (symIterator && value[symIterator]) { - return iteratorToArray(value[symIterator]()); - } - var tag = getTag(value), - func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); - - return func(value); - } - - /** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ - function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - return value === value ? value : 0; - } - - /** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ - function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; - - return result === result ? (remainder ? result - remainder : result) : 0; - } - - /** - * Converts `value` to an integer suitable for use as the length of an - * array-like object. - * - * **Note:** This method is based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toLength(3.2); - * // => 3 - * - * _.toLength(Number.MIN_VALUE); - * // => 0 - * - * _.toLength(Infinity); - * // => 4294967295 - * - * _.toLength('3.2'); - * // => 3 - */ - function toLength(value) { - return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; - } - - /** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ - function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = typeof value.valueOf == 'function' ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ''); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); - } - - /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return copyObject(value, keysIn(value)); - } - - /** - * Converts `value` to a safe integer. A safe integer can be compared and - * represented correctly. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toSafeInteger(3.2); - * // => 3 - * - * _.toSafeInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toSafeInteger(Infinity); - * // => 9007199254740991 - * - * _.toSafeInteger('3.2'); - * // => 3 - */ - function toSafeInteger(value) { - return value - ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) - : (value === 0 ? value : 0); - } - - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } - - /*------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable string keyed properties of source objects to the - * destination object. Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object` and is loosely based on - * [`Object.assign`](https://mdn.io/Object/assign). - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assignIn - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assign({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'c': 3 } - */ - var assign = createAssigner(function(object, source) { - if (isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); - return; - } - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - assignValue(object, key, source[key]); - } - } - }); - - /** - * This method is like `_.assign` except that it iterates over own and - * inherited source properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assign - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assignIn({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } - */ - var assignIn = createAssigner(function(object, source) { - copyObject(source, keysIn(source), object); - }); - - /** - * This method is like `_.assignIn` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extendWith - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignInWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keysIn(source), object, customizer); - }); - - /** - * This method is like `_.assign` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignInWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keys(source), object, customizer); - }); - - /** - * Creates an array of values corresponding to `paths` of `object`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Array} Returns the picked values. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _.at(object, ['a[0].b.c', 'a[1]']); - * // => [3, 4] - */ - var at = flatRest(baseAt); - - /** - * Creates an object that inherits from the `prototype` object. If a - * `properties` object is given, its own enumerable string keyed properties - * are assigned to the created object. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties == null ? result : baseAssign(result, properties); - } - - /** - * Assigns own and inherited enumerable string keyed properties of source - * objects to the destination object for all destination properties that - * resolve to `undefined`. Source objects are applied from left to right. - * Once a property is set, additional values of the same property are ignored. - * - * **Note:** This method mutates `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaultsDeep - * @example - * - * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var defaults = baseRest(function(object, sources) { - object = Object(object); - - var index = -1; - var length = sources.length; - var guard = length > 2 ? sources[2] : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - length = 1; - } - - while (++index < length) { - var source = sources[index]; - var props = keysIn(source); - var propsIndex = -1; - var propsLength = props.length; - - while (++propsIndex < propsLength) { - var key = props[propsIndex]; - var value = object[key]; - - if (value === undefined || - (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { - object[key] = source[key]; - } - } - } - - return object; - }); - - /** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaults - * @example - * - * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); - * // => { 'a': { 'b': 2, 'c': 3 } } - */ - var defaultsDeep = baseRest(function(args) { - args.push(undefined, customDefaultsMerge); - return apply(mergeWith, undefined, args); - }); - - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); - } - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findLastKey(users, function(o) { return o.age < 40; }); - * // => returns 'pebbles' assuming `_.findKey` returns 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - function findLastKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); - } - - /** - * Iterates over own and inherited enumerable string keyed properties of an - * object and invokes `iteratee` for each property. The iteratee is invoked - * with three arguments: (value, key, object). Iteratee functions may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forInRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forIn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). - */ - function forIn(object, iteratee) { - return object == null - ? object - : baseFor(object, getIteratee(iteratee, 3), keysIn); - } - - /** - * This method is like `_.forIn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forIn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forInRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. - */ - function forInRight(object, iteratee) { - return object == null - ? object - : baseForRight(object, getIteratee(iteratee, 3), keysIn); - } - - /** - * Iterates over own enumerable string keyed properties of an object and - * invokes `iteratee` for each property. The iteratee is invoked with three - * arguments: (value, key, object). Iteratee functions may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwnRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forOwn(object, iteratee) { - return object && baseForOwn(object, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.forOwn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwnRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. - */ - function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, getIteratee(iteratee, 3)); - } - - /** - * Creates an array of function property names from own enumerable properties - * of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functionsIn - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functions(new Foo); - * // => ['a', 'b'] - */ - function functions(object) { - return object == null ? [] : baseFunctions(object, keys(object)); - } - - /** - * Creates an array of function property names from own and inherited - * enumerable properties of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functions - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functionsIn(new Foo); - * // => ['a', 'b', 'c'] - */ - function functionsIn(object) { - return object == null ? [] : baseFunctions(object, keysIn(object)); - } - - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; - } - - /** - * Checks if `path` is a direct property of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = { 'a': { 'b': 2 } }; - * var other = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b'); - * // => true - * - * _.has(object, ['a', 'b']); - * // => true - * - * _.has(other, 'a'); - * // => false - */ - function has(object, path) { - return object != null && hasPath(object, path, baseHas); - } - - /** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ - function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); - } - - /** - * Creates an object composed of the inverted keys and values of `object`. - * If `object` contains duplicate values, subsequent values overwrite - * property assignments of previous values. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Object - * @param {Object} object The object to invert. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invert(object); - * // => { '1': 'c', '2': 'b' } - */ - var invert = createInverter(function(result, value, key) { - if (value != null && - typeof value.toString != 'function') { - value = nativeObjectToString.call(value); - } - - result[value] = key; - }, constant(identity)); - - /** - * This method is like `_.invert` except that the inverted object is generated - * from the results of running each element of `object` thru `iteratee`. The - * corresponding inverted value of each inverted key is an array of keys - * responsible for generating the inverted value. The iteratee is invoked - * with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Object - * @param {Object} object The object to invert. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invertBy(object); - * // => { '1': ['a', 'c'], '2': ['b'] } - * - * _.invertBy(object, function(value) { - * return 'group' + value; - * }); - * // => { 'group1': ['a', 'c'], 'group2': ['b'] } - */ - var invertBy = createInverter(function(result, value, key) { - if (value != null && - typeof value.toString != 'function') { - value = nativeObjectToString.call(value); - } - - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - }, getIteratee); - - /** - * Invokes the method at `path` of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - * @example - * - * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; - * - * _.invoke(object, 'a[0].b.c.slice', 1, 3); - * // => [2, 3] - */ - var invoke = baseRest(baseInvoke); - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); - } - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); - } - - /** - * The opposite of `_.mapValues`; this method creates an object with the - * same values as `object` and keys generated by running each own enumerable - * string keyed property of `object` thru `iteratee`. The iteratee is invoked - * with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapValues - * @example - * - * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { - * return key + value; - * }); - * // => { 'a1': 1, 'b2': 2 } - */ - function mapKeys(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); - - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, iteratee(value, key, object), value); - }); - return result; - } - - /** - * Creates an object with the same keys as `object` and values generated - * by running each own enumerable string keyed property of `object` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapKeys - * @example - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * _.mapValues(users, function(o) { return o.age; }); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - * - * // The `_.property` iteratee shorthand. - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); - - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, key, iteratee(value, key, object)); - }); - return result; - } - - /** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ - var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); - }); - - /** - * This method is like `_.merge` except that it accepts `customizer` which - * is invoked to produce the merged values of the destination and source - * properties. If `customizer` returns `undefined`, merging is handled by the - * method instead. The `customizer` is invoked with six arguments: - * (objValue, srcValue, key, object, source, stack). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * function customizer(objValue, srcValue) { - * if (_.isArray(objValue)) { - * return objValue.concat(srcValue); - * } - * } - * - * var object = { 'a': [1], 'b': [2] }; - * var other = { 'a': [3], 'b': [4] }; - * - * _.mergeWith(object, other, customizer); - * // => { 'a': [1, 3], 'b': [2, 4] } - */ - var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { - baseMerge(object, source, srcIndex, customizer); - }); - - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable property paths of `object` that are not omitted. - * - * **Note:** This method is considerably slower than `_.pick`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to omit. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omit(object, ['a', 'c']); - * // => { 'b': '2' } - */ - var omit = flatRest(function(object, paths) { - var result = {}; - if (object == null) { - return result; - } - var isDeep = false; - paths = arrayMap(paths, function(path) { - path = castPath(path, object); - isDeep || (isDeep = path.length > 1); - return path; - }); - copyObject(object, getAllKeysIn(object), result); - if (isDeep) { - result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); - } - var length = paths.length; - while (length--) { - baseUnset(result, paths[length]); - } - return result; - }); - - /** - * The opposite of `_.pickBy`; this method creates an object composed of - * the own and inherited enumerable string keyed properties of `object` that - * `predicate` doesn't return truthy for. The predicate is invoked with two - * arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omitBy(object, _.isNumber); - * // => { 'b': '2' } - */ - function omitBy(object, predicate) { - return pickBy(object, negate(getIteratee(predicate))); - } - - /** - * Creates an object composed of the picked `object` properties. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [paths] The property paths to pick. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pick(object, ['a', 'c']); - * // => { 'a': 1, 'c': 3 } - */ - var pick = flatRest(function(object, paths) { - return object == null ? {} : basePick(object, paths); - }); - - /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } - */ - function pickBy(object, predicate) { - if (object == null) { - return {}; - } - var props = arrayMap(getAllKeysIn(object), function(prop) { - return [prop]; - }); - predicate = getIteratee(predicate); - return basePickBy(object, props, function(value, path) { - return predicate(value, path[0]); - }); - } - - /** - * This method is like `_.get` except that if the resolved value is a - * function it's invoked with the `this` binding of its parent object and - * its result is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to resolve. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; - * - * _.result(object, 'a[0].b.c1'); - * // => 3 - * - * _.result(object, 'a[0].b.c2'); - * // => 4 - * - * _.result(object, 'a[0].b.c3', 'default'); - * // => 'default' - * - * _.result(object, 'a[0].b.c3', _.constant('default')); - * // => 'default' - */ - function result(object, path, defaultValue) { - path = castPath(path, object); - - var index = -1, - length = path.length; - - // Ensure the loop is entered when path is empty. - if (!length) { - length = 1; - object = undefined; - } - while (++index < length) { - var value = object == null ? undefined : object[toKey(path[index])]; - if (value === undefined) { - index = length; - value = defaultValue; - } - object = isFunction(value) ? value.call(object) : value; - } - return object; - } - - /** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 - */ - function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); - } - - /** - * This method is like `_.set` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.setWith(object, '[0][1]', 'a', Object); - * // => { '0': { '1': 'a' } } - */ - function setWith(object, path, value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseSet(object, path, value, customizer); - } - - /** - * Creates an array of own enumerable string keyed-value pairs for `object` - * which can be consumed by `_.fromPairs`. If `object` is a map or set, its - * entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entries - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairs(new Foo); - * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) - */ - var toPairs = createToPairs(keys); - - /** - * Creates an array of own and inherited enumerable string keyed-value pairs - * for `object` which can be consumed by `_.fromPairs`. If `object` is a map - * or set, its entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entriesIn - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairsIn(new Foo); - * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) - */ - var toPairsIn = createToPairs(keysIn); - - /** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable string keyed properties thru `iteratee`, with each invocation - * potentially mutating the `accumulator` object. If `accumulator` is not - * provided, a new object with the same `[[Prototype]]` will be used. The - * iteratee is invoked with four arguments: (accumulator, value, key, object). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @returns {*} Returns the accumulated value. - * @example - * - * _.transform([2, 3, 4], function(result, n) { - * result.push(n *= n); - * return n % 2 == 0; - * }, []); - * // => [4, 9] - * - * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } - */ - function transform(object, iteratee, accumulator) { - var isArr = isArray(object), - isArrLike = isArr || isBuffer(object) || isTypedArray(object); - - iteratee = getIteratee(iteratee, 4); - if (accumulator == null) { - var Ctor = object && object.constructor; - if (isArrLike) { - accumulator = isArr ? new Ctor : []; - } - else if (isObject(object)) { - accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; - } - else { - accumulator = {}; - } - } - (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; - } - - /** - * Removes the property at `path` of `object`. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 7 } }] }; - * _.unset(object, 'a[0].b.c'); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - * - * _.unset(object, ['a', '0', 'b', 'c']); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - */ - function unset(object, path) { - return object == null ? true : baseUnset(object, path); - } - - /** - * This method is like `_.set` except that accepts `updater` to produce the - * value to set. Use `_.updateWith` to customize `path` creation. The `updater` - * is invoked with one argument: (value). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.update(object, 'a[0].b.c', function(n) { return n * n; }); - * console.log(object.a[0].b.c); - * // => 9 - * - * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); - * console.log(object.x[0].y.z); - * // => 0 - */ - function update(object, path, updater) { - return object == null ? object : baseUpdate(object, path, castFunction(updater)); - } - - /** - * This method is like `_.update` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.updateWith(object, '[0][1]', _.constant('a'), Object); - * // => { '0': { '1': 'a' } } - */ - function updateWith(object, path, updater, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); - } - - /** - * Creates an array of the own enumerable string keyed property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ - function values(object) { - return object == null ? [] : baseValues(object, keys(object)); - } - - /** - * Creates an array of the own and inherited enumerable string keyed property - * values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.valuesIn(new Foo); - * // => [1, 2, 3] (iteration order is not guaranteed) - */ - function valuesIn(object) { - return object == null ? [] : baseValues(object, keysIn(object)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Clamps `number` within the inclusive `lower` and `upper` bounds. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Number - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - * @example - * - * _.clamp(-10, -5, 5); - * // => -5 - * - * _.clamp(10, -5, 5); - * // => 5 - */ - function clamp(number, lower, upper) { - if (upper === undefined) { - upper = lower; - lower = undefined; - } - if (upper !== undefined) { - upper = toNumber(upper); - upper = upper === upper ? upper : 0; - } - if (lower !== undefined) { - lower = toNumber(lower); - lower = lower === lower ? lower : 0; - } - return baseClamp(toNumber(number), lower, upper); - } - - /** - * Checks if `n` is between `start` and up to, but not including, `end`. If - * `end` is not specified, it's set to `start` with `start` then set to `0`. - * If `start` is greater than `end` the params are swapped to support - * negative ranges. - * - * @static - * @memberOf _ - * @since 3.3.0 - * @category Number - * @param {number} number The number to check. - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - * @see _.range, _.rangeRight - * @example - * - * _.inRange(3, 2, 4); - * // => true - * - * _.inRange(4, 8); - * // => true - * - * _.inRange(4, 2); - * // => false - * - * _.inRange(2, 2); - * // => false - * - * _.inRange(1.2, 2); - * // => true - * - * _.inRange(5.2, 4); - * // => false - * - * _.inRange(-3, -2, -6); - * // => true - */ - function inRange(number, start, end) { - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - number = toNumber(number); - return baseInRange(number, start, end); - } - - /** - * Produces a random number between the inclusive `lower` and `upper` bounds. - * If only one argument is provided a number between `0` and the given number - * is returned. If `floating` is `true`, or either `lower` or `upper` are - * floats, a floating-point number is returned instead of an integer. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Number - * @param {number} [lower=0] The lower bound. - * @param {number} [upper=1] The upper bound. - * @param {boolean} [floating] Specify returning a floating-point number. - * @returns {number} Returns the random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(lower, upper, floating) { - if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { - upper = floating = undefined; - } - if (floating === undefined) { - if (typeof upper == 'boolean') { - floating = upper; - upper = undefined; - } - else if (typeof lower == 'boolean') { - floating = lower; - lower = undefined; - } - } - if (lower === undefined && upper === undefined) { - lower = 0; - upper = 1; - } - else { - lower = toFinite(lower); - if (upper === undefined) { - upper = lower; - lower = 0; - } else { - upper = toFinite(upper); - } - } - if (lower > upper) { - var temp = lower; - lower = upper; - upper = temp; - } - if (floating || lower % 1 || upper % 1) { - var rand = nativeRandom(); - return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); - } - return baseRandom(lower, upper); - } - - /*------------------------------------------------------------------------*/ - - /** - * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the camel cased string. - * @example - * - * _.camelCase('Foo Bar'); - * // => 'fooBar' - * - * _.camelCase('--foo-bar--'); - * // => 'fooBar' - * - * _.camelCase('__FOO_BAR__'); - * // => 'fooBar' - */ - var camelCase = createCompounder(function(result, word, index) { - word = word.toLowerCase(); - return result + (index ? capitalize(word) : word); - }); - - /** - * Converts the first character of `string` to upper case and the remaining - * to lower case. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('FRED'); - * // => 'Fred' - */ - function capitalize(string) { - return upperFirst(toString(string).toLowerCase()); - } - - /** - * Deburrs `string` by converting - * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) - * letters to basic Latin letters and removing - * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to deburr. - * @returns {string} Returns the deburred string. - * @example - * - * _.deburr('déjà vu'); - * // => 'deja vu' - */ - function deburr(string) { - string = toString(string); - return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); - } - - /** - * Checks if `string` ends with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to inspect. - * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search up to. - * @returns {boolean} Returns `true` if `string` ends with `target`, - * else `false`. - * @example - * - * _.endsWith('abc', 'c'); - * // => true - * - * _.endsWith('abc', 'b'); - * // => false - * - * _.endsWith('abc', 'b', 2); - * // => true - */ - function endsWith(string, target, position) { - string = toString(string); - target = baseToString(target); - - var length = string.length; - position = position === undefined - ? length - : baseClamp(toInteger(position), 0, length); - - var end = position; - position -= target.length; - return position >= 0 && string.slice(position, end) == target; - } - - /** - * Converts the characters "&", "<", ">", '"', and "'" in `string` to their - * corresponding HTML entities. - * - * **Note:** No other characters are escaped. To escape additional - * characters use a third-party library like [_he_](https://mths.be/he). - * - * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't need escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. See - * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * When working with HTML you should always - * [quote attribute values](http://wonko.com/post/html-escaping) to reduce - * XSS vectors. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function escape(string) { - string = toString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; - } - - /** - * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", - * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https://lodash\.com/\)' - */ - function escapeRegExp(string) { - string = toString(string); - return (string && reHasRegExpChar.test(string)) - ? string.replace(reRegExpChar, '\\$&') - : string; - } - - /** - * Converts `string` to - * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the kebab cased string. - * @example - * - * _.kebabCase('Foo Bar'); - * // => 'foo-bar' - * - * _.kebabCase('fooBar'); - * // => 'foo-bar' - * - * _.kebabCase('__FOO_BAR__'); - * // => 'foo-bar' - */ - var kebabCase = createCompounder(function(result, word, index) { - return result + (index ? '-' : '') + word.toLowerCase(); - }); - - /** - * Converts `string`, as space separated words, to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the lower cased string. - * @example - * - * _.lowerCase('--Foo-Bar--'); - * // => 'foo bar' - * - * _.lowerCase('fooBar'); - * // => 'foo bar' - * - * _.lowerCase('__FOO_BAR__'); - * // => 'foo bar' - */ - var lowerCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + word.toLowerCase(); - }); - - /** - * Converts the first character of `string` to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.lowerFirst('Fred'); - * // => 'fred' - * - * _.lowerFirst('FRED'); - * // => 'fRED' - */ - var lowerFirst = createCaseFirst('toLowerCase'); - - /** - * Pads `string` on the left and right sides if it's shorter than `length`. - * Padding characters are truncated if they can't be evenly divided by `length`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.pad('abc', 8); - * // => ' abc ' - * - * _.pad('abc', 8, '_-'); - * // => '_-abc_-_' - * - * _.pad('abc', 3); - * // => 'abc' - */ - function pad(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - if (!length || strLength >= length) { - return string; - } - var mid = (length - strLength) / 2; - return ( - createPadding(nativeFloor(mid), chars) + - string + - createPadding(nativeCeil(mid), chars) - ); - } - - /** - * Pads `string` on the right side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padEnd('abc', 6); - * // => 'abc ' - * - * _.padEnd('abc', 6, '_-'); - * // => 'abc_-_' - * - * _.padEnd('abc', 3); - * // => 'abc' - */ - function padEnd(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (string + createPadding(length - strLength, chars)) - : string; - } - - /** - * Pads `string` on the left side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padStart('abc', 6); - * // => ' abc' - * - * _.padStart('abc', 6, '_-'); - * // => '_-_abc' - * - * _.padStart('abc', 3); - * // => 'abc' - */ - function padStart(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (createPadding(length - strLength, chars) + string) - : string; - } - - /** - * Converts `string` to an integer of the specified radix. If `radix` is - * `undefined` or `0`, a `radix` of `10` is used unless `value` is a - * hexadecimal, in which case a `radix` of `16` is used. - * - * **Note:** This method aligns with the - * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category String - * @param {string} string The string to convert. - * @param {number} [radix=10] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {number} Returns the converted integer. - * @example - * - * _.parseInt('08'); - * // => 8 - * - * _.map(['6', '08', '10'], _.parseInt); - * // => [6, 8, 10] - */ - function parseInt(string, radix, guard) { - if (guard || radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); - } - - /** - * Repeats the given string `n` times. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to repeat. - * @param {number} [n=1] The number of times to repeat the string. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the repeated string. - * @example - * - * _.repeat('*', 3); - * // => '***' - * - * _.repeat('abc', 2); - * // => 'abcabc' - * - * _.repeat('abc', 0); - * // => '' - */ - function repeat(string, n, guard) { - if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { - n = 1; - } else { - n = toInteger(n); - } - return baseRepeat(toString(string), n); - } - - /** - * Replaces matches for `pattern` in `string` with `replacement`. - * - * **Note:** This method is based on - * [`String#replace`](https://mdn.io/String/replace). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to modify. - * @param {RegExp|string} pattern The pattern to replace. - * @param {Function|string} replacement The match replacement. - * @returns {string} Returns the modified string. - * @example - * - * _.replace('Hi Fred', 'Fred', 'Barney'); - * // => 'Hi Barney' - */ - function replace() { - var args = arguments, - string = toString(args[0]); - - return args.length < 3 ? string : string.replace(args[1], args[2]); - } - - /** - * Converts `string` to - * [snake case](https://en.wikipedia.org/wiki/Snake_case). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the snake cased string. - * @example - * - * _.snakeCase('Foo Bar'); - * // => 'foo_bar' - * - * _.snakeCase('fooBar'); - * // => 'foo_bar' - * - * _.snakeCase('--FOO-BAR--'); - * // => 'foo_bar' - */ - var snakeCase = createCompounder(function(result, word, index) { - return result + (index ? '_' : '') + word.toLowerCase(); - }); - - /** - * Splits `string` by `separator`. - * - * **Note:** This method is based on - * [`String#split`](https://mdn.io/String/split). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to split. - * @param {RegExp|string} separator The separator pattern to split by. - * @param {number} [limit] The length to truncate results to. - * @returns {Array} Returns the string segments. - * @example - * - * _.split('a-b-c', '-', 2); - * // => ['a', 'b'] - */ - function split(string, separator, limit) { - if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { - separator = limit = undefined; - } - limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; - if (!limit) { - return []; - } - string = toString(string); - if (string && ( - typeof separator == 'string' || - (separator != null && !isRegExp(separator)) - )) { - separator = baseToString(separator); - if (!separator && hasUnicode(string)) { - return castSlice(stringToArray(string), 0, limit); - } - } - return string.split(separator, limit); - } - - /** - * Converts `string` to - * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). - * - * @static - * @memberOf _ - * @since 3.1.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the start cased string. - * @example - * - * _.startCase('--foo-bar--'); - * // => 'Foo Bar' - * - * _.startCase('fooBar'); - * // => 'Foo Bar' - * - * _.startCase('__FOO_BAR__'); - * // => 'FOO BAR' - */ - var startCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + upperFirst(word); - }); - - /** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to inspect. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, - * else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ - function startsWith(string, target, position) { - string = toString(string); - position = position == null - ? 0 - : baseClamp(toInteger(position), 0, string.length); - - target = baseToString(target); - return string.slice(position, position + target.length) == target; - } - - /** - * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escape interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data - * properties may be accessed as free variables in the template. If a setting - * object is given, it takes precedence over `_.templateSettings` values. - * - * **Note:** In the development build `_.template` utilizes - * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for easier debugging. - * - * For more information on precompiling templates see - * [lodash's custom builds documentation](https://lodash.com/custom-builds). - * - * For more information on Chrome extension sandboxes see - * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options={}] The options object. - * @param {RegExp} [options.escape=_.templateSettings.escape] - * The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] - * The "evaluate" delimiter. - * @param {Object} [options.imports=_.templateSettings.imports] - * An object to import into the template as free variables. - * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] - * The "interpolate" delimiter. - * @param {string} [options.sourceURL='lodash.templateSources[n]'] - * The sourceURL of the compiled template. - * @param {string} [options.variable='obj'] - * The data object variable name. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the compiled template function. - * @example - * - * // Use the "interpolate" delimiter to create a compiled template. - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // Use the HTML "escape" delimiter to escape data property values. - * var compiled = _.template('<%- value %>'); - * compiled({ 'value': ' - - - - - - - - - - - - diff --git a/adev/src/content/examples/setup/src/main.ts b/adev/src/content/examples/setup/src/main.ts deleted file mode 100644 index 430d51ace216..000000000000 --- a/adev/src/content/examples/setup/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; - -import {AppModule} from './app/app.module'; - -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err) => console.error(err)); diff --git a/adev/src/content/examples/setup/src/systemjs.config.extras.js b/adev/src/content/examples/setup/src/systemjs.config.extras.js deleted file mode 100644 index 027dfe58cf28..000000000000 --- a/adev/src/content/examples/setup/src/systemjs.config.extras.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Add barrels and stuff - * Adjust as necessary for your application needs. - */ -// (function (global) { -// System.config({ -// packages: { -// // add packages here -// } -// }); -// })(this); diff --git a/adev/src/content/examples/signal-forms/src/comparison/app/reactive-forms.ts b/adev/src/content/examples/signal-forms/src/comparison/app/reactive-forms.ts new file mode 100644 index 000000000000..105e5fbae4ea --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/comparison/app/reactive-forms.ts @@ -0,0 +1,62 @@ +import {Component, ChangeDetectionStrategy} from '@angular/core'; +import {FormGroup, FormControl, Validators, ReactiveFormsModule} from '@angular/forms'; + +@Component({ + selector: 'app-login', + imports: [ReactiveFormsModule], + template: ` +
+
+ + @if (loginForm.controls.email.touched && loginForm.controls.email.invalid) { + + @if (loginForm.controls.email.errors?.['required']) { + Email is required + } + @if (loginForm.controls.email.errors?.['email']) { + Enter a valid email address + } + + } +
+ +
+ + @if (loginForm.controls.password.touched && loginForm.controls.password.invalid) { + + @if (loginForm.controls.password.errors?.['required']) { + Password is required + } + @if (loginForm.controls.password.errors?.['minlength']) { + Password must be at least 8 characters + } + + } +
+ + +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LoginComponent { + loginForm = new FormGroup({ + email: new FormControl('', [Validators.required, Validators.email]), + password: new FormControl('', [Validators.required, Validators.minLength(8)]), + }); + + onSubmit() { + if (this.loginForm.valid) { + const credentials = this.loginForm.value; + console.log('Submitting:', credentials); + } + } +} diff --git a/adev/src/content/examples/signal-forms/src/comparison/app/signal-forms.ts b/adev/src/content/examples/signal-forms/src/comparison/app/signal-forms.ts new file mode 100644 index 000000000000..c2ff0a82ef95 --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/comparison/app/signal-forms.ts @@ -0,0 +1,60 @@ +import {Component, signal, ChangeDetectionStrategy} from '@angular/core'; +import {form, Field, required, email, minLength} from '@angular/forms/signals'; + +@Component({ + selector: 'app-login', + imports: [Field], + template: ` +
+
+ + @if (loginForm.email().touched() && loginForm.email().invalid()) { + + {{ loginForm.email().errors()[0].message }} + + } +
+ +
+ + @if (loginForm.password().touched() && loginForm.password().invalid()) { + + {{ loginForm.password().errors()[0].message }} + + } +
+ + +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LoginComponent { + loginModel = signal({ + email: '', + password: '', + }); + + loginForm = form(this.loginModel, (fieldPath) => { + required(fieldPath.email, {message: 'Email is required'}); + email(fieldPath.email, {message: 'Enter a valid email address'}); + + required(fieldPath.password, {message: 'Password is required'}); + minLength(fieldPath.password, 8, {message: 'Password must be at least 8 characters'}); + }); + + onSubmit() { + if (this.loginForm().valid()) { + const credentials = this.loginModel(); + console.log('Submitting:', credentials); + } + } +} diff --git a/adev/src/content/examples/signal-forms/src/comparison/app/template-driven-forms.ts b/adev/src/content/examples/signal-forms/src/comparison/app/template-driven-forms.ts new file mode 100644 index 000000000000..978855f0807b --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/comparison/app/template-driven-forms.ts @@ -0,0 +1,75 @@ +import {Component, ChangeDetectionStrategy} from '@angular/core'; +import {FormsModule} from '@angular/forms'; + +@Component({ + selector: 'app-login', + imports: [FormsModule], + template: ` +
+
+ + @if (emailInput.touched && emailInput.invalid) { + + @if (emailInput.errors?.['required']) { + Email is required + } + @if (emailInput.errors?.['email']) { + Enter a valid email address + } + + } +
+ +
+ + @if (passwordInput.touched && passwordInput.invalid) { + + @if (passwordInput.errors?.['required']) { + Password is required + } + @if (passwordInput.errors?.['minlength']) { + Password must be at least 8 characters + } + + } +
+ + +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LoginComponent { + email = ''; + password = ''; + + onSubmit() { + const credentials = { + email: this.email, + password: this.password, + }; + console.log('Submitting:', credentials); + } +} diff --git a/adev/src/content/examples/signal-forms/src/login-simple/app/app.css b/adev/src/content/examples/signal-forms/src/login-simple/app/app.css new file mode 100644 index 000000000000..effcb966291d --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-simple/app/app.css @@ -0,0 +1,27 @@ +form { + display: flex; + flex-direction: column; + gap: 1rem; + max-width: 400px; + padding: 1rem; + font-family: Inter, system-ui, -apple-system, sans-serif; +} + +label { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +input { + padding: 0.5rem; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 1rem; + font-family: inherit; +} + +p { + margin: 0.5rem 0; + color: #666; +} diff --git a/adev/src/content/examples/signal-forms/src/login-simple/app/app.html b/adev/src/content/examples/signal-forms/src/login-simple/app/app.html new file mode 100644 index 000000000000..7c0aeb275f7c --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-simple/app/app.html @@ -0,0 +1,14 @@ +
+ + + + +

Hello {{ loginForm.email().value() }}!

+

Password length: {{ loginForm.password().value().length }}

+
diff --git a/adev/src/content/examples/signal-forms/src/login-simple/app/app.ts b/adev/src/content/examples/signal-forms/src/login-simple/app/app.ts new file mode 100644 index 000000000000..5e6ef8e7670c --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-simple/app/app.ts @@ -0,0 +1,23 @@ +import {Component, signal, ChangeDetectionStrategy} from '@angular/core'; +import {form, Field} from '@angular/forms/signals'; + +interface LoginData { + email: string; + password: string; +} + +@Component({ + selector: 'app-root', + templateUrl: 'app.html', + styleUrl: 'app.css', + imports: [Field], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class App { + loginModel = signal({ + email: '', + password: '', + }); + + loginForm = form(this.loginModel); +} diff --git a/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.css b/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.css new file mode 100644 index 000000000000..08907951c7e8 --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.css @@ -0,0 +1,70 @@ +form { + display: flex; + flex-direction: column; + gap: 1rem; + max-width: 400px; + padding: 1rem; + font-family: + Inter, + system-ui, + -apple-system, + sans-serif; +} + +div { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +label { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-weight: 500; +} + +input { + padding: 0.5rem; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 1rem; + font-family: inherit; +} + +input:focus { + outline: none; + border-color: #4285f4; +} + +button { + padding: 0.75rem 1.5rem; + background-color: #4285f4; + color: white; + border: none; + border-radius: 4px; + font-size: 1rem; + font-family: inherit; + cursor: pointer; + transition: background-color 0.2s; +} + +button:hover { + background-color: #357ae8; +} + +button:active { + background-color: #2a65c8; +} + +.error-list { + color: red; + font-size: 0.875rem; + margin: 0.25rem 0 0 0; + padding-left: 0; + list-style-position: inside; +} + +.error-list li { + margin: 0; +} diff --git a/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.html b/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.html new file mode 100644 index 000000000000..9ca4d2ac979e --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.html @@ -0,0 +1,33 @@ +
+
+ + + @if (loginForm.email().touched() && loginForm.email().invalid()) { +
    + @for (error of loginForm.email().errors(); track error) { +
  • {{ error.message }}
  • + } +
+ } +
+ +
+ + + @if (loginForm.password().touched() && loginForm.password().invalid()) { +
    + @for (error of loginForm.password().errors(); track error) { +
  • {{ error.message }}
  • + } +
+ } +
+ + +
diff --git a/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.ts b/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.ts new file mode 100644 index 000000000000..2614be573be8 --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-validation-complete/app/app.ts @@ -0,0 +1,38 @@ +import {Component, signal, ChangeDetectionStrategy} from '@angular/core'; +import {form, Field, required, email, submit} from '@angular/forms/signals'; + +interface LoginData { + email: string; + password: string; +} + +@Component({ + selector: 'app-root', + templateUrl: 'app.html', + styleUrl: 'app.css', + imports: [Field], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class App { + loginModel = signal({ + email: '', + password: '', + }); + + loginForm = form(this.loginModel, (schemaPath) => { + required(schemaPath.email, {message: 'Email is required'}); + email(schemaPath.email, {message: 'Enter a valid email address'}); + + required(schemaPath.password, {message: 'Password is required'}); + }); + + onSubmit(event: Event) { + event.preventDefault(); + submit(this.loginForm, async () => { + const credentials = this.loginModel(); + // In a real app, this would be async: + // await this.authService.login(credentials); + console.log('Logging in with:', credentials); + }); + } +} diff --git a/adev/src/content/examples/signal-forms/src/login-validation/app/app.css b/adev/src/content/examples/signal-forms/src/login-validation/app/app.css new file mode 100644 index 000000000000..2b9a3100a697 --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-validation/app/app.css @@ -0,0 +1,70 @@ +form { + display: flex; + flex-direction: column; + gap: 1rem; + max-width: 400px; + padding: 1rem; + font-family: + Inter, + system-ui, + -apple-system, + sans-serif; +} + +div { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +label { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-weight: 500; +} + +input { + padding: 0.5rem; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 1rem; + font-family: inherit; +} + +input:focus { + outline: none; + border-color: #4285f4; +} + +button { + padding: 0.75rem 1.5rem; + background-color: #4285f4; + color: white; + border: none; + border-radius: 4px; + font-size: 1rem; + font-family: inherit; + cursor: pointer; + transition: background-color 0.2s; +} + +button:hover { + background-color: #357ae8; +} + +button:active { + background-color: #2a65c8; +} + +.error-list { + color: red; + font-size: 0.875rem; + margin: 0.25rem 0 0 0; + padding-left: 0; + list-style-position: inside; +} + +.error-list p { + margin: 0; +} diff --git a/adev/src/content/examples/signal-forms/src/login-validation/app/app.html b/adev/src/content/examples/signal-forms/src/login-validation/app/app.html new file mode 100644 index 000000000000..ff1f14c49b83 --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-validation/app/app.html @@ -0,0 +1,33 @@ +
+
+ + + @if (loginForm.email().touched() && loginForm.email().invalid()) { +
    + @for (error of loginForm.email().errors(); track error) { +
  • {{ error.message }}
  • + } +
+ } +
+ +
+ + + @if (loginForm.password().touched() && loginForm.password().invalid()) { +
+ @for (error of loginForm.password().errors(); track error) { +

{{ error.message }}

+ } +
+ } +
+ + +
diff --git a/adev/src/content/examples/signal-forms/src/login-validation/app/app.ts b/adev/src/content/examples/signal-forms/src/login-validation/app/app.ts new file mode 100644 index 000000000000..f0acd516bc8e --- /dev/null +++ b/adev/src/content/examples/signal-forms/src/login-validation/app/app.ts @@ -0,0 +1,36 @@ +import {Component, signal, ChangeDetectionStrategy} from '@angular/core'; +import {form, Field, required, email} from '@angular/forms/signals'; + +interface LoginData { + email: string; + password: string; +} + +@Component({ + selector: 'app-root', + templateUrl: 'app.html', + styleUrl: 'app.css', + imports: [Field], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class App { + loginModel = signal({ + email: '', + password: '', + }); + + loginForm = form(this.loginModel, (schemaPath) => { + required(schemaPath.email, {message: 'Email is required'}); + email(schemaPath.email, {message: 'Enter a valid email address'}); + + required(schemaPath.password, {message: 'Password is required'}); + }); + + onSubmit(event: Event) { + event.preventDefault(); + // Perform login logic here + const credentials = this.loginModel(); + console.log('Logging in with:', credentials); + // e.g., await this.authService.login(credentials); + } +} diff --git a/adev/src/content/examples/ssr/e2e/src/app.e2e-spec.ts b/adev/src/content/examples/ssr/e2e/src/app.e2e-spec.ts deleted file mode 100644 index 6218e864760c..000000000000 --- a/adev/src/content/examples/ssr/e2e/src/app.e2e-spec.ts +++ /dev/null @@ -1,300 +0,0 @@ -import {browser, by, element, ElementArrayFinder, ElementFinder, logging} from 'protractor'; - -class Hero { - constructor( - public id: number, - public name: string, - ) {} - - // Factory methods - - // Hero from string formatted as ' '. - static fromString(s: string): Hero { - return new Hero(+s.substring(0, s.indexOf(' ')), s.slice(s.indexOf(' ') + 1)); - } - - // Hero from hero list
  • element. - static async fromLi(li: ElementFinder): Promise { - const stringsFromA = await li.all(by.css('a')).getText(); - const strings = stringsFromA[0].split(' '); - return {id: +strings[0], name: strings[1]}; - } - - // Hero id and name from the given detail element. - static async fromDetail(detail: ElementFinder): Promise { - // Get hero id from the first
    - const id = await detail.all(by.css('div')).first().getText(); - // Get name from the h2 - const name = await detail.element(by.css('h2')).getText(); - return { - id: +id.slice(id.indexOf(' ') + 1), - name: name.substring(0, name.lastIndexOf(' ')), - }; - } -} - -describe('Universal', () => { - const expectedH1 = 'Tour of Heroes'; - const expectedTitle = `${expectedH1}`; - const targetHero = {id: 15, name: 'Magneta'}; - const targetHeroDashboardIndex = 2; - const nameSuffix = 'X'; - const newHeroName = targetHero.name + nameSuffix; - - afterEach(async () => { - // Assert that there are no errors emitted from the browser - const logs = await browser.manage().logs().get(logging.Type.BROWSER); - const severeLogs = logs.filter((entry) => entry.level === logging.Level.SEVERE); - expect(severeLogs).toEqual([]); - }); - - describe('Initial page', () => { - beforeAll(() => browser.get('')); - - it(`has title '${expectedTitle}'`, async () => { - expect(await browser.getTitle()).toEqual(expectedTitle); - }); - - it(`has h1 '${expectedH1}'`, async () => { - await expectHeading(1, expectedH1); - }); - - const expectedViewNames = ['Dashboard', 'Heroes']; - it(`has views ${expectedViewNames}`, async () => { - const viewNames = await getPageElts().navElts.map((el) => el!.getText()); - expect(viewNames).toEqual(expectedViewNames); - }); - - it('has dashboard as the active view', async () => { - const page = getPageElts(); - expect(await page.appDashboard.isPresent()).toBeTruthy(); - }); - }); - - describe('Dashboard tests', () => { - beforeAll(() => browser.get('')); - - it('has top heroes', async () => { - const page = getPageElts(); - expect(await page.topHeroes.count()).toEqual(4); - }); - - it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero); - - it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); - - it(`cancels and shows ${targetHero.name} in Dashboard`, async () => { - await element(by.buttonText('go back')).click(); - await browser.waitForAngular(); // seems necessary to gets tests to pass for toh-pt6 - - const targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); - expect(await targetHeroElt.getText()).toEqual(targetHero.name); - }); - - it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero); - - it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); - - it(`saves and shows ${newHeroName} in Dashboard`, async () => { - await element(by.buttonText('save')).click(); - await browser.waitForAngular(); // seems necessary to gets tests to pass for toh-pt6 - - const targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); - expect(await targetHeroElt.getText()).toEqual(newHeroName); - }); - }); - - describe('Heroes tests', () => { - beforeAll(() => browser.get('')); - - it('can switch to Heroes view', async () => { - await getPageElts().appHeroesHref.click(); - const page = getPageElts(); - expect(await page.appHeroes.isPresent()).toBeTruthy(); - expect(await page.allHeroes.count()).toEqual(9, 'number of heroes'); - }); - - it('can route to hero details', async () => { - await getHeroLiEltById(targetHero.id).click(); - - const page = getPageElts(); - expect(await page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); - const hero = await Hero.fromDetail(page.heroDetail); - expect(hero.id).toEqual(targetHero.id); - expect(hero.name).toEqual(targetHero.name.toUpperCase()); - }); - - it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); - - it(`shows ${newHeroName} in Heroes list`, async () => { - await element(by.buttonText('save')).click(); - await browser.waitForAngular(); - const expectedText = `${targetHero.id} ${newHeroName}`; - expect(await getHeroAEltById(targetHero.id).getText()).toEqual(expectedText); - }); - - it(`deletes ${newHeroName} from Heroes list`, async () => { - const heroesBefore = await toHeroArray(getPageElts().allHeroes); - const li = getHeroLiEltById(targetHero.id); - await li.element(by.buttonText('x')).click(); - - const page = getPageElts(); - expect(await page.appHeroes.isPresent()).toBeTruthy(); - expect(await page.allHeroes.count()).toEqual(8, 'number of heroes'); - const heroesAfter = await toHeroArray(page.allHeroes); - // console.log(await Hero.fromLi(page.allHeroes[0])); - const expectedHeroes = heroesBefore.filter((h) => h.name !== newHeroName); - expect(heroesAfter).toEqual(expectedHeroes); - // expect(await page.selectedHeroSubview.isPresent()).toBeFalsy(); - }); - - it(`adds back ${targetHero.name}`, async () => { - const updatedHeroName = 'Alice'; - const heroesBefore = await toHeroArray(getPageElts().allHeroes); - const numHeroes = heroesBefore.length; - - await element(by.css('input')).sendKeys(updatedHeroName); - await element(by.buttonText('add')).click(); - - const page = getPageElts(); - const heroesAfter = await toHeroArray(page.allHeroes); - expect(heroesAfter.length).toEqual(numHeroes + 1, 'number of heroes'); - - expect(heroesAfter.slice(0, numHeroes)).toEqual(heroesBefore, 'Old heroes are still there'); - - const maxId = heroesBefore[heroesBefore.length - 1].id; - expect(heroesAfter[numHeroes]).toEqual({id: maxId + 1, name: updatedHeroName}); - }); - - it('displays correctly styled buttons', async () => { - const buttons = await element.all(by.buttonText('x')); - - for (const button of buttons) { - // Inherited styles from styles.css - expect(await button.getCssValue('font-family')).toBe('Arial, sans-serif'); - expect(await button.getCssValue('border')).toContain('none'); - expect(await button.getCssValue('padding')).toBe('5px 10px'); - expect(await button.getCssValue('border-radius')).toBe('4px'); - // Styles defined in heroes.component.css - expect(await button.getCssValue('right')).toBe('0px'); - expect(await button.getCssValue('top')).toBe('0px'); - expect(await button.getCssValue('bottom')).toBe('0px'); - } - - const addButton = element(by.buttonText('add')); - // Inherited styles from styles.css - expect(await addButton.getCssValue('font-family')).toBe('Arial, sans-serif'); - expect(await addButton.getCssValue('border')).toContain('none'); - expect(await addButton.getCssValue('padding')).toBe('5px 10px'); - expect(await addButton.getCssValue('border-radius')).toBe('4px'); - }); - }); - - describe('Progressive hero search', () => { - beforeAll(() => browser.get('')); - - it(`searches for 'Ma'`, async () => { - await getPageElts().searchBox.sendKeys('Ma'); - await browser.sleep(1000); - - expect(await getPageElts().searchResults.count()).toBe(4); - }); - - it(`continues search with 'g'`, async () => { - await getPageElts().searchBox.sendKeys('g'); - await browser.sleep(1000); - expect(await getPageElts().searchResults.count()).toBe(2); - }); - - it(`continues search with 'n' and gets ${targetHero.name}`, async () => { - await getPageElts().searchBox.sendKeys('n'); - await browser.sleep(1000); - const page = getPageElts(); - expect(await page.searchResults.count()).toBe(1); - const hero = page.searchResults.get(0); - expect(await hero.getText()).toEqual(targetHero.name); - }); - - it(`navigates to ${targetHero.name} details view`, async () => { - const hero = getPageElts().searchResults.get(0); - expect(await hero.getText()).toEqual(targetHero.name); - await hero.click(); - - const page = getPageElts(); - expect(await page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); - const hero2 = await Hero.fromDetail(page.heroDetail); - expect(hero2.id).toEqual(targetHero.id); - expect(hero2.name).toEqual(targetHero.name.toUpperCase()); - }); - }); - - // Helpers - async function addToHeroName(text: string): Promise { - await element(by.css('input')).sendKeys(text); - } - - async function dashboardSelectTargetHero(): Promise { - const targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); - expect(await targetHeroElt.getText()).toEqual(targetHero.name); - await targetHeroElt.click(); - await browser.waitForAngular(); // seems necessary to gets tests to pass for toh-pt6 - - const page = getPageElts(); - expect(await page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); - const hero = await Hero.fromDetail(page.heroDetail); - expect(hero.id).toEqual(targetHero.id); - expect(hero.name).toEqual(targetHero.name.toUpperCase()); - } - - async function expectHeading(hLevel: number, expectedText: string): Promise { - const hTag = `h${hLevel}`; - const hText = await element(by.css(hTag)).getText(); - expect(hText).toEqual(expectedText, hTag); - } - - function getHeroAEltById(id: number): ElementFinder { - const spanForId = element(by.cssContainingText('li span.badge', id.toString())); - return spanForId.element(by.xpath('..')); - } - - function getHeroLiEltById(id: number): ElementFinder { - const spanForId = element(by.cssContainingText('li span.badge', id.toString())); - return spanForId.element(by.xpath('../..')); - } - - function getPageElts() { - const navElts = element.all(by.css('app-root nav a')); - - return { - navElts, - - appDashboardHref: navElts.get(0), - appDashboard: element(by.css('app-root app-dashboard')), - topHeroes: element.all(by.css('app-root app-dashboard > div h4')), - - appHeroesHref: navElts.get(1), - appHeroes: element(by.css('app-root app-heroes')), - allHeroes: element.all(by.css('app-root app-heroes li')), - selectedHeroSubview: element(by.css('app-root app-heroes > div:last-child')), - - heroDetail: element(by.css('app-root app-hero-detail > div')), - - searchBox: element(by.css('#search-box')), - searchResults: element.all(by.css('.search-result li')), - }; - } - - async function toHeroArray(allHeroes: ElementArrayFinder): Promise { - return await allHeroes.map((hero) => Hero.fromLi(hero!)); - } - - async function updateHeroNameInDetailView(): Promise { - // Assumes that the current view is the hero details view. - await addToHeroName(nameSuffix); - - const page = getPageElts(); - const hero = await Hero.fromDetail(page.heroDetail); - expect(hero.id).toEqual(targetHero.id); - expect(hero.name).toEqual(newHeroName.toUpperCase()); - } -}); diff --git a/adev/src/content/examples/ssr/example-config.json b/adev/src/content/examples/ssr/example-config.json deleted file mode 100644 index d170d9ff8bfc..000000000000 --- a/adev/src/content/examples/ssr/example-config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "projectType": "ssr", - "e2e": [ - {"cmd": "yarn", "args": ["e2e", "--configuration=production", "--protractor-config=e2e/protractor-bazel.conf.js", "--no-webdriver-update", "--port=0"]}, - {"cmd": "yarn", "args": ["build"]} - ] -} diff --git a/adev/src/content/examples/ssr/readme.md b/adev/src/content/examples/ssr/readme.md deleted file mode 100644 index 26a204eabcfb..000000000000 --- a/adev/src/content/examples/ssr/readme.md +++ /dev/null @@ -1,9 +0,0 @@ -# Instructions for Angular SSR Example Download - -This is the downloaded sample code for the [Angular SSR (Standalone) guide](https://angular.io/guide/ssr). - -## Install and Run - -1. `npm install` to install the `node_module` packages -2. `ng serve` to launch the dev-server -3. Launch the browser to `http://localhost:4200` diff --git a/adev/src/content/examples/ssr/server.ts b/adev/src/content/examples/ssr/server.ts deleted file mode 100644 index e21008c35eb5..000000000000 --- a/adev/src/content/examples/ssr/server.ts +++ /dev/null @@ -1,60 +0,0 @@ -// #docplaster - -import { - AngularNodeAppEngine, - createNodeRequestHandler, - isMainModule, - writeResponseToNodeResponse, -} from '@angular/ssr/node'; -import express from 'express'; -import {dirname, resolve} from 'node:path'; -import {fileURLToPath} from 'node:url'; - -const serverDistFolder = dirname(fileURLToPath(import.meta.url)); -const browserDistFolder = resolve(serverDistFolder, '../browser'); - -const app = express(); -const angularApp = new AngularNodeAppEngine(); - -/** - * Serve static files from /browser - */ -app.use( - express.static(browserDistFolder, { - maxAge: '1y', - index: false, - redirect: false, - }), -); - -// TODO: implement data requests securely -// Serve data from URLS that begin "/api/" -app.get('/api/**', (req, res) => { - res.status(404).send('data requests are not yet supported'); -}); - -/** - * Handle all other requests by rendering the Angular application. - */ -app.use('/**', (req, res, next) => { - angularApp - .handle(req) - .then((response) => (response ? writeResponseToNodeResponse(response, res) : next())) - .catch(next); -}); - -/** - * Start the server if this module is the main entry point. - * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. - */ -if (isMainModule(import.meta.url)) { - const port = process.env['PORT'] || 4000; - app.listen(port, () => { - console.log(`Node Express server listening on http://localhost:${port}`); - }); -} - -/** - * Request handler used by the Angular CLI (for dev-server and during build) or Firebase Cloud Functions. - */ -export const reqHandler = createNodeRequestHandler(app); diff --git a/adev/src/content/examples/ssr/src/app/app.component.css b/adev/src/content/examples/ssr/src/app/app.component.css deleted file mode 100644 index 1bdf7bdd583e..000000000000 --- a/adev/src/content/examples/ssr/src/app/app.component.css +++ /dev/null @@ -1,23 +0,0 @@ -/* AppComponent's private CSS styles */ -h1 { - font-size: 1.2em; - margin-bottom: 0; -} -nav a { - padding: 5px 10px; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #334953; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.active { - color: #039be5; -} diff --git a/adev/src/content/examples/ssr/src/app/app.component.html b/adev/src/content/examples/ssr/src/app/app.component.html deleted file mode 100644 index 49c7d171b698..000000000000 --- a/adev/src/content/examples/ssr/src/app/app.component.html +++ /dev/null @@ -1,7 +0,0 @@ -

    {{title}}

    - - - diff --git a/adev/src/content/examples/ssr/src/app/app.component.ts b/adev/src/content/examples/ssr/src/app/app.component.ts deleted file mode 100644 index 9ef13f6543c4..000000000000 --- a/adev/src/content/examples/ssr/src/app/app.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Component} from '@angular/core'; -import {RouterLink, RouterOutlet} from '@angular/router'; - -import {PLATFORM_ID, APP_ID, Inject} from '@angular/core'; -import {isPlatformBrowser} from '@angular/common'; - -import {MessagesComponent} from './messages/messages.component'; - -@Component({ - selector: 'app-root', - templateUrl: './app.component.html', - imports: [RouterLink, RouterOutlet, MessagesComponent], - styleUrls: ['./app.component.css'], -}) -export class AppComponent { - title = 'Tour of Heroes'; - - constructor(@Inject(PLATFORM_ID) platformId: object, @Inject(APP_ID) appId: string) { - const platform = isPlatformBrowser(platformId) ? 'in the browser' : 'on the server'; - console.log(`Running ${platform} with appId=${appId}`); - } -} diff --git a/adev/src/content/examples/ssr/src/app/app.config.ts b/adev/src/content/examples/ssr/src/app/app.config.ts deleted file mode 100644 index dbcfd38f12d3..000000000000 --- a/adev/src/content/examples/ssr/src/app/app.config.ts +++ /dev/null @@ -1,30 +0,0 @@ -// #docplaster -import {importProvidersFrom} from '@angular/core'; -import {provideProtractorTestingSupport, withEventReplay} from '@angular/platform-browser'; -import {provideClientHydration} from '@angular/platform-browser'; -import {ApplicationConfig} from '@angular/core'; -import {provideRouter} from '@angular/router'; -import {provideHttpClient, withFetch} from '@angular/common/http'; - -import {routes} from './app.routes'; - -import {HttpClientInMemoryWebApiModule} from 'angular-in-memory-web-api'; -import {InMemoryDataService} from './in-memory-data.service'; - -export const appConfig: ApplicationConfig = { - providers: [ - provideRouter(routes), - provideHttpClient(withFetch()), - provideClientHydration(withEventReplay()), - provideProtractorTestingSupport(), // essential for e2e testing - - // TODO: Remove from production apps - importProvidersFrom( - // The HttpClientInMemoryWebApiModule module intercepts HTTP requests - // and returns simulated server responses. - // Remove it when a real server is ready to receive requests. - HttpClientInMemoryWebApiModule.forRoot(InMemoryDataService, {dataEncapsulation: false}), - ), - // ... - ], -}; diff --git a/adev/src/content/examples/ssr/src/app/app.routes.ts b/adev/src/content/examples/ssr/src/app/app.routes.ts deleted file mode 100644 index a512e57893c7..000000000000 --- a/adev/src/content/examples/ssr/src/app/app.routes.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Routes} from '@angular/router'; - -import {DashboardComponent} from './dashboard/dashboard.component'; -import {HeroesComponent} from './heroes/heroes.component'; -import {HeroDetailComponent} from './hero-detail/hero-detail.component'; - -export const routes: Routes = [ - {path: '', redirectTo: '/dashboard', pathMatch: 'full'}, - {path: 'dashboard', component: DashboardComponent}, - {path: 'detail/:id', component: HeroDetailComponent}, - {path: 'heroes', component: HeroesComponent}, -]; diff --git a/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.css b/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.css deleted file mode 100644 index 031b2e382fb8..000000000000 --- a/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.css +++ /dev/null @@ -1,61 +0,0 @@ -/* DashboardComponent's private CSS styles */ -[class*='col-'] { - float: left; - padding-right: 20px; - padding-bottom: 20px; -} -[class*='col-']:last-of-type { - padding-right: 0; -} -a { - text-decoration: none; -} -*, *::after, *::before { - box-sizing: border-box; -} -h3 { - text-align: center; - margin-bottom: 0; -} -h4 { - position: relative; -} -.grid { - margin: 0; -} -.col-1-4 { - width: 25%; -} -.module { - padding: 20px; - text-align: center; - color: #eee; - max-height: 120px; - min-width: 120px; - background-color: #3f525c; - border-radius: 2px; -} -.module:hover { - background-color: #EEE; - cursor: pointer; - color: #607d8b; -} -.grid-pad { - padding: 10px 0; -} -.grid-pad > [class*='col-']:last-of-type { - padding-right: 20px; -} -@media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } -} -@media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } -} diff --git a/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.html b/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.html deleted file mode 100644 index fbdd5d79058c..000000000000 --- a/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.html +++ /dev/null @@ -1,12 +0,0 @@ -

    Top Heroes

    -
    - @for (hero of heroes; track hero.id) { - -
    -

    {{hero.name}}

    -
    -
    - } -
    - - diff --git a/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.ts b/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.ts deleted file mode 100644 index 702eb0a17831..000000000000 --- a/adev/src/content/examples/ssr/src/app/dashboard/dashboard.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Component, inject, OnInit} from '@angular/core'; -import {NgFor} from '@angular/common'; -import {RouterLink} from '@angular/router'; - -import {Hero} from '../hero'; -import {HeroSearchComponent} from '../hero-search/hero-search.component'; -import {HeroService} from '../hero.service'; - -@Component({ - selector: 'app-dashboard', - templateUrl: './dashboard.component.html', - imports: [RouterLink, HeroSearchComponent], - styleUrls: ['./dashboard.component.css'], -}) -export class DashboardComponent { - heroes: Hero[] = []; - - private heroService = inject(HeroService); - - constructor() { - this.getHeroes(); - } - - getHeroes(): void { - this.heroService.getHeroes().subscribe((heroes) => (this.heroes = heroes.slice(1, 5))); - } -} diff --git a/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.css b/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.css deleted file mode 100644 index 6a860b871da3..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.css +++ /dev/null @@ -1,30 +0,0 @@ -/* HeroDetailComponent's private CSS styles */ -label { - display: inline-block; - width: 3em; - margin: .5em 0; - color: #607D8B; - font-weight: bold; -} -input { - height: 2em; - font-size: 1em; - padding-left: .4em; -} -button { - margin-top: 20px; - font-family: Arial, sans-serif; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; -} -button:hover { - background-color: #cfd8dc; -} -button:disabled { - background-color: #eee; - color: #ccc; - cursor: auto; -} diff --git a/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.html b/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.html deleted file mode 100644 index 6625082ec968..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.html +++ /dev/null @@ -1,11 +0,0 @@ -
    -

    {{hero.name | uppercase}} Details

    -
    id: {{hero.id}}
    -
    - -
    - - -
    diff --git a/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.ts b/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.ts deleted file mode 100644 index 47317a8d0150..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero-detail/hero-detail.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {Component, OnInit, Input} from '@angular/core'; -import {ActivatedRoute} from '@angular/router'; -import {Location, NgIf, UpperCasePipe} from '@angular/common'; -import {FormsModule} from '@angular/forms'; - -import {Hero} from '../hero'; -import {HeroService} from '../hero.service'; - -@Component({ - selector: 'app-hero-detail', - templateUrl: './hero-detail.component.html', - imports: [FormsModule, NgIf, UpperCasePipe], - styleUrls: ['./hero-detail.component.css'], -}) -export class HeroDetailComponent implements OnInit { - @Input() hero!: Hero; - - constructor( - private route: ActivatedRoute, - private heroService: HeroService, - private location: Location, - ) {} - - ngOnInit(): void { - this.getHero(); - } - - getHero(): void { - const id = parseInt(this.route.snapshot.paramMap.get('id')!, 10); - this.heroService.getHero(id).subscribe((hero) => (this.hero = hero)); - } - - goBack(): void { - this.location.back(); - } - - save(): void { - this.heroService.updateHero(this.hero).subscribe(() => this.goBack()); - } -} diff --git a/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.css b/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.css deleted file mode 100644 index 190d9bbc1071..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.css +++ /dev/null @@ -1,39 +0,0 @@ -/* HeroSearch private styles */ -.search-result li { - border-bottom: 1px solid gray; - border-left: 1px solid gray; - border-right: 1px solid gray; - width: 195px; - height: 16px; - padding: 5px; - background-color: white; - cursor: pointer; - list-style-type: none; -} - -.search-result li:hover { - background-color: #607D8B; -} - -.search-result li a { - color: #888; - display: block; - text-decoration: none; -} - -.search-result li a:hover { - color: white; -} -.search-result li a:active { - color: white; -} -#search-box { - width: 200px; - height: 20px; -} - - -ul.search-result { - margin-top: 0; - padding-left: 0; -} diff --git a/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.html b/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.html deleted file mode 100644 index cce62888acb3..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.html +++ /dev/null @@ -1,13 +0,0 @@ -
    -

    - - - - -
    diff --git a/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.ts b/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.ts deleted file mode 100644 index ff8f4d9c9b62..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero-search/hero-search.component.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {Component, inject, OnInit} from '@angular/core'; -import {AsyncPipe, NgFor} from '@angular/common'; -import {RouterLink} from '@angular/router'; - -import {Observable, Subject} from 'rxjs'; - -import {debounceTime, distinctUntilChanged, switchMap} from 'rxjs/operators'; - -import {Hero} from '../hero'; -import {HeroService} from '../hero.service'; - -@Component({ - selector: 'app-hero-search', - templateUrl: './hero-search.component.html', - imports: [AsyncPipe, NgFor, RouterLink], - styleUrls: ['./hero-search.component.css'], -}) -export class HeroSearchComponent { - private searchTerms = new Subject(); - - private heroService = inject(HeroService); - - heroes$: Observable = this.searchTerms.pipe( - // wait 300ms after each keystroke before considering the term - debounceTime(300), - - // ignore new term if same as previous term - distinctUntilChanged(), - - // switch to new search observable each time the term changes - switchMap((term: string) => this.heroService.searchHeroes(term)), - ); - - // Push a search term into the observable stream. - search(term: string): void { - this.searchTerms.next(term); - } -} diff --git a/adev/src/content/examples/ssr/src/app/hero.service.ts b/adev/src/content/examples/ssr/src/app/hero.service.ts deleted file mode 100644 index 1f7bfe81cf6d..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero.service.ts +++ /dev/null @@ -1,122 +0,0 @@ -import {Injectable} from '@angular/core'; -import {HttpClient, HttpHeaders} from '@angular/common/http'; - -import {Observable, of} from 'rxjs'; -import {catchError, map, tap} from 'rxjs/operators'; - -import {Hero} from './hero'; -import {MessageService} from './message.service'; - -@Injectable({providedIn: 'root'}) -export class HeroService { - private heroesUrl = 'api/heroes'; // URL to web api - - httpOptions = { - headers: new HttpHeaders({'Content-Type': 'application/json'}), - }; - - constructor( - private http: HttpClient, - private messageService: MessageService, - ) {} - - /** GET heroes from the server */ - getHeroes(): Observable { - return this.http.get(this.heroesUrl).pipe( - tap((_) => this.log('fetched heroes')), - catchError(this.handleError('getHeroes', [])), - ); - } - - /** GET hero by id. Return `undefined` when id not found */ - getHeroNo404(id: number): Observable { - const url = `${this.heroesUrl}/?id=${id}`; - return this.http.get(url).pipe( - map((heroes) => heroes[0]), // returns a {0|1} element array - tap((h) => { - const outcome = h ? 'fetched' : 'did not find'; - this.log(`${outcome} hero id=${id}`); - }), - catchError(this.handleError(`getHero id=${id}`)), - ); - } - - /** GET hero by id. Will 404 if id not found */ - getHero(id: number): Observable { - const url = `${this.heroesUrl}/${id}`; - return this.http.get(url).pipe( - tap((_) => this.log(`fetched hero id=${id}`)), - catchError(this.handleError(`getHero id=${id}`)), - ); - } - - /* GET heroes whose name contains search term */ - searchHeroes(term: string): Observable { - if (!term.trim()) { - // if not search term, return empty hero array. - return of([]); - } - return this.http.get(`${this.heroesUrl}/?name=${term}`).pipe( - tap((x) => - x.length - ? this.log(`found heroes matching "${term}"`) - : this.log(`no heroes matching "${term}"`), - ), - catchError(this.handleError('searchHeroes', [])), - ); - } - - //////// Save methods ////////// - - /** POST: add a new hero to the server */ - addHero(hero: Hero): Observable { - return this.http.post(this.heroesUrl, hero, this.httpOptions).pipe( - tap((newHero: Hero) => this.log(`added hero w/ id=${newHero.id}`)), - catchError(this.handleError('addHero')), - ); - } - - /** DELETE: delete the hero from the server */ - deleteHero(hero: Hero | number): Observable { - const id = typeof hero === 'number' ? hero : hero.id; - const url = `${this.heroesUrl}/${id}`; - - return this.http.delete(url, this.httpOptions).pipe( - tap((_) => this.log(`deleted hero id=${id}`)), - catchError(this.handleError('deleteHero')), - ); - } - - /** PUT: update the hero on the server */ - updateHero(hero: Hero): Observable { - return this.http.put(this.heroesUrl, hero, this.httpOptions).pipe( - tap((_) => this.log(`updated hero id=${hero.id}`)), - catchError(this.handleError('updateHero')), - ); - } - - /** - * Handle Http operation that failed. - * Let the app continue. - * - * @param operation - name of the operation that failed - * @param result - optional value to return as the observable result - */ - private handleError(operation = 'operation', result?: T) { - return (error: any): Observable => { - // TODO: send the error to remote logging infrastructure - console.error(error); // log to console instead - - // TODO: better job of transforming error for user consumption - this.log(`${operation} failed: ${error.message}`); - - // Let the app keep running by returning an empty result. - return of(result as T); - }; - } - - /** Log a HeroService message with the MessageService */ - private log(message: string) { - this.messageService.add(`HeroService: ${message}`); - } -} diff --git a/adev/src/content/examples/ssr/src/app/hero.ts b/adev/src/content/examples/ssr/src/app/hero.ts deleted file mode 100644 index a61b497759b7..000000000000 --- a/adev/src/content/examples/ssr/src/app/hero.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Hero { - id: number; - name: string; -} diff --git a/adev/src/content/examples/ssr/src/app/heroes/heroes.component.css b/adev/src/content/examples/ssr/src/app/heroes/heroes.component.css deleted file mode 100644 index ccb1e57e3520..000000000000 --- a/adev/src/content/examples/ssr/src/app/heroes/heroes.component.css +++ /dev/null @@ -1,76 +0,0 @@ -/* HeroesComponent's private CSS styles */ -.heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 15em; -} - -.heroes li { - position: relative; - cursor: pointer; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} - -.heroes li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} - -.heroes a { - color: #333; - text-decoration: none; - position: relative; - display: block; - width: 250px; -} - -.heroes a:hover { - color: #607D8B; -} - -.heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #405061; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - min-width: 16px; - text-align: right; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} - -button { - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - font-family: Arial, sans-serif; -} - -button:hover { - background-color: #cfd8dc; -} - -button.delete { - position: absolute; - right: 0; - top: 0; - bottom: 0; - background-color: gray !important; - color: white; - margin: 0; -} - diff --git a/adev/src/content/examples/ssr/src/app/heroes/heroes.component.html b/adev/src/content/examples/ssr/src/app/heroes/heroes.component.html deleted file mode 100644 index 0afd75048b3e..000000000000 --- a/adev/src/content/examples/ssr/src/app/heroes/heroes.component.html +++ /dev/null @@ -1,21 +0,0 @@ -

    My Heroes

    - -
    - - - -
    - - diff --git a/adev/src/content/examples/ssr/src/app/heroes/heroes.component.ts b/adev/src/content/examples/ssr/src/app/heroes/heroes.component.ts deleted file mode 100644 index 5b914181940b..000000000000 --- a/adev/src/content/examples/ssr/src/app/heroes/heroes.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {Component, inject, OnInit} from '@angular/core'; -import {NgFor} from '@angular/common'; -import {RouterLink} from '@angular/router'; - -import {Hero} from '../hero'; -import {HeroService} from '../hero.service'; - -@Component({ - selector: 'app-heroes', - templateUrl: './heroes.component.html', - imports: [NgFor, RouterLink], - styleUrls: ['./heroes.component.css'], -}) -export class HeroesComponent { - private heroService = inject(HeroService); - heroes: Hero[] = []; - - constructor() { - this.getHeroes(); - } - - getHeroes(): void { - this.heroService.getHeroes().subscribe((heroes) => (this.heroes = heroes)); - } - - add(name: string): void { - name = name.trim(); - if (!name) { - return; - } - this.heroService.addHero({name} as Hero).subscribe((hero) => { - this.heroes.push(hero); - }); - } - - delete(hero: Hero): void { - this.heroes = this.heroes.filter((h) => h !== hero); - this.heroService.deleteHero(hero).subscribe(); - } -} diff --git a/adev/src/content/examples/ssr/src/app/in-memory-data.service.ts b/adev/src/content/examples/ssr/src/app/in-memory-data.service.ts deleted file mode 100644 index d625a0cb3f53..000000000000 --- a/adev/src/content/examples/ssr/src/app/in-memory-data.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {Injectable} from '@angular/core'; -import {InMemoryDbService} from 'angular-in-memory-web-api'; -import {Hero} from './hero'; - -@Injectable({ - providedIn: 'root', -}) -export class InMemoryDataService implements InMemoryDbService { - createDb() { - const heroes = [ - {id: 12, name: 'Dr. Nice'}, - {id: 13, name: 'Bombasto'}, - {id: 14, name: 'Celeritas'}, - {id: 15, name: 'Magneta'}, - {id: 16, name: 'RubberMan'}, - {id: 17, name: 'Dynama'}, - {id: 18, name: 'Dr. IQ'}, - {id: 19, name: 'Magma'}, - {id: 20, name: 'Tornado'}, - ]; - return {heroes}; - } - - // Overrides the genId method to ensure that a hero always has an id. - // If the heroes array is empty, - // the method below returns the initial number (11). - // if the heroes array is not empty, the method below returns the highest - // hero id + 1. - genId(heroes: Hero[]): number { - return heroes.length > 0 ? Math.max(...heroes.map((hero) => hero.id)) + 1 : 11; - } -} diff --git a/adev/src/content/examples/ssr/src/app/message.service.ts b/adev/src/content/examples/ssr/src/app/message.service.ts deleted file mode 100644 index 53b4cfcc7e78..000000000000 --- a/adev/src/content/examples/ssr/src/app/message.service.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {Injectable} from '@angular/core'; - -@Injectable({providedIn: 'root'}) -export class MessageService { - messages: string[] = []; - - add(message: string) { - this.messages.push(message); - } - - clear() { - this.messages = []; - } -} diff --git a/adev/src/content/examples/ssr/src/app/messages/messages.component.css b/adev/src/content/examples/ssr/src/app/messages/messages.component.css deleted file mode 100644 index 08585dcbaf8a..000000000000 --- a/adev/src/content/examples/ssr/src/app/messages/messages.component.css +++ /dev/null @@ -1,20 +0,0 @@ -/* MessagesComponent's private CSS styles */ -h2 { - color: red; - font-family: Arial, Helvetica, sans-serif; - font-weight: lighter; -} - -button.clear { - font-family: Arial, sans-serif; - color: #333; - background-color: #eee; - margin-bottom: 12px; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; -} -button:hover { - background-color: #cfd8dc; -} diff --git a/adev/src/content/examples/ssr/src/app/messages/messages.component.html b/adev/src/content/examples/ssr/src/app/messages/messages.component.html deleted file mode 100644 index ddc61f281eb2..000000000000 --- a/adev/src/content/examples/ssr/src/app/messages/messages.component.html +++ /dev/null @@ -1,8 +0,0 @@ -@if(messageService.messages.length) -
    -

    Messages

    - - @for (message of messageService.messages; track $index) { -
    {{message}}
    - } -
    diff --git a/adev/src/content/examples/ssr/src/app/messages/messages.component.ts b/adev/src/content/examples/ssr/src/app/messages/messages.component.ts deleted file mode 100644 index 1345d1a18fb8..000000000000 --- a/adev/src/content/examples/ssr/src/app/messages/messages.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Component, inject} from '@angular/core'; -import {NgFor, NgIf} from '@angular/common'; - -import {MessageService} from '../message.service'; - -@Component({ - selector: 'app-messages', - templateUrl: './messages.component.html', - styleUrls: ['./messages.component.css'], -}) -export class MessagesComponent { - public messageService = inject(MessageService); -} diff --git a/adev/src/content/examples/ssr/src/app/mock-heroes.ts b/adev/src/content/examples/ssr/src/app/mock-heroes.ts deleted file mode 100644 index 8761b672e728..000000000000 --- a/adev/src/content/examples/ssr/src/app/mock-heroes.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Hero} from './hero'; - -export const HEROES: Hero[] = [ - {id: 12, name: 'Dr. Nice'}, - {id: 13, name: 'Bombasto'}, - {id: 14, name: 'Celeritas'}, - {id: 15, name: 'Magneta'}, - {id: 16, name: 'RubberMan'}, - {id: 17, name: 'Dynama'}, - {id: 18, name: 'Dr. IQ'}, - {id: 19, name: 'Magma'}, - {id: 20, name: 'Tornado'}, -]; diff --git a/adev/src/content/examples/ssr/src/index.html b/adev/src/content/examples/ssr/src/index.html deleted file mode 100644 index 5ddce3f5eb3b..000000000000 --- a/adev/src/content/examples/ssr/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Tour of Heroes - - - - - - - - diff --git a/adev/src/content/examples/ssr/src/main.server.ts b/adev/src/content/examples/ssr/src/main.server.ts deleted file mode 100644 index bd1c56ea01ce..000000000000 --- a/adev/src/content/examples/ssr/src/main.server.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {bootstrapApplication} from '@angular/platform-browser'; -import {AppComponent} from './app/app.component'; -import {config} from './app/app.config.server'; - -const bootstrap = () => bootstrapApplication(AppComponent, config); -export default bootstrap; diff --git a/adev/src/content/examples/ssr/src/main.ts b/adev/src/content/examples/ssr/src/main.ts deleted file mode 100644 index bf030b9489d3..000000000000 --- a/adev/src/content/examples/ssr/src/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {bootstrapApplication} from '@angular/platform-browser'; -import {AppComponent} from './app/app.component'; -import {appConfig} from './app/app.config'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)); diff --git a/adev/src/content/examples/ssr/tsconfig.app.json b/adev/src/content/examples/ssr/tsconfig.app.json deleted file mode 100644 index 7dc7284f6c98..000000000000 --- a/adev/src/content/examples/ssr/tsconfig.app.json +++ /dev/null @@ -1,18 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./out-tsc/app", - "types": [ - "node" - ] - }, - "files": [ - "src/main.ts", - "src/main.server.ts", - "server.ts" - ], - "include": [ - "src/**/*.d.ts" - ] -} diff --git a/adev/src/content/examples/ssr/zipper.json b/adev/src/content/examples/ssr/zipper.json deleted file mode 100644 index ce44927d99cc..000000000000 --- a/adev/src/content/examples/ssr/zipper.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "files": [ - "!dist/", - "!**/*.d.ts", - "!**/src/**/*.js" - ] -} diff --git a/adev/src/content/examples/structural-directives/src/app/app.component.html b/adev/src/content/examples/structural-directives/src/app/app.component.html index e02ce08a9af7..b609e6bb1d6e 100644 --- a/adev/src/content/examples/structural-directives/src/app/app.component.html +++ b/adev/src/content/examples/structural-directives/src/app/app.component.html @@ -167,49 +167,6 @@

    NgSwitch with <ng-template>


    - -

    UnlessDirective

    - -

    - The condition is currently - {{condition}}. - -

    - - - -

    - (A) This paragraph is displayed because the condition is false. -

    - -

    - (B) Although the condition is true, - this paragraph is displayed because appUnless is set to false. -

    - - - -

    UnlessDirective with template

    - - -

    Show this sentence unless the condition is true.

    - - -

    - (A) <p *appUnless="condition" class="code unless"> -

    - - -

    - (A) <ng-template [appUnless]="condition"> -

    -
    -

    IfLoadedDirective

    diff --git a/adev/src/content/examples/structural-directives/src/app/app.component.ts b/adev/src/content/examples/structural-directives/src/app/app.component.ts index 5d1962412323..f4f377a005c2 100644 --- a/adev/src/content/examples/structural-directives/src/app/app.component.ts +++ b/adev/src/content/examples/structural-directives/src/app/app.component.ts @@ -4,7 +4,6 @@ import {FormsModule} from '@angular/forms'; import {heroSwitchComponents} from './hero-switch.components'; import {HeroComponent} from './hero.component'; -import {UnlessDirective} from './unless.directive'; import {TrigonometryDirective} from './trigonometry.directive'; import {Hero, heroes} from './hero'; @@ -13,14 +12,7 @@ import {Hero, heroes} from './hero'; selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], - imports: [ - CommonModule, - FormsModule, - heroSwitchComponents, - HeroComponent, - UnlessDirective, - TrigonometryDirective, - ], + imports: [CommonModule, FormsModule, heroSwitchComponents, HeroComponent, TrigonometryDirective], }) export class AppComponent { heroes = heroes; diff --git a/adev/src/content/examples/structural-directives/src/app/hero-switch.components.ts b/adev/src/content/examples/structural-directives/src/app/hero-switch.components.ts index c97e15b21279..9d2b14c2e1d8 100644 --- a/adev/src/content/examples/structural-directives/src/app/hero-switch.components.ts +++ b/adev/src/content/examples/structural-directives/src/app/hero-switch.components.ts @@ -1,42 +1,42 @@ // #docregion -import {Component, Input} from '@angular/core'; +import {Component, computed, input} from '@angular/core'; import {Hero} from './hero'; @Component({ selector: 'app-happy-hero', - template: 'Wow. You like {{hero.name}}. What a happy hero ... just like you.', + template: 'Wow. You like {{hero().name}}. What a happy hero ... just like you.', }) export class HappyHeroComponent { - @Input() hero!: Hero; + readonly hero = input.required(); } @Component({ selector: 'app-sad-hero', - template: 'You like {{hero.name}}? Such a sad hero. Are you sad too?', + template: 'You like {{hero().name}}? Such a sad hero. Are you sad too?', }) export class SadHeroComponent { - @Input() hero!: Hero; + readonly hero = input.required(); } @Component({ selector: 'app-confused-hero', - template: 'Are you as confused as {{hero.name}}?', + template: 'Are you as confused as {{hero().name}}?', }) export class ConfusedHeroComponent { - @Input() hero!: Hero; + readonly hero = input.required(); } @Component({ selector: 'app-unknown-hero', - template: '{{message}}', + template: '{{message()}}', }) export class UnknownHeroComponent { - @Input() hero!: Hero; - get message() { - return this.hero && this.hero.name - ? `${this.hero.name} is strange and mysterious.` - : 'Are you feeling indecisive?'; - } + readonly hero = input.required(); + + readonly message = computed(() => { + const heroName = this.hero()?.name; + return heroName ? `${heroName} is strange and mysterious.` : 'Are you feeling indecisive?'; + }); } export const heroSwitchComponents = [ diff --git a/adev/src/content/examples/structural-directives/src/app/hero.component.ts b/adev/src/content/examples/structural-directives/src/app/hero.component.ts index 038037e7c12c..87c7070f9984 100644 --- a/adev/src/content/examples/structural-directives/src/app/hero.component.ts +++ b/adev/src/content/examples/structural-directives/src/app/hero.component.ts @@ -1,5 +1,5 @@ import {Component} from '@angular/core'; -import {CommonModule} from '@angular/common'; +import {JsonPipe} from '@angular/common'; import {IfLoadedDirective} from './if-loaded.directive'; @@ -12,7 +12,7 @@ import {Hero, heroes} from './hero';

    {{ heroLoadingState.data | json }}

    `, - imports: [CommonModule, IfLoadedDirective], + imports: [IfLoadedDirective, JsonPipe], }) export class HeroComponent { heroLoadingState: LoadingState = {type: 'loading'}; diff --git a/adev/src/content/examples/structural-directives/src/app/if-loaded.directive.ts b/adev/src/content/examples/structural-directives/src/app/if-loaded.directive.ts index 3225acb0ad2f..5fde1d5a6edb 100644 --- a/adev/src/content/examples/structural-directives/src/app/if-loaded.directive.ts +++ b/adev/src/content/examples/structural-directives/src/app/if-loaded.directive.ts @@ -1,4 +1,4 @@ -import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core'; +import {Directive, effect, input, TemplateRef, ViewContainerRef} from '@angular/core'; import {Loaded, LoadingState} from './loading-state'; @@ -8,20 +8,22 @@ import {Loaded, LoadingState} from './loading-state'; export class IfLoadedDirective { private isViewCreated = false; - @Input('appIfLoaded') set state(state: LoadingState) { - if (!this.isViewCreated && state.type === 'loaded') { - this.viewContainerRef.createEmbeddedView(this.templateRef); - this.isViewCreated = true; - } else if (this.isViewCreated && state.type !== 'loaded') { - this.viewContainerRef.clear(); - this.isViewCreated = false; - } - } + state = input.required>({alias: 'appIfLoaded'}); constructor( private readonly viewContainerRef: ViewContainerRef, private readonly templateRef: TemplateRef, - ) {} + ) { + effect(() => { + if (!this.isViewCreated && this.state().type === 'loaded') { + this.viewContainerRef.createEmbeddedView(this.templateRef); + this.isViewCreated = true; + } else if (this.isViewCreated && this.state().type !== 'loaded') { + this.viewContainerRef.clear(); + this.isViewCreated = false; + } + }); + } static ngTemplateGuard_appIfLoaded( dir: IfLoadedDirective, diff --git a/adev/src/content/examples/structural-directives/src/app/trigonometry.directive.ts b/adev/src/content/examples/structural-directives/src/app/trigonometry.directive.ts index 415e1a082b90..f209f0563da2 100644 --- a/adev/src/content/examples/structural-directives/src/app/trigonometry.directive.ts +++ b/adev/src/content/examples/structural-directives/src/app/trigonometry.directive.ts @@ -1,4 +1,4 @@ -import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core'; +import {Directive, effect, input, TemplateRef, ViewContainerRef} from '@angular/core'; @Directive({ selector: '[appTrigonometry]', @@ -7,22 +7,24 @@ export class TrigonometryDirective { private isViewCreated = false; private readonly context = new TrigonometryContext(); - @Input('appTrigonometry') set angle(angleInDegrees: number) { - const angleInRadians = toRadians(angleInDegrees); - this.context.sin = Math.sin(angleInRadians); - this.context.cos = Math.cos(angleInRadians); - this.context.tan = Math.tan(angleInRadians); - - if (!this.isViewCreated) { - this.viewContainerRef.createEmbeddedView(this.templateRef, this.context); - this.isViewCreated = true; - } - } + angleInDegrees = input.required({alias: 'appTrigonometry'}); constructor( private readonly viewContainerRef: ViewContainerRef, private readonly templateRef: TemplateRef, - ) {} + ) { + effect(() => { + const angleInRadians = toRadians(this.angleInDegrees()); + this.context.sin = Math.sin(angleInRadians); + this.context.cos = Math.cos(angleInRadians); + this.context.tan = Math.tan(angleInRadians); + + if (!this.isViewCreated) { + this.viewContainerRef.createEmbeddedView(this.templateRef, this.context); + this.isViewCreated = true; + } + }); + } // Make sure the template checker knows the type of the context with which the // template of this directive will be rendered diff --git a/adev/src/content/examples/structural-directives/src/app/unless.directive.ts b/adev/src/content/examples/structural-directives/src/app/unless.directive.ts deleted file mode 100644 index 0d5b9b56a12c..000000000000 --- a/adev/src/content/examples/structural-directives/src/app/unless.directive.ts +++ /dev/null @@ -1,53 +0,0 @@ -// #docplaster -// #docregion -// #docregion no-docs, skeleton -import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core'; - -// #enddocregion skeleton -/** - * Add the template content to the DOM unless the condition is true. -// #enddocregion no-docs - * - * If the expression assigned to `appUnless` evaluates to a truthy value - * then the templated elements are removed from the DOM, - * the templated elements are (re)inserted into the DOM. - * - *
    - * Congrats! Everything is great! - *
    - * - * ### Syntax - * - * - `
    ...
    ` - * - `
    ...
    ` - * -// #docregion no-docs - */ -// #docregion skeleton -@Directive({ - selector: '[appUnless]', -}) -export class UnlessDirective { - // #enddocregion skeleton - private hasView = false; - - // #docregion ctor - constructor( - private templateRef: TemplateRef, - private viewContainer: ViewContainerRef, - ) {} - // #enddocregion ctor - - // #docregion set - @Input() set appUnless(condition: boolean) { - if (!condition && !this.hasView) { - this.viewContainer.createEmbeddedView(this.templateRef); - this.hasView = true; - } else if (condition && this.hasView) { - this.viewContainer.clear(); - this.hasView = false; - } - } - // #enddocregion set - // #docregion skeleton -} diff --git a/adev/src/content/examples/testing/src/app/about/about.component.ts b/adev/src/content/examples/testing/src/app/about/about.component.ts index b49431c55e45..0d863133be08 100755 --- a/adev/src/content/examples/testing/src/app/about/about.component.ts +++ b/adev/src/content/examples/testing/src/app/about/about.component.ts @@ -8,7 +8,7 @@ import {TwainComponent} from '../twain/twain.component'; template: `

    About

    Quote of the day:

    - + `, imports: [TwainComponent, HighlightDirective], }) diff --git a/adev/src/content/examples/testing/src/app/app.component.html b/adev/src/content/examples/testing/src/app/app.component.html index d73c1162c034..c0d2670fab5e 100644 --- a/adev/src/content/examples/testing/src/app/app.component.html +++ b/adev/src/content/examples/testing/src/app/app.component.html @@ -1,6 +1,6 @@ - - + + - + diff --git a/adev/src/content/examples/testing/src/app/app.component.router.spec.ts b/adev/src/content/examples/testing/src/app/app.component.router.spec.ts index b25464e59b36..4b9c47bdb3f9 100755 --- a/adev/src/content/examples/testing/src/app/app.component.router.spec.ts +++ b/adev/src/content/examples/testing/src/app/app.component.router.spec.ts @@ -28,7 +28,6 @@ describe('AppComponent & router testing', () => { Object.assign({}, appConfig, { providers: [ {provide: HeroService, useClass: TestHeroService}, - UserService, TwainService, provideHttpClient(), provideLocationMocks(), diff --git a/adev/src/content/examples/testing/src/app/app.component.spec.ts b/adev/src/content/examples/testing/src/app/app.component.spec.ts index ae66f1302a20..a573f2c168bb 100755 --- a/adev/src/content/examples/testing/src/app/app.component.spec.ts +++ b/adev/src/content/examples/testing/src/app/app.component.spec.ts @@ -1,12 +1,13 @@ // #docplaster import {Component, DebugElement, NO_ERRORS_SCHEMA} from '@angular/core'; -import {ComponentFixture, fakeAsync, TestBed, tick, waitForAsync} from '@angular/core/testing'; +import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; -import {provideRouter, Router, RouterLink} from '@angular/router'; +import {provideRouter, Router, RouterLink, RouterOutlet} from '@angular/router'; import {AppComponent} from './app.component'; import {appConfig} from './app.config'; import {UserService} from './model'; +import {WelcomeComponent} from './welcome/welcome.component'; // #docregion component-stubs @Component({selector: 'app-banner', template: ''}) @@ -23,54 +24,67 @@ let comp: AppComponent; let fixture: ComponentFixture; describe('AppComponent & TestModule', () => { - beforeEach(waitForAsync(() => { + beforeEach(() => { // #docregion testbed-stubs TestBed.configureTestingModule( Object.assign({}, appConfig, { - imports: [ - AppComponent, - BannerStubComponent, - RouterLink, - RouterOutletStubComponent, - WelcomeStubComponent, - ], providers: [provideRouter([]), UserService], }), - ) - // #enddocregion testbed-stubs - - .then(() => { - fixture = TestBed.createComponent(AppComponent); - comp = fixture.componentInstance; - }); - })); + ).overrideComponent(AppComponent, { + set: { + imports: [BannerStubComponent, RouterLink, RouterOutletStubComponent, WelcomeStubComponent], + }, + }); + // #enddocregion testbed-stubs + + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + }); tests(); }); //////// Testing w/ NO_ERRORS_SCHEMA ////// describe('AppComponent & NO_ERRORS_SCHEMA', () => { - beforeEach(waitForAsync(() => { - // #docregion no-errors-schema, mixed-setup + beforeEach(() => { + // #docregion no-errors-schema TestBed.configureTestingModule( Object.assign({}, appConfig, { - imports: [ - AppComponent, - // #enddocregion no-errors-schema - BannerStubComponent, - // #docregion no-errors-schema - RouterLink, - ], providers: [provideRouter([]), UserService], + }), + ).overrideComponent(AppComponent, { + set: { + imports: [], // resets all imports schemas: [NO_ERRORS_SCHEMA], + }, + }); + // #enddocregion no-errors-schema + + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + }); + tests(); +}); + +describe('AppComponent & NO_ERRORS_SCHEMA', () => { + beforeEach(() => { + // #docregion mixed-setup + TestBed.configureTestingModule( + Object.assign({}, appConfig, { + providers: [provideRouter([]), UserService], }), - ) - // #enddocregion no-errors-schema, mixed-setup + ).overrideComponent(AppComponent, { + remove: { + imports: [RouterOutlet, WelcomeComponent], + }, + set: { + schemas: [NO_ERRORS_SCHEMA], + }, + }); + // #enddocregion mixed-setup - .then(() => { - fixture = TestBed.createComponent(AppComponent); - comp = fixture.componentInstance; - }); - })); + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + }); tests(); }); diff --git a/adev/src/content/examples/testing/src/app/banner/banner-external.component.spec.ts b/adev/src/content/examples/testing/src/app/banner/banner-external.component.spec.ts index 5febcddd4e4c..6badd6972b72 100755 --- a/adev/src/content/examples/testing/src/app/banner/banner-external.component.spec.ts +++ b/adev/src/content/examples/testing/src/app/banner/banner-external.component.spec.ts @@ -28,7 +28,7 @@ describe('BannerComponent (external files)', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [BannerComponent], - }); // compile template and css + }).compileComponents(); // compile template and css }); // #enddocregion async-before-each diff --git a/adev/src/content/examples/testing/src/app/banner/banner.component.spec.ts b/adev/src/content/examples/testing/src/app/banner/banner.component.spec.ts index 956c2755fa7a..34d043fbb6a7 100755 --- a/adev/src/content/examples/testing/src/app/banner/banner.component.spec.ts +++ b/adev/src/content/examples/testing/src/app/banner/banner.component.spec.ts @@ -11,9 +11,6 @@ describe('BannerComponent (inline template)', () => { let h1: HTMLElement; beforeEach(() => { - TestBed.configureTestingModule({ - imports: [BannerComponent], - }); fixture = TestBed.createComponent(BannerComponent); component = fixture.componentInstance; // BannerComponent test instance h1 = fixture.nativeElement.querySelector('h1'); diff --git a/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.spec.ts b/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.spec.ts index 16550730e7cb..13750e348209 100755 --- a/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.spec.ts +++ b/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.spec.ts @@ -109,7 +109,6 @@ describe('DashboardHeroComponent when inside a test host', () => { // #docregion test-host-setup TestBed.configureTestingModule({ providers: appProviders, - imports: [DashboardHeroComponent, TestHostComponent], }); // #enddocregion test-host-setup })); diff --git a/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.ts b/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.ts index 56729b6828d7..4036eea2bd35 100755 --- a/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.ts +++ b/adev/src/content/examples/testing/src/app/dashboard/dashboard-hero.component.ts @@ -17,8 +17,8 @@ import {Hero} from '../model/hero'; }) // #docregion class export class DashboardHeroComponent { - hero = input.required(); - selected = output(); + readonly hero = input.required(); + readonly selected = output(); click() { this.selected.emit(this.hero()); } diff --git a/adev/src/content/examples/testing/src/app/dashboard/dashboard.component.spec.ts b/adev/src/content/examples/testing/src/app/dashboard/dashboard.component.spec.ts index 47c3f06ffe47..1f3e02c9b170 100755 --- a/adev/src/content/examples/testing/src/app/dashboard/dashboard.component.spec.ts +++ b/adev/src/content/examples/testing/src/app/dashboard/dashboard.component.spec.ts @@ -69,7 +69,6 @@ function compileAndCreate() { // #docregion router-harness TestBed.configureTestingModule( Object.assign({}, appConfig, { - imports: [DashboardComponent], providers: [ provideRouter([{path: '**', component: DashboardComponent}]), provideHttpClient(), diff --git a/adev/src/content/examples/testing/src/app/demo/demo-main.ts b/adev/src/content/examples/testing/src/app/demo/demo-main.ts deleted file mode 100644 index 66b0ec18e1dd..000000000000 --- a/adev/src/content/examples/testing/src/app/demo/demo-main.ts +++ /dev/null @@ -1,5 +0,0 @@ -// main app entry point -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; -import {DemoModule} from './demo'; - -platformBrowserDynamic().bootstrapModule(DemoModule); diff --git a/adev/src/content/examples/testing/src/app/demo/demo.testbed.spec.ts b/adev/src/content/examples/testing/src/app/demo/demo.testbed.spec.ts index a0414808d42c..403eb656a7e5 100755 --- a/adev/src/content/examples/testing/src/app/demo/demo.testbed.spec.ts +++ b/adev/src/content/examples/testing/src/app/demo/demo.testbed.spec.ts @@ -268,7 +268,7 @@ describe('demo (with TestBed):', () => { input.value = expectedNewName; // that change doesn't flow to the component immediately - expect(comp.name) + expect(comp.name()) .withContext( `comp.name should still be ${expectedOrigName} after value change, before binding happens`, ) @@ -280,7 +280,7 @@ describe('demo (with TestBed):', () => { return fixture.whenStable(); }) .then(() => { - expect(comp.name) + expect(comp.name()) .withContext(`After ngModel updates the model, comp.name should be ${expectedNewName} `) .toBe(expectedNewName); }); @@ -571,134 +571,6 @@ describe('demo (with TestBed):', () => { expect(fixture).toHaveText('Parent(Fake Child(Fake Grandchild))'); }); }); - - describe('lifecycle hooks w/ MyIfParentComp', () => { - let fixture: ComponentFixture; - let parent: MyIfParentComponent; - let child: MyIfChildComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, MyIfChildComponent, MyIfParentComponent], - }); - - fixture = TestBed.createComponent(MyIfParentComponent); - parent = fixture.componentInstance; - }); - - it('should instantiate parent component', () => { - expect(parent).withContext('parent component should exist').not.toBeNull(); - }); - - it('parent component OnInit should NOT be called before first detectChanges()', () => { - expect(parent.ngOnInitCalled).toBe(false); - }); - - it('parent component OnInit should be called after first detectChanges()', () => { - fixture.detectChanges(); - expect(parent.ngOnInitCalled).toBe(true); - }); - - it('child component should exist after OnInit', () => { - fixture.detectChanges(); - getChild(); - expect(child instanceof MyIfChildComponent) - .withContext('should create child') - .toBe(true); - }); - - it("should have called child component's OnInit ", () => { - fixture.detectChanges(); - getChild(); - expect(child.ngOnInitCalled).toBe(true); - }); - - it('child component called OnChanges once', () => { - fixture.detectChanges(); - getChild(); - expect(child.ngOnChangesCounter).toBe(1); - }); - - it('changed parent value flows to child', () => { - fixture.detectChanges(); - getChild(); - - parent.parentValue = 'foo'; - fixture.detectChanges(); - - expect(child.ngOnChangesCounter) - .withContext('expected 2 changes: initial value and changed value') - .toBe(2); - expect(child.childValue).withContext('childValue should eq changed parent value').toBe('foo'); - }); - - // must be async test to see child flow to parent - it('changed child value flows to parent', waitForAsync(() => { - fixture.detectChanges(); - getChild(); - - child.childValue = 'bar'; - - return new Promise((resolve) => { - // Wait one JS engine turn! - setTimeout(() => resolve(), 0); - }).then(() => { - fixture.detectChanges(); - - expect(child.ngOnChangesCounter) - .withContext('expected 2 changes: initial value and changed value') - .toBe(2); - expect(parent.parentValue) - .withContext('parentValue should eq changed parent value') - .toBe('bar'); - }); - })); - - it('clicking "Close Child" triggers child OnDestroy', () => { - fixture.detectChanges(); - getChild(); - - const btn = fixture.debugElement.query(By.css('button')); - click(btn); - - fixture.detectChanges(); - expect(child.ngOnDestroyCalled).toBe(true); - }); - - ////// helpers /// - /** - * Get the MyIfChildComp from parent; fail w/ good message if cannot. - */ - function getChild() { - let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp - - // The Hard Way: requires detailed knowledge of the parent template - try { - childDe = fixture.debugElement.children[4].children[0]; - } catch (err) { - /* we'll report the error */ - } - - // DebugElement.queryAll: if we wanted all of many instances: - childDe = fixture.debugElement.queryAll( - (de) => de.componentInstance instanceof MyIfChildComponent, - )[0]; - - // WE'LL USE THIS APPROACH ! - // DebugElement.query: find first instance (if any) - childDe = fixture.debugElement.query( - (de) => de.componentInstance instanceof MyIfChildComponent, - ); - - if (childDe && childDe.componentInstance) { - child = childDe.componentInstance; - } else { - fail('Unable to find MyIfChildComp within MyIfParentComp'); - } - - return child; - } - }); }); ////////// Fakes /////////// diff --git a/adev/src/content/examples/testing/src/app/demo/demo.ts b/adev/src/content/examples/testing/src/app/demo/demo.ts index b36060d0ad43..81b49880f8cc 100755 --- a/adev/src/content/examples/testing/src/app/demo/demo.ts +++ b/adev/src/content/examples/testing/src/app/demo/demo.ts @@ -9,15 +9,15 @@ import { HostListener, inject, Injectable, - Input, + input, + output, OnChanges, OnDestroy, OnInit, - Optional, - Output, Pipe, PipeTransform, SimpleChanges, + signal, } from '@angular/core'; import {FormsModule} from '@angular/forms'; import {of} from 'rxjs'; @@ -84,11 +84,11 @@ export class ReversePipe implements PipeTransform { //////////// Components ///////////// @Component({ selector: 'bank-account', - template: ` Bank Name: {{ bank }} Account Id: {{ id }} `, + template: ` Bank Name: {{ bank() }} Account Id: {{ id() }} `, }) export class BankAccountComponent { - @Input() bank = ''; - @Input('account') id = ''; + bank = input(''); + id = input('', {alias: 'account'}); } /** A component with attributes, styles, classes, and property setting */ @@ -131,18 +131,18 @@ export class LightswitchComponent { @Component({ selector: 'child-1', - template: 'Child-1({{text}})', + template: 'Child-1({{text()}})', }) export class Child1Component { - @Input() text = 'Original'; + text = input('Original'); } @Component({ selector: 'child-2', - template: '
    Child-2({{text}})
    ', + template: '
    Child-2({{text()}})
    ', }) export class Child2Component { - @Input() text = ''; + text = input(''); } @Component({ @@ -150,7 +150,7 @@ export class Child2Component { template: '
    Child-3({{text}})
    ', }) export class Child3Component { - @Input() text = ''; + text = input(''); } @Component({ @@ -159,35 +159,7 @@ export class Child3Component { imports: [FormsModule], }) export class InputComponent { - name = 'John'; -} - -/* Prefer this metadata syntax */ -// @Directive({ -// selector: 'input[value]', -// host: { -// '[value]': 'value', -// '(input)': 'valueChange.emit($event.target.value)' -// }, -// inputs: ['value'], -// outputs: ['valueChange'] -// }) -// export class InputValueBinderDirective { -// value: any; -// valueChange: EventEmitter = new EventEmitter(); -// } - -// As the styleguide recommends -@Directive({selector: 'input[value]'}) -export class InputValueBinderDirective { - @HostBinding() @Input() value: any; - - @Output() valueChange: EventEmitter = new EventEmitter(); - - @HostListener('input', ['$event.target.value']) - onInput(value: any) { - this.valueChange.emit(value); - } + name = signal('John'); } @Component({ @@ -207,11 +179,13 @@ export class ParentComponent {} @Component({ selector: 'io-comp', - template: '', + template: + '', }) export class IoComponent { - @Input() hero!: Hero; - @Output() selected = new EventEmitter(); + readonly hero = input.required(); + readonly selected = output(); + click() { this.selected.emit(this.hero); } @@ -293,99 +267,6 @@ export class NeedsContentComponent { @ContentChildren('content') children: any; } -///////// MyIfChildComp //////// -@Component({ - selector: 'my-if-child-1', - template: `

    MyIfChildComp

    -
    - -
    -

    Change log:

    - @for (log of changeLog; track log; let i = $index) { -
    {{ i + 1 }} - {{ log }}
    - }`, - imports: [FormsModule, sharedImports], -}) -export class MyIfChildComponent implements OnInit, OnChanges, OnDestroy { - @Input() value = ''; - @Output() valueChange = new EventEmitter(); - - get childValue() { - return this.value; - } - set childValue(v: string) { - if (this.value === v) { - return; - } - this.value = v; - this.valueChange.emit(v); - } - - changeLog: string[] = []; - - ngOnInitCalled = false; - ngOnChangesCounter = 0; - ngOnDestroyCalled = false; - - ngOnInit() { - this.ngOnInitCalled = true; - this.changeLog.push('ngOnInit called'); - } - - ngOnDestroy() { - this.ngOnDestroyCalled = true; - this.changeLog.push('ngOnDestroy called'); - } - - ngOnChanges(changes: SimpleChanges) { - for (const propName in changes) { - this.ngOnChangesCounter += 1; - const prop = changes[propName]; - const cur = JSON.stringify(prop.currentValue); - const prev = JSON.stringify(prop.previousValue); - this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); - } - } -} - -///////// MyIfParentComp //////// - -@Component({ - selector: 'my-if-parent-comp', - template: ` -

    MyIfParentComp

    - -
    - @if (showChild) { -
    - -
    - } - `, - imports: [FormsModule, MyIfChildComponent, sharedImports], -}) -export class MyIfParentComponent implements OnInit { - ngOnInitCalled = false; - parentValue = 'Hello, World'; - showChild = false; - toggleLabel = 'Unknown'; - - ngOnInit() { - this.ngOnInitCalled = true; - this.clicked(); - } - - clicked() { - this.showChild = !this.showChild; - this.toggleLabel = this.showChild ? 'Close' : 'Show'; - } -} - @Component({ selector: 'reverse-pipe-comp', template: ` @@ -448,7 +329,6 @@ export class ShellComponent {} LightswitchComponent, NeedsContentComponent, ReversePipeComponent, - MyIfParentComponent, ], }) export class DemoComponent {} diff --git a/adev/src/content/examples/testing/src/app/hero/hero-detail.component.ts b/adev/src/content/examples/testing/src/app/hero/hero-detail.component.ts index 21d5081b3307..c7e1d51293a1 100755 --- a/adev/src/content/examples/testing/src/app/hero/hero-detail.component.ts +++ b/adev/src/content/examples/testing/src/app/hero/hero-detail.component.ts @@ -13,7 +13,7 @@ import {HeroDetailService} from './hero-detail.service'; templateUrl: './hero-detail.component.html', styleUrls: ['./hero-detail.component.css'], providers: [HeroDetailService], - imports: [sharedImports, RouterLink], + imports: [...sharedImports], }) export class HeroDetailComponent { // #docregion inject diff --git a/adev/src/content/examples/testing/src/app/shared/canvas.component.spec.ts b/adev/src/content/examples/testing/src/app/shared/canvas.component.spec.ts index c1127063e215..3d8f0006427d 100755 --- a/adev/src/content/examples/testing/src/app/shared/canvas.component.spec.ts +++ b/adev/src/content/examples/testing/src/app/shared/canvas.component.spec.ts @@ -17,12 +17,6 @@ describe('CanvasComponent', () => { }); // #enddocregion enable-toBlob-macrotask // #docregion without-toBlob-macrotask - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [CanvasComponent], - }); - }); - it('should be able to generate blob data from canvas', fakeAsync(() => { const fixture = TestBed.createComponent(CanvasComponent); const canvasComp = fixture.componentInstance; diff --git a/adev/src/content/examples/testing/src/app/shared/highlight.directive.ts b/adev/src/content/examples/testing/src/app/shared/highlight.directive.ts index 3a1555e1df70..858d38436604 100755 --- a/adev/src/content/examples/testing/src/app/shared/highlight.directive.ts +++ b/adev/src/content/examples/testing/src/app/shared/highlight.directive.ts @@ -1,6 +1,6 @@ /* eslint-disable @angular-eslint/directive-selector */ // #docregion -import {Directive, ElementRef, inject, Input, OnChanges} from '@angular/core'; +import {Directive, ElementRef, inject, input, OnChanges} from '@angular/core'; @Directive({selector: '[highlight]'}) /** @@ -10,7 +10,7 @@ import {Directive, ElementRef, inject, Input, OnChanges} from '@angular/core'; export class HighlightDirective implements OnChanges { defaultColor = 'rgb(211, 211, 211)'; // lightgray - @Input('highlight') bgColor = ''; + bgColor = input('', {alias: 'highlight'}); private el = inject(ElementRef); diff --git a/adev/src/content/examples/testing/src/app/shared/shared.ts b/adev/src/content/examples/testing/src/app/shared/shared.ts index 98c8dbec0b3c..01bf42aa126a 100755 --- a/adev/src/content/examples/testing/src/app/shared/shared.ts +++ b/adev/src/content/examples/testing/src/app/shared/shared.ts @@ -2,6 +2,5 @@ import {FormsModule} from '@angular/forms'; import {HighlightDirective} from './highlight.directive'; import {TitleCasePipe} from './title-case.pipe'; -import {NgFor, NgIf} from '@angular/common'; -export const sharedImports = [FormsModule, HighlightDirective, TitleCasePipe, NgIf, NgFor]; +export const sharedImports = [FormsModule, HighlightDirective, TitleCasePipe]; diff --git a/adev/src/content/examples/testing/src/app/twain/twain.component.spec.ts b/adev/src/content/examples/testing/src/app/twain/twain.component.spec.ts index b2336adde877..874c1f677288 100755 --- a/adev/src/content/examples/testing/src/app/twain/twain.component.spec.ts +++ b/adev/src/content/examples/testing/src/app/twain/twain.component.spec.ts @@ -26,7 +26,6 @@ describe('TwainComponent', () => { // #docregion setup beforeEach(() => { TestBed.configureTestingModule({ - imports: [TwainComponent], providers: [TwainService], }); testQuote = 'Test Quote'; diff --git a/adev/src/content/examples/v21-game-world/e2e/src/app.e2e-spec.ts b/adev/src/content/examples/v21-game-world/e2e/src/app.e2e-spec.ts new file mode 100644 index 000000000000..2b018bbf1f42 --- /dev/null +++ b/adev/src/content/examples/v21-game-world/e2e/src/app.e2e-spec.ts @@ -0,0 +1,172 @@ +import {browser, element, by, Key, ExpectedConditions} from 'protractor'; + +describe('Angular v21 World', () => { + beforeEach(() => browser.get('')); + + async function getCharacterPosition(): Promise<{x: string; y: string}> { + const character = element(by.css('.character')); + const left = await character.getCssValue('left'); + const top = await character.getCssValue('top'); + return {x: left, y: top}; + } + + it('should display the initial game state correctly', async () => { + // Character is visible + expect(await element(by.css('.character')).isDisplayed()).toBe(true); + + // Info sign is shown with welcome message + const infoSign = element(by.css('.info-sign')); + expect(await infoSign.isDisplayed()).toBe(true); + expect(await infoSign.getAttribute('src')).toContain('welcome-sign.png'); + + // D-pad is visible + expect(await element(by.css('.d-pad')).isDisplayed()).toBe(true); + + // Explore button is not visible + expect(await element(by.css('.explore-button')).isPresent()).toBe(false); + + // No keys are present + expect(await element.all(by.css('.key-icon')).count()).toBe(0); + }); + + it('should move the character with the D-pad buttons', async () => { + const initialPosition = await getCharacterPosition(); + const leftButton = element(by.css('.d-pad-button.left')); + + // Hold the button down for a short period to simulate walking + await browser.actions().mouseDown(leftButton).perform(); + await browser.sleep(200); + await browser.actions().mouseUp(leftButton).perform(); + + const newPosition = await getCharacterPosition(); + expect(newPosition.x).not.toEqual(initialPosition.x); + }); + + it('should move the character with keyboard arrow keys', async () => { + const initialPosition = await getCharacterPosition(); + + // Send arrow key press + await browser.actions().sendKeys(Key.ARROW_RIGHT).perform(); + await browser.sleep(200); // Allow time for movement + await browser.actions().sendKeys(Key.NULL).perform(); // Release key + + const newPosition = await getCharacterPosition(); + expect(newPosition.x).not.toEqual(initialPosition.x); + }); + + it('should show explore button, open dialog, and collect a key when a destination is reached', async () => { + const body = element(by.css('body')); + const exploreButton = element(by.css('.explore-button')); + const dialog = element(by.css('.dialog-overlay')); + + // Move left until we reach the Palm Tree destination + for (let i = 0; i < 20; i++) { + await body.sendKeys(Key.ARROW_LEFT); + await browser.sleep(100); + } + + // Wait for the explore button to appear and check info sign + await browser.wait(ExpectedConditions.visibilityOf(exploreButton), 5000); + expect(await exploreButton.isDisplayed()).toBe(true); + expect(await element(by.css('.info-sign')).getAttribute('src')).toContain('enter-sign.png'); + + // Click explore button to open dialog + await exploreButton.click(); + await browser.wait(ExpectedConditions.visibilityOf(dialog), 1000); + expect(await dialog.isDisplayed()).toBe(true); + expect(await dialog.element(by.css('h2')).getText()).toEqual("What's new in Angular AI"); + + // Close the dialog + await dialog.element(by.css('.close-button')).click(); + await browser.wait(ExpectedConditions.invisibilityOf(dialog), 1000); + expect(await dialog.isPresent()).toBe(false); + + // Check that one key has been collected + expect(await element.all(by.css('.key-icon')).count()).toBe(1); + }); + + it('should show entry denied at castle without all keys', async () => { + const body = element(by.css('body')); + const exploreButton = element(by.css('.explore-button')); + + // Move to a position near the castle without collecting keys + for (let i = 0; i < 20; i++) (await body.sendKeys(Key.ARROW_RIGHT), await browser.sleep(100)); + for (let i = 0; i < 20; i++) (await body.sendKeys(Key.ARROW_DOWN), await browser.sleep(100)); + + await browser.sleep(1000); // Settle + + // Check that the entry denied sign is shown and the button is not present + expect(await element(by.css('.info-sign')).getAttribute('src')).toContain( + 'entry-denied-sign.png', + ); + expect(await exploreButton.isPresent()).toBe(false); + }); + + it('should handle the full game flow and show congrats state', async () => { + const body = element(by.css('body')); + const exploreButton = element(by.css('.explore-button')); + const dialog = element(by.css('.dialog-overlay')); + const keys = element.all(by.css('.key-icon')); + const mascot = element(by.css('.mascot-icon')); + + // **Navigate to Palm Tree (d1) and collect the first key** + for (let i = 0; i < 20; i++) { + await body.sendKeys(Key.ARROW_LEFT); + await browser.sleep(100); + } + await browser.wait(ExpectedConditions.visibilityOf(exploreButton), 5000); + await exploreButton.click(); + await browser.wait(ExpectedConditions.visibilityOf(dialog), 1000); + await dialog.element(by.css('.close-button')).click(); + await browser.wait(ExpectedConditions.invisibilityOf(dialog), 1000); + expect(await keys.count()).toBe(1); + + // **Navigate to Red Door (d2) and collect the second key** + for (let i = 0; i < 15; i++) { + await body.sendKeys(Key.ARROW_UP); + await browser.sleep(100); + } + await browser.wait(ExpectedConditions.visibilityOf(exploreButton), 5000); + await exploreButton.click(); + await browser.wait(ExpectedConditions.visibilityOf(dialog), 1000); + await dialog.element(by.css('.close-button')).click(); + await browser.wait(ExpectedConditions.invisibilityOf(dialog), 1000); + expect(await keys.count()).toBe(2); + + // **Navigate to Volcano (d3) and collect the third key** + for (let i = 0; i < 25; i++) { + await body.sendKeys(Key.ARROW_RIGHT); + await browser.sleep(100); + } + await browser.wait(ExpectedConditions.visibilityOf(exploreButton), 5000); + await exploreButton.click(); + await browser.wait(ExpectedConditions.visibilityOf(dialog), 1000); + await dialog.element(by.css('.close-button')).click(); + await browser.wait(ExpectedConditions.invisibilityOf(dialog), 1000); + expect(await keys.count()).toBe(3); + + // **Navigate to Castle (d4) with all keys** + for (let i = 0; i < 15; i++) { + await body.sendKeys(Key.ARROW_DOWN); + await browser.sleep(100); + } + await browser.sleep(1000); // Wait for character to settle + + // Check for correct sign and button visibility + expect(await element(by.css('.info-sign')).getAttribute('src')).toContain('castle-sign.png'); + await browser.wait(ExpectedConditions.visibilityOf(exploreButton), 5000); + + // **Open Castle dialog, close it, and see mascot and final sign** + await exploreButton.click(); + await browser.wait(ExpectedConditions.visibilityOf(dialog), 1000); + await dialog.element(by.css('.close-button')).click(); + await browser.wait(ExpectedConditions.invisibilityOf(dialog), 1000); + + // Mascot appears + await browser.wait(ExpectedConditions.visibilityOf(mascot), 1000); + expect(await mascot.isDisplayed()).toBe(true); + + // Congrats sign appears + expect(await element(by.css('.info-sign')).getAttribute('src')).toContain('congrats-sign.png'); + }); +}); diff --git a/adev/src/content/examples/setup/example-config.json b/adev/src/content/examples/v21-game-world/example-config.json similarity index 100% rename from adev/src/content/examples/setup/example-config.json rename to adev/src/content/examples/v21-game-world/example-config.json diff --git a/adev/src/content/examples/v21-game-world/src/app/app.ts b/adev/src/content/examples/v21-game-world/src/app/app.ts new file mode 100644 index 000000000000..039a95d86db2 --- /dev/null +++ b/adev/src/content/examples/v21-game-world/src/app/app.ts @@ -0,0 +1,723 @@ +import {ChangeDetectionStrategy, Component, computed, effect, inject, signal} from '@angular/core'; +import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser'; + +// 1. INTERFACES +interface Point { + x: number; + y: number; +} + +interface Destination { + id: string; + name: string; + position: Point; + videoUrl: string; + display: string; +} + +interface RoadSegment { + id: string; + orientation: 'horizontal' | 'vertical'; + fixedCoordinate: number; + start: number; + end: number; +} + +type WalkingDirection = 'left' | 'right' | 'up' | 'down' | null; + +const STAND = 'assets/images/v21-event/mascot.png'; +const WALK_LEFT_1 = 'assets/images/v21-event/mascot-left-1.png'; +const WALK_LEFT_2 = 'assets/images/v21-event/mascot-left-2.png'; +const WALK_RIGHT_1 = 'assets/images/v21-event/mascot-right-1.png'; +const WALK_RIGHT_2 = 'assets/images/v21-event/mascot-right-2.png'; +const WALK_UP_1 = 'assets/images/v21-event/mascot-up-1.png'; +const WALK_UP_2 = 'assets/images/v21-event/mascot-up-2.png'; +const WALK_DOWN_1 = 'assets/images/v21-event/mascot-down-1.png'; +const WALK_DOWN_2 = 'assets/images/v21-event/mascot-down-2.png'; + +// Define all unique coordinates as constants for readability and maintanence. +const START_X = 0.45; +const LEFT_X = 0.19; +const RIGHT_X = 0.85; +const PALM_TREE_X = LEFT_X; +const RED_DOOR_X = LEFT_X; // Aligned with Palm Tree for a straight vertical path +const VOLCANO_X = RIGHT_X; +const CASTLE_X = RIGHT_X; + +const BOTTOM_Y = 0.6; +const TOP_Y = 0.2; +const RED_DOOR_Y = TOP_Y; +const VOLCANO_Y = TOP_Y; +const PALM_TREE_Y = BOTTOM_Y; +const START_Y = BOTTOM_Y; +const CASTLE_Y = 0.7; + +// 2. GAME DATA CONSTANTS +const STARTING_POINT: Point = {x: START_X, y: START_Y}; + +const DESTINATIONS: Destination[] = [ + { + id: 'd1', + name: 'Palm Tree', + position: {x: PALM_TREE_X, y: PALM_TREE_Y}, + videoUrl: 'https://www.youtube.com/embed/FteCOhQb4Ow', + display: "What's new in Angular AI", + }, + { + id: 'd2', + name: 'Red Door', + position: {x: RED_DOOR_X, y: RED_DOOR_Y}, + videoUrl: 'https://www.youtube.com/embed/Cegc5JtWbrI', + display: 'Meet Angular Aria', + }, + { + id: 'd3', + name: 'Volcano', + position: {x: VOLCANO_X, y: VOLCANO_Y}, + videoUrl: 'https://www.youtube.com/embed/7v8mIW9_NXw', + display: 'Introducing Signal Forms', + }, + { + id: 'd4', + name: 'Castle', + position: {x: CASTLE_X, y: CASTLE_Y}, + videoUrl: 'https://www.youtube.com/embed/wiWUpCsJ9Os', + display: "Say hello to Angular's new Mascot!", + }, +]; + +const ALL_ROAD_SEGMENTS: RoadSegment[] = [ + // Road 1 (Dest 1 <-> Start) + { + id: 'r1', + orientation: 'horizontal', + fixedCoordinate: PALM_TREE_Y, + start: PALM_TREE_X, + end: START_X, + }, + // Road 2 (Palm Tree <-> Red Door) + { + id: 'r2', + orientation: 'vertical', + fixedCoordinate: PALM_TREE_X, + start: RED_DOOR_Y, + end: PALM_TREE_Y, + }, + // Road 3 (Dest 2 <-> Dest 3) + { + id: 'r3', + orientation: 'horizontal', + fixedCoordinate: RED_DOOR_Y, + start: RED_DOOR_X, + end: VOLCANO_X, + }, + // Road 4 (Dest 3 <-> Dest 4) + {id: 'r4', orientation: 'vertical', fixedCoordinate: VOLCANO_X, start: VOLCANO_Y, end: CASTLE_Y}, +]; + +// 3. GAME MECHANICS CONSTANTS +const MOVE_STEP = 0.0025; +const ANIMATION_SPEED = 28; // Higher is slower. Update image every 10 frames. +// How far off a road's axis the character can be +const MOVE_TOLERANCE = 0.002; +// How close to a destination to "arrive" (must be very small) +const DESTINATION_TOLERANCE = 0.005; + +@Component({ + selector: 'app-root', + template: ` +
    + +
    + @for (key of keysToShow(); track key) { + + } + @if (showMascot()) { + + } +
    + + + @if (!isDialogOpen()) { +
    + } + + + @for (dest of destinations(); track dest.id) { +
    + } + + +
    + + + + +
    + + + @if (!isDialogOpen()) { + Info Sign + } + + + @if (isDialogOpen()) { +
    +
    + +

    {{ activeDestination()?.display }}

    + @if (safeVideoUrl(); as url) { + + } + +
    +
    + } + + @if (activeDestination() && (activeDestination()?.id !== 'd4' || allKeysCollected())) { + + } +
    + `, + styles: [ + ` + .keys-container { + position: absolute; + top: 1cqw; + left: 1cqw; + display: flex; + z-index: 20; + } + + .key-icon { + width: 4cqw; + height: 5cqw; + } + + .mascot-icon { + width: 4cqw; + height: 5cqw; + margin-left: 1cqw; + } + + .key-enter-animation { + animation: growIn 0.5s ease-in-out; + } + + @keyframes growIn { + from { + transform: scale(0.1); + } + to { + transform: scale(1); + } + } + + :host { + display: block; + width: 100%; + height: 100%; + } + + .game-container { + width: 100%; + aspect-ratio: 16 / 9; + position: relative; + overflow: hidden; + background-size: 100% 100%; + background-repeat: no-repeat; + background-color: #3a3a3a; /* Fallback color */ + container-type: inline-size; + container-name: game-container; + } + + .character { + z-index: 10; + position: absolute; + width: 9cqw; + height: 9cqw; + background-size: contain; + background-repeat: no-repeat; + background-position: center; + transform: translate(-50%, -60%); + } + + .destination-hotspot { + position: absolute; + width: 4cqw; + height: 4cqw; + border-radius: 50%; + transform: translate(-50%, -10%); + transition: all 0.3s ease; + } + + .destination-hotspot.glowing { + background-color: rgba(255, 0, 242, 0.5); + box-shadow: 0 0 5px 15px rgba(255, 0, 242, 0.7); + } + + .d-pad { + position: absolute; + bottom: 2cqw; + left: 2cqw; + width: 12cqw; + height: 12cqw; + display: grid; + grid-template-areas: + '. up .' + 'left . right' + '. down .'; + grid-template-rows: 1fr 1fr 1fr; + grid-template-columns: 1fr 1fr 1fr; + gap: 0.5cqw; + z-index: 20; + } + + .d-pad-button { + background-color: rgba(0, 0, 0, 0.5); + border: none; + border-radius: 0.5cqw; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: background-color 0.2s; + touch-action: manipulation; /* Prevent double tap zoom */ + color: white; + font-size: 2.5cqw; + font-weight: bold; + } + + .d-pad-button:hover, + .d-pad-button:active { + background-color: rgba(0, 0, 0, 0.8); + } + + .d-pad-button.up { + grid-area: up; + } + .d-pad-button.down { + grid-area: down; + } + .d-pad-button.left { + grid-area: left; + } + .d-pad-button.right { + grid-area: right; + } + + .info-sign { + position: absolute; + top: 69%; + left: 50%; + transform: translate(-50%, 0%); + width: 50cqw; + height: 18cqw; + object-fit: contain; /* Ensures the image fits within the bounds */ + } + + .dialog-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.6); + z-index: 1000; + } + + .dialog-content { + position: absolute; + top: 70%; + left: 50%; + transform: translate(-50%, -80%); + background: white; + border-radius: 5px; + color: black; + text-align: center; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); + width: 60%; + height: 76%; + padding: 1rem; + box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: center; + } + + .dialog-content h2 { + margin-top: 0; + margin-bottom: 1rem; + font-family: 'Jersey 10', sans-serif; + } + + .dialog-content iframe { + width: 100%; + flex-grow: 1; + border: none; + border-radius: 8px; + } + + .close-button { + margin-top: 1rem; + padding: 10px 20px; + border: none; + background-color: #5c44e4; + color: white; + border-radius: 5px; + cursor: pointer; + font-size: 1rem; + transition: background-color 0.3s ease; + } + + .close-button:hover { + background-color: #8514f5; + } + + .close-icon { + position: absolute; + top: 10px; + right: 10px; + background: transparent; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: #888; + padding: 5px; + line-height: 1; + } + + .close-icon:hover { + color: #000; + } + + .explore-button { + position: absolute; + bottom: 2cqw; + right: 2cqw; + padding: 1.5cqw 3cqw; + background-color: #e90464; + color: white; + border: 2px solid white; /* White border */ + border-radius: 1cqw; + font-size: 2cqw; + font-weight: bold; + cursor: pointer; + transition: background-color 0.2s, opacity 0.3s ease-in-out, visibility 0.3s ease-in-out; + z-index: 20; + opacity: 0; + visibility: hidden; + pointer-events: none; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + } + + .explore-button:hover { + background-color: #c20354; + } + + /* When activeDestination() is true, the button is in the DOM */ + @if (activeDestination()) { + .explore-button { + opacity: 1; + visibility: visible; + pointer-events: auto; + } + } + `, + ], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '(window:keydown)': 'handleKeydown($event)', + '(window:keyup)': 'handleKeyup($event)', + }, +}) +export class App { + characterPosition = signal(STARTING_POINT); + isDialogOpen = signal(false); + visitedKeyDestinations = signal>(new Set()); + keysToShow = computed(() => Array.from(this.visitedKeyDestinations())); + allKeysCollected = computed(() => this.keysToShow().length === 3); + showMascot = signal(false); + destinations = signal(DESTINATIONS); + walkingDirection = signal(null); + walkFrame = signal(0); + characterImageUrl = computed(() => { + if (this.activeDestination()) { + return STAND; + } + + const direction = this.walkingDirection(); + const frame = this.walkFrame(); + const animationFrame = Math.floor(frame / ANIMATION_SPEED) % 2; + switch (direction) { + case 'left': + return animationFrame === 0 ? WALK_LEFT_1 : WALK_LEFT_2; + case 'right': + return animationFrame === 0 ? WALK_RIGHT_1 : WALK_RIGHT_2; + case 'up': + return animationFrame === 0 ? WALK_UP_1 : WALK_UP_2; + case 'down': + return animationFrame === 0 ? WALK_DOWN_1 : WALK_DOWN_2; + default: + return STAND; + } + }); + safeVideoUrl = signal(null); + pressedKeys = signal>(new Set()); + + infoSignImageUrl = computed(() => { + const activeDest = this.activeDestination(); + if (this.allKeysCollected() && this.showMascot()) { + return 'assets/images/v21-event/congrats-sign.png'; + } else if (!activeDest) { + return 'assets/images/v21-event/welcome-sign.png'; + } else if (activeDest.name === 'Castle') { + return this.allKeysCollected() + ? 'assets/images/v21-event/castle-sign.png' + : 'assets/images/v21-event/entry-denied-sign.png'; + } else { + return 'assets/images/v21-event/enter-sign.png'; + } + }); + + private sanitizer = inject(DomSanitizer); + + constructor() { + effect(() => { + const destination = this.activeDestination(); + if (destination?.videoUrl) { + this.safeVideoUrl.set(this.sanitizer.bypassSecurityTrustResourceUrl(destination.videoUrl)); + } else { + this.safeVideoUrl.set(null); + } + }); + + this.gameLoop(); + } + + gameLoop() { + const keys = this.pressedKeys(); + if (!this.isDialogOpen()) { + const currentPos = this.characterPosition(); + let newPos = {...currentPos}; + let moveDirection: 'horizontal' | 'vertical' | null = null; + + if (keys.has('ArrowUp')) { + newPos.y -= MOVE_STEP; + moveDirection = 'vertical'; + this.walkingDirection.set('up'); + } else if (keys.has('ArrowDown')) { + newPos.y += MOVE_STEP; + moveDirection = 'vertical'; + this.walkingDirection.set('down'); + } else if (keys.has('ArrowLeft')) { + newPos.x -= MOVE_STEP; + moveDirection = 'horizontal'; + this.walkingDirection.set('left'); + } else if (keys.has('ArrowRight')) { + newPos.x += MOVE_STEP; + moveDirection = 'horizontal'; + this.walkingDirection.set('right'); + } else { + this.walkingDirection.set(null); + } + + if (moveDirection && this.isMoveAllowed(currentPos, newPos, moveDirection)) { + this.characterPosition.set(newPos); + this.walkFrame.update((frame) => frame + 1); + } + } + + requestAnimationFrame(() => this.gameLoop()); + } + + // 5. COMPUTED SIGNALS (DERIVED STATE) + characterXPercent = computed(() => this.characterPosition().x * 100); + characterYPercent = computed(() => this.characterPosition().y * 100); + + activeDestination = computed(() => { + const pos = this.characterPosition(); + for (const dest of this.destinations()) { + const distance = Math.sqrt( + Math.pow(pos.x - dest.position.x, 2) + Math.pow(pos.y - dest.position.y, 2), + ); + if (distance < DESTINATION_TOLERANCE) { + return dest; + } + } + return null; + }); + + // 6. EVENT HANDLERS & METHODS + handleKeydown(event: KeyboardEvent) { + if (this.isDialogOpen() && event.key !== 'Escape') { + return; + } + + this.preventArrowDefault(event); + this.pressedKeys.update((keys) => keys.add(event.key)); + + if ( + event.key === 'Enter' && + this.activeDestination() && + (this.activeDestination()?.id !== 'd4' || this.allKeysCollected()) + ) { + this.isDialogOpen.set(true); + } + if (event.key === 'Escape' && this.isDialogOpen()) { + this.closeDialog(); + } + } + + handleKeyup(event: KeyboardEvent) { + this.preventArrowDefault(event); + this.pressedKeys.update((keys) => { + keys.delete(event.key); + return keys; + }); + } + + preventArrowDefault(event: KeyboardEvent) { + const arrowKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']; + if (arrowKeys.includes(event.key)) { + event.preventDefault(); + } + } + + handleButtonPress(key: string) { + this.pressedKeys.update((keys) => keys.add(key)); + } + + handleButtonRelease(key: string) { + this.pressedKeys.update((keys) => { + keys.delete(key); + return keys; + }); + } + + closeDialog(): void { + const activeDest = this.activeDestination(); + if (activeDest && ['d1', 'd2', 'd3'].includes(activeDest.id)) { + this.visitedKeyDestinations.update((visited) => { + if (!visited.has(activeDest.id)) { + visited.add(activeDest.id); + return new Set(visited); // Return new Set to trigger update + } + return visited; + }); + } + + if (activeDest?.id === 'd4' && this.allKeysCollected()) { + this.showMascot.set(true); + } + + this.isDialogOpen.set(false); + } + + private isMoveAllowed( + currentPos: Point, + newPos: Point, + direction: 'horizontal' | 'vertical', + ): boolean { + // Find the road the character is currently on by checking the axis perpendicular to movement. + let currentRoad: RoadSegment | null = null; + let minDistance = Infinity; + + for (const road of ALL_ROAD_SEGMENTS) { + if (direction === 'horizontal' && road.orientation === 'horizontal') { + const distance = Math.abs(currentPos.y - road.fixedCoordinate); + if (distance < minDistance) { + minDistance = distance; + currentRoad = road; + } + } else if (direction === 'vertical' && road.orientation === 'vertical') { + const distance = Math.abs(currentPos.x - road.fixedCoordinate); + if (distance < minDistance) { + minDistance = distance; + currentRoad = road; + } + } + } + + // If no road is close enough, movement is not allowed. + if (!currentRoad || minDistance > MOVE_TOLERANCE) { + return false; + } + + // Check if the new position is within the bounds of the identified road. + if (currentRoad.orientation === 'horizontal') { + return ( + newPos.x >= Math.min(currentRoad.start, currentRoad.end) - MOVE_TOLERANCE && + newPos.x <= Math.max(currentRoad.start, currentRoad.end) + MOVE_TOLERANCE + ); + } else { + // Vertical + return ( + newPos.y >= Math.min(currentRoad.start, currentRoad.end) - MOVE_TOLERANCE && + newPos.y <= Math.max(currentRoad.start, currentRoad.end) + MOVE_TOLERANCE + ); + } + } +} diff --git a/adev/src/content/examples/v21-game-world/src/index.html b/adev/src/content/examples/v21-game-world/src/index.html new file mode 100644 index 000000000000..2b169cb432bf --- /dev/null +++ b/adev/src/content/examples/v21-game-world/src/index.html @@ -0,0 +1,13 @@ + + + + + v21 Game World + + + + + + + + diff --git a/adev/src/content/examples/v21-game-world/src/main.ts b/adev/src/content/examples/v21-game-world/src/main.ts new file mode 100644 index 000000000000..438d1c34c7e5 --- /dev/null +++ b/adev/src/content/examples/v21-game-world/src/main.ts @@ -0,0 +1,9 @@ +import {bootstrapApplication, provideProtractorTestingSupport} from '@angular/platform-browser'; + +import {App} from './app/app'; + +bootstrapApplication(App, { + providers: [ + provideProtractorTestingSupport(), // essential for e2e testing + ], +}); diff --git a/adev/src/content/examples/v21-game-world/stackblitz.json b/adev/src/content/examples/v21-game-world/stackblitz.json new file mode 100644 index 000000000000..a27408cfec17 --- /dev/null +++ b/adev/src/content/examples/v21-game-world/stackblitz.json @@ -0,0 +1,7 @@ +{ + "description": "Pipes", + "files":[ + "!**/*.d.ts", + "!**/*.js"], + "tags": ["pipe"] +} diff --git a/adev/src/content/guide/BUILD.bazel b/adev/src/content/guide/BUILD.bazel index 8be5db6ec368..baaba0422f66 100644 --- a/adev/src/content/guide/BUILD.bazel +++ b/adev/src/content/guide/BUILD.bazel @@ -1,3 +1,4 @@ +load("//adev/shared-docs:defaults.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -5,8 +6,30 @@ generate_guides( srcs = glob([ "*.md", ]), + api_manifest = "//adev/src/assets:docs_api_manifest", data = [ "//adev/src/content/examples", ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = [ + "//adev/src/content/guide/animations:guide_files", + "//adev/src/content/guide/aria:guide_files", + "//adev/src/content/guide/components:guide_files", + "//adev/src/content/guide/di:guide_files", + "//adev/src/content/guide/directives:guide_files", + "//adev/src/content/guide/forms:guide_files", + "//adev/src/content/guide/forms/signals:guide_files", + "//adev/src/content/guide/http:guide_files", + "//adev/src/content/guide/i18n:guide_files", + "//adev/src/content/guide/performance:guide_files", + "//adev/src/content/guide/routing:guide_files", + "//adev/src/content/guide/signals:guide_files", + "//adev/src/content/guide/templates:guide_files", + "//adev/src/content/guide/testing:guide_files", + ] + glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/animations/BUILD.bazel b/adev/src/content/guide/animations/BUILD.bazel index 3c76e01e3b4e..64926046863a 100644 --- a/adev/src/content/guide/animations/BUILD.bazel +++ b/adev/src/content/guide/animations/BUILD.bazel @@ -1,3 +1,4 @@ +load("//adev/shared-docs:defaults.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -5,8 +6,15 @@ generate_guides( srcs = glob([ "*.md", ]), + api_manifest = "//adev/src/assets:docs_api_manifest", data = [ "//adev/src/content/examples", ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/animations/complex-sequences.md b/adev/src/content/guide/animations/complex-sequences.md index de743b5a6dd0..27a69f3879d9 100644 --- a/adev/src/content/guide/animations/complex-sequences.md +++ b/adev/src/content/guide/animations/complex-sequences.md @@ -1,6 +1,6 @@ # Complex animation sequences -IMPORTANT: The Angular team recommends using native CSS for animations instead of the Animations package for all new code. Use this guide to understand existing code built with the Animations Package. See [Migrating away from Angular's Animations package](guide/animations/migration#complex-sequences) to learn how you can start using pure CSS animations in your apps. +IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps. So far, we've learned simple animations of single HTML elements. Angular also lets you animate coordinated sequences, such as an entire grid or list of elements as they enter and leave a page. @@ -8,26 +8,26 @@ You can choose to run multiple animations in parallel, or run discrete animation The functions that control complex animation sequences are: -| Functions | Details | -|:--- |:--- | -| `query()` | Finds one or more inner HTML elements. | +| Functions | Details | +| :-------------------------------- | :------------------------------------------------------------- | +| `query()` | Finds one or more inner HTML elements. | | `stagger()` | Applies a cascading delay to animations for multiple elements. | -| [`group()`](api/animations/group) | Runs multiple animation steps in parallel. | -| `sequence()` | Runs animation steps one after another. | +| [`group()`](api/animations/group) | Runs multiple animation steps in parallel. | +| `sequence()` | Runs animation steps one after another. | ## The query() function Most complex animations rely on the `query()` function to find child elements and apply animations to them, basic examples of such are: -| Examples | Details | -|:--- |:--- | -| `query()` followed by `animate()` | Used to query simple HTML elements and directly apply animations to them. | +| Examples | Details | +| :------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `query()` followed by `animate()` | Used to query simple HTML elements and directly apply animations to them. | | `query()` followed by `animateChild()` | Used to query child elements, which themselves have animations metadata applied to them and trigger such animation \(which would be otherwise be blocked by the current/parent element's animation\). | The first argument of `query()` is a [css selector](https://developer.mozilla.org/docs/Web/CSS/CSS_Selectors) string which can also contain the following Angular-specific tokens: -| Tokens | Details | -|:--- |:--- | +| Tokens | Details | +| :------------------------- | :------------------------------------------- | | `:enter`
    `:leave` | For entering/leaving elements. | | `:animating` | For elements currently animating. | | `@*`
    `@triggerName` | For elements with any—or a specific—trigger. | @@ -37,7 +37,7 @@ The first argument of `query()` is a [css selector](https://developer.mozilla.or Not all child elements are actually considered as entering/leaving; this can, at times, be counterintuitive and confusing. Please see the [query api docs](api/animations/query#entering-and-leaving-elements) for more information. -You can also see an illustration of this in the animations example \(introduced in the animations [introduction section](guide/animations#about-this-guide)\) under the Querying tab. +You can also see an illustration of this in the animations example \(introduced in the animations [introduction section](guide/legacy-animations#about-this-guide)\) under the Querying tab. @@ -47,14 +47,14 @@ After having queried child elements via `query()`, the `stagger()` function lets The following example demonstrates how to use the `query()` and `stagger()` functions to animate a list \(of heroes\) adding each in sequence, with a slight delay, from top to bottom. -* Use `query()` to look for an element entering the page that meets certain criteria -* For each of these elements, use `style()` to set the same initial style for the element. - Make it transparent and use `transform` to move it out of position so that it can slide into place. +- Use `query()` to look for an element entering the page that meets certain criteria +- For each of these elements, use `style()` to set the same initial style for the element. + Make it transparent and use `transform` to move it out of position so that it can slide into place. -* Use `stagger()` to delay each animation by 30 milliseconds -* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it +- Use `stagger()` to delay each animation by 30 milliseconds +- Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it - + ## Parallel animation using group() function @@ -63,11 +63,11 @@ But you might also want to configure animations that happen in parallel. For example, you might want to animate two CSS properties of the same element but use a different `easing` function for each one. For this, you can use the animation [`group()`](api/animations/group) function. -HELPFUL: The [`group()`](api/animations/group) function is used to group animation *steps*, rather than animated elements. +HELPFUL: The [`group()`](api/animations/group) function is used to group animation _steps_, rather than animated elements. The following example uses [`group()`](api/animations/group)s on both `:enter` and `:leave` for two different timing configurations, thus applying two independent animations to the same element in parallel. - + ## Sequential vs. parallel animations @@ -77,8 +77,8 @@ But what if you want to create an animation involving several animations happeni A second function called `sequence()` lets you run those same animations one after the other. Within `sequence()`, the animation steps consist of either `style()` or `animate()` function calls. -* Use `style()` to apply the provided styling data immediately. -* Use `animate()` to apply styling data over a given time interval. +- Use `style()` to apply the provided styling data immediately. +- Use `animate()` to apply styling data over a given time interval. ## Filter animation example @@ -91,24 +91,24 @@ The heroes list gradually re-enters the page as you delete each letter in the fi The HTML template contains a trigger called `filterAnimation`. - + The `filterAnimation` in the component's decorator contains three transitions. - + The code in this example performs the following tasks: -* Skips animations when the user first opens or navigates to this page \(the filter animation narrows what is already there, so it only works on elements that already exist in the DOM\) -* Filters heroes based on the search input's value +- Skips animations when the user first opens or navigates to this page \(the filter animation narrows what is already there, so it only works on elements that already exist in the DOM\) +- Filters heroes based on the search input's value For each change: -* Hides an element leaving the DOM by setting its opacity and width to 0 -* Animates an element entering the DOM over 300 milliseconds. - During the animation, the element assumes its default width and opacity. +- Hides an element leaving the DOM by setting its opacity and width to 0 +- Animates an element entering the DOM over 300 milliseconds. + During the animation, the element assumes its default width and opacity. -* If there are multiple elements entering or leaving the DOM, staggers each animation starting at the top of the page, with a 50-millisecond delay between each element +- If there are multiple elements entering or leaving the DOM, staggers each animation starting at the top of the page, with a 50-millisecond delay between each element ## Animating the items of a reordering list @@ -121,11 +121,11 @@ IMPORTANT: If you need to animate the items of an `*ngFor` list and there is a p ## Animations and Component View Encapsulation -Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](guide/components/styling#style-scoping) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they were using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` behaves differently as we'll discuss shortly). +Angular animations are based on the components DOM structure and do not directly take [View Encapsulation](guide/components/styling#style-scoping) into account, this means that components using `ViewEncapsulation.Emulated` behave exactly as if they were using `ViewEncapsulation.None` (`ViewEncapsulation.ShadowDom` and `ViewEncapsulation.ExperimentalIsolatedShadowDom` behave differently as we'll discuss shortly). For example if the `query()` function (which you'll see more of in the rest of the Animations guide) were to be applied at the top of a tree of components using the emulated view encapsulation, such query would be able to identify (and thus animate) DOM elements on any depth of the tree. -On the other hand the `ViewEncapsulation.ShadowDom` changes the component's DOM structure by "hiding" DOM elements inside [`ShadowRoot`](https://developer.mozilla.org/docs/Web/API/ShadowRoot) elements. Such DOM manipulations do prevent some of the animations implementation to work properly since it relies on simple DOM structures and doesn't take `ShadowRoot` elements into account. Therefore it is advised to avoid applying animations to views incorporating components using the ShadowDom view encapsulation. +On the other hand the `ViewEncapsulation.ShadowDom` and `ViewEncapsulation.ExperimentalIsolatedShadowDom` changes the component's DOM structure by "hiding" DOM elements inside [`ShadowRoot`](https://developer.mozilla.org/docs/Web/API/ShadowRoot) elements. Such DOM manipulations do prevent some of the animations implementation to work properly since it relies on simple DOM structures and doesn't take `ShadowRoot` elements into account. Therefore it is advised to avoid applying animations to views incorporating components using the ShadowDom view encapsulation. ## Animation sequence summary @@ -137,8 +137,9 @@ The remaining functions, `stagger()`, [`group()`](api/animations/group), and `se You might also be interested in the following: - - - - + + + + + diff --git a/adev/src/content/guide/animations/css.md b/adev/src/content/guide/animations/css.md index b94a2a6ac152..0e68cf254042 100644 --- a/adev/src/content/guide/animations/css.md +++ b/adev/src/content/guide/animations/css.md @@ -4,14 +4,14 @@ CSS offers a robust set of tools for you to create beautiful and engaging animat ## How to write animations in native CSS -If you've never written any native CSS animations, there are a number of excellent guides to get you started. Here's a few of them: -[MDN's CSS Animations guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations/Using_CSS_animations) -[W3Schools CSS3 Animations guide](https://www.w3schools.com/css/css3_animations.asp) -[The Complete CSS Animations Tutorial](https://www.lambdatest.com/blog/css-animations-tutorial/) -[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners) - -and a couple of videos: -[Learn CSS Animation in 9 Minutes](https://www.youtube.com/watch?v=z2LQYsZhsFw) +If you've never written any native CSS animations, there are a number of excellent guides to get you started. Here's a few of them: +[MDN's CSS Animations guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations/Using_CSS_animations) +[W3Schools CSS3 Animations guide](https://www.w3schools.com/css/css3_animations.asp) +[The Complete CSS Animations Tutorial](https://www.lambdatest.com/blog/css-animations-tutorial/) +[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners) + +and a couple of videos: +[Learn CSS Animation in 9 Minutes](https://www.youtube.com/watch?v=z2LQYsZhsFw) [Net Ninja CSS Animation Tutorial Playlist](https://www.youtube.com/watch?v=jgw82b5Y2MU&list=PL4cUxeGkcC9iGYgmEd2dm3zAKzyCGDtM5) Check some of these various guides and tutorials out, and then come back to this guide. @@ -20,7 +20,7 @@ Check some of these various guides and tutorials out, and then come back to this You can create reusable animations that can be shared across your application using `@keyframes`. Define keyframe animations in a shared CSS file, and you'll be able to re-use those keyframe animations wherever you want within your application. - + Adding the class `animated-class` to an element would trigger the animation on that element. @@ -30,7 +30,7 @@ Adding the class `animated-class` to an element would trigger the animation on t You may want to animate between two different states, for example when an element is opened or closed. You can accomplish this by using CSS classes either using a keyframe animation or transition styling. - + Triggering the `open` or `closed` state is done by toggling classes on the element in your component. You can find examples of how to do this in our [template guide](guide/templates/binding#css-class-and-style-property-bindings). @@ -42,20 +42,20 @@ Animating often requires adjusting timing, delays and easeing behaviors. This ca Specify `animation-duration`, `animation-delay`, and `animation-timing-function` for a keyframe animation in CSS, or alternatively use the `animation` shorthand property. - + Similarly, you can use `transition-duration`, `transition-delay`, and `transition-timing-function` and the `transition` shorthand for animations that are not using `@keyframes`. - + ### Triggering an Animation Animations can be triggered by toggling CSS styles or classes. Once a class is present on an element, the animation will occur. Removing the class will revert the element back to whatever CSS is defined for that element. Here's an example: - - - + + + ## Transition and Triggers @@ -65,39 +65,41 @@ Animations can be triggered by toggling CSS styles or classes. Once a class is p You can use css-grid to animate to auto height. - - - + + + If you don't have to worry about supporting all browsers, you can also check out `calc-size()`, which is the true solution to animating auto height. See [MDN's docs](https://developer.mozilla.org/en-US/docs/Web/CSS/calc-size) and (this tutorial)[https://frontendmasters.com/blog/one-of-the-boss-battles-of-css-is-almost-won-transitioning-to-auto/] for more information. ### Animate entering and leaving a view -You can create animations for when an item enters a view or leaves a view. Let's start by looking at how to animate an element leaving a view. +You can create animations for when an item enters a view or leaves a view. Let's start by looking at how to animate an element entering a view. We'll do this with `animate.enter`, which will apply animation classes when an element enters the view. - - - + + + -Leaving a view is slightly more complex. The element removal needs to be delayed until the exit animation is complete. This requires a bit of extra code in your component class to accomplish. +Animating an element when it leaves the view is similar to animating when entering a view. Use `animate.leave` to specify which CSS classes to apply when the element leaves the view. - - - + + + +For more information on `animate.enter` and `animate.leave`, see the [Enter and Leave animations guide](guide/animations). + ### Animating increment and decrement Animating on increment and decrement is a common pattern in applications. Here's an example of how you can accomplish that behavior. - - - + + + ### Disabling an animation or all animations @@ -126,12 +128,12 @@ If you have actions you would like to execute at certain points during animation [`OnAnimationStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationstart_event) [`OnAnimationEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationend_event) [`OnAnimationIteration`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationitration_event) -[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event) +[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event) [`OnTransitionStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionstart_event) [`OnTransitionRun`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionrun_event) [`OnTransitionEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionend_event) -[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event) +[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event) The Web Animations API has a lot of additional functionality. [Take a look at the documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) to see all the available animation APIs. @@ -146,9 +148,9 @@ Animations are often more complicated than just a simple fade in or fade out. Yo One common effect is to stagger the animations of each item in a list to create a cascade effect. This can be accomplished by utilizing `animation-delay` or `transition-delay`. Here is an example of what that CSS might look like. - - - + + + ### Parallel Animations @@ -165,14 +167,23 @@ In this example, the `rotate` and `fade-in` animations fire at the same time, bu ### Animating the items of a reordering list -Items in a `@for` loop will be removed and re-added, which will fire off animations using `@starting-styles` for entry animations. Removal animations will require additional code to add the event listener, as seen in the example above. +Items in a `@for` loop will be removed and re-added, which will fire off animations using `@starting-styles` for entry animations. Alternatively, you can use `animate.enter` for this same behavior. Use `animate.leave` to animate elements as they are removed, as seen in the example below. - - - + + + ## Programmatic control of animations You can retrieve animations off an element directly using [`Element.getAnimations()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getAnimations). This returns an array of every [`Animation`](https://developer.mozilla.org/en-US/docs/Web/API/Animation) on that element. You can use the `Animation` API to do much more than you could with what the `AnimationPlayer` from the animations package offered. From here you can `cancel()`, `play()`, `pause()`, `reverse()` and much more. This native API should provide everything you need to control your animations. + +## More on Angular animations + +You might also be interested in the following: + + + + + diff --git a/adev/src/content/guide/animations/enter-and-leave.md b/adev/src/content/guide/animations/enter-and-leave.md new file mode 100644 index 000000000000..8ab48087deb7 --- /dev/null +++ b/adev/src/content/guide/animations/enter-and-leave.md @@ -0,0 +1,103 @@ +# Animating your applications with `animate.enter` and `animate.leave` + +Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic. +Animations can improve your application and user experience in a number of ways: + +- Without animations, web page transitions can seem abrupt and jarring +- Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions +- Good animations can smoothly direct the user's attention throughout a workflow + +Angular provides `animate.enter` and `animate.leave` to animate your application's elements. These two features apply enter and leave CSS classes at the appropriate times or call functions to apply animations from third party libraries. `animate.enter` and `animate.leave` are not directives. They are special API supported directly by the Angular compiler. They can be used on elements directly and can also be used as a host binding. + +## `animate.enter` + +You can use `animate.enter` to animate elements as they _enter_ the DOM. You can define enter animations using CSS classes with either transitions or keyframe animations. + + + + + + + +When the animation completes, Angular removes the class or classes that you specified in `animate.enter` from the DOM. Animation classes are only be present while the animation is active. + +NOTE: When using multiple keyframe animations or transition properties on an element, Angular removes all classes only _after_ the longest animation has completed. + +You can use `animate.enter` with any other Angular features, such as control flow or dynamic expressions. `animate.enter` accepts both a single class string (with multiple classes separated by spaces), or an array of class strings. + +A quick note about using CSS transitions: If you choose to use transitions instead of keyframe animations, the classes added to the element with `animate.enter` represent the state that the transition will animate _to_. Your base element CSS is what the element will look like when no animations run, which is likely similar to the end state of the CSS transition. So you would still need to pair it with `@starting-style` to have an appropriate _from_ state for your transition to work. + + + + + + + +## `animate.leave` + +You can use `animate.leave` to animate elements as they _leave_ the DOM. You can define leave animations using CSS classes with either transforms or keyframe animations. + + + + + + + +When the animation completes, Angular automatically removes the animated element from the DOM. + +NOTE: When using multiple keyframe animations or transition properties on a an element, Angular waits to remove the element only _after_ the longest of those animations has completed. + +`animate.leave` can also be used with signals, and other bindings. You can use `animate.leave` with a single class or multiple classes. Either specify it as a simple string with spaces or a string array. + + + + + + + +## Event Bindings, Functions, and Third-party Libraries + +Both `animate.enter` and `animate.leave` support event binding syntax that allows for function calls. You can use this syntax to call a function in your component code or utilize third-party animation libraries, like [GSAP](https://gsap.com/), [anime.js](https://animejs.com/), or any other JavaScript animation library. + + + + + + + +The `$event` object has the type `AnimationCallbackEvent`. It includes the element as the `target` and provides an `animationComplete()` function to notify the framework when the animation finishes. + +IMPORTANT: You **must** call the `animationComplete()` function when using `animate.leave` for Angular to remove the element. + +If you don't call `animationComplete()` when using `animate.leave`, Angular calls the function automatically after a four-second delay. You can configure the duration of the delay by providing the token `MAX_ANIMATION_TIMEOUT` in milliseconds. + +```typescript + { provide: MAX_ANIMATION_TIMEOUT, useValue: 6000 } +``` + +## Compatibility with Legacy Angular Animations + +You cannot use legacy animations alongside `animate.enter` and `animate.leave` within the same component. Doing so would result in enter classes remaining on the element or leaving nodes not being removed. It is otherwise fine to use both legacy animations and the new `animate.enter` and `animate.leave` animations within the same _application_. The only caveat is content projection. If you are projecting content from one component with legacy animations into another component with `animate.enter` or `animate.leave`, or vice versa, this will result in the same behavior as if they are used together in the same component. This is not supported. + +## Testing + +TestBed provides built-in support for enabling or disabling animations in your test environment. CSS animations require a browser to run, and many of the APIs are not available in a test environment. By default, TestBed disables animations for you in your test environments. + +If you want to test that the animations are animating in a browser test, for example an end-to-end test, you can configure TestBed to enable animations by specifying `animationsEnabled: true` in your test configuration. + +```typescript + TestBed.configureTestingModule({animationsEnabled: true}); +``` + +This will configure animations in your test environment to behave normally. + +NOTE: Some test environments do not emit animation events like `animationstart`, `animationend` and their transition event equivalents. + +## More on Angular animations + +You might also be interested in the following: + + + + + diff --git a/adev/src/content/guide/animations/migration.md b/adev/src/content/guide/animations/migration.md index c62ec4f17e4c..60890a17368b 100644 --- a/adev/src/content/guide/animations/migration.md +++ b/adev/src/content/guide/animations/migration.md @@ -1,6 +1,6 @@ # Migrating away from Angular's Animations package -Almost all the features supported by `@angular/animations` have simpler alternatives with native CSS. Consider removing the Angular Animations package from your application, as the package can contribute around 60 kilobytes to your JavaScript bundle. Native CSS animations offer superior performance, as they can benefit from hardware acceleration. Animations defined in the animations package lack that ability. This guide walks through the process of refactoring your code from `@angular/animations` to native CSS animations. +The `@angular/animations` package is deprecated as of v20.2, which also introduced the new `animate.enter` and `animate.leave` feature to add animations to your application. Using these new features, you can replace all animations based on `@angular/animations` with plain CSS or JS animation libraries. Removing `@angular/animations` from your application can significantly reduce the size of your JavaScript bundle. Native CSS animations generally offer superior performance, as they can benefit from hardware acceleration. This guide walks through the process of refactoring your code from `@angular/animations` to native CSS animations. ## How to write animations in native CSS @@ -8,7 +8,7 @@ If you've never written any native CSS animations, there are a number of excelle [MDN's CSS Animations guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations/Using_CSS_animations) [W3Schools CSS3 Animations guide](https://www.w3schools.com/css/css3_animations.asp) [The Complete CSS Animations Tutorial](https://www.lambdatest.com/blog/css-animations-tutorial/) -[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners) +[CSS Animation for Beginners](https://thoughtbot.com/blog/css-animation-for-beginners) and a couple of videos: [Learn CSS Animation in 9 Minutes](https://www.youtube.com/watch?v=z2LQYsZhsFw) @@ -21,10 +21,12 @@ Check some of these various guides and tutorials out, and then come back to this Just like with the animations package, you can create reusable animations that can be shared across your application. The animations package version of this had you using the `animation()` function in a shared typescript file. The native CSS version of this is similar, but lives in a shared CSS file. #### With Animations Package - + + #### With Native CSS - + + Adding the class `animated-class` to an element would trigger the animation on that element. @@ -35,12 +37,14 @@ Adding the class `animated-class` to an element would trigger the animation on t The animations package allowed you to define various states using the [`state()`](api/animations/state) function within a component. Examples might be an `open` or `closed` state containing the styles for each respective state within the definition. For example: #### With Animations Package - + + This same behavior can be accomplished natively by using CSS classes either using a keyframe animation or transition styling. #### With Native CSS - + + Triggering the `open` or `closed` state is done by toggling classes on the element in your component. You can find examples of how to do this in our [template guide](guide/templates/binding#css-class-and-style-property-bindings). @@ -52,28 +56,30 @@ The animations package `animate()` function allows for providing timing, like du Specify `animation-duration`, `animation-delay`, and `animation-timing-function` for a keyframe animation in CSS, or alternatively use the `animation` shorthand property. - + Similarly, you can use `transition-duration`, `transition-delay`, and `transition-timing-function` and the `transition` shorthand for animations that are not using `@keyframes`. - + ### Triggering an Animation The animations package required specifying triggers using the `trigger()` function and nesting all of your states within it. With native CSS, this is unnecessary. Animations can be triggered by toggling CSS styles or classes. Once a class is present on an element, the animation will occur. Removing the class will revert the element back to whatever CSS is defined for that element. This results in significantly less code to do the same animation. Here's an example: #### With Animations Package + - - - + + + #### With Native CSS + - - - + + + ## Transition and Triggers @@ -89,19 +95,21 @@ These state matching patterns are not needed at all when animating with CSS dire The animations package offers the ability to animate things that have been historically difficult to animate, like animating a set height to `height: auto`. You can now do this with pure CSS as well. #### With Animations Package + - - - + + + You can use css-grid to animate to auto height. #### With Native CSS + - - - + + + If you don't have to worry about supporting all browsers, you can also check out `calc-size()`, which is the true solution to animating auto height. See [MDN's docs](https://developer.mozilla.org/en-US/docs/Web/CSS/calc-size) and (this tutorial)[https://frontendmasters.com/blog/one-of-the-boss-battles-of-css-is-almost-won-transitioning-to-auto/] for more information. @@ -111,46 +119,53 @@ If you don't have to worry about supporting all browsers, you can also check out The animations package offered the previously mentioned pattern matching for entering and leaving but also included the shorthand aliases of `:enter` and `:leave`. #### With Animations Package + - - - + + + -Here's how the same thing can be accomplished without the animations package. +Here's how the same thing can be accomplished without the animations package using `animate.enter`. #### With Native CSS + - - - + + + -Leaving a view is slightly more complex. The element removal needs to be delayed until the exit animation is complete. This requires a bit of extra code in your component class to accomplish. +Use `animate.leave` to animate elements as they leave the view, which will apply the specified CSS classes to the element as it leaves the view. #### With Native CSS + - - - + + + +For more information on `animate.enter` and `animate.leave`, see the [Enter and Leave animations guide](guide/animations). + ### Animating increment and decrement Along with the aforementioned `:enter` and `:leave`, there's also `:increment` and `:decrement`. You can animate these also by adding and removing classes. Unlike the animation package built-in aliases, there is no automatic application of classes when the values go up or down. You can apply the appropriate classes programmatically. Here's an example: #### With Animations Package + - - - + + + #### With Native CSS + - - - + + + ### Parent / Child Animations @@ -183,12 +198,12 @@ The animations package exposed callbacks for you to use in the case that you wan [`OnAnimationStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationstart_event) [`OnAnimationEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationend_event) [`OnAnimationIteration`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationitration_event) -[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event) +[`OnAnimationCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event) [`OnTransitionStart`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionstart_event) [`OnTransitionRun`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionrun_event) [`OnTransitionEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionend_event) -[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event) +[`OnTransitionCancel`](https://developer.mozilla.org/en-US/docs/Web/API/Element/transitioncancel_event) The Web Animations API has a lot of additional functionality. [Take a look at the documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) to see all the available animation APIs. @@ -209,17 +224,19 @@ To toggle classes for child nodes within a template, you can use class and style The `stagger()` function allowed you to delay the animation of each item in a list of items by a specified time to create a cascade effect. You can replicate this behavior in native CSS by utilizing `animation-delay` or `transition-delay`. Here is an example of what that CSS might look like. #### With Animations Package + - - - + + + #### With Native CSS + - - - + + + ### Parallel Animations @@ -236,23 +253,24 @@ In this example, the `rotate` and `fade-in` animations fire at the same time. ### Animating the items of a reordering list -Items reordering in a list works out of the box using the previously described techniques. No additional special work is required. Items in a `@for` loop will be removed and re-added properly, which will fire off animations using `@starting-styles` for entry animations. Removal animations will require additional code to add the event listener, as seen in the example above. +Items reordering in a list works out of the box using the previously described techniques. No additional special work is required. Items in a `@for` loop will be removed and re-added properly, which will fire off animations using `@starting-styles` for entry animations. Alternatively, you can use `animate.enter` for this same behavior. Use `animate.leave` to animate elements as they are removed, as seen in the example above. #### With Animations Package< + - - - + + + #### With Native CSS + - - - + + + - ## Migrating usages of AnimationPlayer The `AnimationPlayer` class allows access to an animation to do more advanced things like pause, play, restart, and finish an animation through code. All of these things can be handled natively as well. @@ -261,4 +279,4 @@ You can retrieve animations off an element directly using [`Element.getAnimation ## Route Transitions -You can use view transitions to animate between routes. See the [Route Transition Animations Guide](guide/animations/route-animations) to get started. \ No newline at end of file +You can use view transitions to animate between routes. See the [Route Transition Animations Guide](guide/routing/route-transition-animations) to get started. diff --git a/adev/src/content/guide/animations/overview.md b/adev/src/content/guide/animations/overview.md index 1403f21d18b2..e1d042d6344f 100644 --- a/adev/src/content/guide/animations/overview.md +++ b/adev/src/content/guide/animations/overview.md @@ -1,16 +1,16 @@ # Introduction to Angular animations -IMPORTANT: The Angular team recommends using native CSS for animations instead of the Animations package for all new code. Use this guide to understand existing code built with the Animations Package. See [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start using pure CSS animations in your apps. +IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps. Animation provides the illusion of motion: HTML elements change styling over time. Well-designed animations can make your application more fun and straightforward to use, but they aren't just cosmetic. Animations can improve your application and user experience in a number of ways: -* Without animations, web page transitions can seem abrupt and jarring -* Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions -* Good animations intuitively call the user's attention to where it is needed +- Without animations, web page transitions can seem abrupt and jarring +- Motion greatly enhances the user experience, so animations give users a chance to detect the application's response to their actions +- Good animations intuitively call the user's attention to where it is needed -Typically, animations involve multiple style *transformations* over time. +Typically, animations involve multiple style _transformations_ over time. An HTML element can move, change color, grow or shrink, fade, or slide off the page. These changes can occur simultaneously or sequentially. You can control the timing of each transformation. @@ -49,21 +49,21 @@ bootstrapApplication(AppComponent, { For `NgModule` based applications import `BrowserAnimationsModule`, which introduces the animation capabilities into your Angular root application module. - + If you plan to use specific animation functions in component files, import those functions from `@angular/animations`. - + -See all [available animation functions](guide/animations#animations-api-summary) at the end of this guide. +See all [available animation functions](guide/legacy-animations#animations-api-summary) at the end of this guide. In the component file, add a metadata property called `animations:` within the `@Component()` decorator. You put the trigger that defines an animation within the `animations` metadata property. - + @@ -82,11 +82,9 @@ HELPFUL: Let's create a new `open-close` component to animate with simple transi Run the following command in terminal to generate the component: - - +```shell ng g component open-close - - +``` This will create the component at `src/app/open-close.component.ts`. @@ -97,24 +95,24 @@ This function takes two arguments: A unique name like `open` or `closed` and a `style()` function. Use the `style()` function to define a set of styles to associate with a given state name. -You must use *camelCase* for style attributes that contain dashes, such as `backgroundColor` or wrap them in quotes, such as `'background-color'`. +You must use _camelCase_ for style attributes that contain dashes, such as `backgroundColor` or wrap them in quotes, such as `'background-color'`. Let's see how Angular's [`state()`](api/animations/state) function works with the `style⁣­(⁠)` function to set CSS style attributes. In this code snippet, multiple style attributes are set at the same time for the state. In the `open` state, the button has a height of 200 pixels, an opacity of 1, and a yellow background color. - + In the following `closed` state, the button has a height of 100 pixels, an opacity of 0.8, and a background color of blue. - + ### Transitions and timing In Angular, you can set multiple styles without any animation. However, without further refinement, the button instantly transforms with no fade, no shrinkage, or other visible indicator that a change is occurring. -To make the change less abrupt, you need to define an animation *transition* to specify the changes that occur between one state and another over a period of time. +To make the change less abrupt, you need to define an animation _transition_ to specify the changes that occur between one state and another over a period of time. The `transition()` function accepts two arguments: The first argument accepts an expression that defines the direction between two transition states, and the second argument accepts one or a series of `animate()` steps. @@ -146,40 +144,40 @@ The first part, `duration`, is required. The duration can be expressed in milliseconds as a number without quotes, or in seconds with quotes and a time specifier. For example, a duration of a tenth of a second can be expressed as follows: -* As a plain number, in milliseconds: - `100` +- As a plain number, in milliseconds: + `100` -* In a string, as milliseconds: - `'100ms'` +- In a string, as milliseconds: + `'100ms'` -* In a string, as seconds: - `'0.1s'` +- In a string, as seconds: + `'0.1s'` The second argument, `delay`, has the same syntax as `duration`. For example: -* Wait for 100ms and then run for 200ms: `'0.2s 100ms'` +- Wait for 100ms and then run for 200ms: `'0.2s 100ms'` The third argument, `easing`, controls how the animation [accelerates and decelerates](https://easings.net) during its runtime. For example, `ease-in` causes the animation to begin slowly, and to pick up speed as it progresses. -* Wait for 100ms, run for 200ms. - Use a deceleration curve to start out fast and slowly decelerate to a resting point: - `'0.2s 100ms ease-out'` +- Wait for 100ms, run for 200ms. + Use a deceleration curve to start out fast and slowly decelerate to a resting point: + `'0.2s 100ms ease-out'` -* Run for 200ms, with no delay. - Use a standard curve to start slow, accelerate in the middle, and then decelerate slowly at the end: - `'0.2s ease-in-out'` +- Run for 200ms, with no delay. + Use a standard curve to start slow, accelerate in the middle, and then decelerate slowly at the end: + `'0.2s ease-in-out'` -* Start immediately, run for 200ms. - Use an acceleration curve to start slow and end at full velocity: - `'0.2s ease-in'` +- Start immediately, run for 200ms. + Use an acceleration curve to start slow and end at full velocity: + `'0.2s ease-in'` HELPFUL: See the Material Design website's topic on [Natural easing curves](https://material.io/design/motion/speed.html#easing) for general information on easing curves. This example provides a state transition from `open` to `closed` with a 1-second transition between states. - + In the preceding code snippet, the `=>` operator indicates unidirectional transitions, and `<=>` is bidirectional. Within the transition, `animate()` specifies how long the transition takes. @@ -187,24 +185,24 @@ In this case, the state change from `open` to `closed` takes 1 second, expressed This example adds a state transition from the `closed` state to the `open` state with a 0.5-second transition animation arc. - + HELPFUL: Some additional notes on using styles within [`state`](api/animations/state) and `transition` functions. -* Use [`state()`](api/animations/state) to define styles that are applied at the end of each transition, they persist after the animation completes -* Use `transition()` to define intermediate styles, which create the illusion of motion during the animation -* When animations are disabled, `transition()` styles can be skipped, but [`state()`](api/animations/state) styles can't -* Include multiple state pairs within the same `transition()` argument: +- Use [`state()`](api/animations/state) to define styles that are applied at the end of each transition, they persist after the animation completes +- Use `transition()` to define intermediate styles, which create the illusion of motion during the animation +- When animations are disabled, `transition()` styles can be skipped, but [`state()`](api/animations/state) styles can't +- Include multiple state pairs within the same `transition()` argument: - transition( 'on => off, off => void' ) + transition( 'on => off, off => void' ) ### Triggering the animation -An animation requires a *trigger*, so that it knows when to start. +An animation requires a _trigger_, so that it knows when to start. The `trigger()` function collects the states and transitions, and gives the animation a name, so that you can attach it to the triggering element in the HTML template. The `trigger()` function describes the property name to watch for changes. @@ -222,7 +220,7 @@ However, it's possible for multiple triggers to be active at once. Animations are defined in the metadata of the component that controls the HTML element to be animated. Put the code that defines your animations under the `animations:` property within the `@Component()` decorator. - + When you've defined an animation trigger for a component, attach it to an element in that component's template by wrapping the trigger name in brackets and preceding it with an `@` symbol. Then, you can bind the trigger to a template expression using standard Angular property binding syntax as shown below, where `triggerName` is the name of the trigger, and `expression` evaluates to a defined animation state. @@ -237,7 +235,7 @@ The animation is executed or triggered when the expression value changes to a ne The following code snippet binds the trigger to the value of the `isOpen` property. - + In this example, when the `isOpen` expression evaluates to a defined state of `open` or `closed`, it notifies the trigger `openClose` of a state change. Then it's up to the `openClose` code to handle the state change and kick off a state change animation. @@ -254,16 +252,16 @@ In the HTML template file, use the trigger name to attach the defined animations Here are the code files discussed in the transition example. - - - + + + ### Summary You learned to add animation to a transition between two states, using `style()` and [`state()`](api/animations/state) along with `animate()` for the timing. -Learn about more advanced features in Angular animations under the Animation section, beginning with advanced techniques in [transition and triggers](guide/animations/transition-and-triggers). +Learn about more advanced features in Angular animations under the Animation section, beginning with advanced techniques in [transition and triggers](guide/legacy-animations/transition-and-triggers). ## Animations API summary @@ -271,14 +269,14 @@ The functional API provided by the `@angular/animations` module provides a domai See the [API reference](api#animations) for a complete listing and syntax details of the core functions and related data structures. | Function name | What it does | -|:--- |:--- | +| :-------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `trigger()` | Kicks off the animation and serves as a container for all other animation function calls. HTML template binds to `triggerName`. Use the first argument to declare a unique trigger name. Uses array syntax. | | `style()` | Defines one or more CSS styles to use in animations. Controls the visual appearance of HTML elements during animations. Uses object syntax. | | [`state()`](api/animations/state) | Creates a named set of CSS styles that should be applied on successful transition to a given state. The state can then be referenced by name within other animation functions. | | `animate()` | Specifies the timing information for a transition. Optional values for `delay` and `easing`. Can contain `style()` calls within. | | `transition()` | Defines the animation sequence between two named states. Uses array syntax. | | `keyframes()` | Allows a sequential change between styles within a specified time interval. Use within `animate()`. Can include multiple `style()` calls within each `keyframe()`. Uses array syntax. | -| [`group()`](api/animations/group) | Specifies a group of animation steps \(*inner animations*\) to be run in parallel. Animation continues only after all inner animation steps have completed. Used within `sequence()` or `transition()`. | +| [`group()`](api/animations/group) | Specifies a group of animation steps \(_inner animations_\) to be run in parallel. Animation continues only after all inner animation steps have completed. Used within `sequence()` or `transition()`. | | `query()` | Finds one or more inner HTML elements within the current element. | | `sequence()` | Specifies a list of animation steps that are run sequentially, one by one. | | `stagger()` | Staggers the starting time for animations for multiple elements. | @@ -295,8 +293,9 @@ HELPFUL: Check out this [presentation](https://www.youtube.com/watch?v=rnTK9meY5 You might also be interested in the following: - - - - + + + + + diff --git a/adev/src/content/guide/animations/reusable-animations.md b/adev/src/content/guide/animations/reusable-animations.md index 76f02b9512cf..17c2e9bdd8e1 100644 --- a/adev/src/content/guide/animations/reusable-animations.md +++ b/adev/src/content/guide/animations/reusable-animations.md @@ -1,6 +1,6 @@ # Reusable animations -IMPORTANT: The Angular team recommends using native CSS for animations instead of the Animations package for all new code. Use this guide to understand existing code built with the Animations Package. See [Migrating away from Angular's Animations package](guide/animations/migration#creating-reusable-animations) to learn how you can start using pure CSS animations in your apps. +IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps. This topic provides some examples of how to create reusable animations. @@ -9,7 +9,7 @@ This topic provides some examples of how to create reusable animations. To create a reusable animation, use the [`animation()`](api/animations/animation) function to define an animation in a separate `.ts` file and declare this animation definition as a `const` export variable. You can then import and reuse this animation in any of your application components using the [`useAnimation()`](api/animations/useAnimation) function. - + In the preceding code snippet, `transitionAnimation` is made reusable by declaring it as an export variable. @@ -18,20 +18,21 @@ HELPFUL: The `height`, `opacity`, `backgroundColor`, and `time` inputs are repla You can also export a part of an animation. For example, the following snippet exports the animation `trigger`. - + From this point, you can import reusable animation variables in your component class. For example, the following code snippet imports the `transitionAnimation` variable and uses it via the `useAnimation()` function. - + ## More on Angular animations You might also be interested in the following: - - - - + + + + + diff --git a/adev/src/content/guide/animations/route-animations.md b/adev/src/content/guide/animations/route-animations.md deleted file mode 100644 index 1fbbd973d084..000000000000 --- a/adev/src/content/guide/animations/route-animations.md +++ /dev/null @@ -1,157 +0,0 @@ -# Route transition animations - -When a user navigates from one route to another, the Angular Router maps the URL path to the relevant component and displays its view. Animating this route transition can greatly enhance the user experience. The Router has support for the View Transitions API when navigating between routes in Chrome/Chromium browsers. - -HELPFUL: The Router's native View Transitions integration is currently in [developer preview](/reference/releases#developer-preview). Native View Transitions are also a relatively new feature so there may be limited support in some browsers. - -## How View Transitions work - -The native browser method that’s used for view transitions is `document.startViewTransition`. When `startViewTransition()` is called, the browser captures the current state of the page which includes taking a screenshot. The method takes a callback that updates the DOM and this function can be asynchronous. The new state is captured and the transition begins in the next animation frame when the promise returned by the callback resolves. - -Here’s an example of the startViewTransition api: - -```ts -document.startViewTransition(async () => { - await updateTheDOMSomehow(); -}); -``` - -If you’re curious to read more about the details of the browser API, the [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions) is an invaluable resource. - -## How the Router uses view transitions - -Several things happen after navigation starts in the router: route matching, loading lazy routes and components, executing guards and resolvers to name a few. Once these have completed successfully, the new routes are ready to be activated. This route activation is the DOM update that we want to perform as part of the view transition. - -When the view transition feature is enabled, navigation “pauses” and a call is made to the browser’s `startViewTransition` method. Once the `startViewTransition` callback executes (this happens asynchronously, as outlined in the spec here), navigation “resumes”. The remaining steps for the router navigation include updating the browser URL and activating or deactivating the matched routes (the DOM update). - -Finally, the callback passed to `startViewTransition` returns a Promise that resolves once Angular has finished rendering. As described above, this indicates to the browser that the new DOM state should be captured and the transition should begin. - -View transitions are a [progressive enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement). If the browser does not support the API, the Router will perform the DOM updates without calling `startViewTransition` and the navigation will not be animated. - -## Enabling View Transitions in the Router - -To enable this feature, simply add `withViewTransitions` to the `provideRouter` or set `enableViewTransitions: true` in `RouterModule.forRoot`: - -```ts -// Standalone bootstrap -bootstrapApplication(MyApp, {providers: [ - provideRouter(ROUTES, withViewTransitions()), -]}); - -// NgModule bootstrap -@NgModule({ - imports: [RouterModule.forRoot(routes, {enableViewTransitions: true})] -}) -export class AppRouting {} -``` - -[Try the “count” example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-2dnvtm?file=src%2Fmain.ts) - -This example uses the counter application from the Chrome explainer and replaces the direct call to startViewTransition when the counter increments with a router navigation. - -## Using CSS to customize transitions - -View transitions can be customized with CSS. We can also instruct the browser to create separate elements for the transition by setting a view-transition-name. We can expand the first example by adding view-transition-name: count to the .count style in the Counter component. Then, in the global styles, we can define a custom animation for this view transition: - -```css -/* Custom transition */ -@keyframes rotate-out { - to { - transform: rotate(90deg); - } -} -@keyframes rotate-in { - from { - transform: rotate(-90deg); - } -} -::view-transition-old(count), -::view-transition-new(count) { - animation-duration: 200ms; - animation-name: -ua-view-transition-fade-in, rotate-in; -} -::view-transition-old(count) { - animation-name: -ua-view-transition-fade-out, rotate-out; -} -``` - -It is important that the view transition animations are defined in a global style file. They cannot be defined in the component styles because the default view encapsulation will scope the styles to the component. - -[Try the updated “count” example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-fwn4i7?file=src%2Fmain.ts) - -## Controlling transitions with onViewTransitionCreated - -The `withViewTransitions` router feature can also be called with an options object that includes an `onViewTransitionCreated` callback. This callback is run in an [injection context](/guide/di/dependency-injection-context#run-within-an-injection-context) and receives a [ViewTransitionInfo](/api/router/ViewTransitionInfo) object that includes the `ViewTransition` returned from `startViewTransition`, as well as the `ActivatedRouteSnapshot` that the navigation is transitioning from and the new one that it is transitioning to. - -This callback can be used for any number of customizations. For example, you might want to skip transitions under certain conditions. We use this on the new angular.dev docs site: - -```ts -withViewTransitions({ - onViewTransitionCreated: ({transition}) => { - const router = inject(Router); - const targetUrl = router.getCurrentNavigation()!.finalUrl!; - // Skip the transition if the only thing - // changing is the fragment and queryParams - const config = { - paths: 'exact', - matrixParams: 'exact', - fragment: 'ignored', - queryParams: 'ignored', - }; - - if (router.isActive(targetUrl, config)) { - transition.skipTransition(); - } - }, -}), -``` - -In this code snippet, we create a `UrlTree` from the `ActivatedRouteSnapshot` the navigation is going to. We then check with the Router to see if this `UrlTree` is already active, ignoring any differences in the fragment or query parameters. If it is already active, we call skipTransition which will skip the animation portion of the view transition. This is the case when clicking on an anchor link that will only scroll to another location in the same document. - -## Examples from the Chrome explainer adapted to Angular - -We’ve recreated some of the great examples from the Chrome Team in Angular for you to explore. - -### Transitioning elements don’t need to be the same DOM element - -* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#transitioning_elements_dont_need_to_be_the_same_dom_element) -* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-dh8npr?file=src%2Fmain.ts) - -### Custom entry and exit animations - -* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#custom_entry_and_exit_transitions) -* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-8kly3o) - -### Async DOM updates and waiting for content - -* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#async_dom_updates_and_waiting_for_content) - -> During this time, the page is frozen, so delays here should be kept to a minimum…in some cases it’s better to avoid the delay altogether, and use the content you already have. - -The view transition feature in the Angular router does not provide a way to delay the animation. For the moment, our stance is that it’s always better to use the content you have rather than making the page non-interactive for any additional amount of time. - -### Handle multiple view transition styles with view transition types - -* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#view-transition-types) -* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-vxzcam) - -### Handle multiple view transition styles with a class name on the view transition root (deprecated) - -* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#changing-on-navigation-type) -* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-nmnzzg?file=src%2Fmain.ts) - -### Transitioning without freezing other animations - -* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#transitioning-without-freezing) -* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-76kgww) - -### Animating with Javascript - -* [Chrome Explainer](https://developer.chrome.com/docs/web-platform/view-transitions/same-document#animating-with-javascript) -* [Angular Example on StackBlitz](https://stackblitz.com/edit/stackblitz-starters-cklnkm) - -## Native View Transitions Alternative - -Animating the transition between routes can also be done with the `@angular/animations` package. -The animation [triggers and transitions](/guide/animations/transition-and-triggers) -can be derived from the router state, such as the current URL or `ActivatedRoute`. diff --git a/adev/src/content/guide/animations/transition-and-triggers.md b/adev/src/content/guide/animations/transition-and-triggers.md index 3b7780232822..13be61108daf 100644 --- a/adev/src/content/guide/animations/transition-and-triggers.md +++ b/adev/src/content/guide/animations/transition-and-triggers.md @@ -1,6 +1,6 @@ # Animation transitions and triggers -IMPORTANT: The Angular team recommends using native CSS for animations instead of the Animations package for all new code. Use this guide to understand existing code built with the Animations Package. See [Migrating away from Angular's Animations package](guide/animations/migration#transition-and-triggers) to learn how you can start using pure CSS animations in your apps. +IMPORTANT: The `@angular/animations` package is now deprecated. The Angular team recommends using native CSS with `animate.enter` and `animate.leave` for animations for all new code. Learn more at the new enter and leave [animation guide](guide/animations/enter-and-leave). Also see [Migrating away from Angular's Animations package](guide/animations/migration) to learn how you can start migrating to pure CSS animations in your apps. This guide goes into depth on special transition states such as the `*` wildcard and `void`. It shows how these special states are used for elements entering and leaving a view. This section also explores multiple animation triggers, animation callbacks, and sequence-based animation using keyframes. @@ -11,7 +11,7 @@ In Angular, transition states can be defined explicitly through the [`state()`]( ### Wildcard state -An asterisk `*` or *wildcard* matches any animation state. +An asterisk `*` or _wildcard_ matches any animation state. This is useful for defining transitions that apply regardless of the HTML element's start or end state. For example, a transition of `open => *` applies when the element's state changes from open to anything else. @@ -23,11 +23,11 @@ Instead of defining each state-to-state transition pair, any transition to `clos This allows the addition of new states without having to include separate transitions for each one. - + Use a double arrow syntax to specify state-to-state transitions in both directions. - + ### Use wildcard state with multiple transition states @@ -37,7 +37,7 @@ If the button can change from `open` to either `closed` or something like `inPro wildcard state with 3 states - + The `* => *` transition applies when any change between two states takes place. @@ -45,27 +45,27 @@ Transitions are matched in the order in which they are defined. Thus, you can apply other transitions on top of the `* => *` transition. For example, define style changes or animations that would apply just to `open => closed`, then use `* => *` as a fallback for state pairings that aren't otherwise called out. -To do this, list the more specific transitions *before* `* => *`. +To do this, list the more specific transitions _before_ `* => *`. ### Use wildcards with styles Use the wildcard `*` with a style to tell the animation to use whatever the current style value is, and animate with that. Wildcard is a fallback value that's used if the state being animated isn't declared within the trigger. - + ### Void state Use the `void` state to configure transitions for an element that is entering or leaving a page. -See [Animating entering and leaving a view](guide/animations/transition-and-triggers#aliases-enter-and-leave). +See [Animating entering and leaving a view](guide/legacy-animations/transition-and-triggers#aliases-enter-and-leave). ### Combine wildcard and void states Combine wildcard and void states in a transition to trigger animations that enter and leave the page: -* A transition of `* => void` applies when the element leaves a view, regardless of what state it was in before it left -* A transition of `void => *` applies when the element enters a view, regardless of what state it assumes when entering -* The wildcard state `*` matches to *any* state, including `void` +- A transition of `* => void` applies when the element leaves a view, regardless of what state it was in before it left +- A transition of `void => *` applies when the element enters a view, regardless of what state it assumes when entering +- The wildcard state `*` matches to _any_ state, including `void` ## Animate entering and leaving a view @@ -73,10 +73,10 @@ This section shows how to animate elements entering or leaving a page. Add a new behavior: -* When you add a hero to the list of heroes, it appears to fly onto the page from the left -* When you remove a hero from the list, it appears to fly out to the right +- When you add a hero to the list of heroes, it appears to fly onto the page from the left +- When you remove a hero from the list, it appears to fly out to the right - + In the preceding code, you applied the `void` state when the HTML element isn't attached to a view. @@ -87,8 +87,8 @@ These aliases are used by several animation functions. -transition ( ':enter', [ … ] ); // alias for void => * -transition ( ':leave', [ … ] ); // alias for * => void +transition ( ':enter', [ … ] ); // alias for void => _ +transition ( ':leave', [ … ] ); // alias for _ => void @@ -105,11 +105,11 @@ As a rule of thumb consider that any element being added to the DOM by Angular p This example has a special trigger for the enter and leave animation called `myInsertRemoveTrigger`. The HTML template contains the following code. - + In the component file, the `:enter` transition sets an initial opacity of 0. It then animates it to change that opacity to 1 as the element is inserted into the view. - + Note that this example doesn't need to use [`state()`](api/animations/state). @@ -119,15 +119,15 @@ The `transition()` function takes other selector values, `:increment` and `:decr Use these to kick off a transition when a numeric value has increased or decreased in value. HELPFUL: The following example uses `query()` and `stagger()` methods. -For more information on these methods, see the [complex sequences](guide/animations/complex-sequences) page. +For more information on these methods, see the [complex sequences](guide/legacy-animations/complex-sequences) page. - + ## Boolean values in transitions If a trigger contains a Boolean value as a binding value, then this value can be matched using a `transition()` expression that compares `true` and `false`, or `1` and `0`. - + In the code snippet above, the HTML template binds a `
    ` element to a trigger named `openClose` with a status expression of `isOpen`, and with possible values of `true` and `false`. This pattern is an alternative to the practice of creating two named states like `open` and `close`. @@ -136,7 +136,7 @@ Inside the `@Component` metadata under the `animations:` property, when the stat In this case, the animation uses whatever height the element already had before the animation started. When the element is `closed`, the element gets animated to a height of 0, which makes it invisible. - + ## Multiple animation triggers @@ -156,8 +156,8 @@ When true, the `@.disabled` binding prevents all animations from rendering. The following code sample shows how to use this feature. - - + + When the `@.disabled` binding is true, the `@childAnimation` trigger doesn't kick off. @@ -167,31 +167,31 @@ You can't selectively turn off multiple animations on a single element. -* A child animation can be queried by a parent and then later animated with the `animateChild()` function +- A child animation can be queried by a parent and then later animated with the `animateChild()` function #### Disable all animations To turn off all animations for an Angular application, place the `@.disabled` host binding on the topmost Angular component. - + HELPFUL: Disabling animations application-wide is useful during end-to-end \(E2E\) testing. ## Animation callbacks -The animation `trigger()` function emits *callbacks* when it starts and when it finishes. +The animation `trigger()` function emits _callbacks_ when it starts and when it finishes. The following example features a component that contains an `openClose` trigger. - + In the HTML template, the animation event is passed back via `$event`, as `@triggerName.start` and `@triggerName.done`, where `triggerName` is the name of the trigger being used. In this example, the trigger `openClose` appears as follows. - + A potential use for animation callbacks could be to cover for a slow API call, such as a database lookup. For example, an **InProgress** button can be set up to have its own looping animation while the backend system operation finishes. @@ -199,16 +199,16 @@ For example, an **InProgress** button can be set up to have its own looping anim Another animation can be called when the current animation finishes. For example, the button goes from the `inProgress` state to the `closed` state when the API call is completed. -An animation can influence an end user to *perceive* the operation as faster, even when it is not. +An animation can influence an end user to _perceive_ the operation as faster, even when it is not. Callbacks can serve as a debugging tool, for example in conjunction with `console.warn()` to view the application's progress in a browser's Developer JavaScript Console. The following code snippet creates console log output for the original example, a button with the two states of `open` and `closed`. - + ## Keyframes -To create an animation with multiple steps run in sequence, use *keyframes*. +To create an animation with multiple steps run in sequence, use _keyframes_. Angular's `keyframe()` function allows several style changes within a single timing segment. For example, the button, instead of fading, could change color several times over a single 2-second time span. @@ -217,7 +217,7 @@ For example, the button, instead of fading, could change color several times ove The code for this color change might look like this. - + ### Offset @@ -233,7 +233,7 @@ Specifying an offset of 0.8 for the middle transition in the preceding example m The code with offsets specified would be as follows. - + You can combine keyframes with `duration`, `delay`, and `easing` within a single animation. @@ -243,14 +243,14 @@ Use keyframes to create a pulse effect in your animations by defining styles at Here's an example of using keyframes to create a pulse effect: -* The original `open` and `closed` states, with the original changes in height, color, and opacity, occurring over a timeframe of 1 second -* A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1 second timeframe +- The original `open` and `closed` states, with the original changes in height, color, and opacity, occurring over a timeframe of 1 second +- A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1 second timeframe keyframes with irregular pulsation The code snippet for this animation might look like this. - + ### Animatable properties and units @@ -260,14 +260,14 @@ The W3C maintains a list of animatable properties on its [CSS Transitions](https For properties with a numeric value, define a unit by providing the value as a string, in quotes, with the appropriate suffix: -* 50 pixels: - `'50px'` +- 50 pixels: + `'50px'` -* Relative font size: - `'3em'` +- Relative font size: + `'3em'` -* Percentage: - `'100%'` +- Percentage: + `'100%'` You can also provide the value as a number. In such cases Angular assumes a default unit of pixels, or `px`. Expressing 50 pixels as `50` is the same as saying `'50px'`. @@ -285,7 +285,7 @@ In these cases, you can use a special wildcard `*` property value under `style() The following example has a trigger called `shrinkOut`, used when an HTML element leaves the page. The animation takes whatever height the element has before it leaves, and animates from that height to zero. - + ### Keyframes summary @@ -296,8 +296,9 @@ The `keyframes()` function in Angular allows you to specify multiple interim sty You might also be interested in the following: - - - - + + + + + diff --git a/adev/src/content/guide/aria/BUILD.bazel b/adev/src/content/guide/aria/BUILD.bazel new file mode 100644 index 000000000000..2aa462faedde --- /dev/null +++ b/adev/src/content/guide/aria/BUILD.bazel @@ -0,0 +1,19 @@ +load("//adev/shared-docs:defaults.bzl", "copy_to_bin") +load("//adev/shared-docs:index.bzl", "generate_guides") + +generate_guides( + name = "aria", + srcs = glob([ + "*.md", + ]), + data = [ + "//adev/src/content/examples", + ], + visibility = ["//adev:__subpackages__"], +) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/aria/accordion.md b/adev/src/content/guide/aria/accordion.md new file mode 100644 index 000000000000..2588aeeb47e6 --- /dev/null +++ b/adev/src/content/guide/aria/accordion.md @@ -0,0 +1,251 @@ + + + + + + + + +## Overview + +An accordion organizes related content into expandable and collapsible sections, reducing page scrolling and helping users focus on relevant information. Each section has a trigger button and a content panel. Clicking a trigger toggles the visibility of its associated panel. + + + + + + + +## Usage + +Accordions work well for organizing content into logical groups where users typically need to view one section at a time. + +**Use accordions when:** + +- Displaying FAQs with multiple questions and answers +- Organizing long forms into manageable sections +- Reducing scrolling on content-heavy pages +- Progressively disclosing related information + +**Avoid accordions when:** + +- Building navigation menus (use the [Menu](guide/aria/menu) component instead) +- Creating tabbed interfaces (use the [Tabs](guide/aria/tabs) component instead) +- Showing a single collapsible section (use a disclosure pattern instead) +- Users need to see multiple sections simultaneously (consider a different layout) + +## Features + +- **Expansion modes** - Control whether one or multiple panels can be open at the same time +- **Keyboard navigation** - Navigate between triggers using arrow keys, Home, and End +- **Lazy rendering** - Content is only created when a panel first expands, improving initial load performance +- **Disabled states** - Disable the entire group or individual triggers +- **Focus management** - Control whether disabled items can receive keyboard focus +- **Programmatic control** - Expand, collapse, or toggle panels from your component code +- **RTL support** - Automatic support for right-to-left languages + +## Examples + +### Single expansion mode + +Set `[multiExpandable]="false"` to allow only one panel to be open at a time. Opening a new panel automatically closes any previously open panel. + + + + + + + + + + + + + + + + + + + + + + + + + +This mode works well for FAQs or situations where you want users to focus on one answer at a time. + +### Multiple expansion mode + +Set `[multiExpandable]="true"` to allow multiple panels to be open simultaneously. Users can expand as many panels as needed without closing others. + + + + + + + + + + + + + + + + + + + + + + + + + +This mode is useful for form sections or when users need to compare content across multiple panels. + +NOTE: The `multiExpandable` input defaults to `true`. Set it to `false` explicitly if you want single expansion behavior. + +### Disabled accordion items + +Disable specific triggers using the `disabled` input. Control how disabled items behave during keyboard navigation using the `softDisabled` input on the accordion group. + + + + + + + + + + + + + + + + + + + + + + + + + +When `[softDisabled]="true"` (the default), disabled items can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled items are skipped entirely during keyboard navigation. + +### Lazy content rendering + +Use the `ngAccordionContent` directive on an `ng-template` to defer rendering content until the panel first expands. This improves performance for accordions with heavy content like images, charts, or complex components. + +```angular-html +
    +
    + +
    + + + Description + + +
    +
    +
    +``` + +By default, content remains in the DOM after the panel collapses. Set `[preserveContent]="false"` to remove the content from the DOM when the panel closes. + +## APIs + +### AccordionGroup + +The container directive that manages keyboard navigation and expansion behavior for a group of accordion items. + +#### Inputs + +| Property | Type | Default | Description | +| ----------------- | --------- | ------- | ------------------------------------------------------------------------- | +| `disabled` | `boolean` | `false` | Disables all triggers in the group | +| `multiExpandable` | `boolean` | `true` | Whether multiple panels can be expanded simultaneously | +| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable. When `false`, they are skipped | +| `wrap` | `boolean` | `false` | Whether keyboard navigation wraps from last to first item and vice versa | + +#### Methods + +| Method | Parameters | Description | +| ------------- | ---------- | ---------------------------------------------------------------- | +| `expandAll` | none | Expands all panels (only works when `multiExpandable` is `true`) | +| `collapseAll` | none | Collapses all panels | + +### AccordionTrigger + +The directive applied to the button element that toggles panel visibility. + +#### Inputs + +| Property | Type | Default | Description | +| ---------- | --------- | ------- | -------------------------------------------------------------- | +| `id` | `string` | auto | Unique identifier for the trigger | +| `panelId` | `string` | — | **Required.** Must match the `panelId` of the associated panel | +| `disabled` | `boolean` | `false` | Disables this trigger | +| `expanded` | `boolean` | `false` | Whether the panel is expanded (supports two-way binding) | + +#### Signals + +| Property | Type | Description | +| -------- | ----------------- | --------------------------------------- | +| `active` | `Signal` | Whether the trigger currently has focus | + +#### Methods + +| Method | Parameters | Description | +| ---------- | ---------- | --------------------------------- | +| `expand` | none | Expands the associated panel | +| `collapse` | none | Collapses the associated panel | +| `toggle` | none | Toggles the panel expansion state | + +### AccordionPanel + +The directive applied to the element containing the collapsible content. + +#### Inputs + +| Property | Type | Default | Description | +| ----------------- | --------- | ------- | ---------------------------------------------------------------- | +| `id` | `string` | auto | Unique identifier for the panel | +| `panelId` | `string` | — | **Required.** Must match the `panelId` of the associated trigger | +| `preserveContent` | `boolean` | `true` | Whether to keep content in DOM after panel collapses | + +#### Signals + +| Property | Type | Description | +| --------- | ----------------- | --------------------------------------- | +| `visible` | `Signal` | Whether the panel is currently expanded | + +#### Methods + +| Method | Parameters | Description | +| ---------- | ---------- | --------------------------- | +| `expand` | none | Expands this panel | +| `collapse` | none | Collapses this panel | +| `toggle` | none | Toggles the expansion state | + +### AccordionContent + +The structural directive applied to an `ng-template` inside an accordion panel to enable lazy rendering. + +This directive has no inputs, outputs, or methods. Apply it to an `ng-template` element: + +```angular-html +
    + + + +
    +``` diff --git a/adev/src/content/guide/aria/autocomplete.md b/adev/src/content/guide/aria/autocomplete.md new file mode 100644 index 000000000000..73f2ab7a445c --- /dev/null +++ b/adev/src/content/guide/aria/autocomplete.md @@ -0,0 +1,190 @@ + + + +## Overview + +An accessible input field that filters and suggests options as users type, helping them find and select values from a list. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Usage + +Autocomplete works best when users need to select from a large set of options where typing is faster than scrolling. Consider using autocomplete when: + +- **The option list is long** (more than 20 items) - Typing narrows down choices faster than scrolling through a dropdown +- **Users know what they're looking for** - They can type part of the expected value (like a state name, product, or username) +- **Options follow predictable patterns** - Users can guess partial matches (like country codes, email domains, or categories) +- **Speed matters** - Forms benefit from quick selection without extensive navigation + +Avoid autocomplete when: + +- The list has fewer than 10 options - A regular dropdown or radio group provides better visibility +- Users need to browse options - If discovery is important, show all options upfront +- Options are unfamiliar - Users can't type what they don't know exists in the list + +## Features + +Angular's autocomplete provides a fully accessible combobox implementation with: + +- **Keyboard Navigation** - Navigate options with arrow keys, select with Enter, close with Escape +- **Screen Reader Support** - Built-in ARIA attributes for assistive technologies +- **Three Filter Modes** - Choose between auto-select, manual selection, or highlighting behavior +- **Signal-Based Reactivity** - Reactive state management using Angular signals +- **Popover API Integration** - Leverages the native HTML Popover API for optimal positioning +- **Bidirectional Text Support** - Automatically handles right-to-left (RTL) languages + +## Examples + +### Auto-select mode + +Users typing partial text expect immediate confirmation that their input matches an available option. Auto-select mode updates the input value to match the first filtered option as users type, reducing the number of keystrokes needed and providing instant feedback that their search is on the right track. + + + + + + + + + + + + + + + + + + + + + + + + + + + +### Manual selection mode + +Manual selection mode keeps the typed text unchanged while users navigate the suggestion list, preventing confusion from automatic updates. The input only changes when users explicitly confirm their choice with Enter or a click. + + + + + + + + + + + + + + + + + + + + + + + + + + + +### Highlight mode + +Highlight mode allows the user to navigate options with arrow keys without changing the input value as they browse until they explicitly select a new option with Enter or click. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## APIs + +### Combobox Directive + +The `ngCombobox` directive provides the container for autocomplete functionality. + +#### Inputs + +| Property | Type | Default | Description | +| ------------ | ---------------------------------------------- | ---------- | ------------------------------------------------- | +| `filterMode` | `'auto-select'` \| `'manual'` \| `'highlight'` | `'manual'` | Controls selection behavior | +| `disabled` | `boolean` | `false` | Disables the combobox | +| `firstMatch` | `string` | - | The value of the first matching item in the popup | + +#### Outputs + +| Property | Type | Description | +| ---------- | ----------------- | ----------------------------------------------------- | +| `expanded` | `Signal` | Signal indicating whether the popup is currently open | + +### ComboboxInput Directive + +The `ngComboboxInput` directive connects an input element to the combobox. + +#### Model + +| Property | Type | Description | +| -------- | -------- | ------------------------------------------------------------ | +| `value` | `string` | Two-way bindable string value of the input using `[(value)]` | + +### ComboboxPopupContainer Directive + +The `ngComboboxPopupContainer` directive wraps the popup content and manages its display. + +Must be used with `` inside a popover element. + +### Related components + +Autocomplete uses [Listbox](/api/aria/listbox/Listbox) and [Option](/api/aria/listbox/Option) directives to render the suggestion list. See the [Listbox documentation](/guide/aria/listbox) for additional customization options. diff --git a/adev/src/content/guide/aria/combobox.md b/adev/src/content/guide/aria/combobox.md new file mode 100644 index 000000000000..71390217ca46 --- /dev/null +++ b/adev/src/content/guide/aria/combobox.md @@ -0,0 +1,255 @@ + + + + + + + + +## Overview + +A directive that coordinates a text input with a popup, providing the primitive directive for autocomplete, select, and multiselect patterns. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Usage + +Combobox is the primitive directive that coordinates a text input with a popup. It provides the foundation for autocomplete, select, and multiselect patterns. Consider using combobox directly when: + +- **Building custom autocomplete patterns** - Creating specialized filtering or suggestion behavior +- **Creating custom selection components** - Developing dropdowns with unique requirements +- **Coordinating input with popup** - Pairing text input with listbox, tree, or dialog content +- **Implementing specific filter modes** - Using manual, auto-select, or highlight behaviors + +Use documented patterns instead when: + +- Standard autocomplete with filtering is needed - See the [Autocomplete pattern](guide/aria/autocomplete) for ready-to-use examples +- Single-selection dropdowns are needed - See the [Select pattern](guide/aria/select) for complete dropdown implementation +- Multiple-selection dropdowns are needed - See the [Multiselect pattern](guide/aria/multiselect) for multi-select with compact display + +Note: The [Autocomplete](guide/aria/autocomplete), [Select](guide/aria/select), and [Multiselect](guide/aria/multiselect) guides show documented patterns that combine this directive with [Listbox](guide/aria/listbox) for specific use cases. + +## Features + +Angular's combobox provides a fully accessible input-popup coordination system with: + +- **Text Input with Popup** - Coordinates input field with popup content +- **Three Filter Modes** - Manual, auto-select, or highlight behaviors +- **Keyboard Navigation** - Arrow keys, Enter, Escape handling +- **Screen Reader Support** - Built-in ARIA attributes including role="combobox" and aria-expanded +- **Popup Management** - Automatic show/hide based on user interaction +- **Signal-Based Reactivity** - Reactive state management using Angular signals + +## Examples + +### Autocomplete + +An accessible input field that filters and suggests options as users type, helping them find and select values from a list. + + + + + + + + + + + + + + + + + + + + + + + + + + + +The `filterMode="manual"` setting gives complete control over filtering and selection. The input updates a signal that filters the options list. Users navigate with arrow keys and select with Enter or click. This mode provides the most flexibility for custom filtering logic. See the [Autocomplete guide](guide/aria/autocomplete) for complete filtering patterns and examples. + +### Readonly mode + +A pattern that combines a readonly combobox with listbox to create single-selection dropdowns with keyboard navigation and screen reader support. + + + + + + + + + + + + + + + + + + + + + + + + + + + +The `readonly` attribute prevents typing in the input field. The popup opens on click or arrow keys. Users navigate options with keyboard and select with Enter or click. + +This configuration provides the foundation for the [Select](guide/aria/select) and [Multiselect](guide/aria/multiselect) patterns. See those guides for complete dropdown implementations with triggers and overlay positioning. + +### Dialog popup + +Popups sometimes need modal behavior with a backdrop and focus trap. The combobox dialog directive provides this pattern for specialized use cases. + + + + + + + + + + + + + + + + + + + + + + + + + + + +The `ngComboboxDialog` directive creates a modal popup using the native dialog element. This provides backdrop behavior and focus trapping. Use dialog popups when the selection interface requires modal interaction or when the popup content is complex enough to warrant full-screen focus. + +## APIs + +### Combobox Directive + +The `ngCombobox` directive coordinates a text input with a popup. + +#### Inputs + +| Property | Type | Default | Description | +| ---------------- | ---------------------------------------------- | ---------- | ------------------------------------------------ | +| `filterMode` | `'manual'` \| `'auto-select'` \| `'highlight'` | `'manual'` | Controls selection behavior | +| `disabled` | `boolean` | `false` | Disables the combobox | +| `readonly` | `boolean` | `false` | Makes combobox readonly (for Select/Multiselect) | +| `firstMatch` | `V` | - | Value of first matching item for auto-select | +| `alwaysExpanded` | `boolean` | `false` | Keeps popup always open | + +**Filter Modes:** + +- **`'manual'`** - User controls filtering and selection explicitly. The popup shows options based on your filtering logic. Users select with Enter or click. This mode provides the most flexibility. +- **`'auto-select'`** - Input value automatically updates to the first matching option as users type. Requires the `firstMatch` input for coordination. See the [Autocomplete guide](guide/aria/autocomplete#auto-select-mode) for examples. +- **`'highlight'`** - Highlights matching text without changing the input value. Users navigate with arrow keys and select with Enter. + +#### Signals + +| Property | Type | Description | +| ---------- | ----------------- | ------------------------------- | +| `expanded` | `Signal` | Whether popup is currently open | + +#### Methods + +| Method | Parameters | Description | +| ---------- | ---------- | ---------------------- | +| `open` | none | Opens the combobox | +| `close` | none | Closes the combobox | +| `expand` | none | Expands the combobox | +| `collapse` | none | Collapses the combobox | + +### ComboboxInput Directive + +The `ngComboboxInput` directive connects an input element to the combobox. + +#### Model + +| Property | Type | Description | +| -------- | -------- | ---------------------------------------- | +| `value` | `string` | Two-way bindable value using `[(value)]` | + +The input element receives keyboard handling and ARIA attributes automatically. + +### ComboboxPopup Directive + +The `ngComboboxPopup` directive (host directive) manages popup visibility and coordination. Typically used with `ngComboboxPopupContainer` in an `ng-template` or with CDK Overlay. + +### ComboboxPopupContainer Directive + +The `ngComboboxPopupContainer` directive marks an `ng-template` as the popup content. + +```html + +
    ...
    +
    +``` + +Used with Popover API or CDK Overlay for positioning. + +### ComboboxDialog Directive + +The `ngComboboxDialog` directive creates a modal combobox popup. + +```html + +
    ...
    +
    +``` + +Use for modal popup behavior with backdrop and focus trap. + +### Related patterns and directives + +Combobox is the primitive directive for these documented patterns: + +- **[Autocomplete](guide/aria/autocomplete)** - Filtering and suggestions pattern (uses Combobox with filter modes) +- **[Select](guide/aria/select)** - Single selection dropdown pattern (uses Combobox with `readonly`) +- **[Multiselect](guide/aria/multiselect)** - Multiple selection pattern (uses Combobox with `readonly` + multi-enabled Listbox) + +Combobox typically combines with: + +- **[Listbox](guide/aria/listbox)** - Most common popup content +- **[Tree](guide/aria/tree)** - Hierarchical popup content (see Tree guide for examples) diff --git a/adev/src/content/guide/aria/grid.md b/adev/src/content/guide/aria/grid.md new file mode 100644 index 000000000000..2b162aee1502 --- /dev/null +++ b/adev/src/content/guide/aria/grid.md @@ -0,0 +1,214 @@ + + + + + + + + +## Overview + +A grid enables users to navigate two-dimensional data or interactive elements using directional arrow keys, Home, End, and Page Up/Down. Grids work for data tables, calendars, spreadsheets, and layout patterns that group related interactive elements. + + + + + + + +## Usage + +Grids work well for data or interactive elements organized in rows and columns where users need keyboard navigation in multiple directions. + +**Use grids when:** + +- Building interactive data tables with editable or selectable cells +- Creating calendars or date pickers +- Implementing spreadsheet-like interfaces +- Grouping interactive elements (buttons, checkboxes) to reduce tab stops on a page +- Building interfaces requiring two-dimensional keyboard navigation + +**Avoid grids when:** + +- Displaying simple read-only tables (use semantic HTML `` instead) +- Showing single-column lists (use [Listbox](guide/aria/listbox) instead) +- Displaying hierarchical data (use [Tree](guide/aria/tree) instead) +- Building forms without tabular layout (use standard form controls) + +## Features + +- **Two-dimensional navigation** - Arrow keys move between cells in all directions +- **Focus modes** - Choose between roving tabindex or activedescendant focus strategies +- **Selection support** - Optional cell selection with single or multi-select modes +- **Wrapping behavior** - Configure how navigation wraps at grid edges (continuous, loop, or nowrap) +- **Range selection** - Select multiple cells with modifier keys or dragging +- **Disabled states** - Disable the entire grid or individual cells +- **RTL support** - Automatic right-to-left language navigation + +## Examples + +### Data table grid + +Use a grid for interactive tables where users need to navigate between cells using arrow keys. This example shows a basic data table with keyboard navigation. + + + + + + + + + + + + + + + + + + +Apply the `ngGrid` directive to the table element, `ngGridRow` to each row, and `ngGridCell` to each cell. + +### Calendar grid + +Calendars are a common use case for grids. This example shows a month view where users navigate dates using arrow keys. + + + + + + + + + + + + + + + + + + + + + + + + + +Users can activate a date by pressing Enter or Space when focused on a cell. + +### Layout grid + +Use a layout grid to group interactive elements and reduce tab stops. This example shows a grid of pill buttons. + + + + + + + + + + + + + + + + + + + + + + + + + +Instead of tabbing through each button, users navigate with arrow keys and only one button receives tab focus. + +### Selection and focus modes + +Enable selection with `[enableSelection]="true"` and configure how focus and selection interact. + +```angular-html +
    + + + + +
    Cell 1Cell 2
    +``` + +**Selection modes:** + +- `follow`: Focused cell is automatically selected +- `explicit`: Users select cells with Space or click + +**Focus modes:** + +- `roving`: Focus moves to cells using `tabindex` (better for simple grids) +- `activedescendant`: Focus stays on grid container, `aria-activedescendant` indicates active cell (better for virtual scrolling) + +## APIs + +### Grid + +The container directive that provides keyboard navigation and focus management for rows and cells. + +#### Inputs + +| Property | Type | Default | Description | +| ---------------------- | ------------------------------------ | ---------- | ------------------------------------------------------------- | +| `enableSelection` | `boolean` | `false` | Whether selection is enabled for the grid | +| `disabled` | `boolean` | `false` | Disables the entire grid | +| `softDisabled` | `boolean` | `true` | When `true`, disabled cells are focusable but not interactive | +| `focusMode` | `'roving' \| 'activedescendant'` | `'roving'` | Focus strategy used by the grid | +| `rowWrap` | `'continuous' \| 'loop' \| 'nowrap'` | `'loop'` | Navigation wrapping behavior along rows | +| `colWrap` | `'continuous' \| 'loop' \| 'nowrap'` | `'loop'` | Navigation wrapping behavior along columns | +| `multi` | `boolean` | `false` | Whether multiple cells can be selected | +| `selectionMode` | `'follow' \| 'explicit'` | `'follow'` | Whether selection follows focus or requires explicit action | +| `enableRangeSelection` | `boolean` | `false` | Enable range selections with modifier keys or dragging | + +### GridRow + +Represents a row within a grid and serves as a container for grid cells. + +#### Inputs + +| Property | Type | Default | Description | +| ---------- | -------- | ------- | ------------------------------------- | +| `rowIndex` | `number` | auto | The index of this row within the grid | + +### GridCell + +Represents an individual cell within a grid row. + +#### Inputs + +| Property | Type | Default | Description | +| ------------- | ---------------------------- | -------------- | ------------------------------------------------------- | +| `id` | `string` | auto | Unique identifier for the cell | +| `role` | `string` | `'gridcell'` | Cell role: `gridcell`, `columnheader`, or `rowheader` | +| `disabled` | `boolean` | `false` | Disables this cell | +| `selected` | `boolean` | `false` | Whether the cell is selected (supports two-way binding) | +| `selectable` | `boolean` | `true` | Whether the cell can be selected | +| `rowSpan` | `number` | — | Number of rows the cell spans | +| `colSpan` | `number` | — | Number of columns the cell spans | +| `rowIndex` | `number` | — | Row index of the cell | +| `colIndex` | `number` | — | Column index of the cell | +| `orientation` | `'vertical' \| 'horizontal'` | `'horizontal'` | Orientation for widgets within the cell | +| `wrap` | `boolean` | `true` | Whether widget navigation wraps within the cell | + +#### Signals + +| Property | Type | Description | +| -------- | ----------------- | ------------------------------------ | +| `active` | `Signal` | Whether the cell currently has focus | diff --git a/adev/src/content/guide/aria/listbox.md b/adev/src/content/guide/aria/listbox.md new file mode 100644 index 000000000000..a1863dc15141 --- /dev/null +++ b/adev/src/content/guide/aria/listbox.md @@ -0,0 +1,193 @@ + + + + + + + + +## Overview + +A directive that displays a list of options for users to select from, supporting keyboard navigation, single or multiple selection, and screen reader support. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Usage + +Listbox is a foundational directive used by the [Select](guide/aria/select), [Multiselect](guide/aria/multiselect), and [Autocomplete](guide/aria/autocomplete) patterns. For most dropdown needs, use those documented patterns instead. + +Consider using listbox directly when: + +- **Building custom selection components** - Creating specialized interfaces with specific behavior +- **Visible selection lists** - Displaying selectable items directly on the page (not in dropdowns) +- **Custom integration patterns** - Integrating with unique popup or layout requirements + +Avoid listbox when: + +- **Navigation menus are needed** - Use the [Menu](guide/aria/menu) directive for actions and commands + +## Features + +Angular's listbox provides a fully accessible list implementation with: + +- **Keyboard Navigation** - Navigate options with arrow keys, select with Enter or Space +- **Screen Reader Support** - Built-in ARIA attributes including role="listbox" +- **Single or Multiple Selection** - `multi` attribute controls selection mode +- **Horizontal or Vertical** - `orientation` attribute for layout direction +- **Type-ahead Search** - Type characters to jump to matching options +- **Signal-Based Reactivity** - Reactive state management using Angular signals + +## Examples + +### Basic listbox + +Applications sometimes need selectable lists visible directly on the page rather than hidden in a dropdown. A standalone listbox provides keyboard navigation and selection for these visible list interfaces. + + + + + + +The `values` model signal provides two-way binding to the selected items. With `selectionMode="explicit"`, users press Space or Enter to select options. For dropdown patterns that combine listbox with combobox and overlay positioning, see the [Select](guide/aria/select) pattern. + +### Horizontal listbox + +Lists sometimes work better horizontally, such as toolbar-like interfaces or tab-style selections. The `orientation` attribute changes both the layout and keyboard navigation direction. + + + + + + + + + + + + + + + + + + + + + + + + + + + +With `orientation="horizontal"`, left and right arrow keys navigate between options instead of up and down. The listbox automatically handles right-to-left (RTL) languages by reversing navigation direction. + +### Selection modes + +Listbox supports two selection modes that control when items become selected. Choose the mode that matches your interface's interaction pattern. + + + + + + +The `'follow'` mode automatically selects the focused item, providing faster interaction when selection changes frequently. The `'explicit'` mode requires Space or Enter to confirm selection, preventing accidental changes while navigating. Dropdown patterns typically use `'follow'` mode for single selection. + +## APIs + +### Listbox Directive + +The `ngListbox` directive creates an accessible list of selectable options. + +#### Inputs + +| Property | Type | Default | Description | +| ---------------- | ---------------------------------- | ------------ | -------------------------------------------- | +| `id` | `string` | auto | Unique identifier for the listbox | +| `multi` | `boolean` | `false` | Enables multiple selection | +| `orientation` | `'vertical'` \| `'horizontal'` | `'vertical'` | Layout direction of the list | +| `wrap` | `boolean` | `true` | Whether focus wraps at list edges | +| `selectionMode` | `'follow'` \| `'explicit'` | `'follow'` | How selection is triggered | +| `focusMode` | `'roving'` \| `'activedescendant'` | `'roving'` | Focus management strategy | +| `softDisabled` | `boolean` | `true` | Whether disabled items are focusable | +| `disabled` | `boolean` | `false` | Disables the entire listbox | +| `readonly` | `boolean` | `false` | Makes listbox readonly | +| `typeaheadDelay` | `number` | `500` | Milliseconds before type-ahead search resets | + +#### Model + +| Property | Type | Description | +| -------- | ----- | ----------------------------------------- | +| `values` | `V[]` | Two-way bindable array of selected values | + +#### Signals + +| Property | Type | Description | +| -------- | ------------- | ------------------------------------- | +| `values` | `Signal` | Currently selected values as a signal | + +#### Methods + +| Method | Parameters | Description | +| -------------------------- | --------------------------------- | ------------------------------------------ | +| `scrollActiveItemIntoView` | `options?: ScrollIntoViewOptions` | Scrolls the active item into view | +| `gotoFirst` | none | Navigates to the first item in the listbox | + +### Option Directive + +The `ngOption` directive marks an item within a listbox. + +#### Inputs + +| Property | Type | Default | Description | +| ---------- | --------- | ------- | ------------------------------------------------ | +| `id` | `string` | auto | Unique identifier for the option | +| `value` | `V` | - | The value associated with this option (required) | +| `label` | `string` | - | Optional label for screen readers | +| `disabled` | `boolean` | `false` | Whether this option is disabled | + +#### Signals + +| Property | Type | Description | +| ---------- | ----------------- | ------------------------------- | +| `selected` | `Signal` | Whether this option is selected | +| `active` | `Signal` | Whether this option has focus | + +### Related patterns + +Listbox is used by these documented dropdown patterns: + +- **[Select](guide/aria/select)** - Single-selection dropdown pattern using readonly combobox + listbox +- **[Multiselect](guide/aria/multiselect)** - Multiple-selection dropdown pattern using readonly combobox + listbox with `multi` +- **[Autocomplete](guide/aria/autocomplete)** - Filterable dropdown pattern using combobox + listbox + +For complete dropdown patterns with trigger, popup, and overlay positioning, see those pattern guides instead of using listbox alone. + + + + + diff --git a/adev/src/content/guide/aria/menu.md b/adev/src/content/guide/aria/menu.md new file mode 100644 index 000000000000..444325cfd234 --- /dev/null +++ b/adev/src/content/guide/aria/menu.md @@ -0,0 +1,258 @@ + + + + + + + + +## Overview + +A menu offers a list of actions or options to users, typically appearing in response to a button click or right-click. Menus support keyboard navigation with arrow keys, submenus, checkboxes, radio buttons, and disabled items. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Usage + +Menus work well for presenting lists of actions or commands that users can choose from. + +**Use menus when:** + +- Building application command menus (File, Edit, View) +- Creating context menus (right-click actions) +- Showing dropdown action lists +- Implementing toolbar dropdowns +- Organizing settings or options + +**Avoid menus when:** + +- Building site navigation (use navigation landmarks instead) +- Creating form selects (use the [Select](guide/aria/select) component) +- Switching between content panels (use [Tabs](guide/aria/tabs)) +- Showing collapsible content (use [Accordion](guide/aria/accordion)) + +## Features + +- **Keyboard navigation** - Arrow keys, Home/End, and character search for efficient navigation +- **Submenus** - Nested menu support with automatic positioning +- **Menu types** - Standalone menus, triggered menus, and menubars +- **Checkboxes and radios** - Toggle and selection menu items +- **Disabled items** - Soft or hard disabled states with focus management +- **Auto-close behavior** - Configurable close on selection +- **RTL support** - Right-to-left language navigation + +## Examples + +### Menu with trigger + +Create a dropdown menu by pairing a trigger button with a menu. The trigger opens and closes the menu. + + + + + + + + + + + + + + + + + + + + + + + + + + + +The menu automatically closes when a user selects an item or presses Escape. + +### Context menu + +Context menus appear at the cursor position when users right-click an element. + + + + + + +Position the menu using the `contextmenu` event coordinates. + +### Standalone menu + +A standalone menu doesn't require a trigger and remains visible in the interface. + + + + + + + + + + + + + + + + + + + + + + + + + + + +Standalone menus work well for always-visible action lists or navigation. + +### Disabled menu items + +Disable specific menu items using the `disabled` input. Control focus behavior with `softDisabled`. + + + + + + + + + + + + + + + + + + + + + + + + + + + +When `[softDisabled]="true"`, disabled items can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled items are skipped during keyboard navigation. + +## APIs + +### Menu + +The container directive for menu items. + +#### Inputs + +| Property | Type | Default | Description | +| -------------- | --------- | ------- | ------------------------------------------------------------- | +| `disabled` | `boolean` | `false` | Disables all items in the menu | +| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps at edges | +| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive | + +#### Methods + +| Method | Parameters | Description | +| ---------------- | ---------- | ---------------------------------- | +| `close` | none | Closes the menu | +| `focusFirstItem` | none | Moves focus to the first menu item | + +### MenuBar + +A horizontal container for multiple menus. + +#### Inputs + +| Property | Type | Default | Description | +| -------------- | --------- | ------- | ------------------------------------------------------------- | +| `disabled` | `boolean` | `false` | Disables the entire menubar | +| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps at edges | +| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive | + +### MenuItem + +An individual item within a menu. + +#### Inputs + +| Property | Type | Default | Description | +| ------------ | --------- | ------- | ---------------------------------------------------- | +| `value` | `any` | — | **Required.** Value for this item | +| `disabled` | `boolean` | `false` | Disables this menu item | +| `submenu` | `Menu` | — | Reference to a submenu | +| `searchTerm` | `string` | `''` | Search term for typeahead (supports two-way binding) | + +#### Signals + +| Property | Type | Description | +| ---------- | ----------------- | ------------------------------------------ | +| `active` | `Signal` | Whether the item currently has focus | +| `expanded` | `Signal` | Whether the submenu is expanded | +| `hasPopup` | `Signal` | Whether the item has an associated submenu | + +NOTE: MenuItem does not expose public methods. Use the `submenu` input to associate submenus with menu items. + +### MenuTrigger + +A button or element that opens a menu. + +#### Inputs + +| Property | Type | Default | Description | +| -------------- | --------- | ------- | ------------------------------------------ | +| `menu` | `Menu` | — | **Required.** The menu to trigger | +| `disabled` | `boolean` | `false` | Disables the trigger | +| `softDisabled` | `boolean` | `true` | When `true`, disabled trigger is focusable | + +#### Signals + +| Property | Type | Description | +| ---------- | ----------------- | ------------------------------------------ | +| `expanded` | `Signal` | Whether the menu is currently open | +| `hasPopup` | `Signal` | Whether the trigger has an associated menu | + +#### Methods + +| Method | Parameters | Description | +| -------- | ---------- | ---------------------------- | +| `open` | none | Opens the menu | +| `close` | none | Closes the menu | +| `toggle` | none | Toggles the menu open/closed | diff --git a/adev/src/content/guide/aria/menubar.md b/adev/src/content/guide/aria/menubar.md new file mode 100644 index 000000000000..1abedb0c8fcc --- /dev/null +++ b/adev/src/content/guide/aria/menubar.md @@ -0,0 +1,198 @@ + + + + + + + + +## Overview + +The manubar is a horizontal navigation bar that provides persistent access to application menus. Menubars organize commands into logical categories like File, Edit, and View, helping users discover and execute application features through keyboard or mouse interaction. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Usage + +Menubars work well for organizing application commands into persistent, discoverable navigation. + +**Use menubars when:** + +- Building application command bars (such as File, Edit, View, Insert, Format) +- Creating persistent navigation that stays visible across the interface +- Organizing commands into logical top-level categories +- Need horizontal menu navigation with keyboard support +- Building desktop-style application interfaces + +**Avoid menubars when:** + +- Building dropdown menus for individual actions (use [Menu with trigger](guide/aria/menu) instead) +- Creating context menus (use [Menu](guide/aria/menu) guide pattern) +- Simple standalone action lists (use [Menu](guide/aria/menu) instead) +- Mobile interfaces where horizontal space is limited +- Navigation belongs in a sidebar or header navigation pattern + +## Features + +- **Horizontal navigation** - Left/Right arrow keys move between top-level categories +- **Persistent visibility** - Always visible, not modal or dismissable +- **Hover-to-open** - Submenus open on hover after first keyboard or click interaction +- **Nested submenus** - Support multiple levels of menu depth +- **Keyboard navigation** - Arrow keys, Enter/Space, Escape, and typeahead search +- **Disabled states** - Disable entire menubar or individual items +- **RTL support** - Automatic right-to-left language navigation + +## Examples + +### Basic menubar + +A menubar provides persistent access to application commands organized into top-level categories. Users navigate between categories with Left/Right arrows and open menus with Enter or Down arrow. + + + + + + + + + + + + + + + + + + + + + + + + + + + +Press Right arrow to move between File, Edit, and View. Press Enter or Down arrow to open a menu and navigate submenu items with Up/Down arrows. + +### Disabled menubar items + +Disable specific menu items or the entire menubar to prevent interaction. Control whether disabled items can receive keyboard focus with the `softDisabled` input. + + + + + + + + + + + + + + + + + + + + + + + + + + + +When `[softDisabled]="true"` on the menubar, disabled items can receive focus but cannot be activated. When `[softDisabled]="false"`, disabled items are skipped during keyboard navigation. + +### RTL support + +Menubars automatically adapt to right-to-left (RTL) languages. Arrow key navigation reverses direction, and submenus position on the left side. + + + + + + + + + + + + + + + + + + + + + + + + + + + +The `dir="rtl"` attribute enables RTL mode. Left arrow moves right, Right arrow moves left, maintaining natural navigation for RTL language users. + +## APIs + +The menubar pattern uses directives from Angular's Aria library. See the [Menu guide](guide/aria/menu) for complete API documentation. + +### MenuBar + +The horizontal container for top-level menu items. + +#### Inputs + +| Property | Type | Default | Description | +| -------------- | --------- | ------- | ------------------------------------------------------------- | +| `disabled` | `boolean` | `false` | Disables the entire menubar | +| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps from last to first item | +| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive | + +See the [Menu API documentation](guide/aria/menu#apis) for complete details on all available inputs and signals. + +### MenuItem + +Individual items within the menubar. Same API as Menu - see [MenuItem](guide/aria/menu#menuitem). + +**Menubar-specific behavior:** + +- Left/Right arrows navigate between menubar items (vs Up/Down in vertical menus) +- First keyboard interaction or click enables hover-to-open for submenus +- Enter or Down arrow opens the submenu and focuses the first item +- `aria-haspopup="menu"` indicates items with submenus + +### MenuTrigger + +Not typically used in menubars - MenuItem handles trigger behavior directly when it has an associated submenu. See [MenuTrigger](guide/aria/menu#menutrigger) for standalone menu trigger patterns. diff --git a/adev/src/content/guide/aria/multiselect.md b/adev/src/content/guide/aria/multiselect.md new file mode 100644 index 000000000000..dc27f4a676a2 --- /dev/null +++ b/adev/src/content/guide/aria/multiselect.md @@ -0,0 +1,201 @@ + + + +## Overview + +A pattern that combines readonly combobox with multi-enabled listbox to create multiple-selection dropdowns with keyboard navigation and screen reader support. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Usage + +The multiselect pattern works best when users need to choose multiple related items from a familiar set of options. + +Consider using this pattern when: + +- **Users need multiple selections** - Tags, categories, filters, or labels where multiple choices apply +- **The option list is fixed** (fewer than 20 items) - Users can scan options without search +- **Filtering content** - Multiple criteria can be active simultaneously +- **Assigning attributes** - Labels, permissions, or features where multiple values make sense +- **Related choices** - Options that logically work together (such as selecting multiple team members) + +Avoid this pattern when: + +- **Only single selection is needed** - Use the [Select pattern](guide/aria/select) for simpler single-choice dropdowns +- **The list has more than 20 items with search needed** - Use the [Autocomplete pattern](guide/aria/autocomplete) with multiselect capability +- **Most or all options will be selected** - A checklist pattern provides better visibility +- **Choices are independent binary options** - Individual checkboxes communicate the choices more clearly + +## Features + +The multiselect pattern combines [Combobox](guide/aria/combobox) and [Listbox](guide/aria/listbox) directives to provide a fully accessible dropdown with: + +- **Keyboard Navigation** - Navigate options with arrow keys, toggle with Space, close with Escape +- **Screen Reader Support** - Built-in ARIA attributes including aria-multiselectable +- **Selection Count Display** - Shows compact "Item + 2 more" pattern for multiple selections +- **Signal-Based Reactivity** - Reactive state management using Angular signals +- **Smart Positioning** - CDK Overlay handles viewport edges and scrolling +- **Persistent Selection** - Selected options remain visible with checkmarks after selection + +## Examples + +### Basic multiselect + +Users need to select multiple items from a list of options. A readonly combobox paired with a multi-enabled listbox provides familiar multiselect functionality with full accessibility support. + + + + + + + + + + + + + + + + + + + + + + + + + + + +The `multi` attribute on `ngListbox` enables multiple selection. Press Space to toggle options, and the popup remains open for additional selections. The display shows the first selected item plus a count of remaining selections. + +### Multiselect with custom display + +Options often need visual indicators like icons or colors to help users identify choices. Custom templates within options allow rich formatting while the display value shows a compact summary. + + + + + + + + + + + + + + + + + + + + + + + + + + + +Each option displays an icon alongside its label. The display value updates to show the first selection's icon and text, followed by a count of additional selections. Selected options show a checkmark for clear visual feedback. + +### Controlled selection + +Forms sometimes need to limit the number of selections or validate user choices. Programmatic control over selection enables these constraints while maintaining accessibility. + + + + + + + + + + + + + + + + + + + + + + + + + + + +This example limits selections to three items. When the limit is reached, unselected options become disabled, preventing additional selections. A message informs users about the constraint. + +## APIs + +The multiselect pattern uses the following directives from Angular's Aria library. See the full API documentation in the linked guides. + +### Combobox Directives + +The multiselect pattern uses `ngCombobox` with the `readonly` attribute to prevent text input while preserving keyboard navigation. + +#### Inputs + +| Property | Type | Default | Description | +| ---------- | --------- | ------- | ----------------------------------------- | +| `readonly` | `boolean` | `false` | Set to `true` to create dropdown behavior | +| `disabled` | `boolean` | `false` | Disables the entire multiselect | + +See the [Combobox API documentation](guide/aria/combobox#apis) for complete details on all available inputs and signals. + +### Listbox Directives + +The multiselect pattern uses `ngListbox` with the `multi` attribute for multiple selection and `ngOption` for each selectable item. + +#### Inputs + +| Property | Type | Default | Description | +| -------- | --------- | ------- | ------------------------------------------ | +| `multi` | `boolean` | `false` | Set to `true` to enable multiple selection | + +#### Model + +| Property | Type | Description | +| -------- | ------- | ----------------------------------------- | +| `values` | `any[]` | Two-way bindable array of selected values | + +When `multi` is true, users can select multiple options using Space to toggle selection. The popup remains open after selection, allowing additional choices. + +See the [Listbox API documentation](guide/aria/listbox#apis) for complete details on listbox configuration, selection modes, and option properties. + +### Positioning + +The multiselect pattern integrates with [CDK Overlay](api/cdk/overlay/CdkConnectedOverlay) for smart positioning. Use `cdkConnectedOverlay` to handle viewport edges and scrolling automatically. diff --git a/adev/src/content/guide/aria/overview.md b/adev/src/content/guide/aria/overview.md new file mode 100644 index 000000000000..9536e598e96e --- /dev/null +++ b/adev/src/content/guide/aria/overview.md @@ -0,0 +1,102 @@ + + + +## What is Angular Aria? + +Building accessible components seems straightforward, but implementing them according to the W3C Accessibility Guidelines requires significant effort and accessibility expertise. + +Angular Aria is a collection of headless, accessible directives that implement common WAI-ARIA patterns. The directives handle keyboard interactions, ARIA attributes, focus management, and screen reader support. All you have to do is provide the HTML structure, CSS styling, and business logic! + +## Installation + +```shell +npm install @angular/aria +``` + +## Showcase + +For example, let's take a toolbar menu. While it may appear to be a "simple" row of buttons tied with specific logic, keyboard navigation and screen readers add a lot of unexpected complexity to those unfamiliar with accessibility. + + + + + + + + + + + + + + + + + + + + + + + + + + + +In this one scenario, developers need to consider: + +- **Keyboard navigation**. Users need to open the menu with Enter or Space, navigate options with arrow keys, select with Enter, and close with Escape. +- **Screen readers** need to announce the menu's state, the number of options, and which option has focus. +- **Focus management** needs to move logically between the trigger and menu items. +- **Right-to-left languages** require the ability to navigate in reverse. + +## What's included? + +Angular Aria includes directives with comprehensive documentation, working examples and API references for common interactive patterns: + +### Search and selection + +| Component | Description | +| --------------------------------------- | -------------------------------------------------------------- | +| [Autocomplete](guide/aria/autocomplete) | Text input with filtered suggestions that appear as users type | +| [Listbox](guide/aria/listbox) | Single or multi-select option lists with keyboard navigation | +| [Select](guide/aria/select) | Single-selection dropdown pattern with keyboard navigation | +| [Multiselect](guide/aria/multiselect) | Multiple-selection dropdown pattern with compact display | +| [Combobox](guide/aria/combobox) | Primitive directive that coordinates a text input with a popup | + +### Navigation and call to actions + +| Component | Description | +| ----------------------------- | ---------------------------------------------------------- | +| [Menu](guide/aria/menu) | Dropdown menus with nested submenus and keyboard shortcuts | +| [Menubar](guide/aria/menubar) | Horizontal navigation bar for persistent application menus | +| [Toolbar](guide/aria/toolbar) | Grouped sets of controls with logical keyboard navigation | + +### Content organization + +| Component | Description | +| --------------------------------- | ---------------------------------------------------------------------- | +| [Accordion](guide/aria/accordion) | Collapsible content panels that can expand individually or exclusively | +| [Tabs](guide/aria/tabs) | Tabbed interfaces with automatic or manual activation modes | +| [Tree](guide/aria/tree) | Hierarchical lists with expand/collapse functionality | +| [Grid](guide/aria/grid) | Two-dimensional data display with cell-by-cell keyboard navigation | + +## When to use Angular Aria + +Angular Aria works well when you need accessible interactive components that are WCAG compliant with custom styling. Examples include: + +- **Building a design system** - Your team maintains a component library with specific visual standards that need accessible implementations +- **Enterprise component libraries** - You're creating reusable components for multiple applications within an organization +- **Custom brand requirements** - The interface needs to match precise design specifications that pre-styled component libraries cannot easily accommodate + +## When not to use Angular Aria + +Angular Aria might not fit every scenario: + +- **Pre-styled components** - If you need components that look complete without custom styling, use Angular Material instead +- **Simple forms** - Native HTML form controls like ` + + +
    + + +
    + + + +
    +``` + +### Disabled widgets + +Toolbars support two disabled modes: + +1. **Soft-disabled** widgets remain focusable but visually indicate they're unavailable +2. **Hard-disabled** widgets are completely removed from keyboard navigation. + +By default, `softDisabled` is `true`, which allows disabled widgets to still receive focus. If you want to enable hard-disabled mode, set `[softDisabled]="false"` on the toolbar. + + + + + + + + + + + + + + + + + + + + + + + + + + + +### Right-to-left (RTL) support + +Toolbars automatically support right-to-left languages. Wrap the toolbar in a container with `dir="rtl"` to reverse the layout and keyboard navigation direction. Arrow key navigation adjusts automatically: left arrow moves to the next widget, right arrow to the previous. + + + + + + + + + + + + + + + + + + + + + + + + + + + +## APIs + +### Toolbar Directive + +The `ngToolbar` directive provides the container for toolbar functionality. + +#### Inputs + +| Property | Type | Default | Description | +| -------------- | ------------------------------ | -------------- | ------------------------------------------------------ | +| `orientation` | `'vertical'` \| `'horizontal'` | `'horizontal'` | Whether toolbar is vertically or horizontally oriented | +| `disabled` | `boolean` | `false` | Disables the entire toolbar | +| `softDisabled` | `boolean` | `true` | Whether disabled items can receive focus | +| `wrap` | `boolean` | `true` | Whether focus should wrap at the edges | + +### ToolbarWidget Directive + +The `ngToolbarWidget` directive marks an element as a navigable widget within the toolbar. + +#### Inputs + +| Property | Type | Default | Description | +| ---------- | --------- | ------- | ----------------------------------------------- | +| `id` | `string` | auto | Unique identifier for the widget | +| `disabled` | `boolean` | `false` | Disables the widget | +| `value` | `V` | - | The value associated with the widget (required) | + +#### Signals + +| Property | Type | Description | +| ---------- | ----------------- | ------------------------------------------- | +| `active` | `Signal` | Whether the widget is currently focused | +| `selected` | `Signal` | Whether the widget is selected (in a group) | + +### ToolbarWidgetGroup Directive + +The `ngToolbarWidgetGroup` directive groups related widgets together. + +#### Inputs + +| Property | Type | Default | Description | +| ---------- | --------- | ------- | ---------------------------------------- | +| `disabled` | `boolean` | `false` | Disables all widgets in the group | +| `multi` | `boolean` | `false` | Whether multiple widgets can be selected | + +### Related components + +Toolbar can contain various widget types including buttons, trees, and comboboxes. See individual component documentation for specific widget implementations. + + + + + diff --git a/adev/src/content/guide/aria/tree.md b/adev/src/content/guide/aria/tree.md new file mode 100644 index 000000000000..712ab9cc4d08 --- /dev/null +++ b/adev/src/content/guide/aria/tree.md @@ -0,0 +1,230 @@ + + + + + + + + +## Overview + +A tree displays hierarchical data where items can expand to reveal children or collapse to hide them. Users navigate with arrow keys, expand and collapse nodes, and optionally select items for navigation or data selection scenarios. + + + + + + + +## Usage + +Trees work well for displaying hierarchical data where users need to navigate through nested structures. + +**Use trees when:** + +- Building file system navigation +- Showing folder and document hierarchies +- Creating nested menu structures +- Displaying organization charts +- Browsing hierarchical data +- Implementing site navigation with nested sections + +**Avoid trees when:** + +- Displaying flat lists (use [Listbox](guide/aria/listbox) instead) +- Showing data tables (use [Grid](guide/aria/grid) instead) +- Creating simple dropdowns (use [Select](guide/aria/select) instead) +- Building breadcrumb navigation (use breadcrumb patterns) + +## Features + +- **Hierarchical navigation** - Nested tree structure with expand and collapse functionality +- **Selection modes** - Single or multi-selection with explicit or follow-focus behavior +- **Selection follows focus** - Optional automatic selection when focus changes +- **Keyboard navigation** - Arrow keys, Home, End, and type-ahead search +- **Expand/collapse** - Right/Left arrows or Enter to toggle parent nodes +- **Disabled items** - Disable specific nodes with focus management +- **Focus modes** - Roving tabindex or activedescendant focus strategies +- **RTL support** - Right-to-left language navigation + +## Examples + +### Navigation tree + +Use a tree for navigation where clicking items triggers actions rather than selecting them. + + + + + + + + + + + +Set `[nav]="true"` to enable navigation mode. This uses `aria-current` to indicate the current page instead of selection. + +### Single selection + +Enable single selection for scenarios where users choose one item from the tree. + + + + + + + + + + + + + + + + + + +Leave `[multi]="false"` (the default) for single selection. Users press Space to select the focused item. + +### Multi-selection + +Allow users to select multiple items from the tree. + + + + + + + + + + + + + + + + + + +Set `[multi]="true"` on the tree. Users select items individually with Space or select ranges with Shift+Arrow keys. + +### Selection follows focus + +When selection follows focus, the focused item is automatically selected. This simplifies interaction for navigation scenarios. + + + + + + + + + + + + + + + + + + +Set `[selectionMode]="'follow'"` on the tree. Selection automatically updates as users navigate with arrow keys. + +### Disabled tree items + +Disable specific tree nodes to prevent interaction. Control whether disabled items can receive focus. + + + + + + + + + + + + + + + + + + +When `[softDisabled]="true"` on the tree, disabled items can receive focus but cannot be activated or selected. When `[softDisabled]="false"`, disabled items are skipped during keyboard navigation. + +## APIs + +### Tree + +The container directive that manages hierarchical navigation and selection. + +#### Inputs + +| Property | Type | Default | Description | +| --------------- | -------------------------------- | ------------ | ------------------------------------------------------------- | +| `disabled` | `boolean` | `false` | Disables the entire tree | +| `softDisabled` | `boolean` | `true` | When `true`, disabled items are focusable but not interactive | +| `multi` | `boolean` | `false` | Whether multiple items can be selected | +| `selectionMode` | `'explicit' \| 'follow'` | `'explicit'` | Whether selection requires explicit action or follows focus | +| `nav` | `boolean` | `false` | Whether the tree is in navigation mode (uses `aria-current`) | +| `wrap` | `boolean` | `true` | Whether keyboard navigation wraps from last to first item | +| `focusMode` | `'roving' \| 'activedescendant'` | `'roving'` | Focus strategy used by the tree | +| `values` | `any[]` | `[]` | Selected item values (supports two-way binding) | + +#### Methods + +| Method | Parameters | Description | +| ---------------- | ---------- | --------------------------------------------- | +| `expandAll` | none | Expands all tree nodes | +| `collapseAll` | none | Collapses all tree nodes | +| `selectAll` | none | Selects all items (only in multi-select mode) | +| `clearSelection` | none | Clears all selection | + +### TreeItem + +An individual node in the tree that can contain child nodes. + +#### Inputs + +| Property | Type | Default | Description | +| ---------- | --------- | ------- | ------------------------------------------------------- | +| `value` | `any` | — | **Required.** Unique value for this tree item | +| `disabled` | `boolean` | `false` | Disables this item | +| `expanded` | `boolean` | `false` | Whether the node is expanded (supports two-way binding) | + +#### Signals + +| Property | Type | Description | +| ------------- | ----------------- | ------------------------------------ | +| `selected` | `Signal` | Whether the item is selected | +| `active` | `Signal` | Whether the item currently has focus | +| `hasChildren` | `Signal` | Whether the item has child nodes | + +#### Methods + +| Method | Parameters | Description | +| ---------- | ---------- | --------------------------- | +| `expand` | none | Expands this node | +| `collapse` | none | Collapses this node | +| `toggle` | none | Toggles the expansion state | + +### TreeGroup + +A container for child tree items. + +This directive has no inputs, outputs, or methods. It serves as a container to organize child `ngTreeItem` elements: + +```angular-html +
  • + Parent Item +
      +
    • Child 1
    • +
    • Child 2
    • +
    +
  • +``` diff --git a/adev/src/content/guide/components/BUILD.bazel b/adev/src/content/guide/components/BUILD.bazel index a829bf726403..83596c30911d 100644 --- a/adev/src/content/guide/components/BUILD.bazel +++ b/adev/src/content/guide/components/BUILD.bazel @@ -1,3 +1,4 @@ +load("//adev/shared-docs:defaults.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -5,9 +6,16 @@ generate_guides( srcs = glob([ "*.md", ]), + api_manifest = "//adev/src/assets:docs_api_manifest", data = [ "//adev/src/assets/images:components.svg", ], mermaid_blocks = True, visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/components/anatomy-of-components.md b/adev/src/content/guide/components/anatomy-of-components.md index e90ce3677982..5a301b26aaf6 100644 --- a/adev/src/content/guide/components/anatomy-of-components.md +++ b/adev/src/content/guide/components/anatomy-of-components.md @@ -5,9 +5,9 @@ TIP: This guide assumes you've already read the [Essentials Guide](essentials). Every component must have: -* A TypeScript class with _behaviors_ such as handling user input and fetching data from a server -* An HTML template that controls what renders into the DOM -* A [CSS selector](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors) that defines how the component is used in HTML +- A TypeScript class with _behaviors_ such as handling user input and fetching data from a server +- An HTML template that controls what renders into the DOM +- A [CSS selector](https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/Selectors) that defines how the component is used in HTML You provide Angular-specific information for a component by adding a `@Component` [decorator](https://www.typescriptlang.org/docs/handbook/decorators.html) on top of the TypeScript class: @@ -58,7 +58,7 @@ Both `templateUrl` and `styleUrl` are relative to the directory in which the com To use a component, [directive](guide/directives), or [pipe](guide/templates/pipes), you must add it to the `imports` array in the `@Component` decorator: -```angular-ts +```ts import {ProfilePhoto} from './profile-photo'; @Component({ @@ -70,7 +70,7 @@ import {ProfilePhoto} from './profile-photo'; export class UserProfile { } ``` -By default, Angular components are *standalone*, meaning that you can directly add them to the `imports` array of other components. Components created with an earlier version of Angular may instead specify `standalone: false` in their `@Component` decorator. For these components, you instead import the `NgModule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details. +By default, Angular components are _standalone_, meaning that you can directly add them to the `imports` array of other components. Components created with an earlier version of Angular may instead specify `standalone: false` in their `@Component` decorator. For these components, you instead import the `NgModule` in which the component is defined. See the full [`NgModule` guide](guide/ngmodules) for details. Important: In Angular versions before 19.0.0, the `standalone` option defaults to `false`. @@ -97,8 +97,8 @@ You show a component by creating a matching HTML element in the template of _oth export class ProfilePhoto { } @Component({ - imports: [ProfilePhoto], - template: `` +imports: [ProfilePhoto], +template: `` }) export class UserProfile { } @@ -121,5 +121,4 @@ flowchart TD E[UserBio] ``` - This tree structure is important to understanding several other Angular concepts, including [dependency injection](guide/di) and [child queries](guide/components/queries). diff --git a/adev/src/content/guide/components/content-projection.md b/adev/src/content/guide/components/content-projection.md index 666748698bf7..efa351cabf9a 100644 --- a/adev/src/content/guide/components/content-projection.md +++ b/adev/src/content/guide/components/content-projection.md @@ -18,7 +18,7 @@ export class CustomCard {/* ... */} ```angular-ts @Component({ selector: 'custom-card', - template: '
    ', + template: '
    ', }) export class CustomCard {/* ... */} ``` @@ -68,7 +68,7 @@ placeholder that tells Angular where to render content. Angular's compiler proce all `` elements at build-time. You cannot insert, remove, or modify `` at run time. You cannot add directives, styles, or arbitrary attributes to ``. -You should not conditionally include `` with `@if`, `@for`, or `@switch`. Angular always +IMPORTANT: You should not conditionally include `` with `@if`, `@for`, or `@switch`. Angular always instantiates and creates DOM nodes for content rendered to a `` placeholder, even if that `` placeholder is hidden. For conditional rendering of component content, see [Template fragments](api/core/ng-template). @@ -79,21 +79,48 @@ Angular supports projecting multiple different elements into different `card-title`, +}) +export class CardTitle {} + +@Component({ + selector: 'card-body', + template: `card-body`, +}) +export class CardBody {} +``` + +```angular-ts -
    - -
    - -
    +Component({ + selector: 'custom-card', + template: ` +
    + +
    + +
    + `, +}) +export class CustomCard {} ``` -```angular-html +```angular-ts - - Hello - Welcome to the example - +@Component({ + selector: 'app-root', + imports: [CustomCard, CardTitle, CardBody], + template: ` + + Hello + Welcome to the example + +`, +}) +export class App {} ``` ```angular-html @@ -150,7 +177,7 @@ elements that don't match one of the component's placeholders do not render into ## Fallback content -Angular can show *fallback content* for a component's `` placeholder if that component doesn't have any matching child content. You can specify fallback content by adding child content to the `` element itself. +Angular can show _fallback content_ for a component's `` placeholder if that component doesn't have any matching child content. You can specify fallback content by adding child content to the `` element itself. ```angular-html diff --git a/adev/src/content/guide/components/host-elements.md b/adev/src/content/guide/components/host-elements.md index 8401ed41f1dc..38f5080b34ce 100644 --- a/adev/src/content/guide/components/host-elements.md +++ b/adev/src/content/guide/components/host-elements.md @@ -37,7 +37,7 @@ In the above example, `` is the host element of the `ProfilePhoto ## Binding to the host element -A component can bind properties, attributes, and events to its host element. This behaves +A component can bind properties, attributes, styles and events to its host element. This behaves identically to bindings on elements inside the component's template, but instead defined with the `host` property in the `@Component` decorator: @@ -48,6 +48,7 @@ the `host` property in the `@Component` decorator: 'role': 'slider', '[attr.aria-valuenow]': 'value', '[class.active]': 'isActive()', + '[style.background]' : `hasError() ? 'red' : 'green'`, '[tabIndex]': 'disabled ? -1 : 0', '(keydown)': 'updateValue($event)', }, @@ -56,6 +57,7 @@ export class CustomSlider { value: number = 0; disabled: boolean = false; isActive = signal(false); + hasError = signal(false); updateValue(event: KeyboardEvent) { /* ... */ } /* ... */ @@ -67,9 +69,9 @@ export class CustomSlider { You can alternatively bind to the host element by applying the `@HostBinding` and `@HostListener` decorator to class members. -`@HostBinding` lets you bind host properties and attributes to properties and methods: +`@HostBinding` lets you bind host properties and attributes to properties and getters: -```angular-ts +```ts @Component({ /* ... */ }) @@ -78,7 +80,7 @@ export class CustomSlider { value: number = 0; @HostBinding('tabIndex') - getTabIndex() { + get tabIndex() { return this.disabled ? -1 : 0; } @@ -98,8 +100,10 @@ export class CustomSlider { } ``` -**Always prefer using the `host` property over `@HostBinding` and `@HostListener`.** These + + **Always prefer using the `host` property over `@HostBinding` and `@HostListener`.** These decorators exist exclusively for backwards compatibility. + ## Binding collisions @@ -126,3 +130,58 @@ In cases like this, the following rules determine which value wins: - If both values are static, the instance binding wins. - If one value is static and the other dynamic, the dynamic value wins. - If both values are dynamic, the component's host binding wins. + +## Styling with CSS custom properties + +Developers often rely on [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascading_variables/Using_CSS_custom_properties) to enable a flexible configuration of their component's styles. +You can set such custom properties on a host element with a [style binding][style binding](guide/templates/binding#css-style-properties). + +```angular-ts +@Component({ + /* ... */ + host: { + '[style.--my-background]': 'color()', + } +}) +export class MyComponent { + color = signal('lightgreen'); +} +``` + +In this example, the `--my-background` CSS custom property is bound to the `color` signal. The value of the custom property will automatically update whenever the `color` signal changes. This will affect the current component and all its children that rely on this custom property. + +### Setting custom properties on children compoents + +Alternatively, it is also possible to set css custom properties on the host element of children components with a [style binding](guide/templates/binding#css-style-properties). + +```angular-ts +@Component({ + selector: 'my-component', + template: ``, +}) +export class MyComponent { + color = signal('lightgreen'); +} +``` + +## Injecting host element attributes + +Components and directives can read static attributes from their host element by using `HostAttributeToken` together with the [`inject`](api/core/inject) function. + +```ts +import { Component, HostAttributeToken, inject } from '@angular/core'; + +@Component({ + selector: 'app-button', + ..., +}) +export class Button { + variation = inject(new HostAttributeToken('variation')); +} +``` + +```angular-html +Click me +``` + +HELPFUL: `HostAttributeToken` throws an error if the attribute is missing, unless the injection is marked as optional. diff --git a/adev/src/content/guide/components/inheritance.md b/adev/src/content/guide/components/inheritance.md index ede807488d98..b11af7e587a4 100644 --- a/adev/src/content/guide/components/inheritance.md +++ b/adev/src/content/guide/components/inheritance.md @@ -35,7 +35,7 @@ host bindings, inputs, outputs, lifecycle methods. }, }) export class ListboxBase { - @Input() value: string; + value = input.required(); handleKey(event: KeyboardEvent) { /* ... */ } @@ -51,7 +51,7 @@ export class ListboxBase { }, }) export class CustomListbox extends ListboxBase { - @Input() disabled = false; + disabled = input(false); focusActiveOption() { /* ... */ } diff --git a/adev/src/content/guide/components/inputs.md b/adev/src/content/guide/components/inputs.md index b5320540ce7c..73651d757389 100644 --- a/adev/src/content/guide/components/inputs.md +++ b/adev/src/content/guide/components/inputs.md @@ -7,7 +7,7 @@ TIP: If you're familiar with other web frameworks, input properties are similar When you use a component, you commonly want to pass some data to it. A component specifies the data that it accepts by declaring **inputs**: - +```ts {highlight:[5]} import {Component, input} from '@angular/core'; @Component({/*...*/}) @@ -15,7 +15,7 @@ export class CustomSlider { // Declare an input named 'value' with a default value of zero. value = input(0); } - +``` This lets you bind to the property in a template: @@ -25,7 +25,7 @@ This lets you bind to the property in a template: If an input has a default value, TypeScript infers the type from the default value: -```typescript +```ts @Component({/*...*/}) export class CustomSlider { // TypeScript infers that this input is a number, returning InputSignal. @@ -37,7 +37,7 @@ You can explicitly declare a type for the input by specifying a generic paramete If an input without a default value is not set, its value is `undefined`: -```typescript +```ts @Component({/*...*/}) export class CustomSlider { // Produces an InputSignal because `value` may not be set. @@ -57,18 +57,18 @@ When extending a component class, **inputs are inherited by the child class.** The `input` function returns an `InputSignal`. You can read the value by calling the signal: - -import {Component, input} from '@angular/core'; +```ts {highlight:[5]} +import {Component, input, computed} from '@angular/core'; @Component({/*...*/}) export class CustomSlider { - // Declare an input named 'value' with a default value of zero. + // Declare an input named 'value' with a default value of zero. value = input(0); // Create a computed expression that reads the value input - label = computed(() => `The slider's value is ${this.value()}`); + label = computed(() => `The slider's value is ${this.value()}`); } - +``` Signals created by the `input` function are read-only. @@ -76,13 +76,13 @@ Signals created by the `input` function are read-only. You can declare that an input is `required` by calling `input.required` instead of `input`: - +```ts {highlight:[3]} @Component({/*...*/}) export class CustomSlider { // Declare a required input named value. Returns an `InputSignal`. value = input.required(); } - +``` Angular enforces that required inputs _must_ be set when the component is used in a template. If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time. @@ -96,7 +96,7 @@ The `input` function accepts a config object as a second parameter that lets you You can specify a `transform` function to change the value of an input when it's set by Angular. - +```ts {highlight:[6]} @Component({ selector: 'custom-slider', /*...*/ @@ -108,7 +108,7 @@ export class CustomSlider { function trimString(value: string | undefined): string { return value?.trim() ?? ''; } - +``` ```angular-html @@ -126,7 +126,7 @@ The most common use-case for input transforms is to accept a wider range of valu When you specify an input transform, the type of the transform function's parameter determines the types of values that can be set to the input in a template. - +```ts @Component({/*...*/}) export class CustomSlider { widthPx = input('', {transform: appendPx}); @@ -135,7 +135,7 @@ export class CustomSlider { function appendPx(value: number): string { return `${value}px`; } - +``` In the example above, the `widthPx` input accepts a `number` while the `InputSignal` property returns a `string`. @@ -143,15 +143,15 @@ In the example above, the `widthPx` input accepts a `number` while the `InputSig Angular includes two built-in transform functions for the two most common scenarios: coercing values to boolean and numbers. - +```ts import {Component, input, booleanAttribute, numberAttribute} from '@angular/core'; @Component({/*...*/}) export class CustomSlider { - disabled = input(false, {transform: booleanAttribute}); - value = input(0, {transform: numberAttribute}); + disabled = input(false, {transform: booleanAttribute}); + value = input(0, {transform: numberAttribute}); } - +``` `booleanAttribute` imitates the behavior of standard HTML [boolean attributes](https://developer.mozilla.org/docs/Glossary/Boolean/HTML), where the _presence_ of the attribute indicates a "true" value. However, Angular's `booleanAttribute` treats the literal string `"false"` as the boolean `false`. @@ -162,12 +162,12 @@ _presence_ of the attribute indicates a "true" value. However, Angular's `boolea You can specify the `alias` option to change the name of an input in templates. - +```ts {highlight:[3]} @Component({/*...*/}) export class CustomSlider { value = input(0, {alias: 'sliderValue'}); } - +``` ```angular-html @@ -185,14 +185,14 @@ When creating a component, you can define a model input similarly to how you cre Both types of input allow someone to bind a value into the property. However, **model inputs allow the component author to write values into the property**. If the property is bound with a two-way binding, the new value propagates to that binding. -```typescript +```ts @Component({ /* ... */}) export class CustomSlider { // Define a model input named "value". value = model(0); increment() { - // Update the model input with a new value, propagating the value to any bindings. + // Update the model input with a new value, propagating the value to any bindings. this.value.update(oldValue => oldValue + 10); } } @@ -205,7 +205,7 @@ export class CustomSlider { template: ``, }) export class MediaControls { - // Create a writable signal for the `volume` local state. + // Create a writable signal for the `volume` local state. volume = signal(0); } ``` @@ -238,7 +238,7 @@ In the example above, the `CustomSlider` can write values into its `value` model When you declare a model input in a component or directive, Angular automatically creates a corresponding [output](guide/components/outputs) for that model. The output's name is the model input's name suffixed with "Change". -```angular-ts +```ts @Directive({ /* ... */ }) export class CustomCheckbox { // This automatically creates an output named "checkedChange". @@ -273,12 +273,12 @@ TIP: While the Angular team recommends using the signal-based `input` function f You can alternatively declare component inputs by adding the `@Input` decorator to a property: - +```ts {highlight:[3]} @Component({...}) export class CustomSlider { @Input() value = 0; } - +``` Binding to an input is the same in both signal-based and decorator-based inputs: @@ -294,12 +294,12 @@ The `@Input` decorator accepts a config object that lets you change the way that You can specify the `required` option to enforce that a given input must always have a value. - +```ts {highlight:[3]} @Component({...}) export class CustomSlider { @Input({required: true}) value = 0; } - +``` If you try to use a component without specifying all of its required inputs, Angular reports an error at build-time. @@ -307,7 +307,7 @@ If you try to use a component without specifying all of its required inputs, Ang You can specify a `transform` function to change the value of an input when it's set by Angular. This transform function works identically to transform functions for signal-based inputs described above. - +```ts {highlight:[6]} @Component({ selector: 'custom-slider', ... @@ -316,19 +316,21 @@ export class CustomSlider { @Input({transform: trimString}) label = ''; } -function trimString(value: string | undefined) { return value?.trim() ?? ''; } - +function trimString(value: string | undefined) { + return value?.trim() ?? ''; +} +``` #### Input aliases You can specify the `alias` option to change the name of an input in templates. - +```ts {highlight:[3]} @Component({...}) export class CustomSlider { @Input({alias: 'sliderValue'}) value = 0; } - +``` ```angular-html @@ -342,29 +344,31 @@ Input aliases work the same way as for signal-based inputs described above. When using decorator-based inputs, a property implemented with a getter and setter can be an input: - +```ts export class CustomSlider { @Input() get value(): number { return this.internalValue; } -set value(newValue: number) { this.internalValue = newValue; } + set value(newValue: number) { this.internalValue = newValue; } -private internalValue = 0; } - + private internalValue = 0; +} +``` You can even create a _write-only_ input by only defining a public setter: - +```ts export class CustomSlider { @Input() set value(newValue: number) { this.internalValue = newValue; } -private internalValue = 0; } - + private internalValue = 0; +} +``` **Prefer using input transforms instead of getters and setters** if possible. @@ -374,22 +378,22 @@ Avoid complex or costly getters and setters. Angular may invoke an input's sette In addition to the `@Input` decorator, you can also specify a component's inputs with the `inputs` property in the `@Component` decorator. This can be useful when a component inherits a property from a base class: - +```ts {highlight:[4]} // `CustomSlider` inherits the `disabled` property from `BaseSlider`. @Component({ ..., inputs: ['disabled'], }) export class CustomSlider extends BaseSlider { } - +``` You can additionally specify an input alias in the `inputs` list by putting the alias after a colon in the string: - +```ts {highlight:[4]} // `CustomSlider` inherits the `disabled` property from `BaseSlider`. @Component({ ..., inputs: ['disabled: sliderDisabled'], }) export class CustomSlider extends BaseSlider { } - +``` diff --git a/adev/src/content/guide/components/lifecycle.md b/adev/src/content/guide/components/lifecycle.md index 7222eebf3c41..6f075427532f 100644 --- a/adev/src/content/guide/components/lifecycle.md +++ b/adev/src/content/guide/components/lifecycle.md @@ -108,19 +108,20 @@ mapping each component input name to a `SimpleChange` object. Each `SimpleChange input's previous value, its current value, and a flag for whether this is the first time the input has changed. +You can optionally pass the current class or this as the first generic argument for stronger type checking. + ```ts @Component({ /* ... */ }) export class UserProfile { - @Input() name: string = ''; - - ngOnChanges(changes: SimpleChanges) { - for (const inputName in changes) { - const inputValues = changes[inputName]; - console.log(`Previous ${inputName} == ${inputValues.previousValue}`); - console.log(`Current ${inputName} == ${inputValues.currentValue}`); - console.log(`Is first ${inputName} change == ${inputValues.firstChange}`); + name = input(''); + + ngOnChanges(changes: SimpleChanges) { + if (changes.name) { + console.log(`Previous: ${changes.name.previousValue}`); + console.log(`Current: ${changes.name.currentValue}`); + console.log(`Is first ${changes.name.firstChange}`); } } } @@ -161,6 +162,12 @@ destroyed. You can also use `DestroyRef` to keep setup code close to cleanup code, rather than putting all cleanup code in the `ngOnDestroy` method. +##### Detecting instance destruction + +`DestroyRef` provides a `destroyed` property that allows checking whether a given instance has already been destroyed. This is useful for avoiding operations on destroyed components, especially when dealing with delayed or asynchronous logic. + +By checking `destroyRef.destroyed`, you can prevent executing code after the instance has been cleaned up, avoiding potential errors such as `NG0911: View has already been destroyed.`. + ### ngDoCheck The `ngDoCheck` method runs before every time Angular checks a component's template for changes. @@ -237,7 +244,7 @@ See [Using DOM APIs](guide/components/dom-apis) for guidance on working with the Render callbacks do not run during server-side rendering or during build-time pre-rendering. -#### after*Render phases +#### after\*Render phases When using `afterEveryRender` or `afterNextRender`, you can optionally split the work into phases. The phase gives you control over the sequencing of DOM operations, letting you sequence _write_ @@ -285,8 +292,8 @@ There are four phases, run in the following order: | Phase | Description | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `earlyRead` | Use this phase to read any layout-affecting DOM properties and styles that are strictly necessary for subsequent calculation. Avoid this phase if possible, preferring the `write` and `read` phases. | -| `mixedReadWrite` | Default phase. Use for any operations need to both read and write layout-affecting properties and styles. Avoid this phase if possible, preferring the explicit `write` and `read` phases. | | `write` | Use this phase to write layout-affecting DOM properties and styles. | +| `mixedReadWrite` | Default phase. Use for any operations need to both read and write layout-affecting properties and styles. Avoid this phase if possible, preferring the explicit `write` and `read` phases. | | `read` | Use this phase to read any layout-affecting DOM properties. | ## Lifecycle interfaces diff --git a/adev/src/content/guide/components/outputs.md b/adev/src/content/guide/components/outputs.md index ad8bbcacc70a..57a302cc3e70 100644 --- a/adev/src/content/guide/components/outputs.md +++ b/adev/src/content/guide/components/outputs.md @@ -4,12 +4,12 @@ TIP: This guide assumes you've already read the [Essentials Guide](essentials). Angular components can define custom events by assigning a property to the `output` function: - +```ts {highlight:[3]} @Component({/*...*/}) export class ExpandablePanel { panelClosed = output(); } - +``` ```angular-html @@ -17,9 +17,9 @@ export class ExpandablePanel { The `output` function returns an `OutputEmitterRef`. You can emit an event by calling the `emit` method on the `OutputEmitterRef`: - +```ts this.panelClosed.emit(); - +``` Angular refers to properties initialized with the `output` function as **outputs**. You can use outputs to raise custom events, similar to native browser events like `click`. @@ -35,7 +35,7 @@ The `output` function has special meaning to the Angular compiler. **You can exc You can pass event data when calling `emit`: - +```ts // You can emit primitive values. this.valueChanged.emit(7); @@ -44,7 +44,7 @@ this.thumbDropped.emit({ pointerX: 123, pointerY: 456, }) - +``` When defining an event listener in a template, you can access the event data from the `$event` variable: @@ -52,16 +52,30 @@ When defining an event listener in a template, you can access the event data fro ``` +Receive the event data in the parent component: + +```ts +@Component({ + /*...*/ +}) +export class App { + logValue(value: number) { + ... + } +} + +``` + ## Customizing output names The `output` function accepts a parameter that lets you specify a different name for the event in a template: - +```ts @Component({/*...*/}) export class CustomSlider { changed = output({alias: 'valueChanged'}); } - +``` ```angular-html @@ -86,7 +100,7 @@ someComponentRef.instance.someEventProperty.subscribe(eventData => { Angular automatically cleans up event subscriptions when it destroys components with subscribers. Alternatively, you can manually unsubscribe from an event. The `subscribe` function returns an `OutputRefSubscription` with an `unsubscribe` method: -```typescript +```ts const eventSubscription = someComponent.someEventProperty.subscribe(eventData => { console.log(eventData); }); @@ -115,12 +129,12 @@ original decorator-based `@Output` API remains fully supported. You can alternatively define custom events by assigning a property to a new `EventEmitter` and adding the `@Output` decorator: - +```ts @Component({/*...*/}) export class ExpandablePanel { @Output() panelClosed = new EventEmitter(); } - +``` You can emit an event by calling the `emit` method on the `EventEmitter`. @@ -128,12 +142,12 @@ You can emit an event by calling the `emit` method on the `EventEmitter`. The `@Output` decorator accepts a parameter that lets you specify a different name for the event in a template: - +```ts @Component({/*...*/}) export class CustomSlider { @Output('valueChanged') changed = new EventEmitter(); } - +``` ```angular-html @@ -145,22 +159,22 @@ This alias does not affect usage of the property in TypeScript code. In addition to the `@Output` decorator, you can also specify a component's outputs with the `outputs` property in the `@Component` decorator. This can be useful when a component inherits a property from a base class: - +```ts // `CustomSlider` inherits the `valueChanged` property from `BaseSlider`. @Component({ /*...*/ outputs: ['valueChanged'], }) export class CustomSlider extends BaseSlider {} - +``` You can additionally specify an output alias in the `outputs` list by putting the alias after a colon in the string: - +```ts // `CustomSlider` inherits the `valueChanged` property from `BaseSlider`. @Component({ /*...*/ outputs: ['valueChanged: volumeChanged'], }) export class CustomSlider extends BaseSlider {} - +``` diff --git a/adev/src/content/guide/components/programmatic-rendering.md b/adev/src/content/guide/components/programmatic-rendering.md index 9ef477a70dc8..51887ae3591b 100644 --- a/adev/src/content/guide/components/programmatic-rendering.md +++ b/adev/src/content/guide/components/programmatic-rendering.md @@ -2,9 +2,17 @@ TIP: This guide assumes you've already read the [Essentials Guide](essentials). Read that first if you're new to Angular. -In addition to using a component directly in a template, you can also dynamically render components. -There are two main ways to dynamically render a component: in a template with `NgComponentOutlet`, -or in your TypeScript code with `ViewContainerRef`. +In addition to using a component directly in a template, you can also dynamically render components +programmatically. This is helpful for situations when a component is unknown initially (thus can not +be referenced in a template directly) and it depends on some conditions. + +There are two main ways to render a component programmatically: in a template using `NgComponentOutlet`, +or in your TypeScript code using `ViewContainerRef`. + +HELPFUL: for lazy-loading use-cases (for example if you want to delay loading of a heavy component), consider +using the built-in [`@defer` feature](/guide/templates/defer) instead. The `@defer` feature allows the code +of any components, directives, and pipes inside the `@defer` block to be extracted into separate JavaScript +chunks automatically and loaded only when necessary, based on the configured triggers. ## Using NgComponentOutlet @@ -25,10 +33,10 @@ export class StandardBio { /* ... */ } ` }) export class CustomDialog { - @Input() user: User; + user = input.required(); getBioComponent() { - return this.user.isAdmin ? AdminBio : StandardBio; + return this.user().isAdmin ? AdminBio : StandardBio; } } ``` @@ -95,9 +103,11 @@ In the example above, clicking the "Load content" button results in the followin ## Lazy-loading components -You can use both of the approaches described above, `NgComponentOutlet` and `ViewContainerRef`, to -render components that are lazy-loaded with a standard -JavaScript [dynamic import](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import). +HELPFUL: if you want to lazy-load some components, you may consider using the built-in [`@defer` feature](/guide/templates/defer) +instead. + +If your use-case is not covered by the `@defer` feature, you can use either `NgComponentOutlet` or +`ViewContainerRef` with a standard JavaScript [dynamic import](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import). ```angular-ts @Component({ @@ -109,9 +119,11 @@ JavaScript [dynamic import](https://developer.mozilla.org/docs/Web/JavaScript/Re

    Advanced settings

    - + @if(!advancedSettings) { + + }
    ` @@ -127,3 +139,117 @@ export class AdminSettings { ``` The example above loads and displays the `AdvancedSettings` upon receiving a button click. + +## Binding inputs, outputs and setting host directives at creation + +When dynamically creating components, manually setting inputs and subscribing to outputs can be error-prone. You often need to write extra code just to wire up bindings after the component is instantiated. + +To simplify this, both `createComponent` and `ViewContainerRef.createComponent` support passing a `bindings` array with helpers like `inputBinding()`, `outputBinding()`, and `twoWayBinding()` to configure inputs and outputs up front. You can also specify a `directives` array to apply any host directives. This enables creating components programmatically with template-like bindings in a single, declarative call. + +### Host view using `ViewContainerRef.createComponent` + +`ViewContainerRef.createComponent` creates a component and automatically inserts its host view and host element into the container’s view hierarchy at the container’s location. Use this when the dynamic component should become part of the container’s logical and visual structure (for example, adding list items or inline UI). + +By contrast, the standalone `createComponent` API does not attach the new component to any existing view or DOM location — it returns a `ComponentRef` and gives you explicit control over where to place the component’s host element. + +```angular-ts +import { Component, input, model, output } from "@angular/core"; + +@Component({ + selector: 'app-warning', + template: ` + @if(isExpanded()) { +
    +

    Warning: Action needed!

    + +
    + } + ` +}) +export class AppWarningComponent { + readonly canClose = input.required(); + readonly isExpanded = model(); + readonly close = output(); +} +``` + +```ts +import { Component, ViewContainerRef, signal, inputBinding, outputBinding, twoWayBinding, inject } from '@angular/core'; +import { FocusTrap } from "@angular/cdk/a11y"; +import { ThemeDirective } from '../theme.directive'; + +@Component({ + template: `` +}) +export class HostComponent { + private vcr = inject(ViewContainerRef); + readonly canClose = signal(true); + readonly isExpanded = signal(true); + + showWarning() { + const compRef = this.vcr.createComponent(AppWarningComponent, { + bindings: [ + inputBinding('canClose', this.canClose), + twoWayBinding('isExpanded', this.isExpanded), + outputBinding('close', (confirmed) => { + console.log('Closed with result:', confirmed); + }) + ], + directives: [ + FocusTrap, + { type: ThemeDirective, bindings: [inputBinding('theme', () => 'warning')] } + ] + }); + } +} +``` + +In the example above, the dynamic **AppWarningComponent** is created with its `canClose` input bound to a reactive signal, a two-way binding on its `isExpanded` state, and an output listener for `close`. The `FocusTrap` and `ThemeDirective` are attached to the host element via `directives`. + +### Popup attached to `document.body` with `createComponent` + `hostElement` + +Use this when rendering outside the current view hierarchy (e.g., overlays). The provided `hostElement` becomes the component’s host in the DOM, so Angular doesn’t create a new element matching the selector. Lets you configure **bindings** directly. + +```ts +import { + ApplicationRef, + createComponent, + EnvironmentInjector, + inject, + Injectable, + inputBinding, + outputBinding, +} from '@angular/core'; +import { PopupComponent } from './popup.component'; + +@Injectable({ providedIn: 'root' }) +export class PopupService { + private readonly injector = inject(EnvironmentInjector); + private readonly appRef = inject(ApplicationRef); + + show(message: string) { + // Create a host element for the popup + const host = document.createElement('popup-host'); + + // Create the component and bind in one call + const ref = createComponent(PopupComponent, { + environmentInjector: this.injector, + hostElement: host, + bindings: [ + inputBinding('message', () => message), + outputBinding('closed', () => { + document.body.removeChild(host); + this.appRef.detachView(ref.hostView); + ref.destroy(); + }), + ], + }); + + // Registers the component’s view so it participates in change detection cycle. + this.appRef.attachView(ref.hostView); + // Inserts the provided host element into the DOM (outside the normal Angular view hierarchy). + // This is what makes the popup visible on screen, typically used for overlays or modals. + document.body.appendChild(host); + } +} +``` diff --git a/adev/src/content/guide/components/queries.md b/adev/src/content/guide/components/queries.md index 65d7662fec7a..075d2c738afc 100644 --- a/adev/src/content/guide/components/queries.md +++ b/adev/src/content/guide/components/queries.md @@ -15,7 +15,7 @@ There are two categories of query: **view queries** and **content queries.** View queries retrieve results from the elements in the component's _view_ — the elements defined in the component's own template. You can query for a single result with the `viewChild` function. - +```typescript {highlight: [14, 15]} @Component({ selector: 'custom-card-header', /*...*/ @@ -32,7 +32,7 @@ export class CustomCard { header = viewChild(CustomCardHeader); headerText = computed(() => this.header()?.text); } - +``` In this example, the `CustomCard` component queries for a child `CustomCardHeader` and uses the result in a `computed`. @@ -40,7 +40,7 @@ If the query does not find a result, its value is `undefined`. This may occur if You can also query for multiple results with the `viewChildren` function. - +```typescript {highlight: [17]} @Component({ selector: 'custom-card-action', /*...*/ @@ -51,8 +51,7 @@ export class CustomCardAction { @Component({ selector: 'custom-card', - template: ` - Save + template: `Save Cancel `, }) @@ -60,7 +59,7 @@ export class CustomCard { actions = viewChildren(CustomCardAction); actionsTexts = computed(() => this.actions().map(action => action.text); } - +``` `viewChildren` creates a signal with an `Array` of the query results. @@ -70,7 +69,7 @@ export class CustomCard { Content queries retrieve results from the elements in the component's _content_— the elements nested inside the component in the template where it's used. You can query for a single result with the `contentChild` function. - +```typescript {highlight: [14, 15]} @Component({ selector: 'custom-toggle', /*...*/ @@ -81,26 +80,25 @@ export class CustomToggle { @Component({ selector: 'custom-expando', - /*...*/ + /* ... */ }) export class CustomExpando { toggle = contentChild(CustomToggle); toggleText = computed(() => this.toggle()?.text); } -@Component({ - /* ... */ - // CustomToggle is used inside CustomExpando as content. - template: ` +@Component({ +/* ... */ +// CustomToggle is used inside CustomExpando as content. +template: ` Show ` }) -export class UserProfile { } - -In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in a `computed`. +export class UserProfile { } +``` If the query does not find a result, its value is `undefined`. This may occur if the target element is absent or hidden by `@if`. Angular keeps the result of `contentChild` up to date as your application state changes. @@ -108,7 +106,7 @@ By default, content queries find only _direct_ children of the component and do You can also query for multiple results with the `contentChildren` function. - +```typescript {highlight: [14, 16, 17, 18, 19, 20]} @Component({ selector: 'custom-menu-item', /*...*/ @@ -121,6 +119,7 @@ export class CustomMenuItem { selector: 'custom-menu', /*...*/ }) + export class CustomMenu { items = contentChildren(CustomMenuItem); itemTexts = computed(() => this.items().map(item => item.text)); @@ -136,7 +135,7 @@ export class CustomMenu { ` }) export class UserProfile { } - +``` `contentChildren` creates a signal with an `Array` of the query results. @@ -146,7 +145,7 @@ export class UserProfile { } If a child query (`viewChild` or `contentChild`) does not find a result, its value is `undefined`. This may occur if the target element is hidden by a control flow statement like `@if` or `@for`. Because of this, the child queries return a signal that include `undefined` in their value type. -In some cases, especially with `viewChild`, you know with certainty that a specific child is always available. In other cases, you may want to strictly enforce that a specific child is present. For these cases, you can use a *required query*. +In some cases, especially with `viewChild`, you know with certainty that a specific child is always available. In other cases, you may want to strictly enforce that a specific child is present. For these cases, you can use a _required query_. ```angular-ts @Component({/* ... */}) @@ -216,6 +215,7 @@ All query functions accept an options object as a second parameter. These option By default, the query locator indicates both the element you're searching for and the value retrieved. You can alternatively specify the `read` option to retrieve a different value from the element matched by the locator. ```ts + @Component({/*...*/}) export class CustomExpando { toggle = contentChild(ExpandoContent, {read: TemplateRef}); @@ -229,36 +229,37 @@ Developers most commonly use `read` to retrieve `ElementRef` and `TemplateRef`. ### Content descendants -By default, content queries find only _direct_ children of the component and do not traverse into descendants. +By default, `contentChildren` queries find only _direct_ children of the component and do not traverse into descendants. +`contentChild` queries do traverse into descendants by default. - +```typescript {highlight: [13, 14, 15, 16]} @Component({ selector: 'custom-expando', /*...*/ }) export class CustomExpando { - toggle = contentChild(CustomToggle); + toggle = contentChildren(CustomToggle); // none found + // toggle = contentChild(CustomToggle); // found } @Component({ selector: 'user-profile', - template: ` - + template: ` - Show ` }) export class UserProfile { } - +``` -In the example above, `CustomExpando` cannot find `` because it is not a direct child of ``. By setting `descendants: true`, you configure the query to traverse all descendants in the same template. Queries, however, _never_ pierce into components to traverse elements in other templates. +In the example above, `CustomExpando` cannot find `` with `contentChildren` because it is not a direct child of ``. By setting `descendants: true`, you configure the query to traverse all descendants in the same template. Queries, however, _never_ pierce into components to traverse elements in other templates. View queries do not have this option because they _always_ traverse into descendants. ## Decorator-based queries + TIP: While the Angular team recommends using the signal-based query function for new projects, the original decorator-based query APIs remain fully supported. @@ -268,7 +269,7 @@ You can alternatively declare queries by adding the corresponding decorator to a You can query for a single result with the `@ViewChild` decorator. - +```typescript {highlight: [14, 16, 17, 18]} @Component({ selector: 'custom-card-header', /*...*/ @@ -288,7 +289,7 @@ export class CustomCard { console.log(this.header.text); } } - +``` In this example, the `CustomCard` component queries for a child `CustomCardHeader` and accesses the result in `ngAfterViewInit`. @@ -298,7 +299,7 @@ Angular keeps the result of `@ViewChild` up to date as your application state ch You can also query for multiple results with the `@ViewChildren` decorator. - +```typescript {highlight: [17, 19, 20, 21, 22, 23]} @Component({ selector: 'custom-card-action', /*...*/ @@ -323,7 +324,7 @@ export class CustomCard { }); } } - +``` `@ViewChildren` creates a `QueryList` object that contains the query results. You can subscribe to changes to the query results over time via the `changes` property. @@ -331,7 +332,7 @@ export class CustomCard { You can query for a single result with the `@ContentChild` decorator. - +```typescript {highlight: [14, 16, 17, 18, 25]} @Component({ selector: 'custom-toggle', /*...*/ @@ -344,6 +345,7 @@ export class CustomToggle { selector: 'custom-expando', /*...*/ }) + export class CustomExpando { @ContentChild(CustomToggle) toggle: CustomToggle; @@ -361,7 +363,7 @@ export class CustomExpando { ` }) export class UserProfile { } - +``` In this example, the `CustomExpando` component queries for a child `CustomToggle` and accesses the result in `ngAfterContentInit`. @@ -371,7 +373,7 @@ Angular keeps the result of `@ContentChild` up to date as your application state You can also query for multiple results with the `@ContentChildren` decorator. - +```typescript {highlight: [15, 17, 18, 19, 20, 21]} @Component({ selector: 'custom-menu-item', /*...*/ @@ -384,6 +386,7 @@ export class CustomMenuItem { selector: 'custom-menu', /*...*/ }) + export class CustomMenu { @ContentChildren(CustomMenuItem) items: QueryList; @@ -404,7 +407,7 @@ export class CustomMenu { ` }) export class UserProfile { } - +``` `@ContentChildren` creates a `QueryList` object that contains the query results. You can subscribe to changes to the query results over time via the `changes` property. diff --git a/adev/src/content/guide/components/selectors.md b/adev/src/content/guide/components/selectors.md index eb77b16a090c..b473b4d14a2e 100644 --- a/adev/src/content/guide/components/selectors.md +++ b/adev/src/content/guide/components/selectors.md @@ -118,8 +118,7 @@ prefix your components with `yt-`, with components like `yt-menu`, `yt-player`, your selectors like this makes it immediately clear where a particular component comes from. By default, the Angular CLI uses `app-`. -Angular uses the `ng` selector prefix for its own framework APIs. Never use `ng` as a selector -prefix for your own custom components. +IMPORTANT: Angular uses the `ng` selector prefix for its own framework APIs. Never use `ng` as a selector prefix for your own custom components. ### When to use an attribute selector diff --git a/adev/src/content/guide/components/styling.md b/adev/src/content/guide/components/styling.md index d2bdd219fec5..91251274381d 100644 --- a/adev/src/content/guide/components/styling.md +++ b/adev/src/content/guide/components/styling.md @@ -36,7 +36,7 @@ and [stylus](https://stylus-lang.com). ## Style scoping Every component has a **view encapsulation** setting that determines how the framework scopes a -component's styles. There are three view encapsulation modes: `Emulated`, `ShadowDom`, and `None`. +component's styles. There are four view encapsulation modes: `Emulated`, `ShadowDom`, `ExperimentalIsolatedShadowDom`, and `None`. You can specify the mode in the `@Component` decorator: @@ -59,10 +59,11 @@ global styles defined outside of a component may still affect elements inside a emulated encapsulation. In emulated mode, Angular supports -the [`:host`](https://developer.mozilla.org/docs/Web/CSS/:host) -and [`:host-context()`](https://developer.mozilla.org/docs/Web/CSS/:host-context) pseudo -classes without -using [Shadow DOM](https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM). +the [`:host`](https://developer.mozilla.org/docs/Web/CSS/:host) pseudo-class. +While the [`:host-context()`](https://developer.mozilla.org/docs/Web/CSS/:host-context) pseudo-class +is deprecated in modern browsers, Angular's compiler provides full support for it. Both pseudo-classes +can be used without relying on native +[Shadow DOM](https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM). During compilation, the framework transforms these pseudo classes into attributes so it doesn't comply with these native pseudo classes' rules at runtime (e.g. browser compatibility, specificity). Angular's emulated encapsulation mode does not support any other pseudo classes related to Shadow DOM, such @@ -82,9 +83,7 @@ using [the web standard Shadow DOM API](https://developer.mozilla.org/docs/Web/W When enabling this mode, Angular attaches a shadow root to the component's host element and renders the component's template and styles into the corresponding shadow tree. -This mode strictly guarantees that _only_ that component's styles apply to elements in the -component's template. Global styles cannot affect elements in a shadow tree and styles inside the -shadow tree cannot affect elements outside of that shadow tree. +Styles inside the shadow tree cannot affect elements outside of that shadow tree. Enabling `ShadowDom` encapsulation, however, impacts more than style scoping. Rendering the component in a shadow tree affects event propagation, interaction @@ -92,6 +91,12 @@ with [the `` API](https://developer.mozilla.org/docs/Web/Web_Components/Us and how browser developer tools show elements. Always understand the full implications of using Shadow DOM in your application before enabling this option. +### ViewEncapsulation.ExperimentalIsolatedShadowDom + +Behaves as above, except this mode strictly guarantees that _only_ that component's styles apply to elements in the +component's template. Global styles cannot affect elements in a shadow tree and styles inside the +shadow tree cannot affect elements outside of that shadow tree. + ### ViewEncapsulation.None This mode disables all style encapsulation for the component. Any styles associated with the diff --git a/adev/src/content/guide/di/BUILD.bazel b/adev/src/content/guide/di/BUILD.bazel index 04e0e7692746..fd7c2fada68b 100644 --- a/adev/src/content/guide/di/BUILD.bazel +++ b/adev/src/content/guide/di/BUILD.bazel @@ -1,3 +1,4 @@ +load("//adev/shared-docs:defaults.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -5,6 +6,8 @@ generate_guides( srcs = glob([ "*.md", ]), + api_manifest = + "//adev/src/assets:docs_api_manifest", data = [ "//adev/src/assets/images:dependency_injection.svg", "//adev/src/content/examples", @@ -12,3 +15,9 @@ generate_guides( mermaid_blocks = True, visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/di/creating-and-using-services.md b/adev/src/content/guide/di/creating-and-using-services.md new file mode 100644 index 000000000000..f8df5139a9b4 --- /dev/null +++ b/adev/src/content/guide/di/creating-and-using-services.md @@ -0,0 +1,105 @@ +# Creating and using services + +Services are reusable pieces of code that can be shared across your Angular application. They typically handle data fetching, business logic, or other functionality that multiple components need to access. + +## Creating a service + +You can create a service with the [Angular CLI](tools/cli) with the following command: + +```bash +ng generate service CUSTOM_NAME +``` + +This creates a dedicated `CUSTOM_NAME.ts` file in your `src` directory. + +You can also manually create a service by adding the `@Injectable()` decorator to a TypeScript class. This tells Angular that the service can be injected as a dependency. + +Here is an example of a service that allows users to add and request data: + +```ts +// 📄 src/app/basic-data-store.ts +import { Injectable } from '@angular/core'; + +@Injectable({ providedIn: 'root' }) +export class BasicDataStore { + private data: string[] = [] + + addData(item: string): void { + this.data.push(item) + } + + getData(): string[] { + return [...this.data] + } +} +``` + +## How services become available + +When you use `@Injectable({ providedIn: 'root' })` in your service, Angular: + +- **Creates a single instance** (singleton) for your entire application +- **Makes it available everywhere** without any additional configuration +- **Enables tree-shaking** so the service is only included in your JavaScript bundle if it's actually used + +This is the recommended approach for most services. + +## Injecting a service + +Once you've created a service with `providedIn: 'root'`, you can inject it anywhere in your application using the `inject()` function from `@angular/core`. + +### Injecting into a component + +```angular-ts +import { Component, inject } from '@angular/core'; +import { BasicDataStore } from './basic-data-store'; + +@Component({ + selector: 'app-example', + template: ` +
    +

    {{ dataStore.getData() }}

    + +
    + ` +}) +export class ExampleComponent { + dataStore = inject(BasicDataStore); +} +``` + +### Injecting into another service + +```ts +import { inject, Injectable } from '@angular/core'; +import { AdvancedDataStore } from './advanced-data-store'; + +@Injectable({ + providedIn: 'root', +}) +export class BasicDataStore { + private advancedDataStore = inject(AdvancedDataStore); + private data: string[] = []; + + addData(item: string): void { + this.data.push(item); + } + + getData(): string[] { + return [...this.data, ...this.advancedDataStore.getData()]; + } +} +``` + +## Next steps + +While `providedIn: 'root'` covers most use cases, Angular offers additional ways to provide services for specialized scenarios: + +- **Component-specific instances** - When components need their own isolated service instances +- **Manual configuration** - For services that require runtime configuration +- **Factory providers** - For dynamic service creation based on runtime conditions +- **Value providers** - For providing configuration objects or constants + +You can learn more about these advanced patterns in the next guide: [defining dependency providers](/guide/di/defining-dependency-providers). diff --git a/adev/src/content/guide/di/creating-injectable-service.md b/adev/src/content/guide/di/creating-injectable-service.md index ebe5b6a592a0..f8b15a9cc731 100644 --- a/adev/src/content/guide/di/creating-injectable-service.md +++ b/adev/src/content/guide/di/creating-injectable-service.md @@ -21,7 +21,7 @@ Angular helps you follow these principles by making it easy to factor your appli Here's an example of a service class that logs to the browser console: - + export class Logger { log(msg: unknown) { console.log(msg); } error(msg: unknown) { console.error(msg); } @@ -33,27 +33,27 @@ Services can depend on other services. For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes. That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server: - import { inject } from "@angular/core"; export class HeroService { - private heroes: Hero[] = []; +private heroes: Hero[] = []; - private backend = inject(BackendService); - private logger = inject(Logger); +private backend = inject(BackendService); +private logger = inject(Logger); - async getHeroes() { - // Fetch - this.heroes = await this.backend.getAll(Hero); - // Log - this.logger.log(`Fetched ${this.heroes.length} heroes.`); - return this.heroes; - } +async getHeroes() { +// Fetch +this.heroes = await this.backend.getAll(Hero); +// Log +this.logger.log(`Fetched ${this.heroes.length} heroes.`); +return this.heroes; +} } -## Creating an injectable service +## Creating an injectable service with the CLI The Angular CLI provides a command to create a new service. In the following example, you add a new service to an existing application. @@ -67,23 +67,23 @@ ng generate service heroes/hero This command creates the following default `HeroService`: - -import { Injectable } from '@angular/core'; +```ts {header: 'heroes/hero.service.ts (CLI-generated)'} +import {Injectable} from '@angular/core'; @Injectable({ providedIn: 'root', }) export class HeroService {} - +``` The `@Injectable()` decorator specifies that Angular can use this class in the DI system. The metadata, `providedIn: 'root'`, means that the `HeroService` is provided throughout the application. Add a `getHeroes()` method that returns the heroes from `mock.heroes.ts` to get the hero mock data: - -import { Injectable } from '@angular/core'; -import { HEROES } from './mock-heroes'; +```ts {header: 'hero.service.ts'} +import {Injectable} from '@angular/core'; +import {HEROES} from './mock-heroes'; @Injectable({ // declares that this service should be created @@ -95,7 +95,7 @@ export class HeroService { return HEROES; } } - +``` For clarity and maintainability, it is recommended that you define components and services in separate files. @@ -106,19 +106,19 @@ To inject a service as a dependency into a component, you can declare a class fi The following example specifies the `HeroService` in the `HeroListComponent`. The type of `heroService` is `HeroService`. - -import { inject } from "@angular/core"; +```ts +import {inject} from '@angular/core'; export class HeroListComponent { private heroService = inject(HeroService); } - +``` It is also possible to inject a service into a component using the component's constructor: - +```ts {header: 'hero-list.component.ts (constructor signature)'} constructor(private heroService: HeroService) - +``` The `inject` method can be used in both classes and functions, while the constructor method can naturally only be used in a class constructor. However, in either case a dependency may only be injected in a valid [injection context](guide/di/dependency-injection-context), usually in the construction or initialization of a component. @@ -127,11 +127,10 @@ The `inject` method can be used in both classes and functions, while the constru When a service depends on another service, follow the same pattern as injecting into a component. In the following example, `HeroService` depends on a `Logger` service to report its activities: - -import { inject, Injectable } from '@angular/core'; -import { HEROES } from './mock-heroes'; -import { Logger } from '../logger.service'; +```ts {header: 'hero.service.ts, highlight: [[3],[9],[12]]} +import {inject, Injectable} from '@angular/core'; +import {HEROES} from './mock-heroes'; +import {Logger} from '../logger.service'; @Injectable({ providedIn: 'root', @@ -144,7 +143,7 @@ export class HeroService { return HEROES; } } - +``` In this example, the `getHeroes()` method uses the `Logger` service by logging a message when fetching heroes. diff --git a/adev/src/content/guide/di/defining-dependency-providers.md b/adev/src/content/guide/di/defining-dependency-providers.md new file mode 100644 index 000000000000..3702715d59b6 --- /dev/null +++ b/adev/src/content/guide/di/defining-dependency-providers.md @@ -0,0 +1,923 @@ +# Defining dependency providers + +Angular provides two ways to make services available for injection: + +1. **Automatic provision** - Using `providedIn` in the `@Injectable` decorator or by providing a factory in the `InjectionToken` configuration +2. **Manual provision** - Using the `providers` array in components, directives, routes, or application config + +In the [previous guide](/guide/di/creating-and-using-services), you learned how to create services using `providedIn: 'root'`, which handles most common use cases. This guide explores additional patterns for both automatic and manual provider configuration. + +## Automatic provision for non-class dependencies + +While the `@Injectable` decorator with `providedIn: 'root'` works great for services (classes), you might need to provide other types of values globally - like configuration objects, functions, or primitive values. Angular provides `InjectionToken` for this purpose. + +### What is an InjectionToken? + +An `InjectionToken` is an object that Angular's dependency injection system uses to uniquely identify values for injection. Think of it as a special key that lets you store and retrieve any type of value in Angular's DI system: + +```ts +import { InjectionToken } from '@angular/core'; + +// Create a token for a string value +export const API_URL = new InjectionToken('api.url'); + +// Create a token for a function +export const LOGGER = new InjectionToken<(msg: string) => void>('logger.function'); + +// Create a token for a complex type +export interface Config { + apiUrl: string; + timeout: number; +} +export const CONFIG_TOKEN = new InjectionToken('app.config'); +``` + +NOTE: The string parameter (e.g., `'api.url'`) is a description purely for debugging — Angular identifies tokens by their object reference, not this string. + +### InjectionToken with `providedIn: 'root'` + +An `InjectionToken` that has a `factory` results in `providedIn: 'root'` by default (but can be overidden via the `providedIn` prop). + +```ts +// 📁 /app/config.token.ts +import { InjectionToken } from '@angular/core'; + +export interface AppConfig { + apiUrl: string; + version: string; + features: Record; +} + +// Globally available configuration using providedIn +export const APP_CONFIG = new InjectionToken('app.config', { + providedIn: 'root', + factory: () => ({ + apiUrl: 'https://api.example.com', + version: '1.0.0', + features: { + darkMode: true, + analytics: false + } + }) +}); + +// No need to add to providers array - available everywhere! +@Component({ + selector: 'app-header', + template: `

    Version: {{ config.version }}

    ` +}) +export class HeaderComponent { + config = inject(APP_CONFIG); // Automatically available +} +``` + +### When to use InjectionToken with factory functions + +InjectionToken with factory functions is ideal when you can't use a class but need to provide dependencies globally: + +```ts +// 📁 /app/logger.token.ts +import { InjectionToken, inject } from '@angular/core'; +import { APP_CONFIG } from './config.token'; + +// Logger function type +export type LoggerFn = (level: string, message: string) => void; + +// Global logger function with dependencies +export const LOGGER_FN = new InjectionToken('logger.function', { + providedIn: 'root', + factory: () => { + const config = inject(APP_CONFIG); + + return (level: string, message: string) => { + if (config.features.logging !== false) { + console[level](`[${new Date().toISOString()}] ${message}`); + } + }; + } +}); + +// 📁 /app/storage.token.ts +// Providing browser APIs as tokens +export const LOCAL_STORAGE = new InjectionToken('localStorage', { + // providedIn: 'root' is configured as the default + factory: () => window.localStorage +}); + +export const SESSION_STORAGE = new InjectionToken('sessionStorage', { + providedIn: 'root', + factory: () => window.sessionStorage +}); + +// 📁 /app/feature-flags.token.ts +// Complex configuration with runtime logic +export const FEATURE_FLAGS = new InjectionToken>('feature.flags', { + providedIn: 'root', + factory: () => { + const flags = new Map(); + + // Parse from environment or URL params + const urlParams = new URLSearchParams(window.location.search); + const enableBeta = urlParams.get('beta') === 'true'; + + flags.set('betaFeatures', enableBeta); + flags.set('darkMode', true); + flags.set('newDashboard', false); + + return flags; + } +}); +``` + +This approach offers several advantages: + +- **No manual provider configuration needed** - Works just like `providedIn: 'root'` for services +- **Tree-shakeable** - Only included if actually used +- **Type-safe** - Full TypeScript support for non-class values +- **Can inject other dependencies** - Factory functions can use `inject()` to access other services + +## Understanding manual provider configuration + +When you need more control than `providedIn: 'root'` offers, you can manually configure providers. Manual configuration through the `providers` array is useful when: + +1. **The service doesn't have `providedIn`** - Services without automatic provision must be manually provided +2. **You want a new instance** - To create a separate instance at the component/directive level instead of using the shared one +3. **You need runtime configuration** - When service behavior depends on runtime values +4. **You're providing non-class values** - Configuration objects, functions, or primitive values + +### Example: Service without `providedIn` + +```ts +import { Injectable, Component, inject } from '@angular/core'; + +// Service without providedIn +@Injectable() +export class LocalDataStore { + private data: string[] = []; + + addData(item: string) { + this.data.push(item); + } +} + +// Component must provide it +@Component({ + selector: 'app-example', + // A provider is required here because the `LocalDataStore` service has no providedIn. + providers: [LocalDataStore], + template: `...` +}) +export class ExampleComponent { + dataStore = inject(LocalDataStore); +} +``` + +### Example: Creating component-specific instances + +Services with `providedIn: 'root'` can be overridden at the component level. This ties the instance of the service to the life of a component. As a result, when the component gets destroyed, the provided service is also destroyed as well. + +```ts +import { Injectable, Component, inject } from '@angular/core'; + +@Injectable({ providedIn: 'root' }) +export class DataStore { + private data: ListItem[] = []; +} + +// This component gets its own instance +@Component({ + selector: 'app-isolated', + // Creates new instance of `DataStore` rather than using the root-provided instance. + providers: [DataStore], + template: `...` +}) +export class IsolatedComponent { + dataStore = inject(DataStore); // Component-specific instance +} +``` + +## Injector hierarchy in Angular + +Angular's dependency injection system is hierarchical. When a component requests a dependency, Angular starts with that component's injector and walks up the tree until it finds a provider for that dependency. Each component in your application tree can have its own injector, and these injectors form a hierarchy that mirrors your component tree. + +This hierarchy enables: + +- **Scoped instances**: Different parts of your app can have different instances of the same service +- **Override behavior**: Child components can override providers from parent components +- **Memory efficiency**: Services are only instantiated where needed + +In Angular, any element with a component or directive can provide values to all of its descendants. + +```mermaid +graph TD + subgraph platform + subgraph root + direction TB + A[SocialApp] --> B[UserProfile] + A --> C[FriendList] + C --> D[FriendEntry] + end + end +``` + +In the example above: + +1. `SocialApp` can provide values for `UserProfile` and `FriendList` +2. `FriendList` can provide values for injection to `FriendEntry`, but cannot provide values for injection in `UserProfile` because it's not part of the tree + +## Declaring a provider + +Think of Angular's dependency injection system as a hash map or dictionary. Each provider configuration object defines a key-value pair: + +- **Key (Provider identifier)**: The unique identifier you use to request a dependency +- **Value**: What Angular should return when that token is requested + +When manually providing dependencies, you typically see this shorthand syntax: + +```angular-ts +import { Component } from '@angular/core'; +import { LocalService } from './local-service'; + +@Component({ + selector: 'app-example', + providers: [LocalService] // Service without providedIn +}) +export class ExampleComponent { } +``` + +This is actually a shorthand for a more detailed provider configuration: + +```ts +{ + // This is the shorthand version + providers: [LocalService], + + // This is the full version + providers: [ + { provide: LocalService, useClass: LocalService } + ] +} +``` + +### Provider configuration object + +Every provider configuration object has two primary parts: + +1. **Provider identifier**: The unique key that Angular uses to get the dependency (set via the `provide` property) +2. **Value**: The actual dependency that you want Angular to fetch, configured with different keys based on the desired type: + - `useClass` - Provides a JavaScript class + - `useValue` - Provides a static value + - `useFactory` - Provides a factory function that returns the value + - `useExisting` - Provides an alias to an existing provider + +### Provider identifiers + +Provider identifiers allow Angular's dependency injection (DI) system to retrieve a dependency through a unique ID. You can generate provider identifiers in two ways: + +1. [Class names](#class-names) +2. [Injection tokens](#injection-tokens) + +#### Class names + +Class name use the imported class directly as the identifier: + +```angular-ts +import { Component } from '@angular/core'; +import { LocalService } from './local-service'; + +@Component({ + selector: 'app-example', + providers: [ + { provide: LocalService, useClass: LocalService } + ] +}) +export class ExampleComponent { /* ... */ } +``` + +The class serves as both the identifier and the implementation, which is why Angular provides the shorthand `providers: [LocalService]`. + +#### Injection tokens + +Angular provides a built-in [`InjectionToken`](api/core/InjectionToken) class that creates a unique object reference for injectable values or when you want to provide multiple implementations of the same interface. + +```ts +// 📁 /app/tokens.ts +import { InjectionToken } from '@angular/core'; +import { DataService } from './data-service.interface'; + +export const DATA_SERVICE_TOKEN = new InjectionToken('DataService'); +``` + +NOTE: The string `'DataService'` is a description used purely for debugging purposes. Angular identifies the token by its object reference, not this string. + +Use the token in your provider configuration: + +```angular-ts +import { Component, inject } from '@angular/core'; +import { LocalDataService } from './local-data-service'; +import { DATA_SERVICE_TOKEN } from './tokens'; + +@Component({ + selector: 'app-example', + providers: [ + { provide: DATA_SERVICE_TOKEN, useClass: LocalDataService } + ] +}) +export class ExampleComponent { + private dataService = inject(DATA_SERVICE_TOKEN); +} +``` + +#### Can TypeScript interfaces be identifiers for injection? + +TypeScript interfaces cannot be used for injection because they don't exist at runtime: + +```ts +// ❌ This won't work! +interface DataService { + getData(): string[]; +} + +// Interfaces disappear after TypeScript compilation +@Component({ + providers: [ + { provide: DataService, useClass: LocalDataService } // Error! + ] +}) +export class ExampleComponent { + private dataService = inject(DataService); // Error! +} + +// ✅ Use InjectionToken instead +export const DATA_SERVICE_TOKEN = new InjectionToken('DataService'); + +@Component({ + providers: [ + { provide: DATA_SERVICE_TOKEN, useClass: LocalDataService } + ] +}) +export class ExampleComponent { + private dataService = inject(DATA_SERVICE_TOKEN); // Works! +} +``` + +The InjectionToken provides a runtime value that Angular's DI system can use, while still maintaining type safety through TypeScript's generic type parameter. + +### Provider value types + +#### useClass + +`useClass` provides a JavaScript class as a dependency. This is the default when using the shorthand syntax: + +```ts +// Shorthand +providers: [DataService] + +// Full syntax +providers: [ + { provide: DataService, useClass: DataService } +] + +// Different implementation +providers: [ + { provide: DataService, useClass: MockDataService } +] + +// Conditional implementation +providers: [ + { + provide: StorageService, + useClass: environment.production ? CloudStorageService : LocalStorageService + } +] +``` + +#### Practical example: Logger substitution + +You can substitute implementations to extend functionality: + +```ts +import { Injectable, Component, inject } from '@angular/core'; + +// Base logger +@Injectable() +export class Logger { + log(message: string) { + console.log(message); + } +} + +// Enhanced logger with timestamp +@Injectable() +export class BetterLogger extends Logger { + override log(message: string) { + super.log(`[${new Date().toISOString()}] ${message}`); + } +} + +// Logger that includes user context +@Injectable() +export class EvenBetterLogger extends Logger { + private userService = inject(UserService); + + override log(message: string) { + const name = this.userService.user.name; + super.log(`Message to ${name}: ${message}`); + } +} + +// In your component +@Component({ + selector: 'app-example', + providers: [ + UserService, // EvenBetterLogger needs this + { provide: Logger, useClass: EvenBetterLogger } + ] +}) +export class ExampleComponent { + private logger = inject(Logger); // Gets EvenBetterLogger instance +} +``` + +#### useValue + +`useValue` provides any JavaScript data type as a static value: + +```ts +providers: [ + { provide: API_URL_TOKEN, useValue: 'https://api.example.com' }, + { provide: MAX_RETRIES_TOKEN, useValue: 3 }, + { provide: FEATURE_FLAGS_TOKEN, useValue: { darkMode: true, beta: false } } +] +``` + +IMPORTANT: TypeScript types and interfaces cannot serve as dependency values. They exist only at compile-time. + +#### Practical example: Application configuration + +A common use case for `useValue` is providing application configuration: + +```ts +// Define configuration interface +export interface AppConfig { + apiUrl: string; + appTitle: string; + features: { + darkMode: boolean; + analytics: boolean; + }; +} + +// Create injection token +export const APP_CONFIG = new InjectionToken('app.config'); + +// Define configuration +const appConfig: AppConfig = { + apiUrl: 'https://api.example.com', + appTitle: 'My Application', + features: { + darkMode: true, + analytics: false + } +}; + +// Provide in bootstrap +bootstrapApplication(AppComponent, { + providers: [ + { provide: APP_CONFIG, useValue: appConfig } + ] +}); + +// Use in component +@Component({ + selector: 'app-header', + template: `

    {{ title }}

    ` +}) +export class HeaderComponent { + private config = inject(APP_CONFIG); + title = this.config.appTitle; +} +``` + +#### useFactory + +`useFactory` provides a function that generates a new value for injection: + +```ts +export const loggerFactory = (config: AppConfig) => { + return new LoggerService(config.logLevel, config.endpoint); +}; + +providers: [ + { + provide: LoggerService, + useFactory: loggerFactory, + deps: [APP_CONFIG] // Dependencies for the factory function + } +] +``` + +You can mark factory dependencies as optional: + +```ts +import { Optional } from '@angular/core'; + +providers: [ + { + provide: MyService, + useFactory: (required: RequiredService, optional?: OptionalService) => { + return new MyService(required, optional || new DefaultService()); + }, + deps: [RequiredService, [new Optional(), OptionalService]] + } +] +``` + +#### Practical example: Configuration-based API client + +Here's a complete example showing how to use a factory to create a service with runtime configuration: + +```ts +// Service that needs runtime configuration +class ApiClient { + constructor( + private http: HttpClient, + private baseUrl: string, + private rateLimitMs: number + ) {} + + async fetchData(endpoint: string) { + // Apply rate limiting based on user tier + await this.applyRateLimit(); + return this.http.get(`${this.baseUrl}/${endpoint}`); + } + + private async applyRateLimit() { + // Simplified example - real implementation would track request timing + return new Promise(resolve => setTimeout(resolve, this.rateLimitMs)); + } +} + +// Factory function that configures based on user tier +import { inject } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +const apiClientFactory = () => { + const http = inject(HttpClient); + const userService = inject(UserService); + + // Assuming userService provides these values + const baseUrl = userService.getApiBaseUrl(); + const rateLimitMs = userService.getRateLimit(); + + return new ApiClient(http, baseUrl, rateLimitMs); +}; + +// Provider configuration +export const apiClientProvider = { + provide: ApiClient, + useFactory: apiClientFactory +}; + +// Usage in component +@Component({ + selector: 'app-dashboard', + providers: [apiClientProvider] +}) +export class DashboardComponent { + private apiClient = inject(ApiClient); +} +``` + +#### useExisting + +`useExisting` creates an alias for a provider that was already defined. Both tokens return the same instance: + +```ts +providers: [ + NewLogger, // The actual service + { provide: OldLogger, useExisting: NewLogger } // The alias +] +``` + +IMPORTANT: Don't confuse `useExisting` with `useClass`. `useClass` creates separate instances, while `useExisting` ensures you get the same singleton instance. + +### Multiple providers + +Use the `multi: true` flag when multiple providers contribute values to the same token: + +```ts +export const INTERCEPTOR_TOKEN = new InjectionToken('interceptors'); + +providers: [ + { provide: INTERCEPTOR_TOKEN, useClass: AuthInterceptor, multi: true }, + { provide: INTERCEPTOR_TOKEN, useClass: LoggingInterceptor, multi: true }, + { provide: INTERCEPTOR_TOKEN, useClass: RetryInterceptor, multi: true } +] +``` + +When you inject `INTERCEPTOR_TOKEN`, you'll receive an array containing instances of all three interceptors. + +## Where can you specify providers? + +Angular offers several levels where you can register providers, each with different implications for scope, lifecycle, and performance: + +- [**Application bootstrap**](#application-bootstrap) - Global singletons available everywhere +- [**On an element (component or directive)**](#component-or-directive-providers) - Isolated instances for specific component trees +- [**Route**](#route-providers) - Feature-specific services for lazy-loaded modules + +### Application bootstrap + +Use application-level providers in `bootstrapApplication` when: + +- **The service is used across multiple feature areas** - Services like HTTP clients, logging, or authentication that many parts of your app need +- **You want a true singleton** - One instance shared by the entire application +- **The service has no component-specific configuration** - General-purpose utilities that work the same everywhere +- **You're providing global configuration** - API endpoints, feature flags, or environment settings + +```ts +// main.ts +bootstrapApplication(AppComponent, { + providers: [ + { provide: API_BASE_URL, useValue: 'https://api.example.com' }, + { provide: INTERCEPTOR_TOKEN, useClass: AuthInterceptor, multi: true }, + LoggingService, // Used throughout the app + { provide: ErrorHandler, useClass: GlobalErrorHandler } + ] +}); +``` + +**Benefits:** + +- Single instance reduces memory usage +- Available everywhere without additional setup +- Easier to manage global state + +**Drawbacks:** + +- Always included in your JavaScript bundle, even if the value is never injected +- Cannot be easily customized per feature +- Harder to test individual components in isolation + +#### Why provide during bootstrap instead of using `providedIn: 'root'`? + +You might want a provider during bootstrap when: + +- The provider has side-effects (e.g., installing the client-side router) +- The provider requires configuration (e.g., routes) +- You're using Angular's `provideSomething` pattern (e.g., `provideRouter`, `provideHttpClient`) + +### Component or directive providers + +Use component or directive providers when: + +- **The service has component-specific state** - Form validators, component-specific caches, or UI state managers +- **You need isolated instances** - Each component needs its own copy of the service +- **The service is only used by one component tree** - Specialized services that don't need global access +- **You're creating reusable components** - Components that should work independently with their own services + +```angular-ts +// Specialized form component with its own validation service +@Component({ + selector: 'app-advanced-form', + providers: [ + FormValidationService, // Each form gets its own validator + { provide: FORM_CONFIG, useValue: { strictMode: true } } + ] +}) +export class AdvancedFormComponent { } + +// Modal component with isolated state management +@Component({ + selector: 'app-modal', + providers: [ + ModalStateService // Each modal manages its own state + ] +}) +export class ModalComponent { } +``` + +**Benefits:** + +- Better encapsulation and isolation +- Easier to test components individually +- Multiple instances can coexist with different configurations + +**Drawbacks:** + +- New instance created for each component (higher memory usage) +- No shared state between components +- Must be provided wherever needed +- Always included in the same JavaScript bundle as the component or directive, even if the value is never injected + +NOTE: If multiple directives on the same element provide the same token, one will win, but which one is undefined. + +### Route providers + +Use route-level providers for: + +- **Feature-specific services** - Services only needed for particular routes or feature modules +- **Lazy-loaded module dependencies** - Services that should only load with specific features +- **Route-specific configuration** - Settings that vary by application area + +```ts +// routes.ts +export const routes: Routes = [ + { + path: 'admin', + providers: [ + AdminService, // Only loaded with admin routes + { provide: FEATURE_FLAGS, useValue: { adminMode: true } } + ], + loadChildren: () => import('./admin/admin.routes') + }, + { + path: 'shop', + providers: [ + ShoppingCartService, // Isolated shopping state + PaymentService + ], + loadChildren: () => import('./shop/shop.routes') + } +]; +``` + +## Library author patterns + +When creating Angular libraries, you often need to provide flexible configuration options for consumers while maintaining clean APIs. Angular's own libraries demonstrate powerful patterns for achieving this. + +### The `provide` pattern + +Instead of requiring users to manually configure complex providers, library authors can export functions that return provider configurations: + +```ts +// 📁 /libs/analytics/src/providers.ts +import { InjectionToken, Provider, inject } from '@angular/core'; + +// Configuration interface +export interface AnalyticsConfig { + trackingId: string; + enableDebugMode?: boolean; + anonymizeIp?: boolean; +} + +// Internal token for configuration +const ANALYTICS_CONFIG = new InjectionToken('analytics.config'); + +// Main service that uses the configuration +export class AnalyticsService { + private config = inject(ANALYTICS_CONFIG); + + track(event: string, properties?: any) { + // Implementation using config + } +} + +// Provider function for consumers +export function provideAnalytics(config: AnalyticsConfig): Provider[] { + return [ + { provide: ANALYTICS_CONFIG, useValue: config }, + AnalyticsService + ]; +} + +// Usage in consumer app +// main.ts +bootstrapApplication(AppComponent, { + providers: [ + provideAnalytics({ + trackingId: 'GA-12345', + enableDebugMode: !environment.production + }) + ] +}); +``` + +### Advanced provider patterns with options + +For more complex scenarios, you can combine multiple configuration approaches: + +```ts +// 📁 /libs/http-client/src/provider.ts +import { Provider, InjectionToken, inject } from '@angular/core'; + +// Feature flags for optional functionality +export enum HttpFeatures { + Interceptors = 'interceptors', + Caching = 'caching', + Retry = 'retry' +} + +// Configuration interfaces +export interface HttpConfig { + baseUrl?: string; + timeout?: number; + headers?: Record; +} + +export interface RetryConfig { + maxAttempts: number; + delayMs: number; +} + +// Internal tokens +const HTTP_CONFIG = new InjectionToken('http.config'); +const RETRY_CONFIG = new InjectionToken('retry.config'); +const HTTP_FEATURES = new InjectionToken>('http.features'); + +// Core service +class HttpClientService { + private config = inject(HTTP_CONFIG, { optional: true }); + private features = inject(HTTP_FEATURES); + + get(url: string) { + // Use config and check features + } +} + +// Feature services +class RetryInterceptor { + private config = inject(RETRY_CONFIG); + // Retry logic +} + +class CacheInterceptor { + // Caching logic +} + +// Main provider function +export function provideHttpClient( + config?: HttpConfig, + ...features: HttpFeature[] +): Provider[] { + const providers: Provider[] = [ + { provide: HTTP_CONFIG, useValue: config || {} }, + { provide: HTTP_FEATURES, useValue: new Set(features.map(f => f.kind)) }, + HttpClientService + ]; + + // Add feature-specific providers + features.forEach(feature => { + providers.push(...feature.providers); + }); + + return providers; +} + +// Feature configuration functions +export interface HttpFeature { + kind: HttpFeatures; + providers: Provider[]; +} + +export function withInterceptors(...interceptors: any[]): HttpFeature { + return { + kind: HttpFeatures.Interceptors, + providers: interceptors.map(interceptor => ({ + provide: INTERCEPTOR_TOKEN, + useClass: interceptor, + multi: true + })) + }; +} + +export function withCaching(): HttpFeature { + return { + kind: HttpFeatures.Caching, + providers: [CacheInterceptor] + }; +} + +export function withRetry(config: RetryConfig): HttpFeature { + return { + kind: HttpFeatures.Retry, + providers: [ + { provide: RETRY_CONFIG, useValue: config }, + RetryInterceptor + ] + }; +} + +// Consumer usage with multiple features +bootstrapApplication(AppComponent, { + providers: [ + provideHttpClient( + { baseUrl: 'https://api.example.com' }, + withInterceptors(AuthInterceptor, LoggingInterceptor), + withCaching(), + withRetry({ maxAttempts: 3, delayMs: 1000 }) + ) + ] +}); +``` + +### Why use provider functions instead of direct configuration? + +Provider functions offer several advantages for library authors: + +1. **Encapsulation** - Internal tokens and implementation details remain private +2. **Type safety** - TypeScript ensures correct configuration at compile time +3. **Flexibility** - Easily compose features with `with*` pattern +4. **Future-proofing** - Internal implementation can change without breaking consumers +5. **Consistency** - Aligns with Angular's own patterns (`provideRouter`, `provideHttpClient`, etc.) + +This pattern is extensively used in Angular's own libraries and is considered a best practice for library authors who need to provide configurable services. diff --git a/adev/src/content/guide/di/dependency-injection-context.md b/adev/src/content/guide/di/dependency-injection-context.md index b242b87d2c80..e2d4c0111b33 100644 --- a/adev/src/content/guide/di/dependency-injection-context.md +++ b/adev/src/content/guide/di/dependency-injection-context.md @@ -1,32 +1,20 @@ # Injection context The dependency injection (DI) system relies internally on a runtime context where the current injector is available. + This means that injectors can only work when code is executed in such a context. The injection context is available in these situations: -* During construction (via the `constructor`) of a class being instantiated by the DI system, such as an `@Injectable` or `@Component`. -* In the initializer for fields of such classes. -* In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`. -* In the `factory` function specified for an `InjectionToken`. -* Within a stack frame that runs in an injection context. +- During construction (via the `constructor`) of a class being instantiated by the DI system, such as an `@Injectable` or `@Component`. +- In the initializer for fields of such classes. +- In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`. +- In the `factory` function specified for an `InjectionToken`. +- Within a stack frame that runs in an injection context. Knowing when you are in an injection context will allow you to use the [`inject`](api/core/inject) function to inject instances. -## Class constructors - -Every time the DI system instantiates a class, it does so in an injection context. This is handled by the framework itself. The constructor of the class is executed in that runtime context, which also allows injection of a token using the [`inject`](api/core/inject) function. - - -class MyComponent { - private service1: Service1; - private service2: Service2 = inject(Service2); // In context - - constructor() { - this.service1 = inject(Service1) // In context - } -} - +NOTE: For basic examples of using `inject()` in class constructors and field initializers, see the [overview guide](/guide/di#where-can-inject-be-used). ## Stack frame in context @@ -34,22 +22,21 @@ Some APIs are designed to be run in an injection context. This is the case, for Here is an example for `CanActivateFn` - +```ts {highlight: [3]} const canActivateTeam: CanActivateFn = - (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { - return inject(PermissionsService).canActivate(inject(UserToken), route.params.id); - }; - + (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + return inject(PermissionsService).canActivate(inject(UserToken), route.params.id); + }; +``` ## Run within an injection context When you want to run a given function in an injection context without already being in one, you can do so with `runInInjectionContext`. This requires access to a given injector, like the `EnvironmentInjector`, for example: - +```ts {highlight: [9], header"hero.service.ts"} @Injectable({ - providedIn: 'root', + providedIn: 'root' }) export class HeroService { private environmentInjector = inject(EnvironmentInjector); @@ -60,13 +47,38 @@ export class HeroService { }); } } - +``` Note that `inject` will return an instance only if the injector can resolve the required token. ## Asserts the context -Angular provides the `assertInInjectionContext` helper function to assert that the current context is an injection context. +Angular provides the `assertInInjectionContext` helper function to assert that the current context is an injection context and throws a clear error if not. Pass a reference to the calling function so the error message points to the correct API entry point. This produces a clearer, more actionable message than the default generic injection error. + +```ts +import { ElementRef, assertInInjectionContext, inject } from '@angular/core'; + +export function injectNativeElement(): T { + assertInInjectionContext(injectNativeElement); + return inject(ElementRef).nativeElement; +} +``` + +You can then call this helper **from an injection context** (constructor, field initializer, provider factory, or code executed via `runInInjectionContext`): + +```ts +import { Component, inject } from '@angular/core'; +import { injectNativeElement } from './dom-helpers'; + +@Component({ /* … */ }) +export class PreviewCard { + readonly hostEl = injectNativeElement(); // Field initializer runs in an injection context. + + onAction() { + const anotherRef = injectNativeElement(); // Fails: runs outside an injection context. + } +} +``` ## Using DI outside of a context diff --git a/adev/src/content/guide/di/dependency-injection-providers.md b/adev/src/content/guide/di/dependency-injection-providers.md deleted file mode 100644 index cc51d1a682c0..000000000000 --- a/adev/src/content/guide/di/dependency-injection-providers.md +++ /dev/null @@ -1,212 +0,0 @@ -# Configuring dependency providers - -The previous sections described how to use class instances as dependencies. -Aside from classes, you can also use values such as `boolean`, `string`, `Date`, and objects as dependencies. -Angular provides the necessary APIs to make the dependency configuration flexible, so you can make those values available in DI. - -## Specifying a provider token - -If you specify the service class as the provider token, the default behavior is for the injector to instantiate that class using the `new` operator. - -In the following example, the app component provides a `Logger` instance: - - -providers: [Logger], - - -You can, however, configure DI to associate the `Logger` provider token with a different class or any other value. -So when the `Logger` is injected, the configured value is used instead. - -In fact, the class provider syntax is a shorthand expression that expands into a provider configuration, defined by the `Provider` interface. -Angular expands the `providers` value in this case into a full provider object as follows: - - -[{ provide: Logger, useClass: Logger }] - - -The expanded provider configuration is an object literal with two properties: - -- The `provide` property holds the token that serves as the key for consuming the dependency value. -- The second property is a provider definition object, which tells the injector **how** to create the dependency value. The provider-definition can be one of the following: - - `useClass` - this option tells Angular DI to instantiate a provided class when a dependency is injected - - `useExisting` - allows you to alias a token and reference any existing one. - - `useFactory` - allows you to define a function that constructs a dependency. - - `useValue` - provides a static value that should be used as a dependency. - -The sections below describe how to use the different provider definitions. - -### Class providers: useClass - -The `useClass` provider key lets you create and return a new instance of the specified class. - -You can use this type of provider to substitute an alternative implementation for a common or default class. -The alternative implementation can, for example, implement a different strategy, extend the default class, or emulate the behavior of the real class in a test case. - -In the following example, `BetterLogger` would be instantiated when the `Logger` dependency is requested in a component or any other class: - - -[{ provide: Logger, useClass: BetterLogger }] - - -If the alternative class providers have their own dependencies, specify both providers in the providers metadata property of the parent module or component: - - -[ - UserService, // dependency needed in `EvenBetterLogger`. - { provide: Logger, useClass: EvenBetterLogger }, -] - - -In this example, `EvenBetterLogger` displays the user name in the log message. This logger gets the user from an injected `UserService` instance: - - -@Injectable() -export class EvenBetterLogger extends Logger { - private userService = inject(UserService); - - override log(message: string) { - const name = this.userService.user.name; - super.log(`Message to ${name}: ${message}`); - } -} - - -Angular DI knows how to construct the `UserService` dependency, since it has been configured above and is available in the injector. - -### Alias providers: useExisting - -The `useExisting` provider key lets you map one token to another. -In effect, the first token is an alias for the service associated with the second token, creating two ways to access the same service object. - -In the following example, the injector injects the singleton instance of `NewLogger` when the component asks for either the new or the old logger: -In this way, `OldLogger` is an alias for `NewLogger`. - - -[ - NewLogger, - // Alias OldLogger w/ reference to NewLogger - { provide: OldLogger, useExisting: NewLogger}, -] - - -NOTE: Ensure you do not alias `OldLogger` to `NewLogger` with `useClass`, as this creates two different `NewLogger` instances. - -### Factory providers: useFactory - -The `useFactory` provider key lets you create a dependency object by calling a factory function. -With this approach, you can create a dynamic value based on information available in the DI and elsewhere in the app. - -In the following example, only authorized users should see secret heroes in the `HeroService`. -Authorization can change during the course of a single application session, as when a different user logs in . - -To keep security-sensitive information in `UserService` and out of `HeroService`, give the `HeroService` constructor a boolean flag to control display of secret heroes: - - -class HeroService { - constructor( - private logger: Logger, - private isAuthorized: boolean) { } - - getHeroes() { - const auth = this.isAuthorized ? 'authorized' : 'unauthorized'; - this.logger.log(`Getting heroes for ${auth} user.`); - return HEROES.filter(hero => this.isAuthorized || !hero.isSecret); - } -} - - -To implement the `isAuthorized` flag, use a factory provider to create a new logger instance for `HeroService`. -This is necessary as we need to manually pass `Logger` when constructing the hero service: - - -const heroServiceFactory = (logger: Logger, userService: UserService) => - new HeroService(logger, userService.user.isAuthorized); - - -The factory function has access to `UserService`. -You inject both `Logger` and `UserService` into the factory provider so the injector can pass them along to the factory function: - - -export const heroServiceProvider = { - provide: HeroService, - useFactory: heroServiceFactory, - deps: [Logger, UserService] -}; - - -- The `useFactory` field specifies that the provider is a factory function whose implementation is `heroServiceFactory`. -- The `deps` property is an array of provider tokens. -The `Logger` and `UserService` classes serve as tokens for their own class providers. -The injector resolves these tokens and injects the corresponding services into the matching `heroServiceFactory` factory function parameters, based on the order specified. - -Capturing the factory provider in the exported variable, `heroServiceProvider`, makes the factory provider reusable. - -### Value providers: useValue - -The `useValue` key lets you associate a static value with a DI token. - -Use this technique to provide runtime configuration constants such as website base addresses and feature flags. -You can also use a value provider in a unit test to provide mock data in place of a production data service. - -The next section provides more information about the `useValue` key. - -## Using an `InjectionToken` object - -Use an `InjectionToken` object as provider token for non-class dependencies. -The following example defines a token, `APP_CONFIG`. of the type `InjectionToken`: - - -import { InjectionToken } from '@angular/core'; - -export interface AppConfig { - title: string; -} - -export const APP_CONFIG = new InjectionToken('app.config description'); - - -The optional type parameter, ``, and the token description, `app.config description`, specify the token's purpose. - -Next, register the dependency provider in the component using the `InjectionToken` object of `APP_CONFIG`: - - -const MY_APP_CONFIG_VARIABLE: AppConfig = { - title: 'Hello', -}; - -providers: [{ provide: APP_CONFIG, useValue: MY_APP_CONFIG_VARIABLE }] - - -Now, inject the configuration object in the constructor body with the `inject` function: - - -export class AppComponent { - constructor() { - const config = inject(APP_CONFIG); - this.title = config.title; - } -} - - -### Interfaces and DI - -Though the TypeScript `AppConfig` interface supports typing within the class, the `AppConfig` interface plays no role in DI. -In TypeScript, an interface is a design-time artifact, and does not have a runtime representation, or token, that the DI framework can use. - -When the TypeScript transpiles to JavaScript, the interface disappears because JavaScript doesn't have interfaces. -Because there is no interface for Angular to find at runtime, the interface cannot be a token, nor can you inject it: - - -// Can't use interface as provider token -[{ provide: AppConfig, useValue: MY_APP_CONFIG_VARIABLE })] - - - -export class AppComponent { - // Can't inject using the interface as the parameter type - private config = inject(AppConfig); -} - diff --git a/adev/src/content/guide/di/dependency-injection.md b/adev/src/content/guide/di/dependency-injection.md deleted file mode 100644 index 95558f91300f..000000000000 --- a/adev/src/content/guide/di/dependency-injection.md +++ /dev/null @@ -1,140 +0,0 @@ -# Understanding dependency injection - -Dependency injection, or DI, is one of the fundamental concepts in Angular. DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need. - -Two main roles exist in the DI system: dependency consumer and dependency provider. - -Angular facilitates the interaction between dependency consumers and dependency providers using an abstraction called `Injector`. When a dependency is requested, the injector checks its registry to see if there is an instance already available there. If not, a new instance is created and stored in the registry. Angular creates an application-wide injector (also known as the "root" injector) during the application bootstrap process. In most cases you don't need to manually create injectors, but you should know that there is a layer that connects providers and consumers. - -This topic covers basic scenarios of how a class can act as a dependency. Angular also allows you to use functions, objects, primitive types such as string or Boolean, or any other types as dependencies. For more information, see [Dependency providers](guide/di/dependency-injection-providers). - -## Providing a dependency - -Consider a class called `HeroService` that needs to act as a dependency in a component. - -The first step is to add the `@Injectable` decorator to show that the class can be injected. - - -@Injectable() -class HeroService {} - - -The next step is to make it available in the DI by providing it. -A dependency can be provided in multiple places: - -- [**Preferred**: At the application root level using `providedIn`](#preferred-at-the-application-root-level-using-providedin) -- [At the Component level](#at-the-component-level) -- [At the application root level using `ApplicationConfig`](#at-the-application-root-level-using-applicationconfig) -- [`NgModule` based applications](#ngmodule-based-applications) - -### **Preferred**: At the application root level using `providedIn` - -Providing a service at the application root level using `providedIn` allows injecting the service into all other classes. -Using `providedIn` enables Angular and JavaScript code optimizers to effectively remove services that are unused (known as tree-shaking). - -You can provide a service by using `providedIn: 'root'` in the `@Injectable` decorator: - - -@Injectable({ - providedIn: 'root' -}) -class HeroService {} - - -When you provide the service at the root level, Angular creates a single, shared instance of the `HeroService` and injects it into any class that asks for it. - -### At the Component level - -You can provide services at `@Component` level by using the `providers` field of the `@Component` decorator. -In this case the `HeroService` becomes available to all instances of this component and other components and directives used in the template. - -For example: - - -@Component({ - selector: 'hero-list', - template: '...', - providers: [HeroService] -}) -class HeroListComponent {} - - -When you register a provider at the component level, you get a new instance of the service with each new instance of that component. - -NOTE: Declaring a service like this causes `HeroService` to always be included in your application— even if the service is unused. - -### At the application root level using `ApplicationConfig` - -You can use the `providers` field of the `ApplicationConfig` (passed to the `bootstrapApplication` function) to provide a service or other `Injectable` at the application level. - -In the example below, the `HeroService` is available to all components, directives, and pipes: - - -export const appConfig: ApplicationConfig = { - providers: [ - { provide: HeroService }, - ] -}; - - -Then, in `main.ts`: - - -bootstrapApplication(AppComponent, appConfig) - - -NOTE: Declaring a service like this causes `HeroService` to always be included in your application— even if the service is unused. - -### `NgModule` based applications - -`@NgModule`-based applications use the `providers` field of the `@NgModule` decorator to provide a service or other `Injectable` available at the application level. - -A service provided in a module is available to all declarations of the module, or to any other modules which share the same `ModuleInjector`. -To understand all edge-cases, see [Hierarchical injectors](guide/di/hierarchical-dependency-injection). - -NOTE: Declaring a service using `providers` causes the service to be included in your application— even if the service is unused. - -## Injecting/consuming a dependency - -Use Angular's `inject` function to retrieve dependencies. - -```ts -import {inject, Component} from 'angular/core'; - -@Component({/* ... */}) -export class UserProfile { - // You can use the `inject` function in property initializers. - private userClient = inject(UserClient); - - constructor() { - // You can also use the `inject` function in a constructor. - const logger = inject(Logger); - } -} -``` - -You can use the `inject` function in any [injection context](guide/di/dependency-injection-context). Most of the time, this is in a class property initializer or a class constructor for components, directives, services, and pipes. - -When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector creates one using the registered provider, and adds it to the injector before returning the service to Angular. - -When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments. - -```mermaid -graph TD; -subgraph Injector -serviceA[Service A] -heroService[HeroService] -serviceC[Service C] -serviceD[Service D] -end -direction TB -componentProperty["Component
    heroService = inject(HeroService)"] -heroService-->componentProperty -style componentProperty text-align: left -``` - -## What's next - - - - diff --git a/adev/src/content/guide/di/di-in-action.md b/adev/src/content/guide/di/di-in-action.md index 4d1d3b6c7caa..843fc1ba52f7 100644 --- a/adev/src/content/guide/di/di-in-action.md +++ b/adev/src/content/guide/di/di-in-action.md @@ -2,40 +2,7 @@ This guide explores additional features of dependency injection in Angular. -## Custom providers with `@Inject` - -Using a custom provider allows you to provide a concrete implementation for implicit dependencies, such as built-in browser APIs. -The following example uses an `InjectionToken` to provide the [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) browser API as a dependency in the `BrowserStorageService`: - - -import { Inject, Injectable, InjectionToken } from '@angular/core'; - -export const BROWSER_STORAGE = new InjectionToken('Browser Storage', { - providedIn: 'root', - factory: () => localStorage -}); - -@Injectable({ - providedIn: 'root' -}) -export class BrowserStorageService { - public storage = inject(BROWSER_STORAGE); - - get(key: string) { - return this.storage.getItem(key); - } - - set(key: string, value: string) { - this.storage.setItem(key, value); - } -} - - -The `factory` function returns the `localStorage` property that is attached to the browser's window object. -The `inject` function initializes the `storage` property with an instance of the token. - -This custom provider can now be overridden during testing with a mock API of `localStorage` instead of interacting with real browser APIs. +NOTE: For comprehensive coverage of InjectionToken and custom providers, see the [defining dependency providers guide](guide/di/defining-dependency-providers#injection-tokens). ## Inject the component's DOM element @@ -44,42 +11,43 @@ As a result, you might need to access a component's DOM element. Angular exposes the underlying element of a `@Component` or `@Directive` via injection using the `ElementRef` injection token: - -import { Directive, ElementRef } from '@angular/core'; +```ts {highlight:[7]} +import {Directive, ElementRef, inject} from '@angular/core'; @Directive({ - selector: '[appHighlight]' + selector: '[appHighlight]', }) export class HighlightDirective { - private element = inject(ElementRef) + private element = inject(ElementRef); update() { this.element.nativeElement.style.color = 'red'; } } - + +``` ## Resolve circular dependencies with a forward reference The order of class declaration matters in TypeScript. You can't refer directly to a class until it's been defined. -This isn't usually a problem, especially if you adhere to the recommended *one class per file* rule. +This isn't usually a problem, especially if you adhere to the recommended _one class per file_ rule. But sometimes circular references are unavoidable. For example, when class 'A' refers to class 'B' and 'B' refers to 'A', one of them has to be defined first. -The Angular `forwardRef()` function creates an *indirect* reference that Angular can resolve later. +The Angular `forwardRef()` function creates an _indirect_ reference that Angular can resolve later. -You face a similar problem when a class makes *a reference to itself*. +You face a similar problem when a class makes _a reference to itself_. For example, in its `providers` array. The `providers` array is a property of the `@Component()` decorator function, which must appear before the class definition. You can break such circular references by using `forwardRef`. - +```typescript {header: 'app.component.ts', highlight: [4]} providers: [ { provide: PARENT_MENU_ITEM, useExisting: forwardRef(() => MenuItem), }, ], - +``` diff --git a/adev/src/content/guide/di/hierarchical-dependency-injection.md b/adev/src/content/guide/di/hierarchical-dependency-injection.md index 7d59ae3d369f..77dbde0e3976 100644 --- a/adev/src/content/guide/di/hierarchical-dependency-injection.md +++ b/adev/src/content/guide/di/hierarchical-dependency-injection.md @@ -1,23 +1,17 @@ # Hierarchical injectors -Injectors in Angular have rules that you can leverage to achieve the desired visibility of injectables in your applications. -By understanding these rules, you can determine whether to declare a provider at the application level, in a Component, or in a Directive. +This guide provides in-depth coverage of Angular's hierarchical dependency injection system, including resolution rules, modifiers, and advanced patterns. -The applications you build with Angular can become quite large, and one way to manage this complexity is to split up the application into a well-defined tree of components. - -There can be sections of your page that work in a completely independent way than the rest of the application, with its own local copies of the services and other dependencies that it needs. -Some of the services that these sections of the application use might be shared with other parts of the application, or with parent components that are further up in the component tree, while other dependencies are meant to be private. - -With hierarchical dependency injection, you can isolate sections of the application and give them their own private dependencies not shared with the rest of the application, or have parent components share certain dependencies with its child components only but not with the rest of the component tree, and so on. Hierarchical dependency injection enables you to share dependencies between different parts of the application only when and if you need to. +NOTE: For basic concepts about injector hierarchy and provider scoping, see the [defining dependency providers guide](guide/di/defining-dependency-providers#injector-hierarchy-in-angular). ## Types of injector hierarchies Angular has two injector hierarchies: -| Injector hierarchies | Details | -|:--- |:--- | -| `EnvironmentInjector` hierarchy | Configure an `EnvironmentInjector` in this hierarchy using `@Injectable()` or `providers` array in `ApplicationConfig`. | -| `ElementInjector` hierarchy | Created implicitly at each DOM element. An `ElementInjector` is empty by default unless you configure it in the `providers` property on `@Directive()` or `@Component()`. | +| Injector hierarchies | Details | +| :------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `EnvironmentInjector` hierarchy | Configure an `EnvironmentInjector` in this hierarchy using `@Injectable()` or `providers` array in `ApplicationConfig`. | +| `ElementInjector` hierarchy | Created implicitly at each DOM element. An `ElementInjector` is empty by default unless you configure it in the `providers` property on `@Directive()` or `@Component()`. | For `NgModule` based applications, you can provide dependencies with the `ModuleInjector` hierarchy using an `@NgModule()` or `@Injectable()` annotation. @@ -27,8 +21,8 @@ For `NgModule` based applications, you can provide dependencies with the `Module The `EnvironmentInjector` can be configured in one of two ways by using: -* The `@Injectable()` `providedIn` property to refer to `root` or `platform` -* The `ApplicationConfig` `providers` array +- The `@Injectable()` `providedIn` property to refer to `root` or `platform` +- The `ApplicationConfig` `providers` array @@ -42,17 +36,16 @@ Tree-shaking is especially useful for a library because the application which us Provide services using `providedIn` of `@Injectable()` as follows: - +```ts {highlight:[4]} import { Injectable } from '@angular/core'; @Injectable({ - providedIn: 'root' // <--provides this service in the root EnvironmentInjector + providedIn: 'root' // <--provides this service in the root EnvironmentInjector }) export class ItemService { name = 'telephone'; } - - +``` The `@Injectable()` decorator identifies a service class. The `providedIn` property configures a specific `EnvironmentInjector`, here `root`, which makes the service available in the `root` `EnvironmentInjector`. @@ -61,8 +54,8 @@ The `providedIn` property configures a specific `EnvironmentInjector`, here `roo In the case of `NgModule` based applications, the ModuleInjector can be configured in one of two ways by using: -* The `@Injectable()` `providedIn` property to refer to `root` or `platform` -* The `@NgModule()` `providers` array +- The `@Injectable()` `providedIn` property to refer to `root` or `platform` +- The `@NgModule()` `providers` array `ModuleInjector` is configured by the `@NgModule.providers` and `NgModule.imports` property. `ModuleInjector` is a flattening of all the providers arrays that can be reached by following the `NgModule.imports` recursively. @@ -74,9 +67,9 @@ There are two more injectors above `root`, an additional `EnvironmentInjector` a Consider how Angular bootstraps the application with the following in `main.ts`: - +```ts bootstrapApplication(AppComponent, appConfig); - +``` The `bootstrapApplication()` method creates a child injector of the platform injector which is configured by the `ApplicationConfig` instance. This is the `root` `EnvironmentInjector`. @@ -132,13 +125,13 @@ Angular creates `ElementInjector` hierarchies implicitly for each DOM element. Providing a service in the `@Component()` decorator using its `providers` or `viewProviders` property configures an `ElementInjector`. For example, the following `TestComponent` configures the `ElementInjector` by providing the service as follows: - +```ts {highlight:[3]} @Component({ - … + /* … */ providers: [{ provide: ItemService, useValue: { name: 'lamp' } }] }) export class TestComponent - +``` HELPFUL: See the [resolution rules](#resolution-rules) section to understand the relationship between the `EnvironmentInjector` tree, the `ModuleInjector` and the `ElementInjector` tree. @@ -184,17 +177,17 @@ Import each of them from `@angular/core` and use each in the `inject` configurat Resolution modifiers fall into three categories: -* What to do if Angular doesn't find what you're looking for, that is `optional` -* Where to start looking, that is `skipSelf` -* Where to stop looking, `host` and `self` +- What to do if Angular doesn't find what you're looking for, that is `optional` +- Where to start looking, that is `skipSelf` +- Where to stop looking, `host` and `self` By default, Angular always starts at the current `Injector` and keeps searching all the way up. Modifiers allow you to change the starting, or _self_, location and the ending location. Additionally, you can combine all of the modifiers except: -* `host` and `self` -* `skipSelf` and `self`. +- `host` and `self` +- `skipSelf` and `self`. ### `optional` @@ -202,11 +195,11 @@ Additionally, you can combine all of the modifiers except: This way, if it can't be resolved at runtime, Angular resolves the service as `null`, rather than throwing an error. In the following example, the service, `OptionalService`, isn't provided in the service, `ApplicationConfig`, `@NgModule()`, or component class, so it isn't available anywhere in the app. - +```ts {header:"src/app/optional/optional.component.ts"} export class OptionalComponent { public optional? = inject(OptionalService, {optional: true}); } - +``` ### `self` @@ -217,8 +210,7 @@ To avoid errors in this situation, combine `self` with `optional`. For example, in the following `SelfNoDataComponent`, notice the injected `LeafService` as a property. - +```ts {header: 'self-no-data.component.ts', highlight: [7]} @Component({ selector: 'app-self-no-data', templateUrl: './self-no-data.component.html', @@ -227,34 +219,43 @@ For example, in the following `SelfNoDataComponent`, notice the injected `LeafSe export class SelfNoDataComponent { public leaf = inject(LeafService, {optional: true, self: true}); } - +``` In this example, there is a parent provider and injecting the service will return the value, however, injecting the service with `self` and `optional` will return `null` because `self` tells the injector to stop searching in the current host element. Another example shows the component class with a provider for `FlowerService`. -In this case, the injector looks no further than the current `ElementInjector` because it finds the `FlowerService` and returns the tulip 🌷. +In this case, the injector looks no further than the current `ElementInjector` because it finds the `FlowerService` and returns the tulip 🌷. - +```ts {header:"src/app/self/self.component.ts"} +@Component({ + selector: 'app-self', + templateUrl: './self.component.html', + styleUrls: ['./self.component.css'], + providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}], +}) +export class SelfComponent { + constructor(@Self() public flower: FlowerService) {} +} +``` ### `skipSelf` `skipSelf` is the opposite of `self`. With `skipSelf`, Angular starts its search for a service in the parent `ElementInjector`, rather than in the current one. -So if the parent `ElementInjector` were using the fern 🌿 value for `emoji`, but you had maple leaf 🍁 in the component's `providers` array, Angular would ignore maple leaf 🍁 and use fern 🌿. +So if the parent `ElementInjector` were using the fern 🌿 value for `emoji`, but you had maple leaf 🍁 in the component's `providers` array, Angular would ignore maple leaf 🍁 and use fern 🌿. To see this in code, assume that the following value for `emoji` is what the parent component were using, as in this service: - +```ts {header: 'leaf.service.ts'} export class LeafService { emoji = '🌿'; } - +``` -Imagine that in the child component, you had a different value, maple leaf 🍁 but you wanted to use the parent's value instead. +Imagine that in the child component, you had a different value, maple leaf 🍁 but you wanted to use the parent's value instead. This is when you'd use `skipSelf`: - +```ts {header:"skipself.component.ts" highlight:[[6],[10]]} @Component({ selector: 'app-skipself', templateUrl: './skipself.component.html', @@ -266,9 +267,9 @@ export class SkipselfComponent { // Use skipSelf as inject option public leaf = inject(LeafService, {skipSelf: true}); } - +``` -In this case, the value you'd get for `emoji` would be fern 🌿, not maple leaf 🍁. +In this case, the value you'd get for `emoji` would be fern 🌿, not maple leaf 🍁. #### `skipSelf` option with `optional` @@ -277,11 +278,11 @@ Use the `skipSelf` option with `optional` to prevent an error if the value is `n In the following example, the `Person` service is injected during property initialization. `skipSelf` tells Angular to skip the current injector and `optional` will prevent an error should the `Person` service be `null`. - +```ts class Person { parent = inject(Person, {optional: true, skipSelf: true}) } - +``` ### `host` @@ -292,34 +293,33 @@ class Person { Even if there is a service instance further up the tree, Angular won't continue looking. Use `host` as follows: - +```ts {header:"host.component.ts" highlight:[[6],[9]]} @Component({ selector: 'app-host', templateUrl: './host.component.html', styleUrls: ['./host.component.css'], - // provide the service - providers: [{ provide: FlowerService, useValue: { emoji: '🌷' } }] + // provide the service + providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}], }) export class HostComponent { // use host when injecting the service flower = inject(FlowerService, {host: true, optional: true}); } - +``` -Since `HostComponent` has the `host` option , no matter what the parent of `HostComponent` might have as a `flower.emoji` value, the `HostComponent` will use tulip 🌷. +Since `HostComponent` has the `host` option , no matter what the parent of `HostComponent` might have as a `flower.emoji` value, the `HostComponent` will use tulip 🌷. -### Modifiers with constructor injection +### Modifiers with constructor injection Similarly as presented before, the behavior of constructor injection can be modified with `@Optional()`, `@Self()`, `@SkipSelf()` and `@Host()`. Import each of them from `@angular/core` and use each in the component class constructor when you inject your service. - +```ts {header:"self-no-data.component.ts" highlight:[2]} export class SelfNoDataComponent { constructor(@Self() @Optional() public leaf?: LeafService) { } } - +``` ## Logical structure of the template @@ -329,11 +329,11 @@ Understanding the underlying logical structure of the Angular template will give Components are used in your templates, as in the following example: - +```html ; - +``` HELPFUL: Usually, you declare the components and their templates in separate files. For the purposes of understanding how the injection system works, it is useful to look at them from the point of view of a combined logical tree. @@ -342,7 +342,7 @@ To mark the locations of where the component templates are located, this guide u The following is an example of how the `` and `` view trees are combined into a single logical tree: - +```html <#VIEW> @@ -352,7 +352,7 @@ The following is an example of how the `` and `` view trees - +``` Understanding the idea of the `<#VIEW>` demarcation is especially significant when you configure services in the component class. @@ -363,8 +363,8 @@ The following sections demonstrate `providers` and `viewProviders` along with wa A component class can provide services in two ways: -| Arrays | Details | -|:--- |:--- | +| Arrays | Details | +| :--------------------------- | :--------------------------------------------- | | With a `providers` array | `@Component({ providers: [SomeService] })` | | With a `viewProviders` array | `@Component({ viewProviders: [SomeService] })` | @@ -375,40 +375,38 @@ For example, the logical tree will show that `` is a direct chi In the logical tree, you will see special attributes: `@Provide`, `@Inject`, and `@ApplicationConfig`. These aren't real attributes but are here to demonstrate what is going on under the hood. -| Angular service attribute | Details | -|:--- |:--- | -| `@Inject(Token)=>Value` | If `Token` is injected at this location in the logical tree, its value would be `Value`. | -| `@Provide(Token=Value)` | Indicates that `Token` is provided with `Value` at this location in the logical tree. | -| `@ApplicationConfig` | Demonstrates that a fallback `EnvironmentInjector` should be used at this location. | +| Angular service attribute | Details | +| :------------------------ | :--------------------------------------------------------------------------------------- | +| `@Inject(Token)=>Value` | If `Token` is injected at this location in the logical tree, its value would be `Value`. | +| `@Provide(Token=Value)` | Indicates that `Token` is provided with `Value` at this location in the logical tree. | +| `@ApplicationConfig` | Demonstrates that a fallback `EnvironmentInjector` should be used at this location. | ### Example app structure -The example application has a `FlowerService` provided in `root` with an `emoji` value of red hibiscus 🌺. +The example application has a `FlowerService` provided in `root` with an `emoji` value of red hibiscus 🌺. - +```ts {header:"lower.service.ts"} @Injectable({ providedIn: 'root' }) export class FlowerService { emoji = '🌺'; } - +``` Consider an application with only an `AppComponent` and a `ChildComponent`. The most basic rendered view would look like nested HTML elements such as the following: - - +```html - - + + - - +``` However, behind the scenes, Angular uses a logical view representation as follows when resolving injection requests: - +```html <#VIEW> @@ -417,7 +415,7 @@ However, behind the scenes, Angular uses a logical view representation as follow - +``` The `<#VIEW>` here represents an instance of a template. Notice that each component has its own `<#VIEW>`. @@ -426,57 +424,55 @@ Knowledge of this structure can inform how you provide and inject your services, Now, consider that `` injects the `FlowerService`: - +```typescript export class AppComponent { flower = inject(FlowerService); } - +``` Add a binding to the `` template to visualize the result: - +```html

    Emoji from FlowerService: {{flower.emoji}}

    -
    +``` The output in the view would be: - -Emoji from FlowerService: 🌺 - +```shell +Emoji from FlowerService: 🌺 +``` In the logical tree, this would be represented as follows: - +```html "🌺"> + @Inject(FlowerService) flower=>"🌺"> <#VIEW> -

    Emoji from FlowerService: {{flower.emoji}} (🌺)

    +

    Emoji from FlowerService: {{flower.emoji}} (🌺)

    <#VIEW>
    - -
    +``` When `` requests the `FlowerService`, it is the injector's job to resolve the `FlowerService` token. The resolution of the token happens in two phases: 1. The injector determines the starting location in the logical tree and an ending location of the search. - The injector begins with the starting location and looks for the token at each view level in the logical tree. - If the token is found it is returned. + The injector begins with the starting location and looks for the token at each view level in the logical tree. + If the token is found it is returned. 1. If the token is not found, the injector looks for the closest parent `EnvironmentInjector` to delegate the request to. In the example case, the constraints are: 1. Start with `<#VIEW>` belonging to `` and end with ``. - - * Normally the starting point for search is at the point of injection. - However, in this case `` is a component. `@Component`s are special in that they also include their own `viewProviders`, which is why the search starts at `<#VIEW>` belonging to ``. - This would not be the case for a directive matched at the same location. - * The ending location happens to be the same as the component itself, because it is the topmost component in this application. + - Normally the starting point for search is at the point of injection. + However, in this case `` is a component. `@Component`s are special in that they also include their own `viewProviders`, which is why the search starts at `<#VIEW>` belonging to ``. + This would not be the case for a directive matched at the same location. + - The ending location happens to be the same as the component itself, because it is the topmost component in this application. 1. The `EnvironmentInjector` provided by the `ApplicationConfig` acts as the fallback injector when the injection token can't be found in the `ElementInjector` hierarchies. @@ -484,61 +480,59 @@ In the example case, the constraints are: Now, in the `ChildComponent` class, add a provider for `FlowerService` to demonstrate more complex resolution rules in the upcoming sections: - +```ts @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'], // use the providers array to provide a service - providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }] + providers: [{provide: FlowerService, useValue: {emoji: '🌻'}}], }) export class ChildComponent { // inject the service flower = inject(FlowerService); } - +``` Now that the `FlowerService` is provided in the `@Component()` decorator, when the `` requests the service, the injector has only to look as far as the `ElementInjector` in the ``. It won't have to continue the search any further through the injector tree. The next step is to add a binding to the `ChildComponent` template. - +```html

    Emoji from FlowerService: {{flower.emoji}}

    -
    +``` To render the new values, add `` to the bottom of the `AppComponent` template so the view also displays the sunflower: - +```shell Child Component -Emoji from FlowerService: 🌻 - +Emoji from FlowerService: 🌻 +``` In the logical tree, this is represented as follows: - - +```html "🌺"> - <#VIEW> -

    Emoji from FlowerService: {{flower.emoji}} (🌺)

    - "🌻"> - <#VIEW> -

    Child Component

    -

    Emoji from FlowerService: {{flower.emoji}} (🌻)

    - -
    - +@Inject(FlowerService) flower=>"🌺"> +<#VIEW> + +

    Emoji from FlowerService: {{flower.emoji}} (🌺)

    +"🌻"> +<#VIEW> +

    Child Component

    +

    Emoji from FlowerService: {{flower.emoji}} (🌻)

    + +
    +
    - -
    +``` When `` requests the `FlowerService`, the injector begins its search at the `<#VIEW>` belonging to `` \(`<#VIEW>` is included because it is injected from `@Component()`\) and ends with ``. -In this case, the `FlowerService` is resolved in the `providers` array with sunflower 🌻 of the ``. +In this case, the `FlowerService` is resolved in the `providers` array with sunflower 🌻 of the ``. The injector doesn't have to look any further in the injector tree. -It stops as soon as it finds the `FlowerService` and never sees the red hibiscus 🌺. +It stops as soon as it finds the `FlowerService` and never sees the red hibiscus 🌺. ### Using the `viewProviders` array @@ -551,97 +545,92 @@ For step-by-step instructions, continue with this section. If you can set it up on your own, skip ahead to [Modifying service availability](#visibility-of-provided-tokens). For demonstration, we are building an `AnimalService` to demonstrate `viewProviders`. -First, create an `AnimalService` with an `emoji` property of whale 🐳: +First, create an `AnimalService` with an `emoji` property of whale 🐳: - -import { Injectable } from '@angular/core'; +```typescript +import {Injectable} from '@angular/core'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class AnimalService { emoji = '🐳'; } - +``` Following the same pattern as with the `FlowerService`, inject the `AnimalService` in the `AppComponent` class: - +```ts export class AppComponent { - public flower = inject(FlowerService); - public animal = inject(AnimalService); + public flower = inject(FlowerService); + public animal = inject(AnimalService); } - +``` HELPFUL: You can leave all the `FlowerService` related code in place as it will allow a comparison with the `AnimalService`. Add a `viewProviders` array and inject the `AnimalService` in the `` class, too, but give `emoji` a different value. -Here, it has a value of dog 🐶. +Here, it has a value of dog 🐶. - +```typescript @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'], // provide services - providers: [{ provide: FlowerService, useValue: { emoji: '🌻' } }], - viewProviders: [{ provide: AnimalService, useValue: { emoji: '🐶' } }] + providers: [{provide: FlowerService, useValue: {emoji: '🌻'}}], + viewProviders: [{provide: AnimalService, useValue: {emoji: '🐶'}}], }) export class ChildComponent { // inject services - flower = inject(FlowerService); - animal = inject(AnimalService) -... + flower = inject(FlowerService); + animal = inject(AnimalService); } - +``` Add bindings to the `ChildComponent` and the `AppComponent` templates. In the `ChildComponent` template, add the following binding: - +```html

    Emoji from AnimalService: {{animal.emoji}}

    -
    +``` Additionally, add the same to the `AppComponent` template: - +```html

    Emoji from AnimalService: {{animal.emoji}}

    s -
    +``` Now you should see both values in the browser: - - +```shell AppComponent -Emoji from AnimalService: 🐳 +Emoji from AnimalService: 🐳 Child Component -Emoji from AnimalService: 🐶 - - +Emoji from AnimalService: 🐶 +``` The logic tree for this example of `viewProviders` is as follows: - - +```html "🐳"> - <#VIEW> - - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService=>"🐶")> - -

    Emoji from AnimalService: {{animal.emoji}} (🐶)

    - -
    - -
    +@Inject(AnimalService) animal=>"🐳"> +<#VIEW> + +<#VIEW @Provide(AnimalService="🐶") +@Inject(AnimalService=>"🐶")> -
    + +

    Emoji from AnimalService: {{animal.emoji}} (🐶)

    + +
    + +
    +``` Just as with the `FlowerService` example, the `AnimalService` is provided in the `` `@Component()` decorator. -This means that since the injector first looks in the `ElementInjector` of the component, it finds the `AnimalService` value of dog 🐶. +This means that since the injector first looks in the `ElementInjector` of the component, it finds the `AnimalService` value of dog 🐶. It doesn't need to continue searching the `ElementInjector` tree, nor does it need to search the `ModuleInjector`. ### `providers` vs. `viewProviders` @@ -653,36 +642,33 @@ To see the difference between using `providers` and `viewProviders`, add another `InspectorComponent` will be a child of the `ChildComponent`. In `inspector.component.ts`, inject the `FlowerService` and `AnimalService` during property initialization: - +```typescript export class InspectorComponent { flower = inject(FlowerService); animal = inject(AnimalService); } - +``` You do not need a `providers` or `viewProviders` array. Next, in `inspector.component.html`, add the same markup from previous components: - +```html

    Emoji from FlowerService: {{flower.emoji}}

    Emoji from AnimalService: {{animal.emoji}}

    -
    +``` Remember to add the `InspectorComponent` to the `ChildComponent` `imports` array. - +```ts @Component({ ... imports: [InspectorComponent] }) - - +``` Next, add the following to `child.component.html`: - +```html ...
    @@ -692,72 +678,71 @@ Next, add the following to `child.component.html`:

    Inside the view

    - +``` `` allows you to project content, and `` inside the `ChildComponent` template makes the `InspectorComponent` a child component of `ChildComponent`. Next, add the following to `app.component.html` to take advantage of content projection. - +```html - +``` The browser now renders the following, omitting the previous examples for brevity: - +```shell ... Content projection -Emoji from FlowerService: 🌻 -Emoji from AnimalService: 🐳 - -Emoji from FlowerService: 🌻 -Emoji from AnimalService: 🐶 +Emoji from FlowerService: 🌻 +Emoji from AnimalService: 🐳 - +Emoji from FlowerService: 🌻 +Emoji from AnimalService: 🐶 +``` These four bindings demonstrate the difference between `providers` and `viewProviders`. -Remember that the dog emoji 🐶 is declared inside the `<#VIEW>` of `ChildComponent` and isn't visible to the projected content. -Instead, the projected content sees the whale 🐳. +Remember that the dog emoji 🐶 is declared inside the `<#VIEW>` of `ChildComponent` and isn't visible to the projected content. +Instead, the projected content sees the whale 🐳. -However, in the next output section though, the `InspectorComponent` is an actual child component of `ChildComponent`, `InspectorComponent` is inside the `<#VIEW>`, so when it asks for the `AnimalService`, it sees the dog 🐶. +However, in the next output section though, the `InspectorComponent` is an actual child component of `ChildComponent`, `InspectorComponent` is inside the `<#VIEW>`, so when it asks for the `AnimalService`, it sees the dog 🐶. The `AnimalService` in the logical tree would look like this: - - +```html "🐳"> - <#VIEW> - - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService=>"🐶")> - -

    Emoji from AnimalService: {{animal.emoji}} (🐶)

    +@Inject(AnimalService) animal=>"🐳"> +<#VIEW> + +<#VIEW @Provide(AnimalService="🐶") +@Inject(AnimalService=>"🐶")> + + +

    Emoji from AnimalService: {{animal.emoji}} (🐶)

    Content projection

    - "🐳"> -

    Emoji from AnimalService: {{animal.emoji}} (🐳)

    + "🐳"> +

    Emoji from AnimalService: {{animal.emoji}} (🐳)

    - <#VIEW @Inject(AnimalService) animal=>"🐶"> -

    Emoji from AnimalService: {{animal.emoji}} (🐶)

    + <#VIEW @Inject(AnimalService) animal=>"🐶"> +

    Emoji from AnimalService: {{animal.emoji}} (🐶)

    - -
    -
    + + +``` -The projected content of `` sees the whale 🐳, not the dog 🐶, because the dog 🐶 is inside the `` `<#VIEW>`. -The `` can only see the dog 🐶 if it is also within the `<#VIEW>`. +The projected content of `` sees the whale 🐳, not the dog 🐶, because the dog 🐶 is inside the `` `<#VIEW>`. +The `` can only see the dog 🐶 if it is also within the `<#VIEW>`. ### Visibility of provided tokens @@ -767,157 +752,149 @@ To do this, place visibility configuration at the point of injection, that is, w To alter where the injector starts looking for `FlowerService`, add `skipSelf` to the `` `inject()` invocation where `FlowerService` is injected. This invocation is a property initializer the `` as shown in `child.component.ts`: - -flower = inject(FlowerService, { skipSelf: true }) - +```typescript + flower = inject(FlowerService, { skipSelf: true }) +``` With `skipSelf`, the `` injector doesn't look to itself for the `FlowerService`. Instead, the injector starts looking for the `FlowerService` at the `ElementInjector` of the ``, where it finds nothing. -Then, it goes back to the `` `ModuleInjector` and finds the red hibiscus 🌺 value, which is available because `` and `` share the same `ModuleInjector`. +Then, it goes back to the `` `ModuleInjector` and finds the red hibiscus 🌺 value, which is available because `` and `` share the same `ModuleInjector`. The UI renders the following: - - -Emoji from FlowerService: 🌺 - - +```shell +Emoji from FlowerService: 🌺 +``` In a logical tree, this same idea might look like this: - - +```html "🌺"> - <#VIEW> - - <#VIEW @Inject(FlowerService, SkipSelf)=>"🌺"> - - - - - +@Inject(FlowerService) flower=>"🌺"> +<#VIEW> + +<#VIEW @Inject(FlowerService, SkipSelf)=>"🌺"> + + - + + + + +``` -Though `` provides the sunflower 🌻, the application renders the red hibiscus 🌺 because `skipSelf` causes the current injector (`app-child`) to skip itself and look to its parent. +Though `` provides the sunflower 🌻, the application renders the red hibiscus 🌺 because `skipSelf` causes the current injector (`app-child`) to skip itself and look to its parent. If you now add `host` (in addition to the `skipSelf`), the result will be `null`. This is because `host` limits the upper bound of the search to the `app-child` `<#VIEW>`. Here's the idea in the logical tree: - - +```html "🌺"> - <#VIEW> - - <#VIEW inject(FlowerService, {skipSelf: true, host: true, optional:true})=>null> - - - +@Inject(FlowerService) flower=>"🌺"> +<#VIEW> + +<#VIEW inject(FlowerService, {skipSelf: true, host: true, optional:true})=>null> + + + - - +``` Here, the services and their values are the same, but `host` stops the injector from looking any further than the `<#VIEW>` for `FlowerService`, so it doesn't find it and returns `null`. ### `skipSelf` and `viewProviders` -Remember, `` provides the `AnimalService` in the `viewProviders` array with the value of dog 🐶. -Because the injector has only to look at the `ElementInjector` of the `` for the `AnimalService`, it never sees the whale 🐳. +Remember, `` provides the `AnimalService` in the `viewProviders` array with the value of dog 🐶. +Because the injector has only to look at the `ElementInjector` of the `` for the `AnimalService`, it never sees the whale 🐳. -As in the `FlowerService` example, if you add `skipSelf` to the `inject()` of `AnimalService`, the injector won't look in the `ElementInjector` of the current `` for the `AnimalService`. +As in the `FlowerService` example, if you add `skipSelf` to the `inject()` of `AnimalService`, the injector won't look in the `ElementInjector` of the current `` for the `AnimalService`. Instead, the injector will begin at the `` `ElementInjector`. - +```typescript @Component({ selector: 'app-child', … viewProviders: [ - { provide: AnimalService, useValue: { emoji: '🐶' } }, + { provide: AnimalService, useValue: { emoji: '🐶' } }, ], }) - +``` The logical tree looks like this with `skipSelf` in ``: - - +```html "🐳")> - <#VIEW> - - <#VIEW @Provide(AnimalService="🐶") - @Inject(AnimalService, SkipSelf=>"🐳")> - - - - - +@Inject(AnimalService=>"🐳")> +<#VIEW> + +<#VIEW @Provide(AnimalService="🐶") +@Inject(AnimalService, SkipSelf=>"🐳")> + + - + + + + +``` -With `skipSelf` in the ``, the injector begins its search for the `AnimalService` in the `` `ElementInjector` and finds whale 🐳. +With `skipSelf` in the ``, the injector begins its search for the `AnimalService` in the `` `ElementInjector` and finds whale 🐳. ### `host` and `viewProviders` -If you just use `host` for the injection of `AnimalService`, the result is dog 🐶 because the injector finds the `AnimalService` in the `` `<#VIEW>` itself. +If you just use `host` for the injection of `AnimalService`, the result is dog 🐶 because the injector finds the `AnimalService` in the `` `<#VIEW>` itself. The `ChildComponent` configures the `viewProviders` so that the dog emoji is provided as `AnimalService` value. You can also see `host` the `inject()`: - +```typescript @Component({ selector: 'app-child', … viewProviders: [ - { provide: AnimalService, useValue: { emoji: '🐶' } }, + { provide: AnimalService, useValue: { emoji: '🐶' } }, ] }) export class ChildComponent { animal = inject(AnimalService, { host: true }) } - +``` `host: true` causes the injector to look until it encounters the edge of the `<#VIEW>`. - - +```html "🐳")> - <#VIEW> - - <#VIEW @Provide(AnimalService="🐶") - inject(AnimalService, {host: true}=>"🐶")> - - - +@Inject(AnimalService=>"🐳")> +<#VIEW> + +<#VIEW @Provide(AnimalService="🐶") +inject(AnimalService, {host: true}=>"🐶")> + + + +``` - - -Add a `viewProviders` array with a third animal, hedgehog 🦔, to the `app.component.ts` `@Component()` metadata: +Add a `viewProviders` array with a third animal, hedgehog 🦔, to the `app.component.ts` `@Component()` metadata: - +```typescript @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ], viewProviders: [ - { provide: AnimalService, useValue: { emoji: '🦔' } }, + { provide: AnimalService, useValue: { emoji: '🦔' } }, ], }) - - +``` Next, add `skipSelf` along with `host` to the `inject()` for the `AnimalService` injection in `child.component.ts`. Here are `host` and `skipSelf` in the `animal` property initialization: - +```typescript export class ChildComponent { animal = inject(AnimalService, { host: true, skipSelf: true }); } - - +``` - - <#VIEW @Provide(AnimalService="🐶") - inject(AnimalService, {skipSelf:true, host: true, optional: true})=>"🦔"> - - - - - +@Inject(AnimalService=>"🐳")> +<#VIEW @Provide(AnimalService="🦔") +@Inject(AnimalService, @Optional)=>"🦔"> - + + +<#VIEW @Provide(AnimalService="🐶") +inject(AnimalService, {skipSelf:true, host: true, optional: true})=>"🦔"> + + + + + +``` `skipSelf`, causes the injector to start its search for the `AnimalService` at the ``, not the ``, where the request originates, and `host` stops the search at the `` `<#VIEW>`. -Since `AnimalService` is provided by way of the `viewProviders` array, the injector finds hedgehog 🦔 in the `<#VIEW>`. +Since `AnimalService` is provided by way of the `viewProviders` array, the injector finds hedgehog 🦔 in the `<#VIEW>`. ## Example: `ElementInjector` use cases @@ -966,15 +942,14 @@ If you later modify the `VillainsService`, you could break something in other co Instead, you should provide the `VillainsService` in the `providers` metadata of the `VillainsListComponent` like this: - +```typescript @Component({ selector: 'app-villains-list', templateUrl: './villains-list.component.html', - providers: [VillainsService] + providers: [VillainsService], }) export class VillainsListComponent {} - +``` By providing `VillainsService` in the `VillainsListComponent` metadata and nowhere else, the service becomes available only in the `VillainsListComponent` and its subcomponent tree. @@ -993,9 +968,9 @@ Each selected hero tax return opens in its own component and multiple returns ca Each tax return component has the following characteristics: -* Is its own tax return editing session -* Can change a tax return without affecting a return in another component -* Has the ability to save the changes to its tax return or cancel them +- Is its own tax return editing session +- Can change a tax return without affecting a return in another component +- Has the ability to save the changes to its tax return or cancel them Suppose that the `HeroTaxReturnComponent` had logic to manage and restore changes. That would be a straightforward task for a hero tax return. @@ -1005,10 +980,10 @@ You could delegate that management to a helper service, as this example does. The `HeroTaxReturnService` caches a single `HeroTaxReturn`, tracks changes to that return, and can save or restore it. It also delegates to the application-wide singleton `HeroService`, which it gets by injection. - -import { Injectable } from '@angular/core'; -import { HeroTaxReturn } from './hero'; -import { HeroesService } from './heroes.service'; +```typescript +import {inject, Injectable} from '@angular/core'; +import {HeroTaxReturn} from './hero'; +import {HeroesService} from './heroes.service'; @Injectable() export class HeroTaxReturnService { @@ -1019,7 +994,7 @@ export class HeroTaxReturnService { set taxReturn(htr: HeroTaxReturn) { this.originalTaxReturn = htr; - this.currentTaxReturn = htr.clone(); + this.currentTaxReturn = htr.clone(); } get taxReturn(): HeroTaxReturn { @@ -1035,43 +1010,48 @@ export class HeroTaxReturnService { this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe(); } } - +``` Here is the `HeroTaxReturnComponent` that makes use of `HeroTaxReturnService`. - -import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { HeroTaxReturn } from './hero'; -import { HeroTaxReturnService } from './hero-tax-return.service'; +```typescript +import {Component, input, output} from '@angular/core'; +import {HeroTaxReturn} from './hero'; +import {HeroTaxReturnService} from './hero-tax-return.service'; @Component({ selector: 'app-hero-tax-return', templateUrl: './hero-tax-return.component.html', - styleUrls: [ './hero-tax-return.component.css' ], - providers: [ HeroTaxReturnService ] + styleUrls: ['./hero-tax-return.component.css'], + providers: [HeroTaxReturnService], }) export class HeroTaxReturnComponent { message = ''; - @Output() close = new EventEmitter(); + close = output(); get taxReturn(): HeroTaxReturn { return this.heroTaxReturnService.taxReturn; } - @Input() - set taxReturn(htr: HeroTaxReturn) { - this.heroTaxReturnService.taxReturn = htr; + taxReturn = input.required(); + + constructor() { + effect(() => { + this.heroTaxReturnService.taxReturn = this.taxReturn(); + }); } private heroTaxReturnService = inject(HeroTaxReturnService); - onCanceled() { + onCanceled() { this.flashMessage('Canceled'); this.heroTaxReturnService.restoreTaxReturn(); } - onClose() { this.close.emit(); } + onClose() { + this.close.emit(); + } onSaved() { this.flashMessage('Saved'); @@ -1080,12 +1060,12 @@ export class HeroTaxReturnComponent { flashMessage(msg: string) { this.message = msg; - setTimeout(() => this.message = '', 500); + setTimeout(() => (this.message = ''), 500); } } - +``` -The _tax-return-to-edit_ arrives by way of the `@Input()` property, which is implemented with getters and setters. +The _tax-return-to-edit_ arrives by way of the `input` property, which is implemented with getters and setters. The setter initializes the component's own instance of the `HeroTaxReturnService` with the incoming return. The getter always returns what that service says is the current state of the hero. The component also asks the service to save and restore this tax return. @@ -1095,9 +1075,9 @@ Every component would share the same service instance, and each component would To prevent this, configure the component-level injector of `HeroTaxReturnComponent` to provide the service, using the `providers` property in the component metadata. - -providers: [HeroTaxReturnService] - +```typescript + providers: [HeroTaxReturnService] +``` The `HeroTaxReturnComponent` has its own provider of the `HeroTaxReturnService`. Recall that every component _instance_ has its own injector. @@ -1113,7 +1093,7 @@ For example, consider a `Car` component that includes tire service information a The root injector, marked as (A), uses _generic_ providers for details about `CarService` and `EngineService`. -1. `Car` component (A). Component (A) displays tire service data about a car and specifies generic services to provide more information about the car. +1. `Car` component (A). Component (A) displays tire service data about a car and specifies generic services to provide more information about the car. 2. Child component (B). Component (B) defines its own, _specialized_ providers for `CarService` and `EngineService` that have special capabilities suitable for what's going on in component (B). @@ -1138,9 +1118,9 @@ Behind the scenes, each component sets up its own injector with zero, one, or mo When you resolve an instance of `Car` at the deepest component (C), its injector produces: -* An instance of `Car` resolved by injector (C) -* An `Engine` resolved by injector (B) -* Its `Tires` resolved by the root injector (A). +- An instance of `Car` resolved by injector (C) +- An `Engine` resolved by injector (B) +- Its `Tires` resolved by the root injector (A). ```mermaid graph BT; diff --git a/adev/src/content/guide/di/lightweight-injection-tokens.md b/adev/src/content/guide/di/lightweight-injection-tokens.md index b20c8e31d3b8..bb28b41ab927 100644 --- a/adev/src/content/guide/di/lightweight-injection-tokens.md +++ b/adev/src/content/guide/di/lightweight-injection-tokens.md @@ -1,7 +1,7 @@ # Optimizing client application size with lightweight injection tokens This page provides a conceptual overview of a dependency injection technique that is recommended for library developers. -Designing your library with *lightweight injection tokens* helps optimize the bundle size of client applications that use your library. +Designing your library with _lightweight injection tokens_ helps optimize the bundle size of client applications that use your library. You can manage the dependency structure among your components and injectable services to optimize bundle size by using tree-shakable providers. This normally ensures that if a provided component or service is never actually used by the application, the compiler can remove its code from the bundle. @@ -22,17 +22,18 @@ To prevent the retention of unused components, your library should use the light To better explain the condition under which token retention occurs, consider a library that provides a library-card component. This component contains a body and can contain an optional header: - +```angular-html ; - ; +; ; - - +``` In a likely implementation, the `` component uses `@ContentChild()` or `@ContentChildren()` to get `` and ``, as in the following: - +```ts {highlight: [14]} +import {Component, ContentChild} from '@angular/core'; + @Component({ selector: 'lib-header', …, @@ -44,26 +45,25 @@ class LibHeaderComponent {} …, }) class LibCardComponent { - @ContentChild(LibHeaderComponent) header: LibHeaderComponent|null = null; + @ContentChild(LibHeaderComponent) header: LibHeaderComponent | null = null; } - - +``` Because `` is optional, the element can appear in the template in its minimal form, ``. In this case, `` is not used and you would expect it to be tree-shaken, but that is not what happens. This is because `LibCardComponent` actually contains two references to the `LibHeaderComponent`: - +```ts @ContentChild(LibHeaderComponent) header: LibHeaderComponent; - +``` -* One of these reference is in the *type position*-- that is, it specifies `LibHeaderComponent` as a type: `header: LibHeaderComponent;`. -* The other reference is in the *value position*-- that is, LibHeaderComponent is the value of the `@ContentChild()` parameter decorator: `@ContentChild(LibHeaderComponent)`. +- One of these reference is in the _type position_-- that is, it specifies `LibHeaderComponent` as a type: `header: LibHeaderComponent;`. +- The other reference is in the _value position_-- that is, LibHeaderComponent is the value of the `@ContentChild()` parameter decorator: `@ContentChild(LibHeaderComponent)`. The compiler handles token references in these positions differently: -* The compiler erases *type position* references after conversion from TypeScript, so they have no impact on tree-shaking. -* The compiler must keep *value position* references at runtime, which **prevents** the component from being tree-shaken. +- The compiler erases _type position_ references after conversion from TypeScript, so they have no impact on tree-shaking. +- The compiler must keep _value position_ references at runtime, which **prevents** the component from being tree-shaken. In the example, the compiler retains the `LibHeaderComponent` token that occurs in the value position. This prevents the referenced component from being tree-shaken, even if the application does not actually use `` anywhere. @@ -74,18 +74,18 @@ If `LibHeaderComponent` 's code, template, and styles combine to become too larg The tree-shaking problem arises when a component is used as an injection token. There are two cases when that can happen: -* The token is used in the value position of a [content query](guide/components/queries#content-queries). -* The token is used as a type specifier for constructor injection. +- The token is used in the value position of a [content query](guide/components/queries#content-queries). +- The token is used as a type specifier for constructor injection. In the following example, both uses of the `OtherComponent` token cause retention of `OtherComponent`, preventing it from being tree-shaken when it is not used: - +```ts {highlight: [[2],[4]]} class MyComponent { constructor(@Optional() other: OtherComponent) {} - @ContentChild(OtherComponent) other: OtherComponent|null; + @ContentChild(OtherComponent) other: OtherComponent | null; } - +``` Although tokens used only as type specifiers are removed when converted to JavaScript, all tokens used for dependency injection are needed at runtime. These effectively change `constructor(@Optional() other: OtherComponent)` to `constructor(@Optional() @Inject(OtherComponent) other)`. @@ -100,14 +100,12 @@ The abstract class is retained, not tree-shaken, but it is small and has no mate The following example shows how this works for the `LibHeaderComponent`: - +```ts {highlight: [[1],[5], [15]]} abstract class LibHeaderToken {} @Component({ selector: 'lib-header', - providers: [ - {provide: LibHeaderToken, useExisting: LibHeaderComponent} - ] + providers: [{provide: LibHeaderToken, useExisting: LibHeaderComponent}], …, }) class LibHeaderComponent extends LibHeaderToken {} @@ -117,9 +115,9 @@ class LibHeaderComponent extends LibHeaderToken {} …, }) class LibCardComponent { - @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null; + @ContentChild(LibHeaderToken) header: LibHeaderToken | null = null; } - +``` In this example, the `LibCardComponent` implementation no longer refers to `LibHeaderComponent` in either the type position or the value position. This lets full tree-shaking of `LibHeaderComponent` take place. @@ -132,9 +130,9 @@ You can safely use that token as the provider in the component definition, allow To summarize, the lightweight injection token pattern consists of the following: 1. A lightweight injection token that is represented as an abstract class. -1. A component definition that implements the abstract class. -1. Injection of the lightweight pattern, using `@ContentChild()` or `@ContentChildren()`. -1. A provider in the implementation of the lightweight injection token which associates the lightweight injection token with the implementation. +2. A component definition that implements the abstract class. +3. Injection of the lightweight pattern, using `@ContentChild()` or `@ContentChildren()`. +4. A provider in the implementation of the lightweight injection token which associates the lightweight injection token with the implementation. ### Use the lightweight injection token for API definition @@ -146,17 +144,14 @@ This lets the parent communicate with the child, if it is present, in a type-saf For example, the `LibCardComponent` now queries `LibHeaderToken` rather than `LibHeaderComponent`. The following example shows how the pattern lets `LibCardComponent` communicate with the `LibHeaderComponent` without actually referring to `LibHeaderComponent`: - +```ts {highlight: [[2],[9],[11],[19]]} abstract class LibHeaderToken { abstract doSomething(): void; } @Component({ selector: 'lib-header', - providers: [ - {provide: LibHeaderToken, useExisting: LibHeaderComponent} - ] - …, + providers: [{provide: LibHeaderToken, useExisting: LibHeaderComponent}], }) class LibHeaderComponent extends LibHeaderToken { doSomething(): void { @@ -166,10 +161,9 @@ class LibHeaderComponent extends LibHeaderToken { @Component({ selector: 'lib-card', - …, }) -class LibCardComponent implement AfterContentInit { - @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null; +class LibCardComponent implements AfterContentInit { + @ContentChild(LibHeaderToken) header: LibHeaderToken | null = null; ngAfterContentInit(): void { if (this.header !== null) { @@ -177,7 +171,7 @@ class LibCardComponent implement AfterContentInit { } } } - +``` In this example, the parent queries the token to get the child component, and stores the resulting component reference if it is present. Before calling a method in the child, the parent component checks to see if the child component is present. diff --git a/adev/src/content/guide/di/overview.md b/adev/src/content/guide/di/overview.md index 1620a7edcb1b..03de6b1889f4 100644 --- a/adev/src/content/guide/di/overview.md +++ b/adev/src/content/guide/di/overview.md @@ -1,29 +1,154 @@ -"DI" is a design pattern and mechanism for creating and delivering some parts of an app to other parts of an app that require them. + +Dependency Injection (DI) is a design pattern used to organize and share code across an application. TIP: Check out Angular's [Essentials](essentials/dependency-injection) before diving into this comprehensive guide. -When you develop a smaller part of your system, like a module or a class, you may need to use features from other classes. For example, you may need an HTTP service to make backend calls. Dependency Injection, or DI, is a design pattern and mechanism for creating and delivering some parts of an application to other parts of an application that require them. Angular supports this design pattern and you can use it in your applications to increase flexibility and modularity. - -In Angular, dependencies are typically services, but they also can be values, such as strings or functions. An injector for an application (created automatically during bootstrap) instantiates dependencies when needed, using a configured provider of the service or value. - -## Learn about Angular dependency injection - - - - Learn basic principles of dependency injection in Angular. - - - Describes how to create a service and inject it in other services and components. - - - Describes how to configure dependencies using the providers field on the @Component and @NgModule decorators. Also describes how to use InjectionToken to provide and inject values in DI, which can be helpful when you want to use a value other than classes as dependencies. - - - Describes what an injection context is and how to use the DI system where you need it. - - - Hierarchical DI enables you to share dependencies between different parts of the application only when and if you need to. This is an advanced topic. - - +As an application grows, developers often need to reuse and share features across different parts of the codebase. [Dependency Injection (DI)](https://en.wikipedia.org/wiki/Dependency_injection) is a design pattern used to organize and share code across an application by allowing you to "inject" features into different parts. + +Dependency injection is a popular pattern because it allows developers to address common challenges such as: + +- **Improved code maintainability**: Dependency injection allows cleaner separation of concerns which enables easier refactoring and reducing code duplication. +- **Scalability**: Modular functionality can be reused across multiple contexts and allows for easier scaling. +- **Better testing**: DI allows unit tests to easily use [test doubles](https://en.wikipedia.org/wiki/Test_double) for situations when using a real implementation is not practical. + +## How does dependency injection work in Angular? + +A dependency is any object, value, function or service that a class needs to work but does not create itself. In other words, it creates a relationship between different parts of your application since it wouldn't work without the dependency. + +There are two ways that code interacts with any dependency injection system: + +- Code can _provide_, or make available, values. +- Code can _inject_, or ask for, those values as dependencies. + +"Values," in this context, can be any JavaScript value, including objects and functions. Common types of injected dependencies include: + +- **Configuration values**: Environment-specific constants, API URLs, feature flags, etc. +- **Factories**: Functions that create objects or values based on runtime conditions +- **Services**: Classes that provide common functionality, business logic, or state + +Angular components and directives automatically participate in DI, meaning that they can inject dependencies _and_ they are available to be injected. + +## What are services? + +An Angular _service_ is a TypeScript class decorated with `@Injectable`, which makes an instance of the class available to be injected as a dependency. Services are the most common way of sharing data and functionality across an application. + +Common types of services include: + +- **Data clients:** Abstracts the details of making requests to a server for data retrieval and mutation +- **State management:** Defines state shared across multiple components or pages +- **Authentication and authorization:** Manages user authentication, token storage, and access control +- **Logging and error handling:** Establishes a common API for logging or communicating error states to the user +- **Event handling and dispatch:** Handles events or notifications that are not associated with a specific component, or for dispatching events and notifications to components, following the [observer pattern](https://en.wikipedia.org/wiki/Observer_pattern) +- **Utility functions:** Offers reusable utility functions like data formatting, validation, or calculations + +The following example declares a service named `AnalyticsLogger`: + +```ts +import { Injectable } from '@angular/core'; + +@Injectable({ providedIn: 'root' }) +export class AnalyticsLogger { + trackEvent(category: string, value: string) { + console.log('Analytics event logged:', { + category, + value, + timestamp: new Date().toISOString() + }) + } +} +``` + +NOTE: The `providedIn: 'root'` option makes this service available throughout your entire application as a singleton. This is the recommended approach for most services. + +## Injecting dependencies with `inject()` + +You can inject dependencies using Angular's `inject()` function. + +Here is an example of a navigation bar that injects `AnalyticsLogger` and Angular `Router` service to allow users to navigate to a different page while tracking the event. + +```angular-ts +import { Component, inject } from '@angular/core'; +import { Router } from '@angular/router'; +import { AnalyticsLogger } from './analytics-logger'; + +@Component({ + selector: 'app-navbar', + template: ` + Detail Page + `, +}) +export class NavbarComponent { + private router = inject(Router); + private analytics = inject(AnalyticsLogger); + + navigateToDetail(event: Event) { + event.preventDefault(); + this.analytics.trackEvent('navigation', '/details'); + this.router.navigate(['/details']); + } +} +``` + +### Where can `inject()` be used? + +You can inject dependencies during construction of a component, directive, or service. The call to `inject` can appear in either the `constructor` or in a field initializer. Here are some common examples: + +```ts +@Component({...}) +export class MyComponent { + // ✅ In class field initializer + private service = inject(MyService); + + // ✅ In constructor body + private anotherService: MyService; + + constructor() { + this.anotherService = inject(MyService); + } +} +``` + +```ts +@Directive({...}) +export class MyDirective { + // ✅ In class field initializer + private element = inject(ElementRef); +} +``` + +```ts +import { Injectable, inject } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +@Injectable({ providedIn: 'root' }) +export class MyService { + // ✅ In a service + private http = inject(HttpClient); +} +``` + +```ts +export const authGuard = () => { + // ✅ In a route guard + const auth = inject(AuthService); + return auth.isAuthenticated(); +} +``` + +Angular uses the term "injection context" to describe any place in your code where you can call `inject`. While component, directive, and service construction is the most common, see [injection contexts](/guide/di/dependency-injection-context) for more details. + +For more information, see the [inject API docs](api/core/inject#usage-notes). + +## Next steps + +Now that you understand the fundamentals of dependency injection in Angular, you're ready to learn how to create your own services. + +The next guide, [Creating and using services](guide/di/creating-and-using-services), will show you: + +- How to create a service with the Angular CLI or manually +- How the `providedIn: 'root'` pattern works +- How to inject services into components and other services + +This covers the most common use case for services in Angular applications. diff --git a/adev/src/content/guide/directives/BUILD.bazel b/adev/src/content/guide/directives/BUILD.bazel index 53d938f96082..24325441f4d9 100644 --- a/adev/src/content/guide/directives/BUILD.bazel +++ b/adev/src/content/guide/directives/BUILD.bazel @@ -1,3 +1,4 @@ +load("//adev/shared-docs:defaults.bzl", "copy_to_bin") load("//adev/shared-docs:index.bzl", "generate_guides") generate_guides( @@ -5,9 +6,16 @@ generate_guides( srcs = glob([ "*.md", ]), + api_manifest = "//adev/src/assets:docs_api_manifest", data = [ "//adev/src/assets/images:directives.svg", "//adev/src/content/examples", ], visibility = ["//adev:__subpackages__"], ) + +copy_to_bin( + name = "guide_files", + srcs = glob(["**/*.md"]), + visibility = ["//adev:__subpackages__"], +) diff --git a/adev/src/content/guide/directives/attribute-directives.md b/adev/src/content/guide/directives/attribute-directives.md index 46b91a2d4eeb..4d39ac94196e 100644 --- a/adev/src/content/guide/directives/attribute-directives.md +++ b/adev/src/content/guide/directives/attribute-directives.md @@ -8,36 +8,34 @@ This section walks you through creating a highlight directive that sets the back 1. To create a directive, use the CLI command [`ng generate directive`](tools/cli/schematics). - + ```shell + ng generate directive highlight + ``` - ng generate directive highlight + The CLI creates `src/app/highlight.directive.ts`, a corresponding test file `src/app/highlight.directive.spec.ts`. - + - The CLI creates `src/app/highlight.directive.ts`, a corresponding test file `src/app/highlight.directive.spec.ts`. - - - - The `@Directive()` decorator's configuration property specifies the directive's CSS attribute selector, `[appHighlight]`. + The `@Directive()` decorator's configuration property specifies the directive's CSS attribute selector, `[appHighlight]`. 1. Import `ElementRef` from `@angular/core`. - `ElementRef` grants direct access to the host DOM element through its `nativeElement` property. + `ElementRef` grants direct access to the host DOM element through its `nativeElement` property. 1. Add `ElementRef` in the directive's `constructor()` to [inject](guide/di) a reference to the host DOM element, the element to which you apply `appHighlight`. 1. Add logic to the `HighlightDirective` class that sets the background to yellow. - + -HELPFUL: Directives *do not* support namespaces. +HELPFUL: Directives _do not_ support namespaces. - + ## Applying an attribute directive 1. To use the `HighlightDirective`, add a `

    ` element to the HTML template with the directive as an attribute. - + Angular creates an instance of the `HighlightDirective` class and injects a reference to the `

    ` element into the directive's constructor, which sets the `

    ` element's background style to yellow. @@ -45,21 +43,21 @@ Angular creates an instance of the `HighlightDirective` class and injects a refe This section shows you how to detect when a user mouses into or out of the element and to respond by setting or clearing the highlight color. -1. Import `HostListener` from '@angular/core'. +1. Configure host event bindings using the `host` property in the `@Directive()` decorator. - + -1. Add two event handlers that respond when the mouse enters or leaves, each with the `@HostListener()` decorator. +1. Add two event handler methods, and map host element events to them via the `host` property. - + -Subscribe to events of the DOM element that hosts an attribute directive, the `

    ` in this case, with the `@HostListener()` decorator. +Subscribe to events of the DOM element that hosts an attribute directive (the `

    ` in this case) by configuring event listeners on the directive's [`host` property](guide/components/host-elements#binding-to-the-host-element). HELPFUL: The handlers delegate to a helper method, `highlight()`, that sets the color on the host DOM element, `el`. The complete directive is as follows: - + The background color appears when the pointer hovers over the paragraph element and disappears as the pointer moves out. @@ -71,26 +69,25 @@ This section walks you through setting the highlight color while applying the `H 1. In `highlight.directive.ts`, import `Input` from `@angular/core`. - - -1. Add an `appHighlight` `@Input()` property. + - +2. Add an `appHighlight` `input` property. - The `@Input()` decorator adds metadata to the class that makes the directive's `appHighlight` property available for binding. + -1. In `app.component.ts`, add a `color` property to the `AppComponent`. + The `input()` function adds metadata to the class that makes the directive's `appHighlight` property available for binding. - +3. In `app.component.ts`, add a `color` property to the `AppComponent`. -1. To simultaneously apply the directive and the color, use property binding with the `appHighlight` directive selector, setting it equal to `color`. + - +4. To simultaneously apply the directive and the color, use property binding with the `appHighlight` directive selector, setting it equal to `color`. - The `[appHighlight]` attribute binding performs two tasks: + - * Applies the highlighting directive to the `

    ` element - * Sets the directive's highlight color with a property binding + The `[appHighlight]` attribute binding performs two tasks: + - Applies the highlighting directive to the `

    ` element + - Sets the directive's highlight color with a property binding ### Setting the value with user input @@ -98,38 +95,38 @@ This section guides you through adding radio buttons to bind your color choice t 1. Add markup to `app.component.html` for choosing a color as follows: - + 1. Revise the `AppComponent.color` so that it has no initial value. - + 1. In `highlight.directive.ts`, revise `onMouseEnter` method so that it first tries to highlight with `appHighlight` and falls back to `red` if `appHighlight` is `undefined`. - + 1. Serve your application to verify that the user can choose the color with the radio buttons. - Animated gif of the refactored highlight directive changing color according to the radio button the user selects +Animated gif of the refactored highlight directive changing color according to the radio button the user selects ## Binding to a second property This section guides you through configuring your application so the developer can set the default color. -1. Add a second `Input()` property to `HighlightDirective` called `defaultColor`. +1. Add a second `input()` property to `HighlightDirective` called `defaultColor`. - + 1. Revise the directive's `onMouseEnter` so that it first tries to highlight with the `appHighlight`, then with the `defaultColor`, and falls back to `red` if both properties are `undefined`. - + 1. To bind to the `AppComponent.color` and fall back to "violet" as the default color, add the following HTML. - In this case, the `defaultColor` binding doesn't use square brackets, `[]`, because it is static. + In this case, the `defaultColor` binding doesn't use square brackets, `[]`, because it is static. - + - As with components, you can add multiple directive property bindings to a host element. + As with components, you can add multiple directive property bindings to a host element. The default color is red if there is no default color binding. When the user chooses a color the selected color becomes the active highlight color. @@ -143,12 +140,12 @@ To prevent expression evaluation in the browser, add `ngNonBindable` to the host In the following example, the expression `{{ 1 + 1 }}` renders just as it does in your code editor, and does not display `2`. - + Applying `ngNonBindable` to an element stops binding for that element's child elements. However, `ngNonBindable` still lets directives work on the element where you apply `ngNonBindable`. In the following example, the `appHighlight` directive is still active but Angular does not evaluate the expression `{{ 1 + 1 }}`. - + If you apply `ngNonBindable` to a parent element, Angular disables interpolation and binding of any sort, such as property binding or event binding, for the element's children. diff --git a/adev/src/content/guide/directives/directive-composition-api.md b/adev/src/content/guide/directives/directive-composition-api.md index c898326894d0..53694c00b4b8 100644 --- a/adev/src/content/guide/directives/directive-composition-api.md +++ b/adev/src/content/guide/directives/directive-composition-api.md @@ -3,13 +3,13 @@ Angular directives offer a great way to encapsulate reusable behaviors— directives can apply attributes, CSS classes, and event listeners to an element. -The *directive composition API* lets you apply directives to a component's host element from -*within* the component TypeScript class. +The _directive composition API_ lets you apply directives to a component's host element from +_within_ the component TypeScript class. ## Adding directives to a component You apply directives to a component by adding a `hostDirectives` property to a component's -decorator. We call such directives *host directives*. +decorator. We call such directives _host directives_. In this example, we apply the directive `MenuBehavior` to the host element of `AdminMenu`. This works similarly to applying the `MenuBehavior` to the `` element in a template. diff --git a/adev/src/content/guide/directives/overview.md b/adev/src/content/guide/directives/overview.md index 5e59ce2ce6c2..2ea704759ebf 100644 --- a/adev/src/content/guide/directives/overview.md +++ b/adev/src/content/guide/directives/overview.md @@ -6,13 +6,13 @@ Use Angular's built-in directives to manage forms, lists, styles, and what users The different types of Angular directives are as follows: -| Directive Types | Details | -| :------------------------------------------------------- | :-------------------------------------------------------------------------------- | -| [Components](guide/components) | Used with a template. This type of directive is the most common directive type. | -| [Attribute directives](#built-in-attribute-directives) | Change the appearance or behavior of an element, component, or another directive. | -| [Structural directives](#built-in-structural-directives) | Change the DOM layout by adding and removing DOM elements. | +| Directive Types | Details | +| :--------------------------------------------------------------- | :-------------------------------------------------------------------------------- | +| [Components](guide/components) | Used with a template. This type of directive is the most common directive type. | +| [Attribute directives](#built-in-attribute-directives) | Change the appearance or behavior of an element, component, or another directive. | +| [Structural directives](/guide/directives/structural-directives) | Change the DOM layout by adding and removing DOM elements. | -This guide covers built-in [attribute directives](#built-in-attribute-directives) and [structural directives](#built-in-structural-directives). +This guide covers built-in [attribute directives](#built-in-attribute-directives). ## Built-in attribute directives @@ -20,11 +20,11 @@ Attribute directives listen to and modify the behavior of other HTML elements, a The most common attribute directives are as follows: -| Common directives | Details | -| :------------------------------------------------------------ | :------------------------------------------------- | -| [`NgClass`](#adding-and-removing-classes-with-ngclass) | Adds and removes a set of CSS classes. | -| [`NgStyle`](#setting-inline-styles-with-ngstyle) | Adds and removes a set of HTML styles. | -| [`NgModel`](#displaying-and-updating-properties-with-ngmodel) | Adds two-way data binding to an HTML form element. | +| Common directives | Details | +| :----------------------------------------------------- | :------------------------------------------------- | +| [`NgClass`](#adding-and-removing-classes-with-ngclass) | Adds and removes a set of CSS classes. | +| [`NgStyle`](#setting-inline-styles-with-ngstyle) | Adds and removes a set of HTML styles. | +| [`NgModel`](guide/forms/template-driven-forms) | Adds two-way data binding to an HTML form element. | HELPFUL: Built-in directives use only public APIs. They do not have special access to any private APIs that other directives can't access. @@ -38,7 +38,7 @@ HELPFUL: To add or remove a _single_ class, use [class binding](guide/templates/ To use `NgClass`, add it to the component's `imports` list. - + ### Using `NgClass` with an expression @@ -46,7 +46,7 @@ On the element you'd like to style, add `[ngClass]` and set it equal to an expre In this case, `isSpecial` is a boolean set to `true` in `app.component.ts`. Because `isSpecial` is true, `ngClass` applies the class of `special` to the `

    `. - + ### Using `NgClass` with a method @@ -57,11 +57,11 @@ Because `isSpecial` is true, `ngClass` applies the class of `special` to the ` + 1. In the template, add the `ngClass` property binding to `currentClasses` to set the element's classes: - + For this use case, Angular applies the classes on initialization and in case of changes caused by reassigning the `currentClasses` object. The full example calls `setCurrentClasses()` initially with `ngOnInit()` when the user clicks on the `Refresh currentClasses` button. @@ -75,7 +75,7 @@ HELPFUL: To add or remove a _single_ style, use [style bindings](guide/templates To use `NgStyle`, add it to the component's `imports` list. - + Use `NgStyle` to set multiple inline styles simultaneously, based on the state of the component. @@ -83,195 +83,16 @@ Use `NgStyle` to set multiple inline styles simultaneously, based on the state o In the following example, `setCurrentStyles()` sets the property `currentStyles` with an object that defines three styles, based on the state of three other component properties. - + 1. To set the element's styles, add an `ngStyle` property binding to `currentStyles`. - + For this use case, Angular applies the styles upon initialization and in case of changes. To do this, the full example calls `setCurrentStyles()` initially with `ngOnInit()` and when the dependent properties change through a button click. However, these steps are not necessary to implement `ngStyle` on its own. -## Displaying and updating properties with `ngModel` - -Use the `NgModel` directive to display a data property and update that property when the user makes changes. - -1. Import `FormsModule` and add it to the AppComponent's `imports` list. - - - -1. Add an `[(ngModel)]` binding on an HTML `
    ` element and set it equal to the property, here `name`. - - - - This `[(ngModel)]` syntax can only set a data-bound property. - -To customize your configuration, write the expanded form, which separates the property and event binding. -Use [property binding](guide/templates/property-binding) to set the property and [event binding](guide/templates/event-listeners) to respond to changes. -The following example changes the `` value to uppercase: - - - -Here are all variations in action, including the uppercase version: - -NgModel variations - -### `NgModel` and value accessors - -The `NgModel` directive works for an element supported by a [ControlValueAccessor](api/forms/ControlValueAccessor). -Angular provides _value accessors_ for all of the basic HTML form elements. -For more information, see [Forms](guide/forms). - -To apply `[(ngModel)]` to a non-form built-in element or a third-party custom component, you have to write a value accessor. -For more information, see the API documentation on [DefaultValueAccessor](api/forms/DefaultValueAccessor). - -HELPFUL: When you write an Angular component, you don't need a value accessor or `NgModel` if you name the value and event properties according to Angular's [two-way binding syntax](guide/templates/two-way-binding#how-two-way-binding-works). - -## Built-in structural directives - -Structural directives are responsible for HTML layout. -They shape or reshape the DOM's structure, typically by adding, removing, and manipulating the host elements to which they are attached. - -This section introduces the most common built-in structural directives: - -| Common built-in structural directives | Details | -| :------------------------------------------------- | :--------------------------------------------------------------- | -| [`NgIf`](#adding-or-removing-an-element-with-ngif) | Conditionally creates or disposes of subviews from the template. | -| [`NgFor`](#listing-items-with-ngfor) | Repeat a node for each item in a list. | -| [`NgSwitch`](#switching-cases-with-ngswitch) | A set of directives that switch among alternative views. | - -For more information, see [Structural Directives](guide/directives/structural-directives). - -## Adding or removing an element with `NgIf` - -Add or remove an element by applying an `NgIf` directive to a host element. - -When `NgIf` is `false`, Angular removes an element and its descendants from the DOM. -Angular then disposes of their components, which frees up memory and resources. - -### Import `NgIf` in the component - -To use `NgIf`, add it to the component's `imports` list. - - - -### Using `NgIf` - -To add or remove an element, bind `*ngIf` to a condition expression such as `isActive` in the following example. - - - -When the `isActive` expression returns a truthy value, `NgIf` adds the `ItemDetailComponent` to the DOM. -When the expression is falsy, `NgIf` removes the `ItemDetailComponent` from the DOM and disposes of the component and all of its subcomponents. - -For more information on `NgIf` and `NgIfElse`, see the [NgIf API documentation](api/common/NgIf). - -### Guarding against `null` - -By default, `NgIf` prevents display of an element bound to a null value. - -To use `NgIf` to guard a `
    `, add `*ngIf="yourProperty"` to the `
    `. -In the following example, the `currentCustomer` name appears because there is a `currentCustomer`. - - - -However, if the property is `null`, Angular does not display the `
    `. -In this example, Angular does not display the `nullCustomer` because it is `null`. - - - -## Listing items with `NgFor` - -Use the `NgFor` directive to present a list of items. - -### Import `NgFor` in the component - -To use `NgFor`, add it to the component's `imports` list. - - - -### Using `NgFor` - -To use `NgFor`, you have to: - -1. Define a block of HTML that determines how Angular renders a single item. -1. To list your items, assign the shorthand `let item of items` to `*ngFor`. - - - -The string `"let item of items"` instructs Angular to do the following: - -- Store each item in the `items` array in the local `item` looping variable -- Make each item available to the templated HTML for each iteration -- Translate `"let item of items"` into an `` around the host element -- Repeat the `` for each `item` in the list - -For more information see the [Structural directive shorthand](guide/directives/structural-directives#structural-directive-shorthand) section of [Structural directives](guide/directives/structural-directives). - -### Repeating a component view - -To repeat a component element, apply `*ngFor` to the selector. -In the following example, the selector is ``. - - - -Reference a template input variable, such as `item`, in the following locations: - -- Within the `ngFor` host element -- Within the host element descendants to access the item's properties - -The following example references `item` first in an interpolation and then passes in a binding to the `item` property of the `` component. - - - -For more information about template input variables, see [Structural directive shorthand](guide/directives/structural-directives#structural-directive-shorthand). - -### Getting the `index` of `*ngFor` - -Get the `index` of `*ngFor` in a template input variable and use it in the template. - -In the `*ngFor`, add a semicolon and `let i=index` to the shorthand. -The following example gets the `index` in a variable named `i` and displays it with the item name. - - - -The index property of the `NgFor` directive context returns the zero-based index of the item in each iteration. - -Angular translates this instruction into an `` around the host element, -then uses this template repeatedly to create a new set of elements and bindings for each `item` -in the list. -For more information about shorthand, see the [Structural Directives](guide/directives/structural-directives#structural-directive-shorthand) guide. - -## Repeating elements when a condition is true - -To repeat a block of HTML when a particular condition is true, put the `*ngIf` on a container element that wraps an `*ngFor` element. - -For more information see [one structural directive per element](guide/directives/structural-directives#one-structural-directive-per-element). - -### Tracking items with `*ngFor` `trackBy` - -Reduce the number of calls your application makes to the server by tracking changes to an item list. -With the `*ngFor` `trackBy` property, Angular can change and re-render only those items that have changed, rather than reloading the entire list of items. - -1. Add a method to the component that returns the value `NgFor` should track. -In this example, the value to track is the item's `id`. -If the browser has already rendered `id`, Angular keeps track of it and doesn't re-query the server for the same `id`. - - - -1. In the shorthand expression, set `trackBy` to the `trackByItems()` method. - - - -**Change ids** creates new items with new `item.id`s. -In the following illustration of the `trackBy` effect, **Reset items** creates new items with the same `item.id`s. - -- With no `trackBy`, both buttons trigger complete DOM element replacement. -- With `trackBy`, only changing the `id` triggers element replacement. - -Animation of trackBy - ## Hosting a directive without a DOM element The Angular `` is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM. @@ -280,7 +101,7 @@ Use `` when there's no single element to host the directive. Here's a conditional paragraph using ``. - + ngcontainer paragraph with proper style @@ -290,55 +111,10 @@ Here's a conditional paragraph using ``. 1. To conditionally exclude an `