diff --git a/.eslintrc.json b/.eslintrc.json index d2dfe9b0b305..aa1b1b149574 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,13 +8,13 @@ } }, "plugins": [ - "arca" + "arca", + "prettier" ], "rules": { - "arca/curly": 2, - "arca/import-align": 2, "arca/import-ordering": 2, "arca/newline-after-import-section": 2, - "arca/no-default-export": 2 + "arca/no-default-export": 2, + "prettier/prettier": "error" } } diff --git a/.pnp.js b/.pnp.js index cee56f317594..804c9149dab2 100755 --- a/.pnp.js +++ b/.pnp.js @@ -66,6 +66,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "@types/eslint", "npm:4.16.6" ], + [ + "@types/eslint-plugin-prettier", + "npm:2.2.0" + ], [ "@types/eventemitter3", "npm:2.0.2" @@ -122,6 +126,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "@types/node-fetch", "npm:2.1.4" ], + [ + "@types/prettier", + "npm:1.16.3" + ], [ "@types/react", "npm:16.7.20" @@ -186,6 +194,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "eslint-plugin-arca", "npm:0.8.1" ], + [ + "eslint-plugin-prettier", + "virtual:b93debf42822ec38d5fe4e99f4e6f09d7b47888d3ede2fd4d87aea17809e37e43f10d527dd26cf2c5a2c4646a93b42d7dcde25cae5bbb17e5c1c274d58d81e6f#npm:3.0.1" + ], [ "jest", "npm:24.5.0" @@ -198,6 +210,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "jest-junit", "npm:5.2.0" ], + [ + "prettier", + "npm:1.17.0" + ], [ "ts-node", "npm:7.0.1" @@ -9060,6 +9076,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "@types/eslint", "npm:4.16.6" ], + [ + "@types/eslint-plugin-prettier", + "npm:2.2.0" + ], [ "@types/eventemitter3", "npm:2.0.2" @@ -9116,6 +9136,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "@types/node-fetch", "npm:2.1.4" ], + [ + "@types/prettier", + "npm:1.16.3" + ], [ "@types/react", "npm:16.7.20" @@ -9180,6 +9204,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "eslint-plugin-arca", "npm:0.8.1" ], + [ + "eslint-plugin-prettier", + "virtual:b93debf42822ec38d5fe4e99f4e6f09d7b47888d3ede2fd4d87aea17809e37e43f10d527dd26cf2c5a2c4646a93b42d7dcde25cae5bbb17e5c1c274d58d81e6f#npm:3.0.1" + ], [ "jest", "npm:24.5.0" @@ -9192,6 +9220,10 @@ function $$SETUP_STATE(hydrateRuntimeState) { "jest-junit", "npm:5.2.0" ], + [ + "prettier", + "npm:1.17.0" + ], [ "ts-node", "npm:7.0.1" @@ -13476,6 +13508,23 @@ function $$SETUP_STATE(hydrateRuntimeState) { ] ] ], + [ + "@types/eslint-plugin-prettier", + [ + [ + "npm:2.2.0", + { + "packageLocation": "./.yarn/cache/@types-eslint-plugin-prettier-npm-2.2.0-d999f56bab7b902d65ef324d4b06d5b200bfe050b0c9167894f2eb27f743c433.zip/node_modules/@types/eslint-plugin-prettier/", + "packageDependencies": [ + [ + "@types/eslint-plugin-prettier", + "npm:2.2.0" + ] + ] + } + ] + ] + ], [ "@types/estree", [ @@ -13992,6 +14041,23 @@ function $$SETUP_STATE(hydrateRuntimeState) { ] ] ], + [ + "@types/prettier", + [ + [ + "npm:1.16.3", + { + "packageLocation": "./.yarn/cache/@types-prettier-npm-1.16.3-9617c453bdb9561c240e4c2da02927ec6ff2f8507d682c1c7a6a8673cdf419ba.zip/node_modules/@types/prettier/", + "packageDependencies": [ + [ + "@types/prettier", + "npm:1.16.3" + ] + ] + } + ] + ] + ], [ "@types/prop-types", [ @@ -27850,6 +27916,51 @@ function $$SETUP_STATE(hydrateRuntimeState) { ] ] ], + [ + "eslint-plugin-prettier", + [ + [ + "npm:3.0.1", + { + "packageLocation": "./.yarn/cache/eslint-plugin-prettier-npm-3.0.1-0c4ecb0e4e0c7160552cd87393252a2a2e58acd0a376a700f9e4080cf32cd320.zip/node_modules/eslint-plugin-prettier/", + "packageDependencies": [ + [ + "eslint-plugin-prettier", + "npm:3.0.1" + ], + [ + "prettier-linter-helpers", + "npm:1.0.0" + ] + ] + } + ], + [ + "virtual:b93debf42822ec38d5fe4e99f4e6f09d7b47888d3ede2fd4d87aea17809e37e43f10d527dd26cf2c5a2c4646a93b42d7dcde25cae5bbb17e5c1c274d58d81e6f#npm:3.0.1", + { + "packageLocation": "./.yarn/virtual/eslint-plugin-prettier-virtual-5fd75e0be615bcc5b46019ac1417e7730317a6e191ccc7d36e5613357333647a/node_modules/eslint-plugin-prettier/", + "packageDependencies": [ + [ + "eslint-plugin-prettier", + "virtual:b93debf42822ec38d5fe4e99f4e6f09d7b47888d3ede2fd4d87aea17809e37e43f10d527dd26cf2c5a2c4646a93b42d7dcde25cae5bbb17e5c1c274d58d81e6f#npm:3.0.1" + ], + [ + "eslint", + "npm:5.16.0" + ], + [ + "prettier", + "npm:1.17.0" + ], + [ + "prettier-linter-helpers", + "npm:1.0.0" + ] + ] + } + ] + ] + ], [ "eslint-plugin-react", [ @@ -29384,6 +29495,23 @@ function $$SETUP_STATE(hydrateRuntimeState) { ] ] ], + [ + "fast-diff", + [ + [ + "npm:1.2.0", + { + "packageLocation": "./.yarn/cache/fast-diff-npm-1.2.0-3d3f6fd4575f841294b79d72fc3effa685da1adfff2e120d6701ba8ac8fc8cb7.zip/node_modules/fast-diff/", + "packageDependencies": [ + [ + "fast-diff", + "npm:1.2.0" + ] + ] + } + ] + ] + ], [ "fast-glob", [ @@ -51531,6 +51659,39 @@ function $$SETUP_STATE(hydrateRuntimeState) { ] ] } + ], + [ + "npm:1.17.0", + { + "packageLocation": "./.yarn/cache/prettier-npm-1.17.0-8d24ef48856d55b540775cee0771b6dbca5e95581e9bab103a2dc8e60c1ef363.zip/node_modules/prettier/", + "packageDependencies": [ + [ + "prettier", + "npm:1.17.0" + ] + ] + } + ] + ] + ], + [ + "prettier-linter-helpers", + [ + [ + "npm:1.0.0", + { + "packageLocation": "./.yarn/cache/prettier-linter-helpers-npm-1.0.0-d88507b0296e14ad925b60938b75848ae4ff020dc39aecf9c61b89f8bb372d51.zip/node_modules/prettier-linter-helpers/", + "packageDependencies": [ + [ + "prettier-linter-helpers", + "npm:1.0.0" + ], + [ + "fast-diff", + "npm:1.2.0" + ] + ] + } ] ] ], diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000000..6f3d9bf367da --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": false, + "printWidth": 120 +} diff --git a/.yarn/cache/@types-eslint-plugin-prettier-npm-2.2.0-d999f56bab7b902d65ef324d4b06d5b200bfe050b0c9167894f2eb27f743c433.zip b/.yarn/cache/@types-eslint-plugin-prettier-npm-2.2.0-d999f56bab7b902d65ef324d4b06d5b200bfe050b0c9167894f2eb27f743c433.zip new file mode 100644 index 000000000000..888993117165 Binary files /dev/null and b/.yarn/cache/@types-eslint-plugin-prettier-npm-2.2.0-d999f56bab7b902d65ef324d4b06d5b200bfe050b0c9167894f2eb27f743c433.zip differ diff --git a/.yarn/cache/@types-prettier-npm-1.16.3-9617c453bdb9561c240e4c2da02927ec6ff2f8507d682c1c7a6a8673cdf419ba.zip b/.yarn/cache/@types-prettier-npm-1.16.3-9617c453bdb9561c240e4c2da02927ec6ff2f8507d682c1c7a6a8673cdf419ba.zip new file mode 100644 index 000000000000..8e66398e50df Binary files /dev/null and b/.yarn/cache/@types-prettier-npm-1.16.3-9617c453bdb9561c240e4c2da02927ec6ff2f8507d682c1c7a6a8673cdf419ba.zip differ diff --git a/.yarn/cache/eslint-plugin-prettier-npm-3.0.1-0c4ecb0e4e0c7160552cd87393252a2a2e58acd0a376a700f9e4080cf32cd320.zip b/.yarn/cache/eslint-plugin-prettier-npm-3.0.1-0c4ecb0e4e0c7160552cd87393252a2a2e58acd0a376a700f9e4080cf32cd320.zip new file mode 100644 index 000000000000..ac7f7baf6e76 Binary files /dev/null and b/.yarn/cache/eslint-plugin-prettier-npm-3.0.1-0c4ecb0e4e0c7160552cd87393252a2a2e58acd0a376a700f9e4080cf32cd320.zip differ diff --git a/.yarn/cache/fast-diff-npm-1.2.0-3d3f6fd4575f841294b79d72fc3effa685da1adfff2e120d6701ba8ac8fc8cb7.zip b/.yarn/cache/fast-diff-npm-1.2.0-3d3f6fd4575f841294b79d72fc3effa685da1adfff2e120d6701ba8ac8fc8cb7.zip new file mode 100644 index 000000000000..7acb438a3887 Binary files /dev/null and b/.yarn/cache/fast-diff-npm-1.2.0-3d3f6fd4575f841294b79d72fc3effa685da1adfff2e120d6701ba8ac8fc8cb7.zip differ diff --git a/.yarn/cache/prettier-linter-helpers-npm-1.0.0-d88507b0296e14ad925b60938b75848ae4ff020dc39aecf9c61b89f8bb372d51.zip b/.yarn/cache/prettier-linter-helpers-npm-1.0.0-d88507b0296e14ad925b60938b75848ae4ff020dc39aecf9c61b89f8bb372d51.zip new file mode 100644 index 000000000000..cf003acd01a4 Binary files /dev/null and b/.yarn/cache/prettier-linter-helpers-npm-1.0.0-d88507b0296e14ad925b60938b75848ae4ff020dc39aecf9c61b89f8bb372d51.zip differ diff --git a/.yarn/cache/prettier-npm-1.17.0-8d24ef48856d55b540775cee0771b6dbca5e95581e9bab103a2dc8e60c1ef363.zip b/.yarn/cache/prettier-npm-1.17.0-8d24ef48856d55b540775cee0771b6dbca5e95581e9bab103a2dc8e60c1ef363.zip new file mode 100644 index 000000000000..6622a32331ea Binary files /dev/null and b/.yarn/cache/prettier-npm-1.17.0-8d24ef48856d55b540775cee0771b6dbca5e95581e9bab103a2dc8e60c1ef363.zip differ diff --git a/.yarn/virtual/eslint-plugin-prettier-virtual-5fd75e0be615bcc5b46019ac1417e7730317a6e191ccc7d36e5613357333647a b/.yarn/virtual/eslint-plugin-prettier-virtual-5fd75e0be615bcc5b46019ac1417e7730317a6e191ccc7d36e5613357333647a new file mode 120000 index 000000000000..1da32ed05d16 --- /dev/null +++ b/.yarn/virtual/eslint-plugin-prettier-virtual-5fd75e0be615bcc5b46019ac1417e7730317a6e191ccc7d36e5613357333647a @@ -0,0 +1 @@ +../cache/eslint-plugin-prettier-npm-3.0.1-0c4ecb0e4e0c7160552cd87393252a2a2e58acd0a376a700f9e4080cf32cd320.zip \ No newline at end of file diff --git a/package.json b/package.json index 35ab4041b5b5..17c14ce1bacb 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@types/dateformat": "^1.0.1", "@types/emscripten": "^0.0.31", "@types/eslint": "4.16.6", + "@types/eslint-plugin-prettier": "2.2.0", "@types/eventemitter3": "^2.0.2", "@types/execa": "^0.9.0", "@types/faker": "^4.1.4", @@ -29,6 +30,7 @@ "@types/node": "^10.12.0", "@types/node-emoji": "^1.8.0", "@types/node-fetch": "^2.1.2", + "@types/prettier": "1.16.3", "@types/react": "^16.4.14", "@types/react-redux": "^6.0.9", "@types/redux-saga": "^0.10.5", @@ -45,9 +47,11 @@ "babel-jest": "^24.5.0", "eslint": "^5.16.0", "eslint-plugin-arca": "^0.8.1", + "eslint-plugin-prettier": "^3.0.1", "jest": "^24.5.0", "jest-environment-node": "^24.5.0", "jest-junit": "^5.2.0", + "prettier": "^1.17.0", "ts-node": "^7.0.1", "typescript": "^3.3.3333" }, diff --git a/packages/berry-cli/sources/WorkspaceRequiredError.ts b/packages/berry-cli/sources/WorkspaceRequiredError.ts index 66ca60dfef7b..769731d5afd3 100644 --- a/packages/berry-cli/sources/WorkspaceRequiredError.ts +++ b/packages/berry-cli/sources/WorkspaceRequiredError.ts @@ -4,4 +4,4 @@ export class WorkspaceRequiredError extends UsageError { constructor(cwd: string) { super(`This command can only be run from within a workspace of your project.`); } -} \ No newline at end of file +} diff --git a/packages/berry-cli/sources/cli.ts b/packages/berry-cli/sources/cli.ts index acc1f43ddc36..4b24ff358dbf 100644 --- a/packages/berry-cli/sources/cli.ts +++ b/packages/berry-cli/sources/cli.ts @@ -1,21 +1,22 @@ -import {Configuration} from '@berry/core'; -import {xfs, NodeFS} from '@berry/fslib'; -import {execFileSync} from 'child_process'; +import {Configuration} from '@berry/core'; +import {xfs, NodeFS} from '@berry/fslib'; +import {execFileSync} from 'child_process'; import {UsageError, Clipanion} from 'clipanion'; -import {posix} from 'path'; -import * as yup from 'yup'; +import {posix} from 'path'; +import * as yup from 'yup'; -import {pluginConfiguration} from './pluginConfiguration'; +import {pluginConfiguration} from './pluginConfiguration'; const clipanion = new Clipanion({configKey: null}); -clipanion.topLevel(`[--cwd PATH]`) - .validate(yup.object().shape({ +clipanion.topLevel(`[--cwd PATH]`).validate( + yup.object().shape({ cwd: yup.string().transform((cwd = process.cwd()) => { // Note that the `--cwd` option might be a relative path that we need to resolve return posix.resolve(NodeFS.toPortablePath(process.cwd()), NodeFS.toPortablePath(cwd)); }), - })); + }), +); function runBinary(path: string) { const physicalPath = NodeFS.fromPortablePath(path); @@ -24,17 +25,17 @@ function runBinary(path: string) { execFileSync(process.execPath, [physicalPath, ...process.argv.slice(2)], { stdio: `inherit`, env: { - ... process.env, + ...process.env, YARN_IGNORE_PATH: `1`, - } + }, }); } else { execFileSync(physicalPath, process.argv.slice(2), { stdio: `inherit`, env: { - ... process.env, + ...process.env, YARN_IGNORE_PATH: `1`, - } + }, }); } } @@ -47,7 +48,14 @@ async function run() { if (yarnPath !== null && !ignorePath) { if (!xfs.existsSync(yarnPath)) { - clipanion.error(new Error(`The "yarn-path" option has been set (in ${configuration.sources.get(`yarnPath`)}), but the specified location doesn't exist (${yarnPath}).`), {stream: process.stderr}); + clipanion.error( + new Error( + `The "yarn-path" option has been set (in ${configuration.sources.get( + `yarnPath`, + )}), but the specified location doesn't exist (${yarnPath}).`, + ), + {stream: process.stderr}, + ); process.exitCode = 1; } else { try { @@ -58,11 +66,10 @@ async function run() { } } else { for (const plugin of configuration.plugins.values()) - for (const command of plugin.commands || []) - command(clipanion, pluginConfiguration); + for (const command of plugin.commands || []) command(clipanion, pluginConfiguration); clipanion.runExit(`yarn`, process.argv.slice(2), { - cwd: NodeFS.toPortablePath(process.cwd()) + cwd: NodeFS.toPortablePath(process.cwd()), }); } } diff --git a/packages/berry-cli/sources/pluginConfiguration.ts b/packages/berry-cli/sources/pluginConfiguration.ts index b776b53a6cb3..ee255f682651 100644 --- a/packages/berry-cli/sources/pluginConfiguration.ts +++ b/packages/berry-cli/sources/pluginConfiguration.ts @@ -1,4 +1,4 @@ -import {PluginConfiguration} from '@berry/core'; +import {PluginConfiguration} from '@berry/core'; // @ts-ignore import embedPluginConfiguration from './pluginConfiguration.raw.js'; diff --git a/packages/berry-core/sources/AliasResolver.ts b/packages/berry-core/sources/AliasResolver.ts index 7a396775d4d2..72901891a899 100644 --- a/packages/berry-core/sources/AliasResolver.ts +++ b/packages/berry-core/sources/AliasResolver.ts @@ -1,6 +1,6 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {Descriptor, Locator} from './types'; +import * as structUtils from './structUtils'; +import {Descriptor, Locator} from './types'; export class AliasResolver implements Resolver { private next: Resolver; @@ -35,22 +35,18 @@ export class AliasResolver implements Resolver { for (const descriptor of Array.from(pkg.dependencies.values())) { for (const {pattern, reference} of topLevelWorkspace.manifest.resolutions) { - if (pattern.from && pattern.from.fullName !== structUtils.requirableIdent(locator)) - continue; - if (pattern.from && pattern.from.description && pattern.from.description !== locator.reference) - continue; + if (pattern.from && pattern.from.fullName !== structUtils.requirableIdent(locator)) continue; + if (pattern.from && pattern.from.description && pattern.from.description !== locator.reference) continue; - if (pattern.descriptor.fullName !== structUtils.requirableIdent(descriptor)) - continue; - if (pattern.descriptor.description && pattern.descriptor.description !== descriptor.range) - continue; + if (pattern.descriptor.fullName !== structUtils.requirableIdent(descriptor)) continue; + if (pattern.descriptor.description && pattern.descriptor.description !== descriptor.range) continue; const alias = opts.resolver.bindDescriptor( structUtils.makeDescriptor(descriptor, reference), topLevelWorkspace.anchoredLocator, opts, ); - + pkg.dependencies.delete(descriptor.identHash); pkg.dependencies.set(alias.identHash, alias); } diff --git a/packages/berry-core/sources/Cache.ts b/packages/berry-core/sources/Cache.ts index 5779015e5b4a..e325d7f22981 100644 --- a/packages/berry-core/sources/Cache.ts +++ b/packages/berry-core/sources/Cache.ts @@ -1,19 +1,19 @@ import {FakeFS, LazyFS, NodeFS, ZipFS, xfs} from '@berry/fslib'; -import {lock, unlock} from 'lockfile'; -import {posix} from 'path'; -import {promisify} from 'util'; +import {lock, unlock} from 'lockfile'; +import {posix} from 'path'; +import {promisify} from 'util'; -import {Configuration} from './Configuration'; -import {MessageName, ReportError} from './Report'; -import * as hashUtils from './hashUtils'; -import * as structUtils from './structUtils'; -import {LocatorHash, Locator} from './types'; +import {Configuration} from './Configuration'; +import {MessageName, ReportError} from './Report'; +import * as hashUtils from './hashUtils'; +import * as structUtils from './structUtils'; +import {LocatorHash, Locator} from './types'; const lockP = promisify(lock); const unlockP = promisify(unlock); export type FetchFromCacheOptions = { - checksums: Map, + checksums: Map; }; export class Cache { @@ -50,7 +50,11 @@ export class Cache { }); } - async fetchPackageFromCache(locator: Locator, expectedChecksum: string | null, loader?: () => Promise): Promise<[FakeFS, () => void, string]> { + async fetchPackageFromCache( + locator: Locator, + expectedChecksum: string | null, + loader?: () => Promise, + ): Promise<[FakeFS, () => void, string]> { const cachePath = this.getLocatorPath(locator); const baseFs = new NodeFS(); @@ -66,9 +70,17 @@ export class Cache { return actualChecksum; default: - case `throw`: { - throw new ReportError(MessageName.CACHE_CHECKSUM_MISMATCH, `${structUtils.prettyLocator(this.configuration, locator)} doesn't resolve to an archive that matches the expected checksum`); - } break; + case `throw`: + { + throw new ReportError( + MessageName.CACHE_CHECKSUM_MISMATCH, + `${structUtils.prettyLocator( + this.configuration, + locator, + )} doesn't resolve to an archive that matches the expected checksum`, + ); + } + break; } } @@ -77,7 +89,9 @@ export class Cache { const loadPackage = async () => { if (!loader) - throw new Error(`Cache entry required but missing for ${structUtils.prettyLocator(this.configuration, locator)}`); + throw new Error( + `Cache entry required but missing for ${structUtils.prettyLocator(this.configuration, locator)}`, + ); return await this.writeFileIntoCache(cachePath, async () => { const zipFs = await loader(); @@ -108,20 +122,20 @@ export class Cache { } }; - for (let mutex; mutex = this.mutexes.get(locator.locatorHash);) - await mutex; + for (let mutex; (mutex = this.mutexes.get(locator.locatorHash)); ) await mutex; - const checksum = baseFs.existsSync(cachePath) - ? await validateFile(cachePath) - : await loadPackageThroughMutex(); + const checksum = baseFs.existsSync(cachePath) ? await validateFile(cachePath) : await loadPackageThroughMutex(); let zipFs: ZipFS | null = null; const lazyFs: LazyFS = new LazyFS(() => { try { - return zipFs = new ZipFS(cachePath, {readOnly: true, baseFs}); + return (zipFs = new ZipFS(cachePath, {readOnly: true, baseFs})); } catch (error) { - error.message = `Failed to open the cache entry for ${structUtils.prettyLocator(this.configuration, locator)}: ${error.message}`; + error.message = `Failed to open the cache entry for ${structUtils.prettyLocator( + this.configuration, + locator, + )}: ${error.message}`; throw error; } }); diff --git a/packages/berry-core/sources/Configuration.ts b/packages/berry-core/sources/Configuration.ts index 3d910cc36844..3202c9aeac7d 100644 --- a/packages/berry-core/sources/Configuration.ts +++ b/packages/berry-core/sources/Configuration.ts @@ -1,24 +1,24 @@ -import {xfs, NodeFS} from '@berry/fslib'; -import {parseSyml, stringifySyml} from '@berry/parsers'; -import camelcase from 'camelcase'; -import chalk from 'chalk'; -import {UsageError} from 'clipanion'; -import decamelize from 'decamelize'; -import {homedir} from 'os'; -import {posix, win32} from 'path'; -import supportsColor from 'supports-color'; - -import {MultiFetcher} from './MultiFetcher'; -import {MultiResolver} from './MultiResolver'; -import {Plugin, Hooks} from './Plugin'; -import {SemverResolver} from './SemverResolver'; -import {TagResolver} from './TagResolver'; -import {VirtualFetcher} from './VirtualFetcher'; -import {WorkspaceFetcher} from './WorkspaceFetcher'; -import {WorkspaceResolver} from './WorkspaceResolver'; -import * as miscUtils from './miscUtils'; -import * as nodeUtils from './nodeUtils'; -import * as structUtils from './structUtils'; +import {xfs, NodeFS} from '@berry/fslib'; +import {parseSyml, stringifySyml} from '@berry/parsers'; +import camelcase from 'camelcase'; +import chalk from 'chalk'; +import {UsageError} from 'clipanion'; +import decamelize from 'decamelize'; +import {homedir} from 'os'; +import {posix, win32} from 'path'; +import supportsColor from 'supports-color'; + +import {MultiFetcher} from './MultiFetcher'; +import {MultiResolver} from './MultiResolver'; +import {Plugin, Hooks} from './Plugin'; +import {SemverResolver} from './SemverResolver'; +import {TagResolver} from './TagResolver'; +import {VirtualFetcher} from './VirtualFetcher'; +import {WorkspaceFetcher} from './WorkspaceFetcher'; +import {WorkspaceResolver} from './WorkspaceResolver'; +import * as miscUtils from './miscUtils'; +import * as nodeUtils from './nodeUtils'; +import * as structUtils from './structUtils'; // @ts-ignore const ctx: any = new chalk.constructor({enabled: true}); @@ -81,19 +81,19 @@ export enum SettingsType { LOCATOR_LOOSE = 'LOCATOR_LOOSE', STRING = 'STRING', SECRET = 'SECRET', -}; +} export type SettingsDefinition = { - description: string, - type: SettingsType, - default: any, - isArray?: boolean, - isNullable?: boolean, + description: string; + type: SettingsType; + default: any; + isArray?: boolean; + isNullable?: boolean; }; export type PluginConfiguration = { - modules: Map, - plugins: Set, + modules: Map; + plugins: Set; }; // General rules: @@ -240,29 +240,33 @@ function parseBoolean(value: unknown) { case `true`: case `1`: case 1: - case true: { - return true; - } break; + case true: + { + return true; + } + break; case `false`: case `0`: case 0: - case false: { - return false; - } break; + case false: + { + return false; + } + break; - default: { - throw new Error(`Couldn't parse "${value}" as a boolean`); - } break; + default: + { + throw new Error(`Couldn't parse "${value}" as a boolean`); + } + break; } } function parseValue(value: unknown, type: SettingsType, folder: string) { - if (type === SettingsType.BOOLEAN) - return parseBoolean(value); + if (type === SettingsType.BOOLEAN) return parseBoolean(value); - if (typeof value !== `string`) - throw new Error(`Expected value to be a string`); + if (typeof value !== `string`) throw new Error(`Expected value to be a string`); if (type === SettingsType.ABSOLUTE_PATH) { return posix.resolve(folder, NodeFS.toPortablePath(value)); @@ -278,12 +282,10 @@ function parseValue(value: unknown, type: SettingsType, folder: string) { function getDefaultGlobalFolder() { let base; - if (process.platform === `win32`) + if (process.platform === `win32`) base = NodeFS.toPortablePath(process.env.LOCALAPPDATA || win32.join(homedir(), 'AppData', 'Local')); - else if (process.env.XDG_DATA_HOME) - base = NodeFS.toPortablePath(process.env.XDG_DATA_HOME); - else - base = NodeFS.toPortablePath(homedir()); + else if (process.env.XDG_DATA_HOME) base = NodeFS.toPortablePath(process.env.XDG_DATA_HOME); + else base = NodeFS.toPortablePath(homedir()); return posix.resolve(base, `yarn/modern`); } @@ -294,8 +296,7 @@ function getEnvironmentSettings() { for (let [key, value] of Object.entries(process.env)) { key = key.toLowerCase(); - if (!key.startsWith(ENVIRONMENT_PREFIX)) - continue; + if (!key.startsWith(ENVIRONMENT_PREFIX)) continue; key = key.slice(ENVIRONMENT_PREFIX.length); key = key.replace(/[_-]([a-z])/g, ($0, $1) => $1.toUpperCase()); @@ -309,9 +310,7 @@ function getEnvironmentSettings() { function getRcFilename() { const rcKey = `${ENVIRONMENT_PREFIX}rc_filename`; - for (const [key, value] of Object.entries(process.env)) - if (key.toLowerCase() === rcKey) - return value; + for (const [key, value] of Object.entries(process.env)) if (key.toLowerCase() === rcKey) return value; return DEFAULT_RC_FILENAME; } @@ -366,14 +365,12 @@ export class Configuration { const requireEntries = new Map(); for (const request of nodeUtils.builtinModules()) requireEntries.set(request, () => nodeUtils.dynamicRequire(request)); - for (const [request, embedModule] of pluginConfiguration.modules) - requireEntries.set(request, () => embedModule); + for (const [request, embedModule] of pluginConfiguration.modules) requireEntries.set(request, () => embedModule); const dynamicPlugins = new Set(); for (const {path, cwd, data} of rcFiles) { - if (!Array.isArray(data.plugins)) - continue; + if (!Array.isArray(data.plugins)) continue; for (const userProvidedPath of data.plugins) { const pluginPath = posix.resolve(cwd, NodeFS.toPortablePath(userProvidedPath)); @@ -381,23 +378,27 @@ export class Configuration { // Prevent plugin redefinition so that the ones declared deeper in the // filesystem always have precedence over the ones below. - if (dynamicPlugins.has(name)) - continue; + if (dynamicPlugins.has(name)) continue; const pluginRequireEntries = new Map(requireEntries); const pluginRequire = (request: string) => { if (pluginRequireEntries.has(request)) { return pluginRequireEntries.get(request)(); } else { - throw new UsageError(`This plugin cannot access the package referenced via ${request} which is neither a builtin, nor an exposed entry`); + throw new UsageError( + `This plugin cannot access the package referenced via ${request} which is neither a builtin, nor an exposed entry`, + ); } }; - const plugin = miscUtils.prettifySyncErrors(() => { - return factory(pluginRequire).default; - }, message => { - return `${message} (when initializing ${name}, defined in ${path})`; - }); + const plugin = miscUtils.prettifySyncErrors( + () => { + return factory(pluginRequire).default; + }, + message => { + return `${message} (when initializing ${name}, defined in ${path})`; + }, + ); requireEntries.set(name, () => plugin); @@ -427,8 +428,7 @@ export class Configuration { const configuration = new Configuration(projectCwd, plugins); configuration.useWithSource(``, environmentSettings, startingCwd); - for (const {path, cwd, data} of rcFiles) - configuration.useWithSource(path, data, cwd); + for (const {path, cwd, data} of rcFiles) configuration.useWithSource(path, data, cwd); if (configuration.get(`enableGlobalCache`)) { configuration.values.set(`cacheFolder`, `${configuration.get(`globalFolder`)}/cache`); @@ -459,7 +459,7 @@ export class Configuration { nextCwd = posix.dirname(currentCwd); } - + return rcFiles; } @@ -472,11 +472,9 @@ export class Configuration { while (nextCwd !== currentCwd) { currentCwd = nextCwd; - if (xfs.existsSync(`${currentCwd}/package.json`)) - projectCwd = currentCwd; + if (xfs.existsSync(`${currentCwd}/package.json`)) projectCwd = currentCwd; - if (xfs.existsSync(`${currentCwd}/${lockfileFilename}`)) - break; + if (xfs.existsSync(`${currentCwd}/${lockfileFilename}`)) break; nextCwd = posix.dirname(currentCwd); } @@ -488,17 +486,19 @@ export class Configuration { const rcFilename = getRcFilename(); const configurationPath = `${cwd}/${rcFilename}`; - const current = xfs.existsSync(configurationPath) ? parseSyml(await xfs.readFilePromise(configurationPath, `utf8`)) as any : {}; + const current = xfs.existsSync(configurationPath) + ? (parseSyml(await xfs.readFilePromise(configurationPath, `utf8`)) as any) + : {}; const currentKeys = Object.keys(current); - // If some keys already use kebab-case then we keep using this style + // If some keys already use kebab-case then we keep using this style const preferKebabCase = currentKeys.some(key => key.includes(`-`)); let patched = false; for (const key of Object.keys(patch)) { let currentKey; - + if (currentKeys.includes(key)) { currentKey = key; } else { @@ -513,15 +513,13 @@ export class Configuration { } } - if (current[currentKey] === patch[key]) - continue; + if (current[currentKey] === patch[key]) continue; current[currentKey] = patch[key]; patched = true; } - if (!patched) - return; + if (!patched) return; await xfs.writeFilePromise(configurationPath, stringifySyml(current)); } @@ -532,10 +530,8 @@ export class Configuration { const importSettings = (definitions: {[name: string]: SettingsDefinition}) => { for (const [name, definition] of Object.entries(definitions)) { - if (this.settings.has(name)) - throw new Error(`Cannot redefine settings "${name}"`); - else if (name in this) - throw new Error(`Settings named "${name}" conflicts with an actual property`); + if (this.settings.has(name)) throw new Error(`Cannot redefine settings "${name}"`); + else if (name in this) throw new Error(`Settings named "${name}" conflicts with an actual property`); this.settings.set(name, definition); @@ -579,30 +575,32 @@ export class Configuration { } use(source: string, data: {[key: string]: unknown}, folder: string) { - if (typeof data.berry === `object` && data.berry !== null) - data = data.berry; + if (typeof data.berry === `object` && data.berry !== null) data = data.berry; for (const key of Object.keys(data)) { const name = key.replace(/[_-]([a-z])/g, ($0, $1) => $1.toUpperCase()); // The plugins have already been loaded at this point - if (name === `plugins`) - continue; + if (name === `plugins`) continue; // binFolder is the magic location where the parent process stored the current binaries; not an actual configuration settings - if (name === `binFolder`) - continue; + if (name === `binFolder`) continue; // It wouldn't make much sense, would it? if (name === `rcFilename`) - throw new UsageError(`The rcFilename settings can only be set via ${`${ENVIRONMENT_PREFIX}RC_FILENAME`.toUpperCase()}, not via a rc file`); + throw new UsageError( + `The rcFilename settings can only be set via ${`${ENVIRONMENT_PREFIX}RC_FILENAME`.toUpperCase()}, not via a rc file`, + ); const definition = this.settings.get(name); if (!definition) - throw new UsageError(`${legacyNames.has(key) ? `Legacy` : `Unrecognized`} configuration settings found: ${key} - run "yarn config -v" to see the list of settings supported in Yarn`); + throw new UsageError( + `${ + legacyNames.has(key) ? `Legacy` : `Unrecognized` + } configuration settings found: ${key} - run "yarn config -v" to see the list of settings supported in Yarn`, + ); - if (this.sources.has(name)) - continue; + if (this.sources.has(name)) continue; let value = data[key]; if (value === null && !definition.isNullable && definition.default !== null) @@ -625,8 +623,7 @@ export class Configuration { } get(key: string) { - if (!this.values.has(key)) - throw new Error(`Invalid configuration key "${key}"`); + if (!this.values.has(key)) throw new Error(`Invalid configuration key "${key}"`); return this.values.get(key); } @@ -635,60 +632,49 @@ export class Configuration { const pluginResolvers = []; for (const plugin of this.plugins.values()) - for (const resolver of plugin.resolvers || []) - pluginResolvers.push(new resolver()); - - return new MultiResolver([ - new WorkspaceResolver(), - new SemverResolver(), - new TagResolver(), + for (const resolver of plugin.resolvers || []) pluginResolvers.push(new resolver()); - ... pluginResolvers, - ]); + return new MultiResolver([new WorkspaceResolver(), new SemverResolver(), new TagResolver(), ...pluginResolvers]); } makeFetcher() { const pluginFetchers = []; for (const plugin of this.plugins.values()) - for (const fetcher of plugin.fetchers || []) - pluginFetchers.push(new fetcher()); + for (const fetcher of plugin.fetchers || []) pluginFetchers.push(new fetcher()); - return new MultiFetcher([ - new VirtualFetcher(), - new WorkspaceFetcher(), - - ... pluginFetchers, - ]); + return new MultiFetcher([new VirtualFetcher(), new WorkspaceFetcher(), ...pluginFetchers]); } getLinkers() { const linkers = []; - for (const plugin of this.plugins.values()) - for (const linker of plugin.linkers || []) - linkers.push(new linker()); + for (const plugin of this.plugins.values()) for (const linker of plugin.linkers || []) linkers.push(new linker()); return linkers; } - async triggerHook(get: (hooks: HooksDefinition) => ((... args: U) => V) | undefined, ... args: U): Promise { + async triggerHook( + get: (hooks: HooksDefinition) => ((...args: U) => V) | undefined, + ...args: U + ): Promise { for (const plugin of this.plugins.values()) { const hooks = plugin.hooks as HooksDefinition; - if (!hooks) - continue; + if (!hooks) continue; const hook = get(hooks); - if (!hook) - continue; + if (!hook) continue; - await hook(... args); + await hook(...args); } } - async triggerMultipleHooks(get: (hooks: HooksDefinition) => ((... args: U) => V) | undefined, argsList: Array): Promise { + async triggerMultipleHooks( + get: (hooks: HooksDefinition) => ((...args: U) => V) | undefined, + argsList: Array, + ): Promise { for (const args of argsList) { - await this.triggerHook(get, ... args); + await this.triggerHook(get, ...args); } } diff --git a/packages/berry-core/sources/Fetcher.ts b/packages/berry-core/sources/Fetcher.ts index 2df79fadfe54..884762f9bec1 100644 --- a/packages/berry-core/sources/Fetcher.ts +++ b/packages/berry-core/sources/Fetcher.ts @@ -1,27 +1,27 @@ -import {FakeFS} from '@berry/fslib'; +import {FakeFS} from '@berry/fslib'; -import {Cache} from './Cache'; -import {Project} from './Project'; -import {Report} from './Report'; +import {Cache} from './Cache'; +import {Project} from './Project'; +import {Report} from './Report'; import {LocatorHash, Locator} from './types'; export type MinimalFetchOptions = { - project: Project, - fetcher: Fetcher, + project: Project; + fetcher: Fetcher; }; export type FetchOptions = MinimalFetchOptions & { - cache: Cache, - checksums: Map, - report: Report, + cache: Cache; + checksums: Map; + report: Report; }; export type FetchResult = { - packageFs: FakeFS, - releaseFs?: () => void, - prefixPath: string, - localPath?: string | null - checksum?: string, + packageFs: FakeFS; + releaseFs?: () => void; + prefixPath: string; + localPath?: string | null; + checksum?: string; }; /** @@ -36,7 +36,7 @@ export interface Fetcher { * This function must return true if the specified locator is understood by * this resolver (only its syntax is checked, it doesn't have to be valid * and it's fine if the `fetch` ends up returning a 404). - * + * * @param locator The locator that needs to be validated. * @param opts The fetch options. */ @@ -46,7 +46,7 @@ export interface Fetcher { * This function must return the local path for the given package. The local * path is the one that's used to resolve relative dependency sources, for * example "file:./foo". - * + * * @param locator The source locator. * @param opts The fetch options. */ @@ -55,12 +55,12 @@ export interface Fetcher { /** * This function must return a object describing where the package manager * can find the data for the specified package on disk. - * + * * The return value is a more complex than a regular path (cf FetchResult) * because the fetchers are allowed to return virtual paths that point to * things that don't actually exist (for example directories stored within * zip archives). - * + * * @param locator The source locator. * @param opts The fetch options. */ diff --git a/packages/berry-core/sources/Installer.ts b/packages/berry-core/sources/Installer.ts index f3f63cef6324..f56e18ee95c0 100644 --- a/packages/berry-core/sources/Installer.ts +++ b/packages/berry-core/sources/Installer.ts @@ -1,16 +1,16 @@ -import {FetchResult} from './Fetcher'; +import {FetchResult} from './Fetcher'; import {LinkType, Locator, Package} from './types'; export enum BuildType { SCRIPT = 0, SHELLCODE = 1, -}; +} export type BuildDirective = [BuildType, string]; export type InstallStatus = { - packageLocation: string, - buildDirective?: Array | null, + packageLocation: string; + buildDirective?: Array | null; }; export interface Installer { @@ -63,4 +63,4 @@ export interface Installer { * Finalize the install by writing miscellaneous files to the disk. */ finalizeInstall(): Promise; -}; +} diff --git a/packages/berry-core/sources/LightReport.ts b/packages/berry-core/sources/LightReport.ts index a26248765a96..50aa73b0b0b4 100644 --- a/packages/berry-core/sources/LightReport.ts +++ b/packages/berry-core/sources/LightReport.ts @@ -1,13 +1,13 @@ -import {Writable} from 'stream'; +import {Writable} from 'stream'; -import {Configuration} from './Configuration'; +import {Configuration} from './Configuration'; import {Report, MessageName} from './Report'; -import {Locator} from './types'; +import {Locator} from './types'; export type LightReportOptions = { - configuration: Configuration, - stdout: Writable, - suggestInstall?: boolean, + configuration: Configuration; + stdout: Writable; + suggestInstall?: boolean; }; export class LightReport extends Report { @@ -47,11 +47,9 @@ export class LightReport extends Report { return this.hasErrors() ? 1 : 0; } - reportCacheHit(locator: Locator) { - } + reportCacheHit(locator: Locator) {} - reportCacheMiss(locator: Locator) { - } + reportCacheMiss(locator: Locator) {} startTimerSync(what: string, cb: () => T) { return cb(); @@ -61,11 +59,9 @@ export class LightReport extends Report { return await cb(); } - reportInfo(name: MessageName, text: string) { - } + reportInfo(name: MessageName, text: string) {} - reportWarning(name: MessageName, text: string) { - } + reportWarning(name: MessageName, text: string) {} reportError(name: MessageName, text: string) { this.errorCount += 1; @@ -78,10 +74,20 @@ export class LightReport extends Report { async finalize() { if (this.errorCount > 0) { - this.stdout.write(`${this.configuration.format(`➤`, `redBright`)} Errors happened when preparing the environment required to run this command.\n`); + this.stdout.write( + `${this.configuration.format( + `➤`, + `redBright`, + )} Errors happened when preparing the environment required to run this command.\n`, + ); if (this.suggestInstall) { - this.stdout.write(`${this.configuration.format(`➤`, `redBright`)} This might be caused by packages being missing from the lockfile, in which case running "berry install" might help.\n`); + this.stdout.write( + `${this.configuration.format( + `➤`, + `redBright`, + )} This might be caused by packages being missing from the lockfile, in which case running "berry install" might help.\n`, + ); } } } diff --git a/packages/berry-core/sources/Linker.ts b/packages/berry-core/sources/Linker.ts index 5ef997f2550b..8615cfe2c259 100644 --- a/packages/berry-core/sources/Linker.ts +++ b/packages/berry-core/sources/Linker.ts @@ -1,14 +1,14 @@ -import {Installer} from './Installer'; -import {Project} from './Project'; -import {Report} from './Report'; +import {Installer} from './Installer'; +import {Project} from './Project'; +import {Report} from './Report'; import {Locator, Package} from './types'; export type MinimalLinkOptions = { - project: Project, + project: Project; }; export type LinkOptions = MinimalLinkOptions & { - report: Report, + report: Report; }; /** @@ -17,7 +17,7 @@ export type LinkOptions = MinimalLinkOptions & { * and put them on the filesystem in a way that their target environment will * understand (for example, in Node's case, it will be to generate a .pnp.js * file). - * + * * Note that *multiple linkers can coexist in the same dependency tree*. This * makes it possible to have a unique dependency tree containing packages from * different linkers. @@ -29,7 +29,7 @@ export interface Linker { * this linker. Given that this function takes a package definition as * parameter (not only a locator), it's safe to use the languageName field * as detection method. - * + * * @param locator The locator that needs to be validated. * @param opts The link options. */ @@ -38,14 +38,14 @@ export interface Linker { /** * This function must, given a specified locator, find the location where it * has been installed. - * + * * Note that contrary to fetchers (that are allowed to return relatively * complex type of data source thanks to their filesystem abstractions), this * function is only allowed to return a path. That being said, the way this * path is interpreted is open to the package manager, though - in practice * it will be used on a ZipOpenFS, so you can return paths from within zip * archives. - * + * * @param locator The queried package. * @param opts The link options. */ @@ -56,22 +56,22 @@ export interface Linker { * locator for the package that owns it. This function is allowed to fail if * the location doesn't seem to be owned by any package covered by the * current linker, in which case it should return null. - * + * * The main case where this function is called is when a postinstall script * for a third-party package calls another script of its. In this situation, * we must figure out who's making the "run" call, and we can't really rely * on anything else than the location on the disk to do so. - * + * * @param location The queried location on the disk. * @param opts The link options. */ findPackageLocator(location: string, opts: LinkOptions): Promise; - + /** * This function must instantiate an Installer object that describes how to * install the packages on the disk. Check the Installer file for more * details on the installer design. - * + * * @param opts The link options. */ makeInstaller(opts: LinkOptions): Installer; diff --git a/packages/berry-core/sources/LockfileResolver.ts b/packages/berry-core/sources/LockfileResolver.ts index ffa20b2ba366..bb32211d8f74 100644 --- a/packages/berry-core/sources/LockfileResolver.ts +++ b/packages/berry-core/sources/LockfileResolver.ts @@ -1,30 +1,29 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {Descriptor, Locator} from './types'; +import * as structUtils from './structUtils'; +import {Descriptor, Locator} from './types'; export class LockfileResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { const resolution = opts.project.storedResolutions.get(descriptor.descriptorHash); - if (resolution) - return true; + if (resolution) return true; // If the descriptor matches a package that's already been used, we can just use it even if we never resolved the range before // Ex: foo depends on bar@^1.0.0 that we resolved to foo@1.1.0, then we add a package qux that depends on foo@1.1.0 (without the caret) - if (opts.project.storedPackages.has(structUtils.convertDescriptorToLocator(descriptor).locatorHash)) - return true; + if (opts.project.storedPackages.has(structUtils.convertDescriptorToLocator(descriptor).locatorHash)) return true; return false; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (opts.project.storedPackages.has(locator.locatorHash)) - return true; + if (opts.project.storedPackages.has(locator.locatorHash)) return true; return false; } shouldPersistResolution(locator: Locator, opts: MinimalResolveOptions): boolean { - throw new Error(`The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes`); + throw new Error( + `The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes`, + ); } bindDescriptor(descriptor: Descriptor, fromLocator: Locator, opts: MinimalResolveOptions) { @@ -33,16 +32,13 @@ export class LockfileResolver implements Resolver { async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { let pkg = opts.project.storedPackages.get(structUtils.convertDescriptorToLocator(descriptor).locatorHash); - if (pkg) - return [pkg]; + if (pkg) return [pkg]; const resolution = opts.project.storedResolutions.get(descriptor.descriptorHash); - if (!resolution) - throw new Error(`Expected the resolution to have been successful - resolution not found`); + if (!resolution) throw new Error(`Expected the resolution to have been successful - resolution not found`); pkg = opts.project.storedPackages.get(resolution); - if (!pkg) - throw new Error(`Expected the resolution to have been successful - package not found`); + if (!pkg) throw new Error(`Expected the resolution to have been successful - package not found`); return [pkg]; } @@ -51,8 +47,10 @@ export class LockfileResolver implements Resolver { const pkg = opts.project.storedPackages.get(locator.locatorHash); if (!pkg) - throw new Error(`The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache`); - + throw new Error( + `The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache`, + ); + return pkg; } } diff --git a/packages/berry-core/sources/Manifest.ts b/packages/berry-core/sources/Manifest.ts index 3dde199c95d4..67919f08f6c1 100644 --- a/packages/berry-core/sources/Manifest.ts +++ b/packages/berry-core/sources/Manifest.ts @@ -1,31 +1,31 @@ -import {FakeFS, NodeFS} from '@berry/fslib'; -import {parseResolution} from '@berry/parsers'; -import {posix} from 'path'; -import semver from 'semver'; - -import * as miscUtils from './miscUtils'; -import * as structUtils from './structUtils'; -import {IdentHash} from './types'; +import {FakeFS, NodeFS} from '@berry/fslib'; +import {parseResolution} from '@berry/parsers'; +import {posix} from 'path'; +import semver from 'semver'; + +import * as miscUtils from './miscUtils'; +import * as structUtils from './structUtils'; +import {IdentHash} from './types'; import {Ident, Descriptor} from './types'; export interface WorkspaceDefinition { pattern: string; -}; +} export interface DependencyMeta { built?: boolean; unplugged?: boolean; -}; +} export interface PeerDependencyMeta { optional?: boolean; -}; +} export class Manifest { public name: Ident | null = null; public version: string | null = null; - public ["private"]: boolean = false; + public ['private']: boolean = false; public license: string | null = null; public languageName: string | null = null; @@ -42,7 +42,7 @@ export class Manifest { public dependenciesMeta: Map> = new Map(); public peerDependenciesMeta: Map = new Map(); - public resolutions: Array<{pattern: any, reference: string}> = []; + public resolutions: Array<{pattern: any; reference: string}> = []; public files: Set = new Set(); @@ -74,8 +74,7 @@ export class Manifest { } load(data: any) { - if (typeof data !== `object` || data === null) - throw new Error(`Utterly invalid manifest data (${data})`); + if (typeof data !== `object` || data === null) throw new Error(`Utterly invalid manifest data (${data})`); this.raw = data; const errors: Array = []; @@ -88,17 +87,13 @@ export class Manifest { } } - if (typeof data.version === `string`) - this.version = data.version; + if (typeof data.version === `string`) this.version = data.version; - if (typeof data.private === `boolean`) - this.private = data.private; + if (typeof data.private === `boolean`) this.private = data.private; - if (typeof data.license === `string`) - this.license = data.license; + if (typeof data.license === `string`) this.license = data.license; - if (typeof data.languageName === `string`) - this.languageName = data.languageName; + if (typeof data.languageName === `string`) this.languageName = data.languageName; if (typeof data.bin === `string`) { if (this.name !== null) { @@ -191,8 +186,8 @@ export class Manifest { const workspaces = Array.isArray(data.workspaces) ? data.workspaces : typeof data.workspaces === `object` && data.workspaces !== null && Array.isArray(data.workspaces.packages) - ? data.workspaces.packages - : []; + ? data.workspaces.packages + : []; for (const entry of workspaces) { if (typeof entry !== `string`) { @@ -245,7 +240,7 @@ export class Manifest { } catch (error) { errors.push(error); continue; - } + } } } @@ -287,12 +282,10 @@ export class Manifest { const range = descriptor.range !== `unknown` ? descriptor.range : null; let dependencyMetaSet = this.dependenciesMeta.get(identString); - if (!dependencyMetaSet) - this.dependenciesMeta.set(identString, dependencyMetaSet = new Map()); + if (!dependencyMetaSet) this.dependenciesMeta.set(identString, (dependencyMetaSet = new Map())); let dependencyMeta = dependencyMetaSet.get(range); - if (!dependencyMeta) - dependencyMetaSet.set(range, dependencyMeta = {}); + if (!dependencyMeta) dependencyMetaSet.set(range, (dependencyMeta = {})); return dependencyMeta; } @@ -304,73 +297,93 @@ export class Manifest { const identString = structUtils.stringifyIdent(descriptor); let peerDependencyMeta = this.peerDependenciesMeta.get(identString); - if (!peerDependencyMeta) - this.peerDependenciesMeta.set(identString, peerDependencyMeta = {}); + if (!peerDependencyMeta) this.peerDependenciesMeta.set(identString, (peerDependencyMeta = {})); return peerDependencyMeta; } exportTo(data: {[key: string]: any}) { - if (this.name !== null) - data.name = structUtils.stringifyIdent(this.name); - else - delete data.name; - - if (this.version !== null) - data.version = this.version; - else - delete data.version; - - if (this.private) - data.private = true; - else - delete data.private; - - if (this.license !== null) - data.license = this.license; - else - delete data.license; - - if (this.languageName !== null) - data.languageName = this.languageName; - else - delete data.languageName; - - data.dependencies = this.dependencies.size === 0 ? undefined : Object.assign({}, ... structUtils.sortDescriptors(this.dependencies.values()).map(dependency => { - return {[structUtils.stringifyIdent(dependency)]: dependency.range}; - })); - - data.devDependencies = this.devDependencies.size === 0 ? undefined : Object.assign({}, ... structUtils.sortDescriptors(this.devDependencies.values()).map(dependency => { - return {[structUtils.stringifyIdent(dependency)]: dependency.range}; - })); - - data.peerDependencies = this.peerDependencies.size === 0 ? undefined : Object.assign({}, ... structUtils.sortDescriptors(this.peerDependencies.values()).map(dependency => { - return {[structUtils.stringifyIdent(dependency)]: dependency.range}; - })); + if (this.name !== null) data.name = structUtils.stringifyIdent(this.name); + else delete data.name; + + if (this.version !== null) data.version = this.version; + else delete data.version; + + if (this.private) data.private = true; + else delete data.private; + + if (this.license !== null) data.license = this.license; + else delete data.license; + + if (this.languageName !== null) data.languageName = this.languageName; + else delete data.languageName; + + data.dependencies = + this.dependencies.size === 0 + ? undefined + : Object.assign( + {}, + ...structUtils.sortDescriptors(this.dependencies.values()).map(dependency => { + return {[structUtils.stringifyIdent(dependency)]: dependency.range}; + }), + ); + + data.devDependencies = + this.devDependencies.size === 0 + ? undefined + : Object.assign( + {}, + ...structUtils.sortDescriptors(this.devDependencies.values()).map(dependency => { + return {[structUtils.stringifyIdent(dependency)]: dependency.range}; + }), + ); + + data.peerDependencies = + this.peerDependencies.size === 0 + ? undefined + : Object.assign( + {}, + ...structUtils.sortDescriptors(this.peerDependencies.values()).map(dependency => { + return {[structUtils.stringifyIdent(dependency)]: dependency.range}; + }), + ); data.dependenciesMeta = {}; - for (const [identString, dependencyMetaSet] of miscUtils.sortMap(this.dependenciesMeta.entries(), ([identString, dependencyMetaSet]) => identString)) { - for (const [range, meta] of miscUtils.sortMap(dependencyMetaSet.entries(), ([range, meta]) => range !== null ? `0${range}` : `1`)) { - const key = range !== null - ? structUtils.stringifyDescriptor(structUtils.makeDescriptor(structUtils.parseIdent(identString), range)) - : identString; + for (const [identString, dependencyMetaSet] of miscUtils.sortMap( + this.dependenciesMeta.entries(), + ([identString, dependencyMetaSet]) => identString, + )) { + for (const [range, meta] of miscUtils.sortMap(dependencyMetaSet.entries(), ([range, meta]) => + range !== null ? `0${range}` : `1`, + )) { + const key = + range !== null + ? structUtils.stringifyDescriptor(structUtils.makeDescriptor(structUtils.parseIdent(identString), range)) + : identString; data.dependenciesMeta[key] = meta; } } - if (Object.keys(data.dependenciesMeta).length === 0) - data.dependenciesMeta = undefined; - - data.peerDependenciesMeta = this.peerDependenciesMeta.size === 0 ? undefined : Object.assign({}, ... miscUtils.sortMap(this.peerDependenciesMeta.entries(), ([identString, meta]) => identString).map(([identString, meta]) => { - return {[identString]: meta}; - })); - - if(this.files.size === 0) { + if (Object.keys(data.dependenciesMeta).length === 0) data.dependenciesMeta = undefined; + + data.peerDependenciesMeta = + this.peerDependenciesMeta.size === 0 + ? undefined + : Object.assign( + {}, + ...miscUtils + .sortMap(this.peerDependenciesMeta.entries(), ([identString, meta]) => identString) + .map(([identString, meta]) => { + return {[identString]: meta}; + }), + ); + + if (this.files.size === 0) { data.files = undefined; } else { data.files = Array.from(this.files); } } -}; +} diff --git a/packages/berry-core/sources/MultiFetcher.ts b/packages/berry-core/sources/MultiFetcher.ts index 1e03f7a830cf..a106e8361e2f 100644 --- a/packages/berry-core/sources/MultiFetcher.ts +++ b/packages/berry-core/sources/MultiFetcher.ts @@ -1,7 +1,7 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from './Fetcher'; -import {MessageName, ReportError} from './Report'; -import * as structUtils from './structUtils'; -import {Locator} from './types'; +import {MessageName, ReportError} from './Report'; +import * as structUtils from './structUtils'; +import {Locator} from './types'; export class MultiFetcher implements Fetcher { private readonly fetchers: Array; @@ -11,8 +11,7 @@ export class MultiFetcher implements Fetcher { } supports(locator: Locator, opts: MinimalFetchOptions) { - if (!this.tryFetcher(locator, opts)) - return false; + if (!this.tryFetcher(locator, opts)) return false; return true; } @@ -32,8 +31,7 @@ export class MultiFetcher implements Fetcher { private tryFetcher(locator: Locator, opts: MinimalFetchOptions) { const fetcher = this.fetchers.find(fetcher => fetcher.supports(locator, opts)); - if (!fetcher) - return null; + if (!fetcher) return null; return fetcher; } @@ -42,7 +40,10 @@ export class MultiFetcher implements Fetcher { const fetcher = this.fetchers.find(fetcher => fetcher.supports(locator, opts)); if (!fetcher) - throw new ReportError(MessageName.FETCHER_NOT_FOUND, `${structUtils.prettyLocator(opts.project.configuration, locator)} isn't supported by any available fetcher`); + throw new ReportError( + MessageName.FETCHER_NOT_FOUND, + `${structUtils.prettyLocator(opts.project.configuration, locator)} isn't supported by any available fetcher`, + ); return fetcher; } diff --git a/packages/berry-core/sources/MultiResolver.ts b/packages/berry-core/sources/MultiResolver.ts index e2cd50b3cf37..ec519b3ee901 100644 --- a/packages/berry-core/sources/MultiResolver.ts +++ b/packages/berry-core/sources/MultiResolver.ts @@ -1,7 +1,7 @@ -import {MessageName, ReportError} from './Report'; +import {MessageName, ReportError} from './Report'; import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {Descriptor, Locator, Package} from './types'; +import * as structUtils from './structUtils'; +import {Descriptor, Locator, Package} from './types'; export class MultiResolver implements Resolver { private readonly resolvers: Array; @@ -49,8 +49,7 @@ export class MultiResolver implements Resolver { private tryResolverByDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { const resolver = this.resolvers.find(resolver => resolver.supportsDescriptor(descriptor, opts)); - if (!resolver) - return null; + if (!resolver) return null; return resolver; } @@ -59,7 +58,13 @@ export class MultiResolver implements Resolver { const resolver = this.resolvers.find(resolver => resolver.supportsDescriptor(descriptor, opts)); if (!resolver) - throw new ReportError(MessageName.RESOLVER_NOT_FOUND, `${structUtils.prettyDescriptor(opts.project.configuration, descriptor)} isn't supported by any available resolver`); + throw new ReportError( + MessageName.RESOLVER_NOT_FOUND, + `${structUtils.prettyDescriptor( + opts.project.configuration, + descriptor, + )} isn't supported by any available resolver`, + ); return resolver; } @@ -67,8 +72,7 @@ export class MultiResolver implements Resolver { private tryResolverByLocator(locator: Locator, opts: MinimalResolveOptions) { const resolver = this.resolvers.find(resolver => resolver.supportsLocator(locator, opts)); - if (!resolver) - return null; + if (!resolver) return null; return resolver; } @@ -77,7 +81,10 @@ export class MultiResolver implements Resolver { const resolver = this.resolvers.find(resolver => resolver.supportsLocator(locator, opts)); if (!resolver) - throw new ReportError(MessageName.RESOLVER_NOT_FOUND, `${structUtils.prettyLocator(opts.project.configuration, locator)} isn't supported by any available resolver`); + throw new ReportError( + MessageName.RESOLVER_NOT_FOUND, + `${structUtils.prettyLocator(opts.project.configuration, locator)} isn't supported by any available resolver`, + ); return resolver; } diff --git a/packages/berry-core/sources/Plugin.ts b/packages/berry-core/sources/Plugin.ts index 181732978fb4..19c8d3a9025c 100644 --- a/packages/berry-core/sources/Plugin.ts +++ b/packages/berry-core/sources/Plugin.ts @@ -1,20 +1,20 @@ import {SettingsDefinition, PluginConfiguration} from './Configuration'; -import {Fetcher} from './Fetcher'; -import {Linker} from './Linker'; -import {Project} from './Project'; -import {Resolver} from './Resolver'; +import {Fetcher} from './Fetcher'; +import {Linker} from './Linker'; +import {Project} from './Project'; +import {Resolver} from './Resolver'; export interface FetcherPlugin { - new(): Fetcher; -}; + new (): Fetcher; +} export interface LinkerPlugin { - new(): Linker; -}; + new (): Linker; +} export interface ResolverPlugin { - new(): Resolver; -}; + new (): Resolver; +} export type Hooks = { // Called before a script is executed. The hooks are allowed to modify the @@ -29,20 +29,18 @@ export type Hooks = { project: Project, env: {[key: string]: string}, makePathWrapper: (name: string, argv0: string, args: Array) => Promise, - ) => Promise, + ) => Promise; // Called after the `install` method from the `Project` class successfully // completed. - afterAllInstalled?: ( - project: Project, - ) => void, + afterAllInstalled?: (project: Project) => void; }; export type Plugin = { - configuration?: {[key: string]: SettingsDefinition}, - commands?: Array<(clipanion: any, pluginConfiguration: PluginConfiguration) => any>, - fetchers?: Array, - linkers?: Array, - resolvers?: Array, - hooks?: {[key: string]: any}, + configuration?: {[key: string]: SettingsDefinition}; + commands?: Array<(clipanion: any, pluginConfiguration: PluginConfiguration) => any>; + fetchers?: Array; + linkers?: Array; + resolvers?: Array; + hooks?: {[key: string]: any}; }; diff --git a/packages/berry-core/sources/Project.ts b/packages/berry-core/sources/Project.ts index f6e2db891007..7c30e74154c3 100644 --- a/packages/berry-core/sources/Project.ts +++ b/packages/berry-core/sources/Project.ts @@ -1,35 +1,35 @@ -import {xfs} from '@berry/fslib'; -import {parseSyml, stringifySyml} from '@berry/parsers'; -import {createHmac} from 'crypto'; +import {xfs} from '@berry/fslib'; +import {parseSyml, stringifySyml} from '@berry/parsers'; +import {createHmac} from 'crypto'; // @ts-ignore -import Logic from 'logic-solver'; +import Logic from 'logic-solver'; // @ts-ignore -import pLimit from 'p-limit'; -import {posix} from 'path'; -import semver from 'semver'; -import {PassThrough} from 'stream'; -import {tmpNameSync} from 'tmp'; - -import {AliasResolver} from './AliasResolver'; -import {Cache} from './Cache'; -import {Configuration} from './Configuration'; -import {Fetcher} from './Fetcher'; -import {Installer, BuildDirective, BuildType} from './Installer'; -import {Linker} from './Linker'; -import {LockfileResolver} from './LockfileResolver'; -import {DependencyMeta, Manifest} from './Manifest'; -import {MultiResolver} from './MultiResolver'; -import {Report, ReportError, MessageName} from './Report'; -import {RunInstallPleaseResolver} from './RunInstallPleaseResolver'; -import {ThrowReport} from './ThrowReport'; -import {Workspace} from './Workspace'; -import {YarnResolver} from './YarnResolver'; -import * as miscUtils from './miscUtils'; -import * as scriptUtils from './scriptUtils'; -import * as structUtils from './structUtils'; +import pLimit from 'p-limit'; +import {posix} from 'path'; +import semver from 'semver'; +import {PassThrough} from 'stream'; +import {tmpNameSync} from 'tmp'; + +import {AliasResolver} from './AliasResolver'; +import {Cache} from './Cache'; +import {Configuration} from './Configuration'; +import {Fetcher} from './Fetcher'; +import {Installer, BuildDirective, BuildType} from './Installer'; +import {Linker} from './Linker'; +import {LockfileResolver} from './LockfileResolver'; +import {DependencyMeta, Manifest} from './Manifest'; +import {MultiResolver} from './MultiResolver'; +import {Report, ReportError, MessageName} from './Report'; +import {RunInstallPleaseResolver} from './RunInstallPleaseResolver'; +import {ThrowReport} from './ThrowReport'; +import {Workspace} from './Workspace'; +import {YarnResolver} from './YarnResolver'; +import * as miscUtils from './miscUtils'; +import * as scriptUtils from './scriptUtils'; +import * as structUtils from './structUtils'; import {IdentHash, DescriptorHash, LocatorHash} from './types'; -import {Descriptor, Ident, Locator, Package} from './types'; -import {LinkType} from './types'; +import {Descriptor, Ident, Locator, Package} from './types'; +import {LinkType} from './types'; // When upgraded, the lockfile entries have to be resolved again (but the specific // versions are still pinned, no worry). Bump it when you change the fields within @@ -37,11 +37,11 @@ import {LinkType} from './types'; const LOCKFILE_VERSION = 2; export type InstallOptions = { - cache: Cache, - fetcher?: Fetcher, - report: Report, - frozenLockfile?: boolean, - lockfileOnly?: boolean, + cache: Cache; + fetcher?: Fetcher; + report: Report; + frozenLockfile?: boolean; + lockfileOnly?: boolean; }; export class Project { @@ -65,9 +65,11 @@ export class Project { public storedPackages: Map = new Map(); public storedChecksums: Map = new Map(); - static async find(configuration: Configuration, startingCwd: string): Promise<{project: Project, workspace: Workspace | null, locator: Locator}> { - if (!configuration.projectCwd) - throw new Error(`No project found in the initial directory`); + static async find( + configuration: Configuration, + startingCwd: string, + ): Promise<{project: Project; workspace: Workspace | null; locator: Locator}> { + if (!configuration.projectCwd) throw new Error(`No project found in the initial directory`); let packageCwd = null; @@ -77,15 +79,12 @@ export class Project { while (currentCwd !== configuration.projectCwd) { currentCwd = nextCwd; - if (xfs.existsSync(`${currentCwd}/package.json`)) - if (!packageCwd) - packageCwd = currentCwd; + if (xfs.existsSync(`${currentCwd}/package.json`)) if (!packageCwd) packageCwd = currentCwd; nextCwd = posix.dirname(currentCwd); } - if (!packageCwd) - throw new Error(`Assertion failed: No manifest found in the project`); + if (!packageCwd) throw new Error(`Assertion failed: No manifest found in the project`); const project = new Project(configuration.projectCwd, {configuration}); @@ -94,14 +93,12 @@ export class Project { // If we're in a workspace, no need to go any further to find which package we're in const workspace = project.tryWorkspaceByCwd(packageCwd); - if (workspace) - return {project, workspace, locator: workspace.anchoredLocator}; + if (workspace) return {project, workspace, locator: workspace.anchoredLocator}; // Otherwise, we need to ask the project (which will in turn ask the linkers for help) // Note: the trailing slash is caused by a quirk in the PnP implementation that requires folders to end with a trailing slash to disambiguate them from regular files const locator = await project.findLocatorForLocation(`${packageCwd}/`); - if (locator) - return {project, locator, workspace: null}; + if (locator) return {project, locator, workspace: null}; throw new Error(`Assertion failed: The package should have been detected as part of the project`); } @@ -128,8 +125,7 @@ export class Project { const lockfileVersion = parsed.__metadata.version; for (const key of Object.keys(parsed)) { - if (key === `__metadata`) - continue; + if (key === `__metadata`) continue; const data = parsed[key]; const locator = structUtils.parseLocator(data.resolution, true); @@ -148,11 +144,19 @@ export class Project { const dependenciesMeta = manifest.dependenciesMeta; const peerDependenciesMeta = manifest.peerDependenciesMeta; - if (data.checksum != null) - this.storedChecksums.set(locator.locatorHash, data.checksum); + if (data.checksum != null) this.storedChecksums.set(locator.locatorHash, data.checksum); if (lockfileVersion >= LOCKFILE_VERSION) { - const pkg: Package = {...locator, version, languageName, linkType, dependencies, peerDependencies, dependenciesMeta, peerDependenciesMeta}; + const pkg: Package = { + ...locator, + version, + languageName, + linkType, + dependencies, + peerDependencies, + dependenciesMeta, + peerDependenciesMeta, + }; this.storedPackages.set(pkg.locatorHash, pkg); } @@ -197,8 +201,7 @@ export class Project { workspaceCwds = []; for (const workspaceCwd of passCwds) { - if (this.workspacesByCwd.has(workspaceCwd)) - continue; + if (this.workspacesByCwd.has(workspaceCwd)) continue; const workspace = await this.addWorkspace(workspaceCwd); @@ -219,8 +222,7 @@ export class Project { this.workspacesByLocator.set(workspace.anchoredLocator.locatorHash, workspace); let byIdent = this.workspacesByIdent.get(workspace.locator.identHash); - if (!byIdent) - this.workspacesByIdent.set(workspace.locator.identHash, byIdent = []); + if (!byIdent) this.workspacesByIdent.set(workspace.locator.identHash, (byIdent = [])); byIdent.push(workspace); return workspace; @@ -231,39 +233,33 @@ export class Project { } tryWorkspaceByCwd(workspaceCwd: string) { - if (!posix.isAbsolute(workspaceCwd)) - workspaceCwd = posix.resolve(this.cwd, workspaceCwd); + if (!posix.isAbsolute(workspaceCwd)) workspaceCwd = posix.resolve(this.cwd, workspaceCwd); const workspace = this.workspacesByCwd.get(workspaceCwd); - if (!workspace) - return null; + if (!workspace) return null; return workspace; } getWorkspaceByCwd(workspaceCwd: string) { const workspace = this.tryWorkspaceByCwd(workspaceCwd); - if (!workspace) - throw new Error(`Workspace not found (${workspaceCwd})`); + if (!workspace) throw new Error(`Workspace not found (${workspaceCwd})`); return workspace; } tryWorkspaceByLocator(locator: Locator) { - if (structUtils.isVirtualLocator(locator)) - locator = structUtils.devirtualizeLocator(locator); + if (structUtils.isVirtualLocator(locator)) locator = structUtils.devirtualizeLocator(locator); const workspace = this.workspacesByLocator.get(locator.locatorHash); - if (!workspace) - return null; + if (!workspace) return null; return workspace; } getWorkspaceByLocator(locator: Locator) { const workspace = this.tryWorkspaceByLocator(locator); - if (!workspace) - throw new Error(`Workspace not found (${structUtils.prettyLocator(this.configuration, locator)})`); + if (!workspace) throw new Error(`Workspace not found (${structUtils.prettyLocator(this.configuration, locator)})`); return workspace; } @@ -271,8 +267,7 @@ export class Project { findWorkspacesByDescriptor(descriptor: Descriptor) { const candidateWorkspaces = this.workspacesByIdent.get(descriptor.identHash); - if (!candidateWorkspaces) - return []; + if (!candidateWorkspaces) return []; return candidateWorkspaces.filter(workspace => { return workspace.accepts(descriptor.range); @@ -304,19 +299,15 @@ export class Project { const dependenciesMeta = this.topLevelWorkspace.manifest.dependenciesMeta; const dependencyMetaSet = dependenciesMeta.get(structUtils.stringifyIdent(ident)); - if (!dependencyMetaSet) - return dependencyMeta; + if (!dependencyMetaSet) return dependencyMeta; const defaultMeta = dependencyMetaSet.get(null); - if (defaultMeta) - Object.assign(dependencyMeta, defaultMeta); + if (defaultMeta) Object.assign(dependencyMeta, defaultMeta); - if (version === null || !semver.valid(version)) - return dependencyMeta; + if (version === null || !semver.valid(version)) return dependencyMeta; for (const [range, meta] of dependencyMetaSet) - if (range !== null && range === version) - Object.assign(dependencyMeta, meta); + if (range !== null && range === version) Object.assign(dependencyMeta, meta); return dependencyMeta; } @@ -386,32 +377,34 @@ export class Project { // already been resolved previously. for (const descriptorHash of mustBeResolved) - if (allResolutions.has(descriptorHash)) - mustBeResolved.delete(descriptorHash); + if (allResolutions.has(descriptorHash)) mustBeResolved.delete(descriptorHash); // Then we request the resolvers for the list of possible references that // match the given ranges. That will give us a set of candidate references // for each descriptor. - const passCandidates = new Map(await Promise.all(Array.from(mustBeResolved).map(async descriptorHash => { - const descriptor = allDescriptors.get(descriptorHash); - if (!descriptor) - throw new Error(`Assertion failed: The descriptor should have been registered`); + const passCandidates = new Map( + await Promise.all( + Array.from(mustBeResolved).map(async descriptorHash => { + const descriptor = allDescriptors.get(descriptorHash); + if (!descriptor) throw new Error(`Assertion failed: The descriptor should have been registered`); - let candidateLocators; + let candidateLocators; - try { - candidateLocators = await resolver.getCandidates(descriptor, resolverOptions); - } catch (error) { - error.message = `${structUtils.prettyDescriptor(this.configuration, descriptor)}: ${error.message}`; - throw error; - } + try { + candidateLocators = await resolver.getCandidates(descriptor, resolverOptions); + } catch (error) { + error.message = `${structUtils.prettyDescriptor(this.configuration, descriptor)}: ${error.message}`; + throw error; + } - if (candidateLocators.length === 0) - throw new Error(`No candidate found for ${structUtils.prettyDescriptor(this.configuration, descriptor)}`); + if (candidateLocators.length === 0) + throw new Error(`No candidate found for ${structUtils.prettyDescriptor(this.configuration, descriptor)}`); - return [descriptor.descriptorHash, candidateLocators] as [DescriptorHash, Array]; - }))); + return [descriptor.descriptorHash, candidateLocators] as [DescriptorHash, Array]; + }), + ), + ); // That's where we'll store our resolutions until everything has been // resolved and can be injected into the various stores. @@ -430,8 +423,7 @@ export class Project { // can only be satisfied by a single reference. for (const [descriptorHash, candidateLocators] of passCandidates) { - if (candidateLocators.length !== 1) - continue; + if (candidateLocators.length !== 1) continue; passResolutions.set(descriptorHash, candidateLocators[0]); passCandidates.delete(descriptorHash); @@ -442,8 +434,7 @@ export class Project { for (const [descriptorHash, candidateLocators] of passCandidates) { const selectedLocator = candidateLocators.find(locator => allPackages.has(locator.locatorHash)); - if (!selectedLocator) - continue; + if (!selectedLocator) continue; passResolutions.set(descriptorHash, selectedLocator); passCandidates.delete(descriptorHash); @@ -463,7 +454,7 @@ export class Project { const solver = new Logic.Solver(); for (const candidateLocators of passCandidates.values()) - solver.require(Logic.or(... candidateLocators.map(locator => locator.locatorHash))); + solver.require(Logic.or(...candidateLocators.map(locator => locator.locatorHash))); let remainingSolutions = 100; let solution; @@ -483,8 +474,7 @@ export class Project { remainingSolutions -= 1; } - if (!bestSolution) - throw new Error(`Assertion failed: No resolution found by the SAT solver`); + if (!bestSolution) throw new Error(`Assertion failed: No resolution found by the SAT solver`); const solutionSet = new Set(bestSolution as Array); @@ -506,32 +496,48 @@ export class Project { return !allPackages.has(locator.locatorHash); }); - const newPackages = new Map(await Promise.all(newLocators.map(async locator => { - let pkg = await miscUtils.prettifyAsyncErrors(async () => { - return await resolver.resolve(locator, resolverOptions); - }, message => { - return `${structUtils.prettyLocator(this.configuration, locator)}: ${message}`; - }); - - if (!structUtils.areLocatorsEqual(locator, pkg)) - throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${structUtils.prettyLocator(this.configuration, locator)} to ${structUtils.prettyLocator(this.configuration, pkg)})`); - - const rawDependencies = pkg.dependencies; - const rawPeerDependencies = pkg.peerDependencies; - - const dependencies = pkg.dependencies = new Map(); - const peerDependencies = pkg.peerDependencies = new Map(); - - for (const descriptor of miscUtils.sortMap(rawDependencies.values(), descriptor => structUtils.stringifyIdent(descriptor))) { - const normalizedDescriptor = resolver.bindDescriptor(descriptor, locator, resolverOptions); - dependencies.set(normalizedDescriptor.identHash, normalizedDescriptor); - } + const newPackages = new Map( + await Promise.all( + newLocators.map(async locator => { + let pkg = await miscUtils.prettifyAsyncErrors( + async () => { + return await resolver.resolve(locator, resolverOptions); + }, + message => { + return `${structUtils.prettyLocator(this.configuration, locator)}: ${message}`; + }, + ); + + if (!structUtils.areLocatorsEqual(locator, pkg)) + throw new Error( + `Assertion failed: The locator cannot be changed by the resolver (went from ${structUtils.prettyLocator( + this.configuration, + locator, + )} to ${structUtils.prettyLocator(this.configuration, pkg)})`, + ); + + const rawDependencies = pkg.dependencies; + const rawPeerDependencies = pkg.peerDependencies; + + const dependencies = (pkg.dependencies = new Map()); + const peerDependencies = (pkg.peerDependencies = new Map()); + + for (const descriptor of miscUtils.sortMap(rawDependencies.values(), descriptor => + structUtils.stringifyIdent(descriptor), + )) { + const normalizedDescriptor = resolver.bindDescriptor(descriptor, locator, resolverOptions); + dependencies.set(normalizedDescriptor.identHash, normalizedDescriptor); + } - for (const descriptor of miscUtils.sortMap(rawPeerDependencies.values(), descriptor => structUtils.stringifyIdent(descriptor))) - peerDependencies.set(descriptor.identHash, descriptor); + for (const descriptor of miscUtils.sortMap(rawPeerDependencies.values(), descriptor => + structUtils.stringifyIdent(descriptor), + )) + peerDependencies.set(descriptor.identHash, descriptor); - return [pkg.locatorHash, pkg] as [LocatorHash, Package]; - }))); + return [pkg.locatorHash, pkg] as [LocatorHash, Package]; + }), + ), + ); // Now that the resolution is finished, we can finally insert the data // stored inside our pass stores into the resolution ones (we now have @@ -544,14 +550,12 @@ export class Project { for (const descriptorHash of haveBeenResolved) { const locator = passResolutions.get(descriptorHash); - if (!locator) - throw new Error(`Assertion failed: The locator should have been registered`); + if (!locator) throw new Error(`Assertion failed: The locator should have been registered`); allResolutions.set(descriptorHash, locator.locatorHash); const pkg = newPackages.get(locator.locatorHash); - if (!pkg) - continue; + if (!pkg) continue; allPackages.set(pkg.locatorHash, pkg); @@ -562,30 +566,26 @@ export class Project { // We must check and make sure that the descriptor didn't get aliased // to something else const aliasHash = this.resolutionAliases.get(descriptor.descriptorHash); - if (aliasHash === undefined) - continue; + if (aliasHash === undefined) continue; - // It doesn't cost us much to support the case where a descriptor is + // It doesn't cost us much to support the case where a descriptor is // equal to its own alias (which should mean "no alias") - if (descriptor.descriptorHash === aliasHash) - continue; + if (descriptor.descriptorHash === aliasHash) continue; - const alias = this.storedDescriptors.get(aliasHash); - if (!alias) - throw new Error(`Assertion failed: The alias should have been registered`); + const alias = this.storedDescriptors.get(aliasHash); + if (!alias) throw new Error(`Assertion failed: The alias should have been registered`); - // If it's already been "resolved" (in reality it will be the temporary + // If it's already been "resolved" (in reality it will be the temporary // resolution we've set in the next few lines) we simply must skip it - if (allResolutions.has(descriptor.descriptorHash)) - continue; + if (allResolutions.has(descriptor.descriptorHash)) continue; - // Temporarily set an invalid resolution so that it won't be resolved + // Temporarily set an invalid resolution so that it won't be resolved // multiple times if it is found multiple times in the dependency // tree (this is only temporary, we will replace it by the actual // resolution after we've finished resolving everything) allResolutions.set(descriptor.descriptorHash, `temporary` as LocatorHash); - // We can now replace the descriptor by its alias in the list of + // We can now replace the descriptor by its alias in the list of // descriptors that must be resolved mustBeResolved.delete(descriptor.descriptorHash); mustBeResolved.add(aliasHash); @@ -600,36 +600,32 @@ export class Project { // Each package that should have been resolved but was skipped because it // was aliased will now see the resolution for its alias propagated to it - while (haveBeenAliased.size > 0) { + while (haveBeenAliased.size > 0) { let hasChanged = false; - for (const descriptorHash of haveBeenAliased) { + for (const descriptorHash of haveBeenAliased) { const descriptor = allDescriptors.get(descriptorHash); - if (!descriptor) - throw new Error(`Assertion failed: The descriptor should have been registered`); + if (!descriptor) throw new Error(`Assertion failed: The descriptor should have been registered`); - const aliasHash = this.resolutionAliases.get(descriptorHash); - if (aliasHash === undefined) - throw new Error(`Assertion failed: The descriptor should have an alias`); + const aliasHash = this.resolutionAliases.get(descriptorHash); + if (aliasHash === undefined) throw new Error(`Assertion failed: The descriptor should have an alias`); - const resolution = allResolutions.get(aliasHash); - if (resolution === undefined) - throw new Error(`Assertion failed: The resolution should have been registered`); + const resolution = allResolutions.get(aliasHash); + if (resolution === undefined) throw new Error(`Assertion failed: The resolution should have been registered`); - // The following can happen if a package gets aliased to another package + // The following can happen if a package gets aliased to another package // that's itself aliased - in this case we just process all those we can // do, then make new passes until everything is resolved - if (resolution === `temporary`) - continue; + if (resolution === `temporary`) continue; - haveBeenAliased.delete(descriptorHash); + haveBeenAliased.delete(descriptorHash); - allResolutions.set(descriptorHash, resolution); + allResolutions.set(descriptorHash, resolution); - hasChanged = true; + hasChanged = true; } - if (!hasChanged) { + if (!hasChanged) { throw new Error(`Alias loop detected`); } } @@ -643,19 +639,20 @@ export class Project { const volatileDescriptors = new Set(this.resolutionAliases.values()); const resolvePeerDependencies = (parentLocator: Locator) => { - if (hasBeenTraversed.has(parentLocator.locatorHash)) - return; + if (hasBeenTraversed.has(parentLocator.locatorHash)) return; hasBeenTraversed.add(parentLocator.locatorHash); const parentPackage = allPackages.get(parentLocator.locatorHash); if (!parentPackage) - throw new Error(`Assertion failed: The package (${structUtils.prettyLocator(this.configuration, parentLocator)}) should have been registered`); + throw new Error( + `Assertion failed: The package (${structUtils.prettyLocator( + this.configuration, + parentLocator, + )}) should have been registered`, + ); - const subResolutions: Array<[ - Locator, - (() => void) | null - ]> = []; + const subResolutions: Array<[Locator, (() => void) | null]> = []; const firstPass = []; const secondPass = []; @@ -668,21 +665,29 @@ export class Project { // have peer dependencies themselves. for (const descriptor of Array.from(parentPackage.dependencies.values())) { - if (parentPackage.peerDependencies.has(descriptor.identHash)) - continue; + if (parentPackage.peerDependencies.has(descriptor.identHash)) continue; volatileDescriptors.delete(descriptor.descriptorHash); - if (descriptor.range === `missing:`) - continue; + if (descriptor.range === `missing:`) continue; const resolution = allResolutions.get(descriptor.descriptorHash); if (!resolution) - throw new Error(`Assertion failed: The resolution (${structUtils.prettyDescriptor(this.configuration, descriptor)}) should have been registered`); + throw new Error( + `Assertion failed: The resolution (${structUtils.prettyDescriptor( + this.configuration, + descriptor, + )}) should have been registered`, + ); const pkg = allPackages.get(resolution); if (!pkg) - throw new Error(`Assertion failed: The package (${resolution}, resolved from ${structUtils.prettyDescriptor(this.configuration, descriptor)}) should have been registered`); + throw new Error( + `Assertion failed: The package (${resolution}, resolved from ${structUtils.prettyDescriptor( + this.configuration, + descriptor, + )}) should have been registered`, + ); if (pkg.peerDependencies.size === 0) { resolvePeerDependencies(pkg); @@ -720,10 +725,21 @@ export class Project { if (!peerDescriptor) { if (!parentPackage.peerDependencies.has(peerRequest.identHash)) { - const peerDependencyMeta = virtualizedPackage.peerDependenciesMeta.get(structUtils.stringifyIdent(peerRequest)); + const peerDependencyMeta = virtualizedPackage.peerDependenciesMeta.get( + structUtils.stringifyIdent(peerRequest), + ); if (!peerDependencyMeta || !peerDependencyMeta.optional) { - report.reportWarning(MessageName.MISSING_PEER_DEPENDENCY, `${structUtils.prettyLocator(this.configuration, parentLocator)} doesn't provide ${structUtils.prettyDescriptor(this.configuration, peerRequest)} requested by ${structUtils.prettyLocator(this.configuration, pkg)}`); + report.reportWarning( + MessageName.MISSING_PEER_DEPENDENCY, + `${structUtils.prettyLocator( + this.configuration, + parentLocator, + )} doesn't provide ${structUtils.prettyDescriptor( + this.configuration, + peerRequest, + )} requested by ${structUtils.prettyLocator(this.configuration, pkg)}`, + ); } } @@ -738,9 +754,11 @@ export class Project { } // Since we've had to add new dependencies we need to sort them all over again - virtualizedPackage.dependencies = new Map(miscUtils.sortMap(virtualizedPackage.dependencies, ([identHash, descriptor]) => { - return structUtils.stringifyIdent(descriptor); - })); + virtualizedPackage.dependencies = new Map( + miscUtils.sortMap(virtualizedPackage.dependencies, ([identHash, descriptor]) => { + return structUtils.stringifyIdent(descriptor); + }), + ); }); thirdPass.push(() => { @@ -754,20 +772,14 @@ export class Project { }); } - const allPasses = [ - ... firstPass, - ... secondPass, - ... thirdPass, - ... fourthPass - ]; + const allPasses = [...firstPass, ...secondPass, ...thirdPass, ...fourthPass]; for (const fn of allPasses) { fn(); } }; - for (const workspace of this.workspaces) - resolvePeerDependencies(workspace.anchoredLocator); + for (const workspace of this.workspaces) resolvePeerDependencies(workspace.anchoredLocator); // All descriptors still referenced within the volatileDescriptors set are // descriptors that aren't depended upon by anything in the dependency tree. @@ -782,8 +794,7 @@ export class Project { for (const workspace of this.workspaces) { const pkg = allPackages.get(workspace.anchoredLocator.locatorHash); - if (!pkg) - throw new Error(`Assertion failed: Expected workspace to have been resolved`); + if (!pkg) throw new Error(`Assertion failed: Expected workspace to have been resolved`); workspace.dependencies = new Map(pkg.dependencies); } @@ -800,42 +811,44 @@ export class Project { const fetcher = userFetcher || this.configuration.makeFetcher(); const fetcherOptions = {checksums: this.storedChecksums, project: this, cache, fetcher, report}; - const locatorHashes = miscUtils.sortMap(this.storedResolutions.values(), [(locatorHash: LocatorHash) => { - const pkg = this.storedPackages.get(locatorHash); - if (!pkg) - throw new Error(`Assertion failed: The locator should have been registered`); + const locatorHashes = miscUtils.sortMap(this.storedResolutions.values(), [ + (locatorHash: LocatorHash) => { + const pkg = this.storedPackages.get(locatorHash); + if (!pkg) throw new Error(`Assertion failed: The locator should have been registered`); - return structUtils.stringifyLocator(pkg); - }]); + return structUtils.stringifyLocator(pkg); + }, + ]); const limit = pLimit(5); let firstError = false; - await Promise.all(locatorHashes.map(locatorHash => limit(async () => { - const pkg = this.storedPackages.get(locatorHash); - if (!pkg) - throw new Error(`Assertion failed: The locator should have been registered`); + await Promise.all( + locatorHashes.map(locatorHash => + limit(async () => { + const pkg = this.storedPackages.get(locatorHash); + if (!pkg) throw new Error(`Assertion failed: The locator should have been registered`); - let fetchResult; + let fetchResult; - try { - fetchResult = await fetcher.fetch(pkg, fetcherOptions); - } catch (error) { - error.message = `${structUtils.prettyLocator(this.configuration, pkg)}: ${error.message}`; - report.reportExceptionOnce(error); - firstError = error; - return; - } + try { + fetchResult = await fetcher.fetch(pkg, fetcherOptions); + } catch (error) { + error.message = `${structUtils.prettyLocator(this.configuration, pkg)}: ${error.message}`; + report.reportExceptionOnce(error); + firstError = error; + return; + } - if (fetchResult.checksum) - this.storedChecksums.set(pkg.locatorHash, fetchResult.checksum); - else - this.storedChecksums.delete(pkg.locatorHash); + if (fetchResult.checksum) this.storedChecksums.set(pkg.locatorHash, fetchResult.checksum); + else this.storedChecksums.delete(pkg.locatorHash); - if (fetchResult.releaseFs) { - fetchResult.releaseFs(); - } - }))); + if (fetchResult.releaseFs) { + fetchResult.releaseFs(); + } + }), + ), + ); if (firstError) { throw firstError; @@ -849,9 +862,11 @@ export class Project { const linkers = this.configuration.getLinkers(); const linkerOptions = {project: this, report}; - const installers = new Map(linkers.map(linker => { - return [linker, linker.makeInstaller(linkerOptions)] as [Linker, Installer]; - })); + const installers = new Map( + linkers.map(linker => { + return [linker, linker.makeInstaller(linkerOptions)] as [Linker, Installer]; + }), + ); const packageLinkers: Map = new Map(); const packageLocations: Map = new Map(); @@ -862,11 +877,13 @@ export class Project { for (const pkg of this.storedPackages.values()) { const linker = linkers.find(linker => linker.supportsPackage(pkg, linkerOptions)); if (!linker) - throw new ReportError(MessageName.LINKER_NOT_FOUND, `${structUtils.prettyLocator(this.configuration, pkg)} isn't supported by any available linker`); + throw new ReportError( + MessageName.LINKER_NOT_FOUND, + `${structUtils.prettyLocator(this.configuration, pkg)} isn't supported by any available linker`, + ); const installer = installers.get(linker); - if (!installer) - throw new Error(`Assertion failed: The installer should have been registered`); + if (!installer) throw new Error(`Assertion failed: The installer should have been registered`); const fetchResult = await fetcher.fetch(pkg, fetcherOptions); @@ -893,38 +910,55 @@ export class Project { for (const pkg of this.storedPackages.values()) { const packageLinker = packageLinkers.get(pkg.locatorHash); - if (!packageLinker) - throw new Error(`Assertion failed: The linker should have been found`); + if (!packageLinker) throw new Error(`Assertion failed: The linker should have been found`); const installer = installers.get(packageLinker); - if (!installer) - throw new Error(`Assertion failed: The installer should have been registered`); + if (!installer) throw new Error(`Assertion failed: The installer should have been registered`); const packageLocation = packageLocations.get(pkg.locatorHash); if (!packageLocation) - throw new Error(`Assertion failed: The package (${structUtils.prettyLocator(this.configuration, pkg)}) should have been registered`); + throw new Error( + `Assertion failed: The package (${structUtils.prettyLocator( + this.configuration, + pkg, + )}) should have been registered`, + ); const internalDependencies = []; for (const descriptor of pkg.dependencies.values()) { const resolution = this.storedResolutions.get(descriptor.descriptorHash); if (!resolution) - throw new Error(`Assertion failed: The resolution (${structUtils.prettyDescriptor(this.configuration, descriptor)}) should have been registered`); + throw new Error( + `Assertion failed: The resolution (${structUtils.prettyDescriptor( + this.configuration, + descriptor, + )}) should have been registered`, + ); const dependency = this.storedPackages.get(resolution); if (!dependency) - throw new Error(`Assertion failed: The package (${resolution}, resolved from ${structUtils.prettyDescriptor(this.configuration, descriptor)}) should have been registered`); + throw new Error( + `Assertion failed: The package (${resolution}, resolved from ${structUtils.prettyDescriptor( + this.configuration, + descriptor, + )}) should have been registered`, + ); const dependencyLinker = packageLinkers.get(resolution); if (!dependencyLinker) - throw new Error(`Assertion failed: The package (${resolution}, resolved from ${structUtils.prettyDescriptor(this.configuration, descriptor)}) should have been registered`); + throw new Error( + `Assertion failed: The package (${resolution}, resolved from ${structUtils.prettyDescriptor( + this.configuration, + descriptor, + )}) should have been registered`, + ); if (dependencyLinker === packageLinker) { internalDependencies.push(dependency); } else { let externalEntry = externalDependents.get(resolution); - if (!externalEntry) - externalDependents.set(resolution, externalEntry = []); + if (!externalEntry) externalDependents.set(resolution, (externalEntry = [])); externalEntry.push(packageLocation); } @@ -935,32 +969,27 @@ export class Project { for (const [locatorHash, dependentPaths] of externalDependents) { const pkg = this.storedPackages.get(locatorHash); - if (!pkg) - throw new Error(`Assertion failed: The package should have been registered`); + if (!pkg) throw new Error(`Assertion failed: The package should have been registered`); const packageLinker = packageLinkers.get(pkg.locatorHash); - if (!packageLinker) - throw new Error(`Assertion failed: The linker should have been found`); + if (!packageLinker) throw new Error(`Assertion failed: The linker should have been found`); const installer = installers.get(packageLinker); - if (!installer) - throw new Error(`Assertion failed: The installer should have been registered`); + if (!installer) throw new Error(`Assertion failed: The installer should have been registered`); await installer.attachExternalDependents(pkg, dependentPaths); } // Step 3: Inform our linkers that they should have all the info needed - for (const installer of installers.values()) - await installer.finalizeInstall(); + for (const installer of installers.values()) await installer.finalizeInstall(); // Step 4: Build the packages in multiple steps const readyPackages = new Set(this.storedPackages.keys()); const buildablePackages = new Set(packageBuildDirectives.keys()); - for (const locatorHash of buildablePackages) - readyPackages.delete(locatorHash); + for (const locatorHash of buildablePackages) readyPackages.delete(locatorHash); // We'll use this function is order to compute a hash for each package // that exposes a build directive. If the hash changes compared to the @@ -974,19 +1003,21 @@ export class Project { const traverse = (locatorHash: LocatorHash, seenPackages: Set = new Set()) => { hash.update(locatorHash); - if (!seenPackages.has(locatorHash)) - seenPackages.add(locatorHash); - else - return; + if (!seenPackages.has(locatorHash)) seenPackages.add(locatorHash); + else return; const pkg = this.storedPackages.get(locatorHash); - if (!pkg) - throw new Error(`Assertion failed: The package should have been registered`); + if (!pkg) throw new Error(`Assertion failed: The package should have been registered`); for (const dependency of pkg.dependencies.values()) { const resolution = this.storedResolutions.get(dependency.descriptorHash); if (!resolution) - throw new Error(`Assertion failed: The resolution (${structUtils.prettyDescriptor(this.configuration, dependency)}) should have been registered`); + throw new Error( + `Assertion failed: The resolution (${structUtils.prettyDescriptor( + this.configuration, + dependency, + )}) should have been registered`, + ); traverse(resolution, new Set(seenPackages)); } @@ -999,7 +1030,7 @@ export class Project { const bstatePath = this.configuration.get(`bstatePath`); const bstate = xfs.existsSync(bstatePath) - ? parseSyml(await xfs.readFilePromise(bstatePath, `utf8`)) as {[key: string]: string} + ? (parseSyml(await xfs.readFilePromise(bstatePath, `utf8`)) as {[key: string]: string}) : {}; while (buildablePackages.size > 0) { @@ -1008,14 +1039,18 @@ export class Project { for (const locatorHash of buildablePackages) { const pkg = this.storedPackages.get(locatorHash); - if (!pkg) - throw new Error(`Assertion failed: The package should have been registered`); + if (!pkg) throw new Error(`Assertion failed: The package should have been registered`); let isBuildable = true; for (const dependency of pkg.dependencies.values()) { const resolution = this.storedResolutions.get(dependency.descriptorHash); if (!resolution) - throw new Error(`Assertion failed: The resolution (${structUtils.prettyDescriptor(this.configuration, dependency)}) should have been registered`); + throw new Error( + `Assertion failed: The resolution (${structUtils.prettyDescriptor( + this.configuration, + dependency, + )}) should have been registered`, + ); if (buildablePackages.has(resolution)) { isBuildable = false; @@ -1025,8 +1060,7 @@ export class Project { // Wait until all dependencies of the current package have been built // before trying to build it (since it might need them to build itself) - if (!isBuildable) - continue; + if (!isBuildable) continue; buildablePackages.delete(locatorHash); @@ -1037,44 +1071,72 @@ export class Project { continue; if (Object.prototype.hasOwnProperty.call(bstate, pkg.locatorHash)) - report.reportInfo(MessageName.MUST_REBUILD, `${structUtils.prettyLocator(this.configuration, pkg)} must be rebuilt because its dependency tree changed`); + report.reportInfo( + MessageName.MUST_REBUILD, + `${structUtils.prettyLocator(this.configuration, pkg)} must be rebuilt because its dependency tree changed`, + ); else - report.reportInfo(MessageName.MUST_BUILD, `${structUtils.prettyLocator(this.configuration, pkg)} must be built because it never did before or the last one failed`); + report.reportInfo( + MessageName.MUST_BUILD, + `${structUtils.prettyLocator( + this.configuration, + pkg, + )} must be built because it never did before or the last one failed`, + ); const buildDirective = packageBuildDirectives.get(pkg.locatorHash); - if (!buildDirective) - throw new Error(`Assertion failed: The build directive should have been registered`); - - buildPromises.push((async () => { - for (const [buildType, scriptName] of buildDirective) { - const logFile = tmpNameSync({ - prefix: `buildfile-`, - postfix: `.log`, - }); - - const stdin = null; - const stdout = xfs.createWriteStream(logFile); - const stderr = stdout; - - stdout.write(`# This file contains the result of Yarn building a package (${structUtils.stringifyLocator(pkg)})\n`); - stdout.write(`\n`); - - let exitCode; - - if (buildType === BuildType.SCRIPT) - exitCode = await scriptUtils.executePackageScript(pkg, scriptName, [], {project: this, stdin, stdout, stderr}); - else if (buildType === BuildType.SHELLCODE) - exitCode = await scriptUtils.executePackageShellcode(pkg, scriptName, [], {project: this, stdin, stdout, stderr}); - - if (exitCode === 0) { - bstate[pkg.locatorHash] = buildHash; - } else { - report.reportError(MessageName.BUILD_FAILED, `${structUtils.prettyLocator(this.configuration, pkg)} couldn't be built successfully (exit code ${exitCode}, logs can be found here: ${logFile})`); - delete bstate[pkg.locatorHash]; - break; + if (!buildDirective) throw new Error(`Assertion failed: The build directive should have been registered`); + + buildPromises.push( + (async () => { + for (const [buildType, scriptName] of buildDirective) { + const logFile = tmpNameSync({ + prefix: `buildfile-`, + postfix: `.log`, + }); + + const stdin = null; + const stdout = xfs.createWriteStream(logFile); + const stderr = stdout; + + stdout.write( + `# This file contains the result of Yarn building a package (${structUtils.stringifyLocator(pkg)})\n`, + ); + stdout.write(`\n`); + + let exitCode; + + if (buildType === BuildType.SCRIPT) + exitCode = await scriptUtils.executePackageScript(pkg, scriptName, [], { + project: this, + stdin, + stdout, + stderr, + }); + else if (buildType === BuildType.SHELLCODE) + exitCode = await scriptUtils.executePackageShellcode(pkg, scriptName, [], { + project: this, + stdin, + stdout, + stderr, + }); + + if (exitCode === 0) { + bstate[pkg.locatorHash] = buildHash; + } else { + report.reportError( + MessageName.BUILD_FAILED, + `${structUtils.prettyLocator( + this.configuration, + pkg, + )} couldn't be built successfully (exit code ${exitCode}, logs can be found here: ${logFile})`, + ); + delete bstate[pkg.locatorHash]; + break; + } } - } - })()); + })(), + ); } await Promise.all(buildPromises); @@ -1084,15 +1146,19 @@ export class Project { // build scripts, making them unsatisfiable. if (savedSize === buildablePackages.size) { - const prettyLocators = Array.from(buildablePackages).map(locatorHash => { - const pkg = this.storedPackages.get(locatorHash); - if (!pkg) - throw new Error(`Assertion failed: The package should have been registered`); - - return structUtils.prettyLocator(this.configuration, pkg); - }).join(`, `); - - report.reportError(MessageName.CYCLIC_DEPENDENCIES, `Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${prettyLocators})`); + const prettyLocators = Array.from(buildablePackages) + .map(locatorHash => { + const pkg = this.storedPackages.get(locatorHash); + if (!pkg) throw new Error(`Assertion failed: The package should have been registered`); + + return structUtils.prettyLocator(this.configuration, pkg); + }) + .join(`, `); + + report.reportError( + MessageName.CYCLIC_DEPENDENCIES, + `Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${prettyLocators})`, + ); break; } } @@ -1109,13 +1175,15 @@ export class Project { const initialLockfile = opts.frozenLockfile ? this.generateLockfile() : null; // Ensures that we notice it when dependencies are added / removed from all sources coming from the filesystem - if (!opts.lockfileOnly) - await this.forgetTransientResolutions(); + if (!opts.lockfileOnly) await this.forgetTransientResolutions(); await this.resolveEverything(opts); if (opts.frozenLockfile && this.generateLockfile() !== initialLockfile) { - throw new ReportError(MessageName.FROZEN_LOCKFILE_EXCEPTION, `The lockfile would have been modified by this install, which is explicitly forbidden`); + throw new ReportError( + MessageName.FROZEN_LOCKFILE_EXCEPTION, + `The lockfile would have been modified by this install, which is explicitly forbidden`, + ); } }); @@ -1143,8 +1211,7 @@ export class Project { for (const [descriptorHash, locatorHash] of this.storedResolutions.entries()) { let descriptorHashes = reverseLookup.get(locatorHash); - if (!descriptorHashes) - reverseLookup.set(locatorHash, descriptorHashes = new Set()); + if (!descriptorHashes) reverseLookup.set(locatorHash, (descriptorHashes = new Set())); descriptorHashes.add(descriptorHash); } @@ -1157,8 +1224,7 @@ export class Project { for (const [locatorHash, descriptorHashes] of reverseLookup.entries()) { const pkg = this.storedPackages.get(locatorHash); - if (!pkg) - throw new Error(`Assertion failed: The package should have been registered`); + if (!pkg) throw new Error(`Assertion failed: The package should have been registered`); // Virtual packages are not persisted into the lockfile: they need to be // recomputed at runtime through "resolveEverything". We do this (instead @@ -1166,22 +1232,23 @@ export class Project { // or workspaces) because it would otherwise be super annoying to manually // change the resolutions from a lockfile (since you'd need to also update // all its virtual instances). Also it would take a bunch of useless space. - if (structUtils.isVirtualLocator(pkg)) - continue; + if (structUtils.isVirtualLocator(pkg)) continue; const descriptors = []; for (const descriptorHash of descriptorHashes) { const descriptor = this.storedDescriptors.get(descriptorHash); - if (!descriptor) - throw new Error(`Assertion failed: The descriptor should have been registered`); + if (!descriptor) throw new Error(`Assertion failed: The descriptor should have been registered`); descriptors.push(descriptor); } - const key = descriptors.map(descriptor => { - return structUtils.stringifyDescriptor(descriptor); - }).sort().join(`, `); + const key = descriptors + .map(descriptor => { + return structUtils.stringifyDescriptor(descriptor); + }) + .sort() + .join(`, `); const manifest = new Manifest(); @@ -1203,24 +1270,25 @@ export class Project { const serialized = (() => { // Remove the fields we're not interested in to only keep the ones we want - const {identHash, scope, name, locatorHash, reference, dependencies, peerDependencies, ... rest} = pkg; + const {identHash, scope, name, locatorHash, reference, dependencies, peerDependencies, ...rest} = pkg; return rest; })(); manifest.exportTo(serialized); optimizedLockfile[key] = { - ... serialized, + ...serialized, resolution: structUtils.stringifyLocator(pkg), checksum: this.storedChecksums.get(pkg.locatorHash), }; } - const header = [ - `# This file is generated by running "berry install" inside your project.\n`, - `# Manual changes might be lost - proceed with caution!\n` - ].join(``) + `\n`; + const header = + [ + `# This file is generated by running "berry install" inside your project.\n`, + `# Manual changes might be lost - proceed with caution!\n`, + ].join(``) + `\n`; return header + stringifySyml(optimizedLockfile); } diff --git a/packages/berry-core/sources/Resolver.ts b/packages/berry-core/sources/Resolver.ts index 82c68956576b..23d3ec844554 100644 --- a/packages/berry-core/sources/Resolver.ts +++ b/packages/berry-core/sources/Resolver.ts @@ -1,39 +1,37 @@ -import {FetchOptions} from './Fetcher'; -import {Project} from './Project'; +import {FetchOptions} from './Fetcher'; +import {Project} from './Project'; import {Descriptor, Locator, Package} from './types'; export type MinimalResolveOptions = { - project: Project, - resolver: Resolver, + project: Project; + resolver: Resolver; }; -export type ResolveOptions = - MinimalResolveOptions & - FetchOptions; +export type ResolveOptions = MinimalResolveOptions & FetchOptions; /** * Resolvers are the components that do all the lifting needed in order to * produce a lockfile. In clear, they transfom the following: - * + * * webpack@^4.0.0 - * + * * into this: - * + * * webpack@4.28.0 | dependencies: ajv@^6.1.0, ajv-keyword@^3.1.0, ... - * + * * In order to do this, they have three different data structures used to * represents the various states of the package resolution: - * + * * - **Descriptors** contain a package name and a range (for example, using * the previous example, "^4.0.0" would be the range). This range might * point to multiple possible resolutions, so a descriptor alone isn't * enough to fetch the package data from its remote location. - * + * * - **Locators** contain a package name and a reference that is used to * both uniquely identify a package and fetch it from its remote location. * To keep using the same example, "4.28.0" would be the reference. Note * that locators have a funny property: they also are valid descriptors! - * + * * - **Packages** are locators that made it big. While locators are quite * small, package definitions are relatively fat and contain much more * information than their cousins - for example the dependency list of the @@ -45,7 +43,7 @@ export interface Resolver { * This function must return true if the specified descriptor is meant to be * turned into a locator by this resolver. The other functions (except its * locator counterpart) won't be called if it returns false. - * + * * @param descriptor The descriptor that needs to be validated. * @param opts The resolution options. */ @@ -55,7 +53,7 @@ export interface Resolver { * This function must return true if the specified locator is meant to be * turned into a package definition by this resolver. The other functions * (except its locator counterpart) won't be called if it returns false. - * + * * @param locator The locator that needs to be validated. * @param opts The resolution options. */ @@ -66,12 +64,12 @@ export interface Resolver { * locator must be kept between installs. You typically want to return true * for all packages that are cached, but return false for all packages that * hydrate packages directly from the filesystem (for example workspaces). - * + * * Note that even packages returning false are stored within the lockfile! * The difference is that when a new install is done, all package definitions * that return false will be discarded and resolved again (their potential * cache data will be kept, though). - * + * * @param locator The queried package. * @param opts The resolution options. */ @@ -80,18 +78,18 @@ export interface Resolver { /** * This function is called for each dependency present in the dependency list * of a package definition. If it returns a new descriptor, this new - * descriptor will be used - * + * descriptor will be used + * * Note that `fromLocator` is not necessarily a locator that's supported by * the resolver. It simply is the locator of the package that depends on the * specified descriptor, regardless who owns it. - * + * * A typical case where you will want to use this function is when your * resolver must support relative paths (for example the `link:` protocol). * In this situation, you'll want to store the `fromLocator` in the bound * descriptor in order to be able to access the right location during the * next steps of the resolution. - * + * * @param descriptor The depended descriptor. * @param fromLocator The dependent locator. * @param opts The resolution options. @@ -101,11 +99,11 @@ export interface Resolver { /** * This function will, given a descriptor, return the list of locators that * potentially satisfy it. - * + * * The returned array must be sorted in such a way that the preferred * locators are first. This will cause the resolution algorithm to prioritize - * them if possible (it doesn't guarantee that they'll end up being used). - * + * them if possible (it doesn't guarantee that they'll end up being used). + * * @param descriptor The source descriptor. * @param opts The resolution options. */ @@ -114,7 +112,7 @@ export interface Resolver { /** * This function will, given a locator, return the full package definition * for the package pointed at. - * + * * @param locator The source locator. * @param opts The resolution options. */ diff --git a/packages/berry-core/sources/RunInstallPleaseResolver.ts b/packages/berry-core/sources/RunInstallPleaseResolver.ts index 534974715cc7..2b8bc2605260 100644 --- a/packages/berry-core/sources/RunInstallPleaseResolver.ts +++ b/packages/berry-core/sources/RunInstallPleaseResolver.ts @@ -1,7 +1,7 @@ -import {MessageName, ReportError} from './Report'; +import {MessageName, ReportError} from './Report'; import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {Descriptor, Locator} from './types'; +import * as structUtils from './structUtils'; +import {Descriptor, Locator} from './types'; export class RunInstallPleaseResolver implements Resolver { private readonly resolver: Resolver; @@ -23,11 +23,20 @@ export class RunInstallPleaseResolver implements Resolver { } bindDescriptor(descriptor: Descriptor, fromLocator: Locator, opts: MinimalResolveOptions): never { - throw new ReportError(MessageName.MISSING_LOCKFILE_ENTRY, `A dependency (${structUtils.prettyDescriptor(opts.project.configuration, descriptor)}) cannot be retrieved from the lockfile; try to make an install to update your resolutions`); + throw new ReportError( + MessageName.MISSING_LOCKFILE_ENTRY, + `A dependency (${structUtils.prettyDescriptor( + opts.project.configuration, + descriptor, + )}) cannot be retrieved from the lockfile; try to make an install to update your resolutions`, + ); } async getCandidates(descriptor: Descriptor, opts: ResolveOptions): Promise { - throw new ReportError(MessageName.MISSING_LOCKFILE_ENTRY, `This package doesn't seem to be present in your lockfile; try to make an install to update your resolutions`); + throw new ReportError( + MessageName.MISSING_LOCKFILE_ENTRY, + `This package doesn't seem to be present in your lockfile; try to make an install to update your resolutions`, + ); } async resolve(locator: Locator, opts: ResolveOptions): Promise { diff --git a/packages/berry-core/sources/SemverResolver.ts b/packages/berry-core/sources/SemverResolver.ts index 713f59f47baa..937f2e688376 100644 --- a/packages/berry-core/sources/SemverResolver.ts +++ b/packages/berry-core/sources/SemverResolver.ts @@ -1,20 +1,18 @@ -import semver from 'semver'; +import semver from 'semver'; import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {Descriptor, Locator} from './types'; +import * as structUtils from './structUtils'; +import {Descriptor, Locator} from './types'; export class SemverResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!semver.validRange(descriptor.range)) - return false; + if (!semver.validRange(descriptor.range)) return false; return true; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!semver.valid(locator.reference)) - return false; + if (!semver.valid(locator.reference)) return false; return true; } @@ -38,7 +36,10 @@ export class SemverResolver implements Resolver { } private forwardDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - return structUtils.makeDescriptor(descriptor, `${opts.project.configuration.get(`defaultProtocol`)}${descriptor.range}`); + return structUtils.makeDescriptor( + descriptor, + `${opts.project.configuration.get(`defaultProtocol`)}${descriptor.range}`, + ); } private forwardLocator(locator: Locator, opts: MinimalResolveOptions) { diff --git a/packages/berry-core/sources/StreamReport.ts b/packages/berry-core/sources/StreamReport.ts index 770a1b0ba016..8a743e7142f4 100644 --- a/packages/berry-core/sources/StreamReport.ts +++ b/packages/berry-core/sources/StreamReport.ts @@ -1,13 +1,13 @@ -import {Writable} from 'stream'; +import {Writable} from 'stream'; -import {Configuration} from './Configuration'; +import {Configuration} from './Configuration'; import {Report, MessageName} from './Report'; -import {Locator} from './types'; +import {Locator} from './types'; export type StreamReportOptions = { - configuration: Configuration, - json?: boolean, - stdout: Writable, + configuration: Configuration; + json?: boolean; + stdout: Writable; }; export class StreamReport extends Report { @@ -26,7 +26,7 @@ export class StreamReport extends Report { } private configuration: Configuration; - private json: boolean; + private json: boolean; private stdout: Writable; private cacheHitCount: number = 0; @@ -111,7 +111,9 @@ export class StreamReport extends Report { reportInfo(name: MessageName, text: string) { if (!this.json) { - this.stdout.write(`${this.configuration.format(`➤`, `blueBright`)} ${this.formatName(name)}: ${this.formatIndent()}${text}\n`); + this.stdout.write( + `${this.configuration.format(`➤`, `blueBright`)} ${this.formatName(name)}: ${this.formatIndent()}${text}\n`, + ); } } @@ -119,14 +121,18 @@ export class StreamReport extends Report { this.warningCount += 1; if (!this.json) { - this.stdout.write(`${this.configuration.format(`➤`, `yellowBright`)} ${this.formatName(name)}: ${this.formatIndent()}${text}\n`); + this.stdout.write( + `${this.configuration.format(`➤`, `yellowBright`)} ${this.formatName(name)}: ${this.formatIndent()}${text}\n`, + ); } } reportError(name: MessageName, text: string) { this.errorCount += 1; - this.stdout.write(`${this.configuration.format(`➤`, `redBright`)} ${this.formatName(name)}: ${this.formatIndent()}${text}\n`); + this.stdout.write( + `${this.configuration.format(`➤`, `redBright`)} ${this.formatName(name)}: ${this.formatIndent()}${text}\n`, + ); } reportJson(data: any) { @@ -138,19 +144,14 @@ export class StreamReport extends Report { async finalize() { let installStatus = ``; - if (this.errorCount > 0) - installStatus = `Failed with errors`; - else if (this.warningCount > 0) - installStatus = `Done with warnings`; - else - installStatus = `Done`; + if (this.errorCount > 0) installStatus = `Failed with errors`; + else if (this.warningCount > 0) installStatus = `Done with warnings`; + else installStatus = `Done`; let fetchStatus = ``; - if (this.cacheHitCount > 1) - fetchStatus += ` - ${this.cacheHitCount} packages were already cached`; - else if (this.cacheHitCount === 1) - fetchStatus += ` - one package was already cached`; + if (this.cacheHitCount > 1) fetchStatus += ` - ${this.cacheHitCount} packages were already cached`; + else if (this.cacheHitCount === 1) fetchStatus += ` - one package was already cached`; if (this.cacheHitCount > 0) { if (this.cacheMissCount > 1) { @@ -181,9 +182,7 @@ export class StreamReport extends Report { } private formatTiming(timing: number) { - return timing < 60 * 1000 - ? `${Math.round(timing / 10) / 100}s` - : `${Math.round(timing / 600) / 100}m`; + return timing < 60 * 1000 ? `${Math.round(timing / 10) / 100}s` : `${Math.round(timing / 600) / 100}m`; } private formatName(name: MessageName) { diff --git a/packages/berry-core/sources/TagResolver.ts b/packages/berry-core/sources/TagResolver.ts index c8b72079ba9b..1c43b36beb3c 100644 --- a/packages/berry-core/sources/TagResolver.ts +++ b/packages/berry-core/sources/TagResolver.ts @@ -1,20 +1,18 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {Descriptor, Locator} from './types'; +import * as structUtils from './structUtils'; +import {Descriptor, Locator} from './types'; export const TAG_REGEXP = /^[a-z]+$/; export class TagResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!TAG_REGEXP.test(descriptor.range)) - return false; + if (!TAG_REGEXP.test(descriptor.range)) return false; return true; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!TAG_REGEXP.test(locator.reference)) - return false; + if (!TAG_REGEXP.test(locator.reference)) return false; return true; } @@ -38,7 +36,10 @@ export class TagResolver implements Resolver { } private forwardDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - return structUtils.makeDescriptor(descriptor, `${opts.project.configuration.get(`defaultProtocol`)}${descriptor.range}`); + return structUtils.makeDescriptor( + descriptor, + `${opts.project.configuration.get(`defaultProtocol`)}${descriptor.range}`, + ); } private forwardLocator(locator: Locator, opts: MinimalResolveOptions) { diff --git a/packages/berry-core/sources/ThrowReport.ts b/packages/berry-core/sources/ThrowReport.ts index a3f85de8e610..cf3795692cfe 100644 --- a/packages/berry-core/sources/ThrowReport.ts +++ b/packages/berry-core/sources/ThrowReport.ts @@ -1,12 +1,10 @@ import {Report, MessageName} from './Report'; -import {Locator} from './types'; +import {Locator} from './types'; export class ThrowReport extends Report { - reportCacheHit(locator: Locator) { - } + reportCacheHit(locator: Locator) {} - reportCacheMiss(locator: Locator) { - } + reportCacheMiss(locator: Locator) {} startTimerSync(what: string, cb: () => T) { return cb(); @@ -16,19 +14,15 @@ export class ThrowReport extends Report { return await cb(); } - reportInfo(name: MessageName, text: string) { - } + reportInfo(name: MessageName, text: string) {} - reportWarning(name: MessageName, text: string) { - } + reportWarning(name: MessageName, text: string) {} - reportError(name: MessageName, text: string) { - } + reportError(name: MessageName, text: string) {} reportJson(data: any) { // Just ignore the json output } - async finalize() { - } + async finalize() {} } diff --git a/packages/berry-core/sources/VirtualFetcher.ts b/packages/berry-core/sources/VirtualFetcher.ts index d7d6d9b97f79..61345c86e073 100644 --- a/packages/berry-core/sources/VirtualFetcher.ts +++ b/packages/berry-core/sources/VirtualFetcher.ts @@ -1,15 +1,14 @@ -import {AliasFS, NodeFS, xfs} from '@berry/fslib'; -import {posix, win32} from 'path'; +import {AliasFS, NodeFS, xfs} from '@berry/fslib'; +import {posix, win32} from 'path'; import {Fetcher, FetchOptions, FetchResult, MinimalFetchOptions} from './Fetcher'; -import {MessageName, ReportError} from './Report'; -import * as structUtils from './structUtils'; -import {Locator} from './types'; +import {MessageName, ReportError} from './Report'; +import * as structUtils from './structUtils'; +import {Locator} from './types'; export class VirtualFetcher implements Fetcher { supports(locator: Locator) { - if (!locator.reference.startsWith(`virtual:`)) - return false; + if (!locator.reference.startsWith(`virtual:`)) return false; return true; } @@ -17,8 +16,7 @@ export class VirtualFetcher implements Fetcher { getLocalPath(locator: Locator, opts: FetchOptions) { const splitPoint = locator.reference.indexOf(`#`); - if (splitPoint === -1) - throw new Error(`Invalid virtual package reference`); + if (splitPoint === -1) throw new Error(`Invalid virtual package reference`); const nextReference = locator.reference.slice(splitPoint + 1); const nextLocator = structUtils.makeLocator(locator, nextReference); @@ -29,8 +27,7 @@ export class VirtualFetcher implements Fetcher { async fetch(locator: Locator, opts: FetchOptions) { const splitPoint = locator.reference.indexOf(`#`); - if (splitPoint === -1) - throw new Error(`Invalid virtual package reference`); + if (splitPoint === -1) throw new Error(`Invalid virtual package reference`); const nextReference = locator.reference.slice(splitPoint + 1); const nextLocator = structUtils.makeLocator(locator, nextReference); @@ -67,7 +64,12 @@ export class VirtualFetcher implements Fetcher { if (opts.project.configuration.get(`enableAbsoluteVirtuals`)) { target = to; } else { - throw new ReportError(MessageName.CROSS_DRIVE_VIRTUAL_LOCAL, `The virtual folder (${fromParse.root}) must be on the same drive as the local package it references (${toParse.root})`); + throw new ReportError( + MessageName.CROSS_DRIVE_VIRTUAL_LOCAL, + `The virtual folder (${fromParse.root}) must be on the same drive as the local package it references (${ + toParse.root + })`, + ); } } } @@ -94,8 +96,8 @@ export class VirtualFetcher implements Fetcher { }); return { - ... sourceFetch, - packageFs: new AliasFS(virtualPath, {baseFs: sourceFetch.packageFs}) + ...sourceFetch, + packageFs: new AliasFS(virtualPath, {baseFs: sourceFetch.packageFs}), }; } } diff --git a/packages/berry-core/sources/VirtualResolver.ts b/packages/berry-core/sources/VirtualResolver.ts index 1809f98a2b0c..589df13f74ff 100644 --- a/packages/berry-core/sources/VirtualResolver.ts +++ b/packages/berry-core/sources/VirtualResolver.ts @@ -1,20 +1,18 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {Descriptor, Locator} from './types'; +import * as structUtils from './structUtils'; +import {Descriptor, Locator} from './types'; export class VirtualResolver implements Resolver { static protocol = `virtual:`; static isVirtualDescriptor(descriptor: Descriptor) { - if (!descriptor.range.startsWith(VirtualResolver.protocol)) - return false; + if (!descriptor.range.startsWith(VirtualResolver.protocol)) return false; return true; } static isVirtualLocator(locator: Locator) { - if (!locator.reference.startsWith(VirtualResolver.protocol)) - return false; + if (!locator.reference.startsWith(VirtualResolver.protocol)) return false; return true; } diff --git a/packages/berry-core/sources/Workspace.ts b/packages/berry-core/sources/Workspace.ts index 438eb4c304f0..720d3de9a979 100644 --- a/packages/berry-core/sources/Workspace.ts +++ b/packages/berry-core/sources/Workspace.ts @@ -1,19 +1,22 @@ -import {xfs, NodeFS} from '@berry/fslib'; -import {makeUpdater} from '@berry/json-proxy'; -import {createHmac} from 'crypto'; -import globby from 'globby'; -import {posix} from 'path'; -import semver from 'semver'; - -import {Manifest} from './Manifest'; -import {Project} from './Project'; -import {WorkspaceResolver} from './WorkspaceResolver'; -import * as structUtils from './structUtils'; -import {IdentHash} from './types'; -import {Descriptor, Locator} from './types'; +import {xfs, NodeFS} from '@berry/fslib'; +import {makeUpdater} from '@berry/json-proxy'; +import {createHmac} from 'crypto'; +import globby from 'globby'; +import {posix} from 'path'; +import semver from 'semver'; + +import {Manifest} from './Manifest'; +import {Project} from './Project'; +import {WorkspaceResolver} from './WorkspaceResolver'; +import * as structUtils from './structUtils'; +import {IdentHash} from './types'; +import {Descriptor, Locator} from './types'; function hashWorkspaceCwd(cwd: string) { - return createHmac('sha256', 'berry').update(cwd).digest('hex').substr(0, 6); + return createHmac('sha256', 'berry') + .update(cwd) + .digest('hex') + .substr(0, 6); } export class Workspace { @@ -54,14 +57,19 @@ export class Workspace { // @ts-ignore: It's ok to initialize it now, even if it's readonly (setup is called right after construction) this.relativeCwd = posix.relative(this.project.cwd, this.cwd) || `.`; - const ident = this.manifest.name ? this.manifest.name : structUtils.makeIdent(null, `${this.computeCandidateName()}-${hashWorkspaceCwd(this.relativeCwd)}`); + const ident = this.manifest.name + ? this.manifest.name + : structUtils.makeIdent(null, `${this.computeCandidateName()}-${hashWorkspaceCwd(this.relativeCwd)}`); const reference = this.manifest.version ? this.manifest.version : `0.0.0`; // @ts-ignore: It's ok to initialize it now, even if it's readonly (setup is called right after construction) this.locator = structUtils.makeLocator(ident, reference); // @ts-ignore: It's ok to initialize it now, even if it's readonly (setup is called right after construction) - this.anchoredDescriptor = structUtils.makeDescriptor(this.locator, `${WorkspaceResolver.protocol}${this.relativeCwd}`); + this.anchoredDescriptor = structUtils.makeDescriptor( + this.locator, + `${WorkspaceResolver.protocol}${this.relativeCwd}`, + ); // @ts-ignore: It's ok to initialize it now, even if it's readonly (setup is called right after construction) this.anchoredLocator = structUtils.makeLocator(this.locator, `${WorkspaceResolver.protocol}${this.relativeCwd}`); @@ -91,25 +99,18 @@ export class Workspace { accepts(range: string) { const protocolIndex = range.indexOf(`:`); - const protocol = protocolIndex !== -1 - ? range.slice(0, protocolIndex + 1) - : null; + const protocol = protocolIndex !== -1 ? range.slice(0, protocolIndex + 1) : null; - const pathname = protocolIndex !== -1 - ? range.slice(protocolIndex + 1) - : range; + const pathname = protocolIndex !== -1 ? range.slice(protocolIndex + 1) : range; - if (protocol === WorkspaceResolver.protocol && pathname === this.relativeCwd) - return true; + if (protocol === WorkspaceResolver.protocol && pathname === this.relativeCwd) return true; - if (!semver.validRange(pathname)) - return false; + if (!semver.validRange(pathname)) return false; if (protocol === WorkspaceResolver.protocol) return semver.satisfies(this.manifest.version !== null ? this.manifest.version : `0.0.0`, pathname); - if (this.manifest.version !== null) - return semver.satisfies(this.manifest.version, pathname); + if (this.manifest.version !== null) return semver.satisfies(this.manifest.version, pathname); return false; } diff --git a/packages/berry-core/sources/WorkspaceFetcher.ts b/packages/berry-core/sources/WorkspaceFetcher.ts index 6c201227bde5..abfd571ea52c 100644 --- a/packages/berry-core/sources/WorkspaceFetcher.ts +++ b/packages/berry-core/sources/WorkspaceFetcher.ts @@ -1,13 +1,12 @@ -import {JailFS} from '@berry/fslib'; +import {JailFS} from '@berry/fslib'; import {Fetcher, FetchOptions, FetchResult} from './Fetcher'; -import {WorkspaceResolver} from './WorkspaceResolver'; -import {Locator} from './types'; +import {WorkspaceResolver} from './WorkspaceResolver'; +import {Locator} from './types'; export class WorkspaceFetcher implements Fetcher { supports(locator: Locator) { - if (!locator.reference.startsWith(WorkspaceResolver.protocol)) - return false; + if (!locator.reference.startsWith(WorkspaceResolver.protocol)) return false; return true; } diff --git a/packages/berry-core/sources/WorkspaceResolver.ts b/packages/berry-core/sources/WorkspaceResolver.ts index eb118ff182f8..5dee8febdbc8 100644 --- a/packages/berry-core/sources/WorkspaceResolver.ts +++ b/packages/berry-core/sources/WorkspaceResolver.ts @@ -1,25 +1,22 @@ -import {ReportError, MessageName} from './Report'; +import {ReportError, MessageName} from './Report'; import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import {Descriptor, Locator} from './types'; -import {LinkType} from './types'; +import {Descriptor, Locator} from './types'; +import {LinkType} from './types'; export class WorkspaceResolver implements Resolver { static protocol = `workspace:`; supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (descriptor.range.startsWith(WorkspaceResolver.protocol)) - return true; + if (descriptor.range.startsWith(WorkspaceResolver.protocol)) return true; const matchingWorkspaces = opts.project.findWorkspacesByDescriptor(descriptor); - if (matchingWorkspaces.length > 0) - return true; + if (matchingWorkspaces.length > 0) return true; return false; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!locator.reference.startsWith(WorkspaceResolver.protocol)) - return false; + if (!locator.reference.startsWith(WorkspaceResolver.protocol)) return false; return true; } @@ -42,9 +39,12 @@ export class WorkspaceResolver implements Resolver { throw new ReportError(MessageName.WORKSPACE_NOT_FOUND, `No local workspace found for this range`); } } - + if (candidateWorkspaces.length > 1) - throw new ReportError(MessageName.TOO_MANY_MATCHING_WORKSPACES, `Too many workspaces match this range, please disambiguate`); + throw new ReportError( + MessageName.TOO_MANY_MATCHING_WORKSPACES, + `Too many workspaces match this range, please disambiguate`, + ); return [candidateWorkspaces[0].anchoredLocator]; } @@ -53,15 +53,15 @@ export class WorkspaceResolver implements Resolver { const workspace = opts.project.getWorkspaceByCwd(locator.reference.slice(WorkspaceResolver.protocol.length)); return { - ... locator, + ...locator, version: workspace.manifest.version || `0.0.0`, languageName: `unknown`, linkType: LinkType.SOFT, - dependencies: new Map([... workspace.manifest.dependencies, ... workspace.manifest.devDependencies]), - peerDependencies: new Map([... workspace.manifest.peerDependencies]), + dependencies: new Map([...workspace.manifest.dependencies, ...workspace.manifest.devDependencies]), + peerDependencies: new Map([...workspace.manifest.peerDependencies]), dependenciesMeta: workspace.manifest.dependenciesMeta, peerDependenciesMeta: workspace.manifest.peerDependenciesMeta, diff --git a/packages/berry-core/sources/YarnResolver.ts b/packages/berry-core/sources/YarnResolver.ts index 08609adc3546..d84dcb9e6971 100644 --- a/packages/berry-core/sources/YarnResolver.ts +++ b/packages/berry-core/sources/YarnResolver.ts @@ -1,13 +1,13 @@ -import {xfs} from '@berry/fslib'; -import {parseSyml} from '@berry/parsers'; +import {xfs} from '@berry/fslib'; +import {parseSyml} from '@berry/parsers'; -import {Project} from './Project'; -import {MessageName, Report} from './Report'; +import {Project} from './Project'; +import {MessageName, Report} from './Report'; import {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -import * as structUtils from './structUtils'; -import {DescriptorHash, Descriptor, Locator} from './types'; +import * as structUtils from './structUtils'; +import {DescriptorHash, Descriptor, Locator} from './types'; -const IMPORTED_PATTERNS: Array<[RegExp, (version: string, ... args: Array) => string]> = [ +const IMPORTED_PATTERNS: Array<[RegExp, (version: string, ...args: Array) => string]> = [ // This one come from Git urls [/^git\+https:\/\/.*\.git#.*$/, (version, $0) => $0], // These ones come from the npm registry @@ -18,31 +18,32 @@ const IMPORTED_PATTERNS: Array<[RegExp, (version: string, ... args: Array | null = null; - + async setup(project: Project, {report}: {report: Report}) { const lockfilePath = `${project.cwd}/${project.configuration.get(`lockfileFilename`)}`; // No need to enable it if the lockfile doesn't exist - if (!xfs.existsSync(lockfilePath)) - return; + if (!xfs.existsSync(lockfilePath)) return; const content = await xfs.readFilePromise(lockfilePath, `utf8`); const parsed = parseSyml(content); // No need to enable it either if the lockfile is modern - if (Object.prototype.hasOwnProperty.call(parsed, `__metadata`)) - return; + if (Object.prototype.hasOwnProperty.call(parsed, `__metadata`)) return; - const resolutions = this.resolutions = new Map(); + const resolutions = (this.resolutions = new Map()); for (const key of Object.keys(parsed)) { const descriptor = structUtils.tryParseDescriptor(key); - + if (!descriptor) { - report.reportWarning(MessageName.YARN_IMPORT_FAILED, `Failed to parse the string "${key}" into a proper descriptor`); + report.reportWarning( + MessageName.YARN_IMPORT_FAILED, + `Failed to parse the string "${key}" into a proper descriptor`, + ); continue; } - + const {version, resolved} = (parsed as any)[key]; let reference; @@ -50,24 +51,29 @@ export class YarnResolver implements Resolver { const match = resolved.match(pattern); if (match) { - reference = matcher(version, ... match); + reference = matcher(version, ...match); break; } } - + if (!reference) { - report.reportWarning(MessageName.YARN_IMPORT_FAILED, `${structUtils.prettyDescriptor(project.configuration, descriptor)}: Only some patterns can be imported from legacy lockfiles (not "${resolved}")`); + report.reportWarning( + MessageName.YARN_IMPORT_FAILED, + `${structUtils.prettyDescriptor( + project.configuration, + descriptor, + )}: Only some patterns can be imported from legacy lockfiles (not "${resolved}")`, + ); continue; } - + const resolution = structUtils.makeLocator(descriptor, reference); resolutions.set(descriptor.descriptorHash, resolution); } } - + supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!this.resolutions) - return false; + if (!this.resolutions) return false; return this.resolutions.has(descriptor.descriptorHash); } @@ -87,12 +93,10 @@ export class YarnResolver implements Resolver { } async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { - if (!this.resolutions) - throw new Error(`Assertion failed: The resolution store should have been setup`); + if (!this.resolutions) throw new Error(`Assertion failed: The resolution store should have been setup`); const resolution = this.resolutions.get(descriptor.descriptorHash); - if (!resolution) - throw new Error(`Assertion failed: The resolution should have been registered`); + if (!resolution) throw new Error(`Assertion failed: The resolution should have been registered`); return [resolution]; } diff --git a/packages/berry-core/sources/execUtils.ts b/packages/berry-core/sources/execUtils.ts index d135d9a77ba3..405e0f88d6ff 100644 --- a/packages/berry-core/sources/execUtils.ts +++ b/packages/berry-core/sources/execUtils.ts @@ -1,28 +1,28 @@ -import {NodeFS} from '@berry/fslib'; -import crossSpawn from 'cross-spawn'; +import {NodeFS} from '@berry/fslib'; +import crossSpawn from 'cross-spawn'; import {Readable, Writable} from 'stream'; export type PipevpOptions = { - cwd: string, - env?: {[key: string]: string | undefined}, - strict?: boolean, - stdin: Readable | null, - stdout: Writable, - stderr: Writable, + cwd: string; + env?: {[key: string]: string | undefined}; + strict?: boolean; + stdin: Readable | null; + stdout: Writable; + stderr: Writable; }; -export async function pipevp(fileName: string, args: Array, {cwd, env = process.env, strict = false, stdin = null, stdout, stderr}: PipevpOptions): Promise<{code: number}> { +export async function pipevp( + fileName: string, + args: Array, + {cwd, env = process.env, strict = false, stdin = null, stdout, stderr}: PipevpOptions, +): Promise<{code: number}> { const stdio: Array = [`pipe`, `pipe`, `pipe`]; - if (stdin === null) - stdio[0] = `ignore`; - else if (stdin === process.stdin) - stdio[0] = stdin; + if (stdin === null) stdio[0] = `ignore`; + else if (stdin === process.stdin) stdio[0] = stdin; - if (stdout === process.stdout) - stdio[1] = stdout; - if (stderr === process.stderr) - stdio[2] = stderr; + if (stdout === process.stdout) stdio[1] = stdout; + if (stderr === process.stderr) stdio[2] = stderr; const subprocess = crossSpawn(fileName, args, { cwd: NodeFS.fromPortablePath(cwd), @@ -30,13 +30,10 @@ export async function pipevp(fileName: string, args: Array, {cwd, env = stdio, }); - if (stdin !== process.stdin && stdin !== null) - stdin.pipe(subprocess.stdin); + if (stdin !== process.stdin && stdin !== null) stdin.pipe(subprocess.stdin); - if (stdout !== process.stdout) - subprocess.stdout.pipe(stdout); - if (stderr !== process.stderr) - subprocess.stderr.pipe(stderr); + if (stdout !== process.stdout) subprocess.stdout.pipe(stdout); + if (stderr !== process.stderr) subprocess.stderr.pipe(stderr); return new Promise((resolve, reject) => { subprocess.on(`close`, (code: number) => { @@ -50,17 +47,33 @@ export async function pipevp(fileName: string, args: Array, {cwd, env = } export type ExecvpOptions = { - cwd: string, - env?: {[key: string]: string | undefined}, - encoding?: string, - strict?: boolean, + cwd: string; + env?: {[key: string]: string | undefined}; + encoding?: string; + strict?: boolean; }; -export async function execvp(fileName: string, args: Array, opts: ExecvpOptions & {encoding: `buffer`}): Promise<{code: number, stdout: Buffer, stderr: Buffer}>; -export async function execvp(fileName: string, args: Array, opts: ExecvpOptions & {encoding: string}): Promise<{code: number, stdout: string, stderr: string}>; -export async function execvp(fileName: string, args: Array, opts: ExecvpOptions): Promise<{code: number, stdout: string, stderr: string}>; - -export async function execvp(fileName: string, args: Array, {cwd, env = process.env, encoding = `utf8`, strict = false}: ExecvpOptions) { +export async function execvp( + fileName: string, + args: Array, + opts: ExecvpOptions & {encoding: `buffer`}, +): Promise<{code: number; stdout: Buffer; stderr: Buffer}>; +export async function execvp( + fileName: string, + args: Array, + opts: ExecvpOptions & {encoding: string}, +): Promise<{code: number; stdout: string; stderr: string}>; +export async function execvp( + fileName: string, + args: Array, + opts: ExecvpOptions, +): Promise<{code: number; stdout: string; stderr: string}>; + +export async function execvp( + fileName: string, + args: Array, + {cwd, env = process.env, encoding = `utf8`, strict = false}: ExecvpOptions, +) { const stdio: any = [`ignore`, `pipe`, `pipe`]; const stdoutChunks: Array = []; @@ -77,18 +90,16 @@ export async function execvp(fileName: string, args: Array, {cwd, env = }); subprocess.stderr.on(`data`, (chunk: Buffer) => { - stderrChunks.push(chunk) - }) + stderrChunks.push(chunk); + }); return await new Promise((resolve, reject) => { subprocess.on(`close`, (code: number) => { - const stdout = encoding === `buffer` - ? Buffer.concat(stdoutChunks) - : Buffer.concat(stdoutChunks).toString(encoding); + const stdout = + encoding === `buffer` ? Buffer.concat(stdoutChunks) : Buffer.concat(stdoutChunks).toString(encoding); - const stderr = encoding === `buffer` - ? Buffer.concat(stderrChunks) - : Buffer.concat(stderrChunks).toString(encoding); + const stderr = + encoding === `buffer` ? Buffer.concat(stderrChunks) : Buffer.concat(stderrChunks).toString(encoding); if (code === 0 || !strict) { resolve({code, stdout, stderr}); diff --git a/packages/berry-core/sources/hashUtils.ts b/packages/berry-core/sources/hashUtils.ts index 923741676568..d0f681eb1a20 100644 --- a/packages/berry-core/sources/hashUtils.ts +++ b/packages/berry-core/sources/hashUtils.ts @@ -1,13 +1,12 @@ -import {NodeFS} from '@berry/fslib'; +import {NodeFS} from '@berry/fslib'; import {createHmac} from 'crypto'; -export function makeHash(... args: Array): T { +export function makeHash(...args: Array): T { const hmac = createHmac(`sha512`, `berry`); - for (const arg of args) - hmac.update(arg ? arg : ``); + for (const arg of args) hmac.update(arg ? arg : ``); - return hmac.digest(`hex`) as unknown as T; + return (hmac.digest(`hex`) as unknown) as T; } export function checksumFile(path: string) { @@ -19,7 +18,7 @@ export function checksumFile(path: string) { stream.on(`data`, chunk => { hmac.update(chunk); - }) + }); stream.on(`error`, error => { reject(error); diff --git a/packages/berry-core/sources/httpUtils.ts b/packages/berry-core/sources/httpUtils.ts index e3df7a3a920b..fa07cc948fcc 100644 --- a/packages/berry-core/sources/httpUtils.ts +++ b/packages/berry-core/sources/httpUtils.ts @@ -1,9 +1,9 @@ import HttpAgent, {HttpsAgent} from 'agentkeepalive'; -import got from 'got'; -import tunnel, {ProxyOptions} from 'tunnel'; -import {URL} from 'url'; +import got from 'got'; +import tunnel, {ProxyOptions} from 'tunnel'; +import {URL} from 'url'; -import {Configuration} from './Configuration'; +import {Configuration} from './Configuration'; const cache = new Map>(); @@ -14,8 +14,7 @@ function parseProxy(specifier: string) { const url = new URL(specifier); const proxy: ProxyOptions = {host: url.hostname, headers: {}}; - if (url.port) - proxy.port = Number(url.port); + if (url.port) proxy.port = Number(url.port); return {proxy}; } @@ -30,15 +29,9 @@ async function getNoCache(target: string, configuration: Configuration): Promise const httpProxy = configuration.get(`httpProxy`); const httpsProxy = configuration.get(`httpsProxy`); - if (url.protocol === `http:`) - agent = httpProxy - ? tunnel.httpOverHttp(parseProxy(httpProxy)) - : globalHttpAgent; + if (url.protocol === `http:`) agent = httpProxy ? tunnel.httpOverHttp(parseProxy(httpProxy)) : globalHttpAgent; - if (url.protocol === `https:`) - agent = httpsProxy - ? tunnel.httpsOverHttp(parseProxy(httpsProxy)) - : globalHttpsAgent; + if (url.protocol === `https:`) agent = httpsProxy ? tunnel.httpsOverHttp(parseProxy(httpsProxy)) : globalHttpsAgent; const res = await got(target, {agent, encoding: null}); diff --git a/packages/berry-core/sources/index.ts b/packages/berry-core/sources/index.ts index a6ca7fe0447f..76613d84aa01 100644 --- a/packages/berry-core/sources/index.ts +++ b/packages/berry-core/sources/index.ts @@ -1,28 +1,28 @@ -import * as execUtils from './execUtils'; -import * as httpUtils from './httpUtils'; -import * as miscUtils from './miscUtils'; +import * as execUtils from './execUtils'; +import * as httpUtils from './httpUtils'; +import * as miscUtils from './miscUtils'; import * as scriptUtils from './scriptUtils'; import * as structUtils from './structUtils'; -import * as tgzUtils from './tgzUtils'; +import * as tgzUtils from './tgzUtils'; -export {Cache} from './Cache'; +export {Cache} from './Cache'; export {Configuration, PluginConfiguration, SettingsDefinition, SettingsType} from './Configuration'; -export {Fetcher, FetchOptions, FetchResult, MinimalFetchOptions} from './Fetcher'; -export {Installer, BuildDirective, BuildType} from './Installer'; -export {LightReport} from './LightReport'; -export {Linker, LinkOptions, MinimalLinkOptions} from './Linker'; -export {Manifest, DependencyMeta, PeerDependencyMeta} from './Manifest'; -export {Hooks, Plugin} from './Plugin'; -export {Project} from './Project'; -export {ReportError, Report, MessageName} from './Report'; -export {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; -export {StreamReport} from './StreamReport'; -export {ThrowReport} from './ThrowReport'; -export {VirtualFetcher} from './VirtualFetcher'; -export {Workspace} from './Workspace'; -export {IdentHash, DescriptorHash, LocatorHash} from './types'; -export {Ident, Descriptor, Locator, Package} from './types'; -export {LinkType} from './types'; +export {Fetcher, FetchOptions, FetchResult, MinimalFetchOptions} from './Fetcher'; +export {Installer, BuildDirective, BuildType} from './Installer'; +export {LightReport} from './LightReport'; +export {Linker, LinkOptions, MinimalLinkOptions} from './Linker'; +export {Manifest, DependencyMeta, PeerDependencyMeta} from './Manifest'; +export {Hooks, Plugin} from './Plugin'; +export {Project} from './Project'; +export {ReportError, Report, MessageName} from './Report'; +export {Resolver, ResolveOptions, MinimalResolveOptions} from './Resolver'; +export {StreamReport} from './StreamReport'; +export {ThrowReport} from './ThrowReport'; +export {VirtualFetcher} from './VirtualFetcher'; +export {Workspace} from './Workspace'; +export {IdentHash, DescriptorHash, LocatorHash} from './types'; +export {Ident, Descriptor, Locator, Package} from './types'; +export {LinkType} from './types'; export {httpUtils}; export {execUtils}; diff --git a/packages/berry-core/sources/miscUtils.ts b/packages/berry-core/sources/miscUtils.ts index 28e93f980ef5..d0903f058cd6 100644 --- a/packages/berry-core/sources/miscUtils.ts +++ b/packages/berry-core/sources/miscUtils.ts @@ -2,8 +2,7 @@ // if it throws an exception) export async function releaseAfterUseAsync(fn: () => Promise, cleanup?: () => any) { - if (!cleanup) - return await fn(); + if (!cleanup) return await fn(); try { return await fn(); @@ -61,13 +60,11 @@ export function dynamicRequire(path: string) { export function sortMap(values: Iterable, mappers: ((value: T) => string) | Array<(value: T) => string>) { const asArray = Array.from(values); - if (!Array.isArray(mappers)) - mappers = [mappers]; + if (!Array.isArray(mappers)) mappers = [mappers]; const stringified: Array> = []; - - for (const mapper of mappers) - stringified.push(asArray.map(value => mapper(value))); + + for (const mapper of mappers) stringified.push(asArray.map(value => mapper(value))); const indices = asArray.map((_, index) => index); diff --git a/packages/berry-core/sources/nodeUtils.ts b/packages/berry-core/sources/nodeUtils.ts index e0c9e7cbefd0..14effe53a7c4 100644 --- a/packages/berry-core/sources/nodeUtils.ts +++ b/packages/berry-core/sources/nodeUtils.ts @@ -3,9 +3,7 @@ import Module from 'module'; declare var __non_webpack_require__: any; export function dynamicRequire(request: string): any { - const req = typeof __non_webpack_require__ !== `undefined` - ? __non_webpack_require__ - : require; + const req = typeof __non_webpack_require__ !== `undefined` ? __non_webpack_require__ : require; return req(request); } diff --git a/packages/berry-core/sources/scriptUtils.ts b/packages/berry-core/sources/scriptUtils.ts index 7b42340c5b6a..4bd04f9102f1 100644 --- a/packages/berry-core/sources/scriptUtils.ts +++ b/packages/berry-core/sources/scriptUtils.ts @@ -1,22 +1,25 @@ -import {CwdFS, ZipOpenFS, xfs, NodeFS} from '@berry/fslib'; -import {execute} from '@berry/shell'; -import {delimiter, posix} from 'path'; +import {CwdFS, ZipOpenFS, xfs, NodeFS} from '@berry/fslib'; +import {execute} from '@berry/shell'; +import {delimiter, posix} from 'path'; import {PassThrough, Readable, Writable} from 'stream'; -import {dirSync} from 'tmp'; +import {dirSync} from 'tmp'; -import {Manifest} from './Manifest'; -import {Project} from './Project'; -import {StreamReport} from './StreamReport'; -import {Workspace} from './Workspace'; -import * as execUtils from './execUtils'; -import * as structUtils from './structUtils'; -import {Locator} from './types'; +import {Manifest} from './Manifest'; +import {Project} from './Project'; +import {StreamReport} from './StreamReport'; +import {Workspace} from './Workspace'; +import * as execUtils from './execUtils'; +import * as structUtils from './structUtils'; +import {Locator} from './types'; async function makePathWrapper(location: string, name: string, argv0: string, args: Array = []) { if (process.platform === `win32`) { await xfs.writeFilePromise(`${location}/${name}.cmd`, `@"${argv0}" ${args.join(` `)} %*\n`); } else { - await xfs.writeFilePromise(`${location}/${name}`, `#!/usr/bin/env bash\nexec "${argv0}" ${args.map(arg => `'${arg.replace(/'/g, `'"'"'`)}'`).join(` `)} "$@"\n`); + await xfs.writeFilePromise( + `${location}/${name}`, + `#!/usr/bin/env bash\nexec "${argv0}" ${args.map(arg => `'${arg.replace(/'/g, `'"'"'`)}'`).join(` `)} "$@"\n`, + ); await xfs.chmodPromise(`${location}/${name}`, 0o755); } } @@ -24,10 +27,9 @@ async function makePathWrapper(location: string, name: string, argv0: string, ar export async function makeScriptEnv(project: Project) { const scriptEnv: {[key: string]: string} = {}; for (const [key, value] of Object.entries(process.env)) - if (typeof value !== `undefined`) - scriptEnv[key.toLowerCase() !== `path` ? key : `PATH`] = value; + if (typeof value !== `undefined`) scriptEnv[key.toLowerCase() !== `path` ? key : `PATH`] = value; - const binFolder = scriptEnv.BERRY_BIN_FOLDER = dirSync().name; + const binFolder = (scriptEnv.BERRY_BIN_FOLDER = dirSync().name); // Register some binaries that must be made available in all subprocesses // spawned by Yarn (we thus ensure that they always use the right version) @@ -37,9 +39,7 @@ export async function makeScriptEnv(project: Project) { await makePathWrapper(binFolder, `node`, process.execPath); await makePathWrapper(binFolder, `node-gyp`, process.execPath, [process.argv[1], `run`, `--top-level`, `node-gyp`]); - scriptEnv.PATH = scriptEnv.PATH - ? `${binFolder}${delimiter}${scriptEnv.PATH}` - : `${binFolder}`; + scriptEnv.PATH = scriptEnv.PATH ? `${binFolder}${delimiter}${scriptEnv.PATH}` : `${binFolder}`; scriptEnv.npm_execpath = `${binFolder}/yarn`; scriptEnv.npm_node_execpath = `${binFolder}/node`; @@ -57,13 +57,15 @@ export async function makeScriptEnv(project: Project) { } type HasPackageScriptOption = { - project: Project, + project: Project; }; export async function hasPackageScript(locator: Locator, scriptName: string, {project}: HasPackageScriptOption) { const pkg = project.storedPackages.get(locator.locatorHash); if (!pkg) - throw new Error(`Package for ${structUtils.prettyLocator(project.configuration, locator)} not found in the project`); + throw new Error( + `Package for ${structUtils.prettyLocator(project.configuration, locator)} not found in the project`, + ); return await ZipOpenFS.openPromise(async (zipOpenFs: ZipOpenFS) => { const configuration = project.configuration; @@ -73,7 +75,12 @@ export async function hasPackageScript(locator: Locator, scriptName: string, {pr const linker = linkers.find(linker => linker.supportsPackage(pkg, linkerOptions)); if (!linker) - throw new Error(`The package ${structUtils.prettyLocator(project.configuration, pkg)} isn't supported by any of the available linkers`); + throw new Error( + `The package ${structUtils.prettyLocator( + project.configuration, + pkg, + )} isn't supported by any of the available linkers`, + ); const packageLocation = await linker.findPackageLocation(pkg, linkerOptions); const packageFs = new CwdFS(packageLocation, {baseFs: zipOpenFs}); @@ -84,19 +91,23 @@ export async function hasPackageScript(locator: Locator, scriptName: string, {pr } type ExecutePackageScriptOptions = { - cwd?: string | undefined, - project: Project, - stdin: Readable | null, - stdout: Writable, - stderr: Writable, + cwd?: string | undefined; + project: Project; + stdin: Readable | null; + stdout: Writable; + stderr: Writable; }; -export async function executePackageScript(locator: Locator, scriptName: string, args: Array, {cwd, project, stdin, stdout, stderr}: ExecutePackageScriptOptions) { +export async function executePackageScript( + locator: Locator, + scriptName: string, + args: Array, + {cwd, project, stdin, stdout, stderr}: ExecutePackageScriptOptions, +) { const {manifest, binFolder, env, cwd: realCwd} = await initializePackageEnvironment(locator, {project, cwd}); const script = manifest.scripts.get(scriptName); - if (!script) - return; + if (!script) return; try { return await execute(script, args, {cwd: realCwd, env, stdin, stdout, stderr}); @@ -105,7 +116,12 @@ export async function executePackageScript(locator: Locator, scriptName: string, } } -export async function executePackageShellcode(locator: Locator, command: string, args: Array, {cwd, project, stdin, stdout, stderr}: ExecutePackageScriptOptions) { +export async function executePackageShellcode( + locator: Locator, + command: string, + args: Array, + {cwd, project, stdin, stdout, stderr}: ExecutePackageScriptOptions, +) { const {binFolder, env, cwd: realCwd} = await initializePackageEnvironment(locator, {project, cwd}); try { @@ -115,10 +131,15 @@ export async function executePackageShellcode(locator: Locator, command: string, } } -async function initializePackageEnvironment(locator: Locator, {project, cwd}: {project: Project, cwd?: string | undefined}) { +async function initializePackageEnvironment( + locator: Locator, + {project, cwd}: {project: Project; cwd?: string | undefined}, +) { const pkg = project.storedPackages.get(locator.locatorHash); if (!pkg) - throw new Error(`Package for ${structUtils.prettyLocator(project.configuration, locator)} not found in the project`); + throw new Error( + `Package for ${structUtils.prettyLocator(project.configuration, locator)} not found in the project`, + ); return await ZipOpenFS.openPromise(async (zipOpenFs: ZipOpenFS) => { const configuration = project.configuration; @@ -128,7 +149,12 @@ async function initializePackageEnvironment(locator: Locator, {project, cwd}: {p const linker = linkers.find(linker => linker.supportsPackage(pkg, linkerOptions)); if (!linker) - throw new Error(`The package ${structUtils.prettyLocator(project.configuration, pkg)} isn't supported by any of the available linkers`); + throw new Error( + `The package ${structUtils.prettyLocator( + project.configuration, + pkg, + )} isn't supported by any of the available linkers`, + ); const env = await makeScriptEnv(project); const binFolder = env.BERRY_BIN_FOLDER; @@ -140,26 +166,36 @@ async function initializePackageEnvironment(locator: Locator, {project, cwd}: {p const packageFs = new CwdFS(packageLocation, {baseFs: zipOpenFs}); const manifest = await Manifest.find(`.`, {baseFs: packageFs}); - if (typeof cwd === `undefined`) - cwd = packageLocation; + if (typeof cwd === `undefined`) cwd = packageLocation; return {manifest, binFolder, env, cwd}; }); } type ExecuteWorkspaceScriptOptions = { - cwd?: string | undefined, - stdin: Readable | null, - stdout: Writable, - stderr: Writable, + cwd?: string | undefined; + stdin: Readable | null; + stdout: Writable; + stderr: Writable; }; -export async function executeWorkspaceScript(workspace: Workspace, scriptName: string, args: Array, {cwd, stdin, stdout, stderr}: ExecuteWorkspaceScriptOptions) { - return await executePackageScript(workspace.anchoredLocator, scriptName, args, {cwd, project: workspace.project, stdin, stdout, stderr}); +export async function executeWorkspaceScript( + workspace: Workspace, + scriptName: string, + args: Array, + {cwd, stdin, stdout, stderr}: ExecuteWorkspaceScriptOptions, +) { + return await executePackageScript(workspace.anchoredLocator, scriptName, args, { + cwd, + project: workspace.project, + stdin, + stdout, + stderr, + }); } type GetPackageAccessibleBinariesOptions = { - project: Project, + project: Project; }; /** @@ -172,7 +208,9 @@ type GetPackageAccessibleBinariesOptions = { export async function getPackageAccessibleBinaries(locator: Locator, {project}: GetPackageAccessibleBinariesOptions) { const pkg = project.storedPackages.get(locator.locatorHash); if (!pkg) - throw new Error(`Package for ${structUtils.prettyLocator(project.configuration, locator)} not found in the project`); + throw new Error( + `Package for ${structUtils.prettyLocator(project.configuration, locator)} not found in the project`, + ); return await ZipOpenFS.openPromise(async (zipOpenFs: ZipOpenFS) => { const configuration = project.configuration; @@ -183,23 +221,17 @@ export async function getPackageAccessibleBinaries(locator: Locator, {project}: const binaries: Map = new Map(); - const descriptors = [ - ... pkg.dependencies.values(), - ... pkg.peerDependencies.values(), - ]; + const descriptors = [...pkg.dependencies.values(), ...pkg.peerDependencies.values()]; for (const descriptor of descriptors) { const resolution = project.storedResolutions.get(descriptor.descriptorHash); - if (!resolution) - continue; + if (!resolution) continue; const pkg = project.storedPackages.get(resolution); - if (!pkg) - continue; + if (!pkg) continue; const linker = linkers.find(linker => linker.supportsPackage(pkg, linkerOptions)); - if (!linker) - continue; + if (!linker) continue; const packageLocation = await linker.findPackageLocation(pkg, linkerOptions); const packageFs = new CwdFS(packageLocation, {baseFs: zipOpenFs}); @@ -226,11 +258,11 @@ export async function getWorkspaceAccessibleBinaries(workspace: Workspace) { } type ExecutePackageAccessibleBinaryOptions = { - cwd: string, - project: Project, - stdin: Readable | null, - stdout: Writable, - stderr: Writable, + cwd: string; + project: Project; + stdin: Readable | null; + stdout: Writable; + stderr: Writable; }; /** @@ -245,12 +277,19 @@ type ExecutePackageAccessibleBinaryOptions = { * @param args The arguments to pass to the file */ -export async function executePackageAccessibleBinary(locator: Locator, binaryName: string, args: Array, {cwd, project, stdin, stdout, stderr}: ExecutePackageAccessibleBinaryOptions) { +export async function executePackageAccessibleBinary( + locator: Locator, + binaryName: string, + args: Array, + {cwd, project, stdin, stdout, stderr}: ExecutePackageAccessibleBinaryOptions, +) { const packageAccessibleBinaries = await getPackageAccessibleBinaries(locator, {project}); const binary = packageAccessibleBinaries.get(binaryName); if (!binary) - throw new Error(`Binary not found (${binaryName}) for ${structUtils.prettyLocator(project.configuration, locator)}`); + throw new Error( + `Binary not found (${binaryName}) for ${structUtils.prettyLocator(project.configuration, locator)}`, + ); const [pkg, binaryPath] = binary; const env = await makeScriptEnv(project); @@ -260,7 +299,7 @@ export async function executePackageAccessibleBinary(locator: Locator, binaryNam let result; try { - result = await execUtils.pipevp(process.execPath, [binaryPath, ... args], {cwd, env, stdin, stdout, stderr}); + result = await execUtils.pipevp(process.execPath, [binaryPath, ...args], {cwd, env, stdin, stdout, stderr}); } finally { await xfs.removePromise(env.BERRY_BIN_FOLDER); } @@ -269,10 +308,10 @@ export async function executePackageAccessibleBinary(locator: Locator, binaryNam } type ExecuteWorkspaceAccessibleBinaryOptions = { - cwd: string, - stdin: Readable | null, - stdout: Writable, - stderr: Writable, + cwd: string; + stdin: Readable | null; + stdout: Writable; + stderr: Writable; }; /** @@ -283,6 +322,17 @@ type ExecuteWorkspaceAccessibleBinaryOptions = { * @param args The arguments to pass to the file */ -export async function executeWorkspaceAccessibleBinary(workspace: Workspace, binaryName: string, args: Array, {cwd, stdin, stdout, stderr}: ExecuteWorkspaceAccessibleBinaryOptions) { - return await executePackageAccessibleBinary(workspace.anchoredLocator, binaryName, args, {project: workspace.project, cwd, stdin, stdout, stderr}); +export async function executeWorkspaceAccessibleBinary( + workspace: Workspace, + binaryName: string, + args: Array, + {cwd, stdin, stdout, stderr}: ExecuteWorkspaceAccessibleBinaryOptions, +) { + return await executePackageAccessibleBinary(workspace.anchoredLocator, binaryName, args, { + project: workspace.project, + cwd, + stdin, + stdout, + stderr, + }); } diff --git a/packages/berry-core/sources/structUtils.ts b/packages/berry-core/sources/structUtils.ts index 688856785f74..cb5925509270 100644 --- a/packages/berry-core/sources/structUtils.ts +++ b/packages/berry-core/sources/structUtils.ts @@ -1,11 +1,11 @@ -import semver from 'semver'; +import semver from 'semver'; -import {Configuration} from './Configuration'; -import {Workspace} from './Workspace'; -import * as hashUtils from './hashUtils'; -import * as miscUtils from './miscUtils'; +import {Configuration} from './Configuration'; +import {Workspace} from './Workspace'; +import * as hashUtils from './hashUtils'; +import * as miscUtils from './miscUtils'; import {IdentHash, DescriptorHash, LocatorHash} from './types'; -import {Ident, Descriptor, Locator, Package} from './types'; +import {Ident, Descriptor, Locator, Package} from './types'; const VIRTUAL_PROTOCOL = `virtual:`; const VIRTUAL_ABBREVIATE = 12; @@ -15,11 +15,23 @@ export function makeIdent(scope: string | null, name: string): Ident { } export function makeDescriptor(ident: Ident, range: string): Descriptor { - return {identHash: ident.identHash, scope: ident.scope, name: ident.name, descriptorHash: hashUtils.makeHash(ident.identHash, range), range}; + return { + identHash: ident.identHash, + scope: ident.scope, + name: ident.name, + descriptorHash: hashUtils.makeHash(ident.identHash, range), + range, + }; } export function makeLocator(ident: Ident, reference: string): Locator { - return {identHash: ident.identHash, scope: ident.scope, name: ident.name, locatorHash: hashUtils.makeHash(ident.identHash, reference), reference}; + return { + identHash: ident.identHash, + scope: ident.scope, + name: ident.name, + locatorHash: hashUtils.makeHash(ident.identHash, reference), + reference, + }; } export function convertToIdent(source: Descriptor | Locator | Package): Ident { @@ -27,23 +39,41 @@ export function convertToIdent(source: Descriptor | Locator | Package): Ident { } export function convertDescriptorToLocator(descriptor: Descriptor): Locator { - return {identHash: descriptor.identHash, scope: descriptor.scope, name: descriptor.name, locatorHash: descriptor.descriptorHash as unknown as LocatorHash, reference: descriptor.range}; + return { + identHash: descriptor.identHash, + scope: descriptor.scope, + name: descriptor.name, + locatorHash: (descriptor.descriptorHash as unknown) as LocatorHash, + reference: descriptor.range, + }; } export function convertLocatorToDescriptor(locator: Locator): Descriptor { - return {identHash: locator.identHash, scope: locator.scope, name: locator.name, descriptorHash: locator.locatorHash as unknown as DescriptorHash, range: locator.reference}; + return { + identHash: locator.identHash, + scope: locator.scope, + name: locator.name, + descriptorHash: (locator.locatorHash as unknown) as DescriptorHash, + range: locator.reference, + }; } export function convertPackageToLocator(pkg: Package): Locator { - return {identHash: pkg.identHash, scope: pkg.scope, name: pkg.name, locatorHash: pkg.locatorHash, reference: pkg.reference}; + return { + identHash: pkg.identHash, + scope: pkg.scope, + name: pkg.name, + locatorHash: pkg.locatorHash, + reference: pkg.reference, + }; } export function renamePackage(pkg: Package, locator: Locator) { return { - ... locator, + ...locator, version: pkg.version, - + languageName: pkg.languageName, linkType: pkg.linkType, @@ -56,15 +86,13 @@ export function renamePackage(pkg: Package, locator: Locator) { } export function virtualizeDescriptor(descriptor: Descriptor, entropy: string): Descriptor { - if (entropy.includes(`#`)) - throw new Error(`Invalid entropy`); + if (entropy.includes(`#`)) throw new Error(`Invalid entropy`); return makeDescriptor(descriptor, `virtual:${entropy}#${descriptor.range}`); } export function virtualizePackage(pkg: Package, entropy: string): Package { - if (entropy.includes(`#`)) - throw new Error(`Invalid entropy`); + if (entropy.includes(`#`)) throw new Error(`Invalid entropy`); return renamePackage(pkg, makeLocator(pkg, `virtual:${entropy}#${pkg.reference}`)); } @@ -78,15 +106,13 @@ export function isVirtualLocator(locator: Locator): boolean { } export function devirtualizeDescriptor(descriptor: Descriptor): Descriptor { - if (!isVirtualDescriptor(descriptor)) - throw new Error(`Not a virtual descriptor`); + if (!isVirtualDescriptor(descriptor)) throw new Error(`Not a virtual descriptor`); return makeDescriptor(descriptor, descriptor.range.replace(/^.*#/, ``)); } export function devirtualizeLocator(locator: Locator): Locator { - if (!isVirtualLocator(locator)) - throw new Error(`Not a virtual descriptor`); + if (!isVirtualLocator(locator)) throw new Error(`Not a virtual descriptor`); return makeLocator(locator, locator.reference.replace(/^.*#/, ``)); } @@ -106,8 +132,7 @@ export function areLocatorsEqual(a: Locator, b: Locator) { export function parseIdent(string: string): Ident { const match = string.match(/^(?:@([^\/]+?)\/)?([^\/]+)$/); - if (!match) - throw new Error(`Invalid ident (${string})`); + if (!match) throw new Error(`Invalid ident (${string})`); const [, scope, name] = match; return makeIdent(scope, name); @@ -116,8 +141,7 @@ export function parseIdent(string: string): Ident { export function parseDescriptor(string: string, strict: boolean = false): Descriptor { const descriptor = tryParseDescriptor(string, strict); - if (!descriptor) - throw new Error(`Invalid descriptor (${string})`); + if (!descriptor) throw new Error(`Invalid descriptor (${string})`); return descriptor; } @@ -127,16 +151,13 @@ export function tryParseDescriptor(string: string, strict: boolean = false): Des ? string.match(/^(?:@([^\/]+?)\/)?([^\/]+?)(?:@(.+))$/) : string.match(/^(?:@([^\/]+?)\/)?([^\/]+?)(?:@(.+))?$/); - if (!match) - return null; - + if (!match) return null; + let [, scope, name, range] = match; - if (range === `unknown`) - throw new Error(`Invalid range (${string})`); + if (range === `unknown`) throw new Error(`Invalid range (${string})`); - if (!range) - range = `unknown`; + if (!range) range = `unknown`; return makeDescriptor(makeIdent(scope, name), range); } @@ -144,9 +165,8 @@ export function tryParseDescriptor(string: string, strict: boolean = false): Des export function parseLocator(string: string, strict: boolean = false): Locator { const locator = tryParseLocator(string, strict); - if (!locator) - throw new Error(`Invalid locator (${string})`); - + if (!locator) throw new Error(`Invalid locator (${string})`); + return locator; } @@ -155,16 +175,13 @@ export function tryParseLocator(string: string, strict: boolean = false): Locato ? string.match(/^(?:@([^\/]+?)\/)?([^\/]+?)(?:@(.+))$/) : string.match(/^(?:@([^\/]+?)\/)?([^\/]+?)(?:@(.+))?$/); - if (!match) - return null; + if (!match) return null; let [, scope, name, reference] = match; - if (reference === `unknown`) - throw new Error(`Invalid reference (${string})`); + if (reference === `unknown`) throw new Error(`Invalid reference (${string})`); - if (!reference) - reference = `unknown`; + if (!reference) reference = `unknown`; return makeLocator(makeIdent(scope, name), reference); } @@ -181,14 +198,20 @@ export function parseRange(range: string) { return {protocol, source, selector}; } -export function makeRange({protocol, source, selector}: {protocol: string | null, source: string | null, selector: string}) { +export function makeRange({ + protocol, + source, + selector, +}: { + protocol: string | null; + source: string | null; + selector: string; +}) { let range = ``; - if (protocol !== null) - range += `${protocol}`; - if (source !== null) - range += `${source}#`; - + if (protocol !== null) range += `${protocol}`; + if (source !== null) range += `${source}#`; + return range + selector; } @@ -227,17 +250,11 @@ export function stringifyLocator(locator: Locator) { export function slugifyLocator(locator: Locator) { const protocolIndex = locator.reference.indexOf(`:`); - const protocol = protocolIndex !== -1 - ? locator.reference.slice(0, protocolIndex) - : `exotic`; + const protocol = protocolIndex !== -1 ? locator.reference.slice(0, protocolIndex) : `exotic`; + + const version = protocolIndex !== -1 ? semver.valid(locator.reference.slice(protocolIndex + 1)) : null; - const version = protocolIndex !== -1 - ? semver.valid(locator.reference.slice(protocolIndex + 1)) - : null; - - const humanReference = version !== null - ? `${protocol}-${version}` - : protocol; + const humanReference = version !== null ? `${protocol}-${version}` : protocol; // eCryptfs limits the filename size to less than the usual (255); they recommend 140 characters max // https://unix.stackexchange.com/a/32834/24106 @@ -275,7 +292,10 @@ export function prettyRange(configuration: Configuration, range: string) { } export function prettyDescriptor(configuration: Configuration, descriptor: Descriptor) { - return `${prettyIdent(configuration, descriptor)}${configuration.format(`@`, `#00afaf`)}${prettyRange(configuration, descriptor.range)}`; + return `${prettyIdent(configuration, descriptor)}${configuration.format(`@`, `#00afaf`)}${prettyRange( + configuration, + descriptor.range, + )}`; } export function prettyReference(configuration: Configuration, reference: string) { @@ -283,14 +303,14 @@ export function prettyReference(configuration: Configuration, reference: string) } export function prettyLocator(configuration: Configuration, locator: Locator) { - return `${prettyIdent(configuration, locator)}${configuration.format(`@`, `#87afff`)}${prettyReference(configuration, locator.reference)}`; + return `${prettyIdent(configuration, locator)}${configuration.format(`@`, `#87afff`)}${prettyReference( + configuration, + locator.reference, + )}`; } export function sortDescriptors(descriptors: Iterable) { - return miscUtils.sortMap(descriptors, [ - descriptor => stringifyIdent(descriptor), - descriptor => descriptor.range, - ]); + return miscUtils.sortMap(descriptors, [descriptor => stringifyIdent(descriptor), descriptor => descriptor.range]); } export function prettyWorkspace(configuration: Configuration, workspace: Workspace) { diff --git a/packages/berry-core/sources/tgzUtils.ts b/packages/berry-core/sources/tgzUtils.ts index bb9dd46a85cf..37b9706e1d59 100644 --- a/packages/berry-core/sources/tgzUtils.ts +++ b/packages/berry-core/sources/tgzUtils.ts @@ -1,14 +1,17 @@ import {FakeFS, ZipFS, NodeFS} from '@berry/fslib'; -import {posix} from 'path'; -import {Parse} from 'tar'; -import {tmpNameSync} from 'tmp'; +import {posix} from 'path'; +import {Parse} from 'tar'; +import {tmpNameSync} from 'tmp'; interface MakeArchiveFromDirectoryOptions { - baseFs?: FakeFS, - prefixPath?: string | null, -}; + baseFs?: FakeFS; + prefixPath?: string | null; +} -export async function makeArchiveFromDirectory(source: string, {baseFs = new NodeFS(), prefixPath = `/`}: MakeArchiveFromDirectoryOptions = {}): Promise { +export async function makeArchiveFromDirectory( + source: string, + {baseFs = new NodeFS(), prefixPath = `/`}: MakeArchiveFromDirectoryOptions = {}, +): Promise { const zipFs = new ZipFS(tmpNameSync(), {create: true}); const target = posix.resolve(`/`, prefixPath); @@ -18,11 +21,14 @@ export async function makeArchiveFromDirectory(source: string, {baseFs = new Nod } interface MakeArchiveOptions { - prefixPath?: string | null, - stripComponents?: number, -}; + prefixPath?: string | null; + stripComponents?: number; +} -export async function makeArchive(tgz: Buffer, {stripComponents = 0, prefixPath = `.`}: MakeArchiveOptions = {}): Promise { +export async function makeArchive( + tgz: Buffer, + {stripComponents = 0, prefixPath = `.`}: MakeArchiveOptions = {}, +): Promise { const zipFs = new ZipFS(tmpNameSync(), {create: true}); // 1980-01-01, like Fedora @@ -33,17 +39,14 @@ export async function makeArchive(tgz: Buffer, {stripComponents = 0, prefixPath function ignore(entry: any) { // Disallow absolute paths; might be malicious (ex: /etc/passwd) - if (entry[0] === `/`) - return true; + if (entry[0] === `/`) return true; const parts = entry.path.split(/\//g); // We also ignore paths that could lead to escaping outside the archive - if (parts.some((part: string) => part === `..`)) - return true; + if (parts.some((part: string) => part === `..`)) return true; - if (parts.length <= stripComponents) - return true; + if (parts.length <= stripComponents) return true; return false; } @@ -62,8 +65,7 @@ export async function makeArchive(tgz: Buffer, {stripComponents = 0, prefixPath let mode = 0o644; // If a single executable bit is set, normalize so that all are - if (entry.type === `Directory` || (entry.mode & 0o111) !== 0) - mode |= 0o111; + if (entry.type === `Directory` || (entry.mode & 0o111) !== 0) mode |= 0o111; entry.on(`data`, (chunk: Buffer) => { chunks.push(chunk); @@ -71,34 +73,40 @@ export async function makeArchive(tgz: Buffer, {stripComponents = 0, prefixPath entry.on(`end`, () => { switch (entry.type) { - case `Directory`: { - zipFs.mkdirpSync(posix.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); + case `Directory`: + { + zipFs.mkdirpSync(posix.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); - zipFs.mkdirSync(mappedPath); - zipFs.chmodSync(mappedPath, mode); - zipFs.utimesSync(mappedPath, defaultTime, defaultTime); - } break; + zipFs.mkdirSync(mappedPath); + zipFs.chmodSync(mappedPath, mode); + zipFs.utimesSync(mappedPath, defaultTime, defaultTime); + } + break; case `OldFile`: - case `File`: { - zipFs.mkdirpSync(posix.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); - - zipFs.writeFileSync(mappedPath, Buffer.concat(chunks)); - zipFs.chmodSync(mappedPath, mode); - zipFs.utimesSync(mappedPath, defaultTime, defaultTime); - } break; - - case `SymbolicLink`: { - zipFs.mkdirpSync(posix.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); - - zipFs.symlinkSync(entry.linkpath, mappedPath); - zipFs.lutimesSync(mappedPath, defaultTime, defaultTime); - } break; + case `File`: + { + zipFs.mkdirpSync(posix.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); + + zipFs.writeFileSync(mappedPath, Buffer.concat(chunks)); + zipFs.chmodSync(mappedPath, mode); + zipFs.utimesSync(mappedPath, defaultTime, defaultTime); + } + break; + + case `SymbolicLink`: + { + zipFs.mkdirpSync(posix.dirname(mappedPath), {chmod: 0o755, utimes: [defaultTime, defaultTime]}); + + zipFs.symlinkSync(entry.linkpath, mappedPath); + zipFs.lutimesSync(mappedPath, defaultTime, defaultTime); + } + break; } }); }); - return await new Promise((resolve, reject) => { + return await new Promise((resolve, reject) => { parser.on(`error`, (error: Error) => { reject(error); }); diff --git a/packages/berry-core/sources/types.ts b/packages/berry-core/sources/types.ts index 95ccc6eb5980..b2701239cef4 100644 --- a/packages/berry-core/sources/types.ts +++ b/packages/berry-core/sources/types.ts @@ -1,38 +1,41 @@ import {DependencyMeta, PeerDependencyMeta} from './Manifest'; -export type IdentHash = string & { __ident_hash: string }; +export type IdentHash = string & {__ident_hash: string}; export interface Ident { - identHash: IdentHash, - scope: string | null, - name: string, -}; + identHash: IdentHash; + scope: string | null; + name: string; +} -export type DescriptorHash = string & { __descriptor_hash: string }; +export type DescriptorHash = string & {__descriptor_hash: string}; export interface Descriptor extends Ident { - descriptorHash: DescriptorHash, - range: string, -}; + descriptorHash: DescriptorHash; + range: string; +} -export type LocatorHash = string & { __locator_hash: string }; +export type LocatorHash = string & {__locator_hash: string}; export interface Locator extends Ident { - locatorHash: LocatorHash, - reference: string, -}; + locatorHash: LocatorHash; + reference: string; +} -export enum LinkType { HARD = 'hard', SOFT = 'soft' }; +export enum LinkType { + HARD = 'hard', + SOFT = 'soft', +} export interface Package extends Locator { - version: string | null, + version: string | null; - languageName: string, - linkType: LinkType, + languageName: string; + linkType: LinkType; - dependencies: Map, - peerDependencies: Map, + dependencies: Map; + peerDependencies: Map; - dependenciesMeta: Map>, - peerDependenciesMeta: Map, -}; + dependenciesMeta: Map>; + peerDependenciesMeta: Map; +} diff --git a/packages/berry-fslib/sources/AliasFS.ts b/packages/berry-fslib/sources/AliasFS.ts index 259a4233bc53..622b35d56069 100644 --- a/packages/berry-fslib/sources/AliasFS.ts +++ b/packages/berry-fslib/sources/AliasFS.ts @@ -1,10 +1,10 @@ -import {posix} from 'path'; +import {posix} from 'path'; import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; +import {FakeFS, WriteFileOptions} from './FakeFS'; export type AliasFSOptions = { - baseFs: FakeFS, + baseFs: FakeFS; }; export class AliasFS extends FakeFS { diff --git a/packages/berry-fslib/sources/CwdFS.ts b/packages/berry-fslib/sources/CwdFS.ts index eaeb09dc915d..5627017e918f 100644 --- a/packages/berry-fslib/sources/CwdFS.ts +++ b/packages/berry-fslib/sources/CwdFS.ts @@ -1,11 +1,11 @@ -import {posix} from 'path'; +import {posix} from 'path'; import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; -import {NodeFS} from './NodeFS'; +import {FakeFS, WriteFileOptions} from './FakeFS'; +import {NodeFS} from './NodeFS'; export type CwdFSOptions = { - baseFs?: FakeFS, + baseFs?: FakeFS; }; export class CwdFS extends FakeFS { diff --git a/packages/berry-fslib/sources/FakeFS.ts b/packages/berry-fslib/sources/FakeFS.ts index 1b9308e4d372..485133e16ec7 100644 --- a/packages/berry-fslib/sources/FakeFS.ts +++ b/packages/berry-fslib/sources/FakeFS.ts @@ -1,19 +1,21 @@ import {ReadStream, Stats, WriteStream} from 'fs'; -import {posix} from 'path'; +import {posix} from 'path'; export type CreateReadStreamOptions = Partial<{ - encoding: string, + encoding: string; }>; export type CreateWriteStreamOptions = Partial<{ - encoding: string, + encoding: string; }>; -export type WriteFileOptions = Partial<{ - encoding: string, - mode: number, - flag: string, -}> | string; +export type WriteFileOptions = + | Partial<{ + encoding: string; + mode: number; + flag: string; + }> + | string; export abstract class FakeFS { abstract getRealPath(): string; @@ -67,7 +69,11 @@ export abstract class FakeFS { abstract copyFilePromise(sourceP: string, destP: string, flags?: number): Promise; abstract copyFileSync(sourceP: string, destP: string, flags?: number): void; - abstract writeFilePromise(p: string, content: string | Buffer | ArrayBuffer | DataView, opts?: WriteFileOptions): void; + abstract writeFilePromise( + p: string, + content: string | Buffer | ArrayBuffer | DataView, + opts?: WriteFileOptions, + ): void; abstract writeFileSync(p: string, content: string | Buffer | ArrayBuffer | DataView, opts?: WriteFileOptions): void; abstract unlinkPromise(p: string): Promise; @@ -98,8 +104,7 @@ export abstract class FakeFS { } if (stat.isDirectory()) { - for (const entry of await this.readdirPromise(p)) - await this.removePromise(posix.resolve(p, entry)); + for (const entry of await this.readdirPromise(p)) await this.removePromise(posix.resolve(p, entry)); // 5 gives 1s worth of retries at worst for (let t = 0; t < 5; ++t) { @@ -133,19 +138,20 @@ export abstract class FakeFS { } if (stat.isDirectory()) { - for (const entry of this.readdirSync(p)) - this.removeSync(posix.resolve(p, entry)); - + for (const entry of this.readdirSync(p)) this.removeSync(posix.resolve(p, entry)); + this.rmdirSync(p); } else { this.unlinkSync(p); } } - async mkdirpPromise(p: string, {chmod, utimes}: {chmod?: number, utimes?: [Date | string | number, Date | string | number]} = {}) { + async mkdirpPromise( + p: string, + {chmod, utimes}: {chmod?: number; utimes?: [Date | string | number, Date | string | number]} = {}, + ) { p = this.resolve(p); - if (p === `/`) - return; + if (p === `/`) return; const parts = p.split(`/`); @@ -163,8 +169,7 @@ export abstract class FakeFS { } } - if (chmod != null) - await this.chmodPromise(subPath, chmod); + if (chmod != null) await this.chmodPromise(subPath, chmod); if (utimes != null) { await this.utimesPromise(subPath, utimes[0], utimes[1]); @@ -173,10 +178,12 @@ export abstract class FakeFS { } } - mkdirpSync(p: string, {chmod, utimes}: {chmod?: number, utimes?: [Date | string | number, Date | string | number]} = {}) { + mkdirpSync( + p: string, + {chmod, utimes}: {chmod?: number; utimes?: [Date | string | number, Date | string | number]} = {}, + ) { p = this.resolve(p); - if (p === `/`) - return; + if (p === `/`) return; const parts = p.split(`/`); @@ -194,8 +201,7 @@ export abstract class FakeFS { } } - if (chmod != null) - this.chmodSync(subPath, chmod); + if (chmod != null) this.chmodSync(subPath, chmod); if (utimes != null) { this.utimesSync(subPath, utimes[0], utimes[1]); @@ -204,28 +210,32 @@ export abstract class FakeFS { } } - async copyPromise(destination: string, source: string, {baseFs = this, overwrite = true}: {baseFs?: FakeFS, overwrite?: boolean} = {}) { + async copyPromise( + destination: string, + source: string, + {baseFs = this, overwrite = true}: {baseFs?: FakeFS; overwrite?: boolean} = {}, + ) { const stat = await baseFs.lstatPromise(source); const exists = await this.existsSync(destination); if (stat.isDirectory()) { await this.mkdirpPromise(destination); const directoryListing = await baseFs.readdirPromise(source); - await Promise.all(directoryListing.map(entry => { - return this.copyPromise(posix.join(destination, entry), posix.join(source, entry), {baseFs, overwrite}); - })); + await Promise.all( + directoryListing.map(entry => { + return this.copyPromise(posix.join(destination, entry), posix.join(source, entry), {baseFs, overwrite}); + }), + ); } else if (stat.isFile()) { if (!exists || overwrite) { - if (exists) - await this.removePromise(destination); + if (exists) await this.removePromise(destination); const content = await baseFs.readFilePromise(source); await this.writeFilePromise(destination, content); } } else if (stat.isSymbolicLink()) { if (!exists || overwrite) { - if (exists) - await this.removePromise(destination); + if (exists) await this.removePromise(destination); const target = await baseFs.readlinkPromise(source); await this.symlinkPromise(target, destination); @@ -238,7 +248,11 @@ export abstract class FakeFS { await this.chmodPromise(destination, mode); } - copySync(destination: string, source: string, {baseFs = this, overwrite = true}: {baseFs?: FakeFS, overwrite?: boolean} = {}) { + copySync( + destination: string, + source: string, + {baseFs = this, overwrite = true}: {baseFs?: FakeFS; overwrite?: boolean} = {}, + ) { const stat = baseFs.lstatSync(source); const exists = this.existsSync(destination); @@ -250,16 +264,14 @@ export abstract class FakeFS { } } else if (stat.isFile()) { if (!exists || overwrite) { - if (exists) - this.removeSync(destination); + if (exists) this.removeSync(destination); const content = baseFs.readFileSync(source); this.writeFileSync(destination, content); } } else if (stat.isSymbolicLink()) { if (!exists || overwrite) { - if (exists) - this.removeSync(destination); + if (exists) this.removeSync(destination); const target = baseFs.readlinkSync(source); this.symlinkSync(target, destination); @@ -355,4 +367,4 @@ export abstract class FakeFS { await this.unlinkPromise(lockPath); } } -}; +} diff --git a/packages/berry-fslib/sources/JailFS.ts b/packages/berry-fslib/sources/JailFS.ts index 4139b0f47f2f..1c6f4b45d154 100644 --- a/packages/berry-fslib/sources/JailFS.ts +++ b/packages/berry-fslib/sources/JailFS.ts @@ -1,11 +1,11 @@ -import {posix} from 'path'; +import {posix} from 'path'; import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; -import {NodeFS} from './NodeFS'; +import {FakeFS, WriteFileOptions} from './FakeFS'; +import {NodeFS} from './NodeFS'; export type JailFSOptions = { - baseFs?: FakeFS, + baseFs?: FakeFS; }; export class JailFS extends FakeFS { @@ -212,11 +212,9 @@ export class JailFS extends FakeFS { private fromJailedPath(p: string) { const normalized = posix.normalize(p); - if (posix.isAbsolute(p)) - return posix.resolve(this.target, posix.relative(`/`, p)); + if (posix.isAbsolute(p)) return posix.resolve(this.target, posix.relative(`/`, p)); - if (normalized.match(/^\.\.\//)) - throw new Error(`Resolving this path (${p}) would escape the jail`); + if (normalized.match(/^\.\.\//)) throw new Error(`Resolving this path (${p}) would escape the jail`); return posix.resolve(this.target, p); } diff --git a/packages/berry-fslib/sources/LazyFS.ts b/packages/berry-fslib/sources/LazyFS.ts index 122ba804f7a6..fec7e17f1add 100644 --- a/packages/berry-fslib/sources/LazyFS.ts +++ b/packages/berry-fslib/sources/LazyFS.ts @@ -1,5 +1,5 @@ import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; +import {FakeFS, WriteFileOptions} from './FakeFS'; export type LazyFSFactory = () => FakeFS; @@ -197,8 +197,7 @@ export class LazyFS extends FakeFS { private prepareFs() { let baseFs = this.baseFs; - if (baseFs === null) - baseFs = this.baseFs = this.factory(); + if (baseFs === null) baseFs = this.baseFs = this.factory(); return baseFs; } diff --git a/packages/berry-fslib/sources/NodeFS.ts b/packages/berry-fslib/sources/NodeFS.ts index 4b876ce02381..5ce8a3372194 100644 --- a/packages/berry-fslib/sources/NodeFS.ts +++ b/packages/berry-fslib/sources/NodeFS.ts @@ -1,9 +1,8 @@ -import fs, {Stats} from 'fs'; -import {posix, win32} from 'path'; +import fs, {Stats} from 'fs'; +import {posix, win32} from 'path'; import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; - +import {FakeFS, WriteFileOptions} from './FakeFS'; const PORTABLE_PATH_PREFIX = `/mnt/`; const PORTABLE_PREFIX_REGEXP = /^\/mnt\/([a-z])(?:\/(.*))?$/; @@ -113,7 +112,11 @@ export class NodeFS extends FakeFS { async renamePromise(oldP: string, newP: string) { return await new Promise((resolve, reject) => { - this.realFs.rename(NodeFS.fromPortablePath(oldP), NodeFS.fromPortablePath(newP), this.makeCallback(resolve, reject)); + this.realFs.rename( + NodeFS.fromPortablePath(oldP), + NodeFS.fromPortablePath(newP), + this.makeCallback(resolve, reject), + ); }); } @@ -123,7 +126,12 @@ export class NodeFS extends FakeFS { async copyFilePromise(sourceP: string, destP: string, flags: number = 0) { return await new Promise((resolve, reject) => { - this.realFs.copyFile(NodeFS.fromPortablePath(sourceP), NodeFS.fromPortablePath(destP), flags, this.makeCallback(resolve, reject)); + this.realFs.copyFile( + NodeFS.fromPortablePath(sourceP), + NodeFS.fromPortablePath(destP), + flags, + this.makeCallback(resolve, reject), + ); }); } @@ -193,14 +201,23 @@ export class NodeFS extends FakeFS { const type: 'dir' | 'file' = target.endsWith(`/`) ? `dir` : `file`; return await new Promise((resolve, reject) => { - this.realFs.symlink(NodeFS.fromPortablePath(target.replace(/\/+$/, ``)), NodeFS.fromPortablePath(p), type, this.makeCallback(resolve, reject)); + this.realFs.symlink( + NodeFS.fromPortablePath(target.replace(/\/+$/, ``)), + NodeFS.fromPortablePath(p), + type, + this.makeCallback(resolve, reject), + ); }); } symlinkSync(target: string, p: string) { const type: 'dir' | 'file' = target.endsWith(`/`) ? `dir` : `file`; - return this.realFs.symlinkSync(NodeFS.fromPortablePath(target.replace(/\/+$/, ``)), NodeFS.fromPortablePath(p), type); + return this.realFs.symlinkSync( + NodeFS.fromPortablePath(target.replace(/\/+$/, ``)), + NodeFS.fromPortablePath(p), + type, + ); } readFilePromise(p: string, encoding: 'utf8'): Promise; @@ -250,15 +267,13 @@ export class NodeFS extends FakeFS { } static fromPortablePath(p: string) { - if (process.platform !== `win32`) - return p; + if (process.platform !== `win32`) return p; // Path should look like "/mnt/n/berry/scripts/plugin-pack.js" // And transform to "N:\berry/scripts/plugin-pack.js" const match = p.match(PORTABLE_PREFIX_REGEXP); - if (!match) - return p; + if (!match) return p; const [, drive, pathWithoutPrefix = ''] = match; const windowsPath = pathWithoutPrefix.replace(/\//g, '\\'); @@ -267,21 +282,18 @@ export class NodeFS extends FakeFS { } static toPortablePath(p: string) { - if (process.platform !== `win32`) - return p; + if (process.platform !== `win32`) return p; // Path should look like "N:\berry/scripts/plugin-pack.js" // And transform to "/mnt/n/berry/scripts/plugin-pack.js" // Skip if the path is already portable - if (p.startsWith(PORTABLE_PATH_PREFIX)) - return p; + if (p.startsWith(PORTABLE_PATH_PREFIX)) return p; const {root} = win32.parse(p); // If relative path, just replace win32 slashes by posix slashes - if (!root) - return p.replace(/\\/g, '/'); + if (!root) return p.replace(/\\/g, '/'); const driveLetter = root[0].toLowerCase(); const pathWithoutRoot = p.substr(root.length); diff --git a/packages/berry-fslib/sources/PosixFS.ts b/packages/berry-fslib/sources/PosixFS.ts index dd0346aee420..7231e5044bfb 100644 --- a/packages/berry-fslib/sources/PosixFS.ts +++ b/packages/berry-fslib/sources/PosixFS.ts @@ -1,8 +1,8 @@ -import {posix} from 'path'; +import {posix} from 'path'; import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; -import {NodeFS} from './NodeFS'; +import {FakeFS, WriteFileOptions} from './FakeFS'; +import {NodeFS} from './NodeFS'; export class PosixFS extends FakeFS { private readonly baseFs: FakeFS; diff --git a/packages/berry-fslib/sources/ZipFS.ts b/packages/berry-fslib/sources/ZipFS.ts index 8729e8130aed..a33dfb9b40cb 100644 --- a/packages/berry-fslib/sources/ZipFS.ts +++ b/packages/berry-fslib/sources/ZipFS.ts @@ -1,12 +1,12 @@ -import libzip from '@berry/libzip'; -import {ReadStream, Stats, WriteStream, constants} from 'fs'; -import {posix} from 'path'; -import {PassThrough} from 'stream'; -import {isDate} from 'util'; +import libzip from '@berry/libzip'; +import {ReadStream, Stats, WriteStream, constants} from 'fs'; +import {posix} from 'path'; +import {PassThrough} from 'stream'; +import {isDate} from 'util'; import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; -import {NodeFS} from './NodeFS'; +import {FakeFS, WriteFileOptions} from './FakeFS'; +import {NodeFS} from './NodeFS'; const S_IFMT = 0o170000; @@ -52,15 +52,14 @@ class StatEntry { } export type Options = { - baseFs?: FakeFS, - create?: boolean, - readOnly?: boolean, - stats?: Stats, + baseFs?: FakeFS; + create?: boolean; + readOnly?: boolean; + stats?: Stats; }; function toUnixTimestamp(time: Date | string | number) { - if (typeof time === 'string' && String(+time) === time) - return +time; + if (typeof time === 'string' && String(+time) === time) return +time; // @ts-ignore if (Number.isFinite(time)) { @@ -72,8 +71,7 @@ function toUnixTimestamp(time: Date | string | number) { } // convert to 123.456 UNIX timestamp - if (isDate(time)) - return (time as Date).getTime() / 1000; + if (isDate(time)) return (time as Date).getTime() / 1000; throw new Error(`Invalid time`); } @@ -105,7 +103,21 @@ export class ZipFS extends FakeFS { this.stats = this.baseFs.statSync(p); } catch (error) { if (error.code === `ENOENT` && create) { - this.stats = Object.assign(new StatEntry(), {uid: 0, gid: 0, size: 0, blksize: 0, atimeMs: 0, mtimeMs: 0, ctimeMs: 0, birthtimeMs: 0, atime: new Date(0), mtime: new Date(0), ctime: new Date(0), birthtime: new Date(0), mode: S_IFREG | 0o644}); + this.stats = Object.assign(new StatEntry(), { + uid: 0, + gid: 0, + size: 0, + blksize: 0, + atimeMs: 0, + mtimeMs: 0, + ctimeMs: 0, + birthtimeMs: 0, + atime: new Date(0), + mtime: new Date(0), + ctime: new Date(0), + birthtime: new Date(0), + mode: S_IFREG | 0o644, + }); } else { throw error; } @@ -117,11 +129,9 @@ export class ZipFS extends FakeFS { try { let flags = 0; - if (create) - flags |= libzip.ZIP_CREATE | libzip.ZIP_TRUNCATE; + if (create) flags |= libzip.ZIP_CREATE | libzip.ZIP_TRUNCATE; - if (readOnly) - flags |= libzip.ZIP_RDONLY; + if (readOnly) flags |= libzip.ZIP_RDONLY; this.zip = libzip.open(NodeFS.fromPortablePath(p), flags, errPtr); @@ -142,8 +152,7 @@ export class ZipFS extends FakeFS { for (let t = 0; t < entryCount; ++t) { const raw = libzip.getName(this.zip, t, 0); - if (posix.isAbsolute(raw)) - continue; + if (posix.isAbsolute(raw)) continue; const p = posix.resolve(`/`, raw); @@ -164,16 +173,12 @@ export class ZipFS extends FakeFS { } saveAndClose() { - if (!this.ready) - throw Object.assign(new Error(`EBUSY: archive closed, close`), {code: `EBUSY`}); + if (!this.ready) throw Object.assign(new Error(`EBUSY: archive closed, close`), {code: `EBUSY`}); - const previousMod = this.baseFs.existsSync(this.path) - ? this.baseFs.statSync(this.path).mode & 0o777 - : null; + const previousMod = this.baseFs.existsSync(this.path) ? this.baseFs.statSync(this.path).mode & 0o777 : null; const rc = libzip.close(this.zip); - if (rc === -1) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (rc === -1) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); // Libzip overrides the chmod when writing the archive, which is a weird // behavior I don't totally understand (plus the umask seems bogus in some @@ -214,7 +219,7 @@ export class ZipFS extends FakeFS { path: p, close: () => { clearImmediate(immediate); - } + }, }); const immediate = setImmediate(() => { @@ -351,7 +356,22 @@ export class ZipFS extends FakeFS { const mode = S_IFDIR | 0o755; - return Object.assign(new StatEntry(), {uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode}); + return Object.assign(new StatEntry(), { + uid, + gid, + size, + blksize, + blocks, + atime, + birthtime, + ctime, + mtime, + atimeMs, + birthtimeMs, + ctimeMs, + mtimeMs, + mode, + }); } const entry = this.entries.get(p); @@ -360,13 +380,12 @@ export class ZipFS extends FakeFS { const stat = libzip.struct.statS(); const rc = libzip.statIndex(this.zip, entry, 0, 0, stat); - if (rc === -1) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (rc === -1) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); const uid = this.stats.uid; const gid = this.stats.gid; - const size = (libzip.struct.statSize(stat) >>> 0); + const size = libzip.struct.statSize(stat) >>> 0; const blksize = 512; const blocks = Math.ceil(size / blksize); @@ -382,7 +401,22 @@ export class ZipFS extends FakeFS { const mode = this.getUnixMode(entry, S_IFREG | 0o644); - return Object.assign(new StatEntry(), {uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode}); + return Object.assign(new StatEntry(), { + uid, + gid, + size, + blksize, + blocks, + atime, + birthtime, + ctime, + mtime, + atimeMs, + birthtimeMs, + ctimeMs, + mtimeMs, + mode, + }); } throw new Error(`Unreachable`); @@ -390,12 +424,10 @@ export class ZipFS extends FakeFS { private getUnixMode(index: number, defaultMode: number) { const rc = libzip.file.getExternalAttributes(this.zip, index, 0, 0, libzip.uint08S, libzip.uint32S); - if (rc === -1) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (rc === -1) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); const opsys = libzip.getValue(libzip.uint08S, `i8`) >>> 0; - if (opsys !== libzip.ZIP_OPSYS_UNIX) - return defaultMode; + if (opsys !== libzip.ZIP_OPSYS_UNIX) return defaultMode; return libzip.getValue(libzip.uint32S, `i32`) >>> 16; } @@ -403,8 +435,7 @@ export class ZipFS extends FakeFS { private registerListing(p: string) { let listing = this.listings.get(p); - if (listing) - return listing; + if (listing) return listing; const parentListing = this.registerListing(posix.dirname(p)); listing = new Set(); @@ -423,13 +454,11 @@ export class ZipFS extends FakeFS { } private resolveFilename(reason: string, p: string, resolveLastComponent: boolean = true) { - if (!this.ready) - throw Object.assign(new Error(`EBUSY: archive closed, ${reason}`), {code: `EBUSY`}); + if (!this.ready) throw Object.assign(new Error(`EBUSY: archive closed, ${reason}`), {code: `EBUSY`}); let resolvedP = posix.resolve(`/`, p); - if (resolvedP === `/`) - return `/`; + if (resolvedP === `/`) return `/`; while (true) { const parentP = this.resolveFilename(reason, posix.dirname(resolvedP), true); @@ -440,17 +469,14 @@ export class ZipFS extends FakeFS { if (!isDir && !doesExist) throw Object.assign(new Error(`ENOENT: no such file or directory, ${reason}`), {code: `ENOENT`}); - if (!isDir) - throw Object.assign(new Error(`ENOTDIR: not a directory, ${reason}`), {code: `ENOTDIR`}); + if (!isDir) throw Object.assign(new Error(`ENOTDIR: not a directory, ${reason}`), {code: `ENOTDIR`}); resolvedP = posix.resolve(parentP, posix.basename(resolvedP)); - if (!resolveLastComponent) - break; + if (!resolveLastComponent) break; const index = libzip.name.locate(this.zip, resolvedP); - if (index === -1) - break; + if (index === -1) break; if (this.isSymbolicLink(index)) { const target = this.getFileSource(index).toString(); @@ -464,13 +490,11 @@ export class ZipFS extends FakeFS { } private setFileSource(p: string, content: string | Buffer | ArrayBuffer | DataView) { - if (!Buffer.isBuffer(content)) - content = Buffer.from(content as any); + if (!Buffer.isBuffer(content)) content = Buffer.from(content as any); const buffer = libzip.malloc(content.byteLength); - if (!buffer) - throw new Error(`Couldn't allocate enough memory`); + if (!buffer) throw new Error(`Couldn't allocate enough memory`); // Copy the file into the Emscripten heap const heap = new Uint8Array(libzip.HEAPU8.buffer, buffer, content.byteLength); @@ -488,12 +512,10 @@ export class ZipFS extends FakeFS { private isSymbolicLink(index: number) { const attrs = libzip.file.getExternalAttributes(this.zip, index, 0, 0, libzip.uint08S, libzip.uint32S); - if (attrs === -1) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (attrs === -1) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); const opsys = libzip.getValue(libzip.uint08S, `i8`) >>> 0; - if (opsys !== libzip.ZIP_OPSYS_UNIX) - return false; + if (opsys !== libzip.ZIP_OPSYS_UNIX) return false; const attributes = libzip.getValue(libzip.uint32S, `i32`) >>> 16; return (attributes & S_IFMT) === S_IFLNK; @@ -503,26 +525,21 @@ export class ZipFS extends FakeFS { const stat = libzip.struct.statS(); const rc = libzip.statIndex(this.zip, index, 0, 0, stat); - if (rc === -1) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (rc === -1) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); const size = libzip.struct.statSize(stat); const buffer = libzip.malloc(size); try { const file = libzip.fopenIndex(this.zip, index, 0, 0); - if (file === 0) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (file === 0) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); try { const rc = libzip.fread(file, buffer, size, 0); - if (rc === -1) - throw new Error(libzip.error.strerror(libzip.file.getError(file))); - else if (rc < size) - throw new Error(`Incomplete read`); - else if (rc > size) - throw new Error(`Overread`); + if (rc === -1) throw new Error(libzip.error.strerror(libzip.file.getError(file))); + else if (rc < size) throw new Error(`Incomplete read`); + else if (rc > size) throw new Error(`Overread`); const memory = libzip.HEAPU8.subarray(buffer, buffer + size); const data = Buffer.from(memory); @@ -544,15 +561,13 @@ export class ZipFS extends FakeFS { const resolvedP = this.resolveFilename(`chmod '${p}'`, p, false); // We silently ignore chmod requests for directories - if (this.listings.has(resolvedP)) - return; + if (this.listings.has(resolvedP)) return; const entry = this.entries.get(resolvedP); - if (entry === undefined) - throw new Error(`Unreachable`); + if (entry === undefined) throw new Error(`Unreachable`); const oldMod = this.getUnixMode(entry, S_IFREG | 0o000); - const newMod = oldMod & (~0o777) | mask; + const newMod = (oldMod & ~0o777) | mask; const rc = libzip.file.setExternalAttributes(this.zip, entry, 0, 0, libzip.ZIP_OPSYS_UNIX, newMod << 16); if (rc === -1) { @@ -574,7 +589,9 @@ export class ZipFS extends FakeFS { copyFileSync(sourceP: string, destP: string, flags: number = 0) { if ((flags & constants.COPYFILE_FICLONE_FORCE) !== 0) - throw Object.assign(new Error(`ENOSYS: unsupported clone operation, copyfile '${sourceP}' -> ${destP}'`), {code: `ENOSYS`}); + throw Object.assign(new Error(`ENOSYS: unsupported clone operation, copyfile '${sourceP}' -> ${destP}'`), { + code: `ENOSYS`, + }); const resolvedSourceP = this.resolveFilename(`copyfile '${sourceP} -> ${destP}'`, sourceP); const indexSource = this.entries.get(resolvedSourceP); @@ -585,8 +602,13 @@ export class ZipFS extends FakeFS { const resolvedDestP = this.resolveFilename(`copyfile '${sourceP}' -> ${destP}'`, destP); const indexDest = this.entries.get(resolvedDestP); - if ((flags & (constants.COPYFILE_EXCL | constants.COPYFILE_FICLONE_FORCE)) !== 0 && typeof indexDest !== `undefined`) - throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), {code: `EEXIST`}); + if ( + (flags & (constants.COPYFILE_EXCL | constants.COPYFILE_FICLONE_FORCE)) !== 0 && + typeof indexDest !== `undefined` + ) + throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), { + code: `EEXIST`, + }); const source = this.getFileSource(indexSource); const newIndex = this.setFileSource(resolvedDestP, source); @@ -613,13 +635,10 @@ export class ZipFS extends FakeFS { let encoding = null; - if (typeof opts === `string`) - encoding = opts; - else if (typeof opts === `object` && opts.encoding) - encoding = opts.encoding; + if (typeof opts === `string`) encoding = opts; + else if (typeof opts === `object` && opts.encoding) encoding = opts.encoding; - if (encoding !== null) - content = content.toString(encoding); + if (encoding !== null) content = content.toString(encoding); const newIndex = this.setFileSource(resolvedP, content); @@ -657,13 +676,10 @@ export class ZipFS extends FakeFS { } private utimesImpl(resolvedP: string, mtime: Date | string | number) { - if (this.listings.has(resolvedP)) - if (!this.entries.has(resolvedP)) - this.hydrateDirectory(resolvedP); + if (this.listings.has(resolvedP)) if (!this.entries.has(resolvedP)) this.hydrateDirectory(resolvedP); const entry = this.entries.get(resolvedP); - if (entry === undefined) - throw new Error(`Unreachable`); + if (entry === undefined) throw new Error(`Unreachable`); const rc = libzip.file.setMtime(this.zip, entry, 0, toUnixTimestamp(mtime), 0); if (rc === -1) { @@ -694,8 +710,7 @@ export class ZipFS extends FakeFS { private hydrateDirectory(resolvedP: string) { const index = libzip.dir.add(this.zip, posix.relative(`/`, resolvedP)); - if (index === -1) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (index === -1) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); this.registerListing(resolvedP); this.registerEntry(resolvedP, index); @@ -711,7 +726,9 @@ export class ZipFS extends FakeFS { const resolvedP = this.resolveFilename(`symlink '${target}' -> '${p}'`, p); if (this.listings.has(resolvedP)) - throw Object.assign(new Error(`EISDIR: illegal operation on a directory, symlink '${target}' -> '${p}'`), {code: `EISDIR`}); + throw Object.assign(new Error(`EISDIR: illegal operation on a directory, symlink '${target}' -> '${p}'`), { + code: `EISDIR`, + }); if (this.entries.has(resolvedP)) throw Object.assign(new Error(`EEXIST: file already exists, symlink '${target}' -> '${p}'`), {code: `EEXIST`}); @@ -720,7 +737,14 @@ export class ZipFS extends FakeFS { this.registerEntry(resolvedP, index); - const rc = libzip.file.setExternalAttributes(this.zip, index, 0, 0, libzip.ZIP_OPSYS_UNIX, (0o120000 | 0o777) << 16); + const rc = libzip.file.setExternalAttributes( + this.zip, + index, + 0, + 0, + libzip.ZIP_OPSYS_UNIX, + (0o120000 | 0o777) << 16, + ); if (rc === -1) { throw new Error(libzip.error.strerror(libzip.getError(this.zip))); } @@ -759,8 +783,7 @@ export class ZipFS extends FakeFS { throw Object.assign(new Error(`EISDIR: illegal operation on a directory, read`), {code: `EISDIR`}); const entry = this.entries.get(resolvedP); - if (entry === undefined) - throw new Error(`Unreachable`); + if (entry === undefined) throw new Error(`Unreachable`); const data = this.getFileSource(entry); @@ -804,12 +827,10 @@ export class ZipFS extends FakeFS { const entry = this.entries.get(resolvedP); - if (entry === undefined) - throw new Error(`Unreachable`); + if (entry === undefined) throw new Error(`Unreachable`); const rc = libzip.file.getExternalAttributes(this.zip, entry, 0, 0, libzip.uint08S, libzip.uint32S); - if (rc === -1) - throw new Error(libzip.error.strerror(libzip.getError(this.zip))); + if (rc === -1) throw new Error(libzip.error.strerror(libzip.getError(this.zip))); const opsys = libzip.getValue(libzip.uint08S, `i8`) >>> 0; if (opsys !== libzip.ZIP_OPSYS_UNIX) @@ -821,4 +842,4 @@ export class ZipFS extends FakeFS { return this.getFileSource(entry).toString(); } -}; +} diff --git a/packages/berry-fslib/sources/ZipOpenFS.ts b/packages/berry-fslib/sources/ZipOpenFS.ts index 2f2420299ca9..1a07d40f6d18 100644 --- a/packages/berry-fslib/sources/ZipOpenFS.ts +++ b/packages/berry-fslib/sources/ZipOpenFS.ts @@ -1,15 +1,15 @@ -import {constants} from 'fs'; -import {posix} from 'path'; +import {constants} from 'fs'; +import {posix} from 'path'; import {CreateReadStreamOptions, CreateWriteStreamOptions} from './FakeFS'; -import {FakeFS, WriteFileOptions} from './FakeFS'; -import {NodeFS} from './NodeFS'; -import {ZipFS} from './ZipFS'; +import {FakeFS, WriteFileOptions} from './FakeFS'; +import {NodeFS} from './NodeFS'; +import {ZipFS} from './ZipFS'; export type ZipOpenFSOptions = { - baseFs?: FakeFS, - filter?: RegExp | null, - useCache?: boolean, + baseFs?: FakeFS; + filter?: RegExp | null; + useCache?: boolean; }; export class ZipOpenFS extends FakeFS { @@ -76,19 +76,27 @@ export class ZipOpenFS extends FakeFS { } async openPromise(p: string, flags: string, mode?: number) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.openPromise(p, flags, mode); - }, async (zipFs, {archivePath, subPath}) => { - throw new Error(`Unsupported action (we wouldn't be able to disambiguate the close)`); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.openPromise(p, flags, mode); + }, + async (zipFs, {archivePath, subPath}) => { + throw new Error(`Unsupported action (we wouldn't be able to disambiguate the close)`); + }, + ); } openSync(p: string, flags: string, mode?: number) { - return this.makeCallSync(p, () => { - return this.baseFs.openSync(p, flags, mode); - }, (zipFs, {archivePath, subPath}) => { - throw new Error(`Unsupported action (we wouldn't be able to disambiguate the close)`); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.openSync(p, flags, mode); + }, + (zipFs, {archivePath, subPath}) => { + throw new Error(`Unsupported action (we wouldn't be able to disambiguate the close)`); + }, + ); } async closePromise(fd: number) { @@ -100,433 +108,626 @@ export class ZipOpenFS extends FakeFS { } createReadStream(p: string, opts?: CreateReadStreamOptions) { - return this.makeCallSync(p, () => { - return this.baseFs.createReadStream(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.createReadStream(subPath, opts); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.createReadStream(p, opts); + }, + (zipFs, {subPath}) => { + return zipFs.createReadStream(subPath, opts); + }, + ); } createWriteStream(p: string, opts?: CreateWriteStreamOptions) { - return this.makeCallSync(p, () => { - return this.baseFs.createWriteStream(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.createWriteStream(subPath, opts); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.createWriteStream(p, opts); + }, + (zipFs, {subPath}) => { + return zipFs.createWriteStream(subPath, opts); + }, + ); } async realpathPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.realpathPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return posix.resolve(archivePath, posix.relative(`/`, await zipFs.realpathPromise(subPath))); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.realpathPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return posix.resolve(archivePath, posix.relative(`/`, await zipFs.realpathPromise(subPath))); + }, + ); } realpathSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.realpathSync(p); - }, (zipFs, {archivePath, subPath}) => { - return posix.resolve(archivePath, posix.relative(`/`, zipFs.realpathSync(subPath))); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.realpathSync(p); + }, + (zipFs, {archivePath, subPath}) => { + return posix.resolve(archivePath, posix.relative(`/`, zipFs.realpathSync(subPath))); + }, + ); } async existsPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.existsPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.existsPromise(subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.existsPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.existsPromise(subPath); + }, + ); } existsSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.existsSync(p); - }, (zipFs, {subPath}) => { - return zipFs.existsSync(subPath); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.existsSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.existsSync(subPath); + }, + ); } async accessPromise(p: string, mode?: number) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.accessPromise(p, mode); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.accessPromise(subPath, mode); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.accessPromise(p, mode); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.accessPromise(subPath, mode); + }, + ); } accessSync(p: string, mode?: number) { - return this.makeCallSync(p, () => { - return this.baseFs.accessSync(p, mode); - }, (zipFs, {subPath}) => { - return zipFs.accessSync(subPath, mode); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.accessSync(p, mode); + }, + (zipFs, {subPath}) => { + return zipFs.accessSync(subPath, mode); + }, + ); } async statPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.statPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.statPromise(subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.statPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.statPromise(subPath); + }, + ); } statSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.statSync(p); - }, (zipFs, {subPath}) => { - return zipFs.statSync(subPath); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.statSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.statSync(subPath); + }, + ); } async lstatPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.lstatPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.lstatPromise(subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.lstatPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.lstatPromise(subPath); + }, + ); } lstatSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.lstatSync(p); - }, (zipFs, {subPath}) => { - return zipFs.lstatSync(subPath); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.lstatSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.lstatSync(subPath); + }, + ); } async chmodPromise(p: string, mask: number) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.chmodPromise(p, mask); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.chmodPromise(subPath, mask); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.chmodPromise(p, mask); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.chmodPromise(subPath, mask); + }, + ); } chmodSync(p: string, mask: number) { - return this.makeCallSync(p, () => { - return this.baseFs.chmodSync(p, mask); - }, (zipFs, {subPath}) => { - return zipFs.chmodSync(subPath, mask); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.chmodSync(p, mask); + }, + (zipFs, {subPath}) => { + return zipFs.chmodSync(subPath, mask); + }, + ); } async renamePromise(oldP: string, newP: string) { - return await this.makeCallPromise(oldP, async () => { - return await this.makeCallPromise(newP, async () => { - return await this.baseFs.renamePromise(oldP, newP); - }, async () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }); - }, async (zipFsO, {archivePath: archivePathO, subPath: subPathO}) => { - return await this.makeCallPromise(newP, async () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }, async (zipFsN, {archivePath: archivePathN, subPath: subPathN}) => { - if (zipFsO !== zipFsN) { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - } else { - return await zipFsO.renamePromise(subPathO, subPathN); - } - }); - }); + return await this.makeCallPromise( + oldP, + async () => { + return await this.makeCallPromise( + newP, + async () => { + return await this.baseFs.renamePromise(oldP, newP); + }, + async () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); + }, + ); + }, + async (zipFsO, {archivePath: archivePathO, subPath: subPathO}) => { + return await this.makeCallPromise( + newP, + async () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); + }, + async (zipFsN, {archivePath: archivePathN, subPath: subPathN}) => { + if (zipFsO !== zipFsN) { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); + } else { + return await zipFsO.renamePromise(subPathO, subPathN); + } + }, + ); + }, + ); } renameSync(oldP: string, newP: string) { - return this.makeCallSync(oldP, () => { - return this.makeCallSync(newP, () => { - return this.baseFs.renameSync(oldP, newP); - }, async () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }); - }, (zipFsO, {archivePath: archivePathO, subPath: subPathO}) => { - return this.makeCallSync(newP, () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }, (zipFsN, {archivePath: archivePathN, subPath: subPathN}) => { - if (zipFsO !== zipFsN) { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - } else { - return zipFsO.renameSync(subPathO, subPathN); - } - }); - }); + return this.makeCallSync( + oldP, + () => { + return this.makeCallSync( + newP, + () => { + return this.baseFs.renameSync(oldP, newP); + }, + async () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); + }, + ); + }, + (zipFsO, {archivePath: archivePathO, subPath: subPathO}) => { + return this.makeCallSync( + newP, + () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); + }, + (zipFsN, {archivePath: archivePathN, subPath: subPathN}) => { + if (zipFsO !== zipFsN) { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); + } else { + return zipFsO.renameSync(subPathO, subPathN); + } + }, + ); + }, + ); } async copyFilePromise(sourceP: string, destP: string, flags: number = 0) { const fallback = async (sourceFs: FakeFS, sourceP: string, destFs: FakeFS, destP: string) => { if ((flags & constants.COPYFILE_FICLONE_FORCE) !== 0) - throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), {code: `EXDEV`}); - if ((flags & constants.COPYFILE_EXCL) && await this.existsPromise(sourceP)) - throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), {code: `EEXIST`}); + throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), { + code: `EXDEV`, + }); + if (flags & constants.COPYFILE_EXCL && (await this.existsPromise(sourceP))) + throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), { + code: `EEXIST`, + }); let content; try { content = await sourceFs.readFilePromise(sourceP); } catch (error) { - throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), {code: `EINVAL`}); + throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), { + code: `EINVAL`, + }); } await destFs.writeFilePromise(destP, content); }; - return await this.makeCallPromise(sourceP, async () => { - return await this.makeCallPromise(destP, async () => { - return await this.baseFs.copyFilePromise(sourceP, destP, flags); - }, async (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { - return await fallback(this.baseFs, sourceP, zipFsD, subPathD); - }); - }, async (zipFsS, {archivePath: archivePathS, subPath: subPathS}) => { - return await this.makeCallPromise(destP, async () => { - return await fallback(zipFsS, subPathS, this.baseFs, destP); - }, async (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { - if (zipFsS !== zipFsD) { - return await fallback(zipFsS, subPathS, zipFsD, subPathD); - } else { - return await zipFsS.copyFilePromise(subPathS, subPathD, flags); - } - }); - }); + return await this.makeCallPromise( + sourceP, + async () => { + return await this.makeCallPromise( + destP, + async () => { + return await this.baseFs.copyFilePromise(sourceP, destP, flags); + }, + async (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { + return await fallback(this.baseFs, sourceP, zipFsD, subPathD); + }, + ); + }, + async (zipFsS, {archivePath: archivePathS, subPath: subPathS}) => { + return await this.makeCallPromise( + destP, + async () => { + return await fallback(zipFsS, subPathS, this.baseFs, destP); + }, + async (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { + if (zipFsS !== zipFsD) { + return await fallback(zipFsS, subPathS, zipFsD, subPathD); + } else { + return await zipFsS.copyFilePromise(subPathS, subPathD, flags); + } + }, + ); + }, + ); } copyFileSync(sourceP: string, destP: string, flags: number = 0) { const fallback = (sourceFs: FakeFS, sourceP: string, destFs: FakeFS, destP: string) => { if ((flags & constants.COPYFILE_FICLONE_FORCE) !== 0) - throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), {code: `EXDEV`}); - if ((flags & constants.COPYFILE_EXCL) && this.existsSync(sourceP)) - throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), {code: `EEXIST`}); + throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), { + code: `EXDEV`, + }); + if (flags & constants.COPYFILE_EXCL && this.existsSync(sourceP)) + throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), { + code: `EEXIST`, + }); let content; try { content = sourceFs.readFileSync(sourceP); } catch (error) { - throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), {code: `EINVAL`}); + throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), { + code: `EINVAL`, + }); } destFs.writeFileSync(destP, content); }; - return this.makeCallSync(sourceP, () => { - return this.makeCallSync(destP, () => { - return this.baseFs.copyFileSync(sourceP, destP, flags); - }, (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { - return fallback(this.baseFs, sourceP, zipFsD, subPathD); - }); - }, (zipFsS, {archivePath: archivePathS, subPath: subPathS}) => { - return this.makeCallSync(destP, () => { - return fallback(zipFsS, subPathS, this.baseFs, destP); - }, (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { - if (zipFsS !== zipFsD) { - return fallback(zipFsS, subPathS, zipFsD, subPathD); - } else { - return zipFsS.copyFileSync(subPathS, subPathD, flags); - } - }); - }); + return this.makeCallSync( + sourceP, + () => { + return this.makeCallSync( + destP, + () => { + return this.baseFs.copyFileSync(sourceP, destP, flags); + }, + (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { + return fallback(this.baseFs, sourceP, zipFsD, subPathD); + }, + ); + }, + (zipFsS, {archivePath: archivePathS, subPath: subPathS}) => { + return this.makeCallSync( + destP, + () => { + return fallback(zipFsS, subPathS, this.baseFs, destP); + }, + (zipFsD, {archivePath: archivePathD, subPath: subPathD}) => { + if (zipFsS !== zipFsD) { + return fallback(zipFsS, subPathS, zipFsD, subPathD); + } else { + return zipFsS.copyFileSync(subPathS, subPathD, flags); + } + }, + ); + }, + ); } async writeFilePromise(p: string, content: string | Buffer | ArrayBuffer | DataView, opts?: WriteFileOptions) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.writeFilePromise(p, content, opts); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.writeFilePromise(subPath, content, opts); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.writeFilePromise(p, content, opts); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.writeFilePromise(subPath, content, opts); + }, + ); } writeFileSync(p: string, content: string | Buffer | ArrayBuffer | DataView, opts?: WriteFileOptions) { - return this.makeCallSync(p, () => { - return this.baseFs.writeFileSync(p, content, opts); - }, (zipFs, {subPath}) => { - return zipFs.writeFileSync(subPath, content, opts); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.writeFileSync(p, content, opts); + }, + (zipFs, {subPath}) => { + return zipFs.writeFileSync(subPath, content, opts); + }, + ); } async unlinkPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.unlinkPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.unlinkPromise(subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.unlinkPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.unlinkPromise(subPath); + }, + ); } unlinkSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.unlinkSync(p); - }, (zipFs, {subPath}) => { - return zipFs.unlinkSync(subPath); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.unlinkSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.unlinkSync(subPath); + }, + ); } async utimesPromise(p: string, atime: Date | string | number, mtime: Date | string | number) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.utimesPromise(p, atime, mtime); - }, async (zipFs, {subPath}) => { - return await zipFs.utimesPromise(subPath, atime, mtime); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.utimesPromise(p, atime, mtime); + }, + async (zipFs, {subPath}) => { + return await zipFs.utimesPromise(subPath, atime, mtime); + }, + ); } utimesSync(p: string, atime: Date | string | number, mtime: Date | string | number) { - return this.makeCallSync(p, () => { - return this.baseFs.utimesSync(p, atime, mtime); - }, (zipFs, {subPath}) => { - return zipFs.utimesSync(subPath, atime, mtime); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.utimesSync(p, atime, mtime); + }, + (zipFs, {subPath}) => { + return zipFs.utimesSync(subPath, atime, mtime); + }, + ); } async mkdirPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.mkdirPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.mkdirPromise(subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.mkdirPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.mkdirPromise(subPath); + }, + ); } mkdirSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.mkdirSync(p); - }, (zipFs, {subPath}) => { - return zipFs.mkdirSync(subPath); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.mkdirSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.mkdirSync(subPath); + }, + ); } async rmdirPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.rmdirPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.rmdirPromise(subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.rmdirPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.rmdirPromise(subPath); + }, + ); } rmdirSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.rmdirSync(p); - }, (zipFs, {subPath}) => { - return zipFs.rmdirSync(subPath); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.rmdirSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.rmdirSync(subPath); + }, + ); } async symlinkPromise(target: string, p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.symlinkPromise(target, p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.symlinkPromise(target, subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.symlinkPromise(target, p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.symlinkPromise(target, subPath); + }, + ); } symlinkSync(target: string, p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.symlinkSync(target, p); - }, (zipFs, {subPath}) => { - return zipFs.symlinkSync(target, subPath); - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.symlinkSync(target, p); + }, + (zipFs, {subPath}) => { + return zipFs.symlinkSync(target, subPath); + }, + ); } readFilePromise(p: string, encoding?: 'utf8'): Promise; readFilePromise(p: string, encoding?: string): Promise; async readFilePromise(p: string, encoding?: string) { - return this.makeCallPromise(p, async () => { - // This weird switch is required to tell TypeScript that the signatures are proper (otherwise it thinks that only the generic one is covered) - switch (encoding) { - case `utf8`: - return await this.baseFs.readFilePromise(p, encoding); - default: - return await this.baseFs.readFilePromise(p, encoding); - } - }, async (zipFs, {subPath}) => { - return await zipFs.readFilePromise(subPath, encoding); - }); + return this.makeCallPromise( + p, + async () => { + // This weird switch is required to tell TypeScript that the signatures are proper (otherwise it thinks that only the generic one is covered) + switch (encoding) { + case `utf8`: + return await this.baseFs.readFilePromise(p, encoding); + default: + return await this.baseFs.readFilePromise(p, encoding); + } + }, + async (zipFs, {subPath}) => { + return await zipFs.readFilePromise(subPath, encoding); + }, + ); } readFileSync(p: string, encoding?: 'utf8'): string; readFileSync(p: string, encoding?: string): Buffer; readFileSync(p: string, encoding?: string) { - return this.makeCallSync(p, () => { - // This weird switch is required to tell TypeScript that the signatures are proper (otherwise it thinks that only the generic one is covered) - switch (encoding) { - case `utf8`: - return this.baseFs.readFileSync(p, encoding); - default: - return this.baseFs.readFileSync(p, encoding); - } - }, (zipFs, {subPath}) => { - return zipFs.readFileSync(subPath, encoding); - }); + return this.makeCallSync( + p, + () => { + // This weird switch is required to tell TypeScript that the signatures are proper (otherwise it thinks that only the generic one is covered) + switch (encoding) { + case `utf8`: + return this.baseFs.readFileSync(p, encoding); + default: + return this.baseFs.readFileSync(p, encoding); + } + }, + (zipFs, {subPath}) => { + return zipFs.readFileSync(subPath, encoding); + }, + ); } async readdirPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.readdirPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.readdirPromise(subPath); - }, { - requireSubpath: false, - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.readdirPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.readdirPromise(subPath); + }, + { + requireSubpath: false, + }, + ); } readdirSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.readdirSync(p); - }, (zipFs, {subPath}) => { - return zipFs.readdirSync(subPath); - }, { - requireSubpath: false, - }); + return this.makeCallSync( + p, + () => { + return this.baseFs.readdirSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.readdirSync(subPath); + }, + { + requireSubpath: false, + }, + ); } async readlinkPromise(p: string) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.readlinkPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - return await zipFs.readlinkPromise(subPath); - }); + return await this.makeCallPromise( + p, + async () => { + return await this.baseFs.readlinkPromise(p); + }, + async (zipFs, {archivePath, subPath}) => { + return await zipFs.readlinkPromise(subPath); + }, + ); } readlinkSync(p: string) { - return this.makeCallSync(p, () => { - return this.baseFs.readlinkSync(p); - }, (zipFs, {subPath}) => { - return zipFs.readlinkSync(subPath); - }) - } - - private async makeCallPromise(p: string, discard: () => Promise, accept: (zipFS: ZipFS, zipInfo: {archivePath: string, subPath: string}) => Promise, {requireSubpath = true}: {requireSubpath?: boolean} = {}): Promise { + return this.makeCallSync( + p, + () => { + return this.baseFs.readlinkSync(p); + }, + (zipFs, {subPath}) => { + return zipFs.readlinkSync(subPath); + }, + ); + } + + private async makeCallPromise( + p: string, + discard: () => Promise, + accept: (zipFS: ZipFS, zipInfo: {archivePath: string; subPath: string}) => Promise, + {requireSubpath = true}: {requireSubpath?: boolean} = {}, + ): Promise { p = posix.normalize(posix.resolve(`/`, p)); const zipInfo = this.findZip(p); - if (!zipInfo) - return await discard(); - - if (requireSubpath && zipInfo.subPath === `/`) - return await discard(); + if (!zipInfo) return await discard(); + + if (requireSubpath && zipInfo.subPath === `/`) return await discard(); return await this.getZipPromise(zipInfo.archivePath, async zipFs => await accept(zipFs, zipInfo)); } - private makeCallSync(p: string, discard: () => T, accept: (zipFS: ZipFS, zipInfo: {archivePath: string, subPath: string}) => T, {requireSubpath = true}: {requireSubpath?: boolean} = {}): T { + private makeCallSync( + p: string, + discard: () => T, + accept: (zipFS: ZipFS, zipInfo: {archivePath: string; subPath: string}) => T, + {requireSubpath = true}: {requireSubpath?: boolean} = {}, + ): T { p = posix.normalize(posix.resolve(`/`, p)); const zipInfo = this.findZip(p); - if (!zipInfo) - return discard(); + if (!zipInfo) return discard(); - if (requireSubpath && zipInfo.subPath === `/`) - return discard(); + if (requireSubpath && zipInfo.subPath === `/`) return discard(); return this.getZipSync(zipInfo.archivePath, zipFs => accept(zipFs, zipInfo)); } private findZip(p: string) { - if (this.filter && !this.filter.test(p)) - return null; + if (this.filter && !this.filter.test(p)) return null; const parts = p.split(/\//g); for (let t = 2; t <= parts.length; ++t) { const archivePath = parts.slice(0, t).join(`/`); - if (this.notZip.has(archivePath)) - continue; + if (this.notZip.has(archivePath)) continue; - if (this.isZip.has(archivePath)) - return {archivePath, subPath: posix.resolve(`/`, parts.slice(t).join(`/`))}; + if (this.isZip.has(archivePath)) return {archivePath, subPath: posix.resolve(`/`, parts.slice(t).join(`/`))}; let realArchivePath = archivePath; let stat; @@ -566,7 +767,10 @@ export class ZipOpenFS extends FakeFS { let zipFs = this.zipInstances.get(p); if (!zipFs) - this.zipInstances.set(p, zipFs = new ZipFS(p, {baseFs: this.baseFs, stats: await this.baseFs.statPromise(p)})); + this.zipInstances.set( + p, + (zipFs = new ZipFS(p, {baseFs: this.baseFs, stats: await this.baseFs.statPromise(p)})), + ); return await accept(zipFs); } else { @@ -584,8 +788,7 @@ export class ZipOpenFS extends FakeFS { if (this.zipInstances) { let zipFs = this.zipInstances.get(p); - if (!zipFs) - this.zipInstances.set(p, zipFs = new ZipFS(p, {baseFs: this.baseFs})); + if (!zipFs) this.zipInstances.set(p, (zipFs = new ZipFS(p, {baseFs: this.baseFs}))); return accept(zipFs); } else { diff --git a/packages/berry-fslib/sources/index.ts b/packages/berry-fslib/sources/index.ts index 4db488c87c43..04166ba3679c 100644 --- a/packages/berry-fslib/sources/index.ts +++ b/packages/berry-fslib/sources/index.ts @@ -1,16 +1,16 @@ -import fs from 'fs'; - -import {FakeFS} from './FakeFS'; -import {NodeFS} from './NodeFS'; - -export {AliasFS} from './AliasFS'; -export {FakeFS} from './FakeFS'; -export {CwdFS} from './CwdFS'; -export {JailFS} from './JailFS'; -export {LazyFS} from './LazyFS'; -export {NodeFS} from './NodeFS'; -export {PosixFS} from './PosixFS'; -export {ZipFS} from './ZipFS'; +import fs from 'fs'; + +import {FakeFS} from './FakeFS'; +import {NodeFS} from './NodeFS'; + +export {AliasFS} from './AliasFS'; +export {FakeFS} from './FakeFS'; +export {CwdFS} from './CwdFS'; +export {JailFS} from './JailFS'; +export {LazyFS} from './LazyFS'; +export {NodeFS} from './NodeFS'; +export {PosixFS} from './PosixFS'; +export {ZipFS} from './ZipFS'; export {ZipOpenFS} from './ZipOpenFS'; function wrapSync(fn: Function) { @@ -18,16 +18,14 @@ function wrapSync(fn: Function) { } function wrapAsync(fn: Function) { - return function (... args: Array) { - const cb = typeof args[args.length - 1] === `function` - ? args.pop() - : null; + return function(...args: Array) { + const cb = typeof args[args.length - 1] === `function` ? args.pop() : null; setImmediate(() => { let error, result; try { - result = fn(... args); + result = fn(...args); } catch (caught) { error = caught; } @@ -86,30 +84,36 @@ export function patchFs(patchedFs: typeof fs, fakeFs: FakeFS): void { }; (patchedFs as any).exists = (p: string, callback?: (result: boolean) => any) => { - fakeFs.existsPromise(p).then(result => { - if (callback) { - callback(result); - } - }, () => { - if (callback) { - callback(false); - } - }); + fakeFs.existsPromise(p).then( + result => { + if (callback) { + callback(result); + } + }, + () => { + if (callback) { + callback(false); + } + }, + ); }; for (const fnName of ASYNC_IMPLEMENTATIONS) { const fakeImpl: Function = (fakeFs as any)[fnName].bind(fakeFs); const origName = fnName.replace(/Promise$/, ``); - (patchedFs as any)[origName] = (... args: Array) => { + (patchedFs as any)[origName] = (...args: Array) => { const hasCallback = typeof args[args.length - 1] === `function`; const callback = hasCallback ? args.pop() : () => {}; - fakeImpl(... args).then((result: any) => { - callback(undefined, result); - }, (error: Error) => { - callback(error); - }); + fakeImpl(...args).then( + (result: any) => { + callback(undefined, result); + }, + (error: Error) => { + callback(error); + }, + ); }; } diff --git a/packages/berry-json-proxy/sources/index.ts b/packages/berry-json-proxy/sources/index.ts index 4b54ffaf356c..2b62deb75e84 100644 --- a/packages/berry-json-proxy/sources/index.ts +++ b/packages/berry-json-proxy/sources/index.ts @@ -1,2 +1,2 @@ -export {makeTracker, Tracker} from './makeTracker'; +export {makeTracker, Tracker} from './makeTracker'; export {makeUpdater, updateAndSave} from './makeUpdater'; diff --git a/packages/berry-json-proxy/sources/makeTracker.ts b/packages/berry-json-proxy/sources/makeTracker.ts index 1450d8ff806d..b40130048864 100644 --- a/packages/berry-json-proxy/sources/makeTracker.ts +++ b/packages/berry-json-proxy/sources/makeTracker.ts @@ -24,9 +24,8 @@ function cloneValue(value: any): any { function cloneValueChecked(value: any, version: Object) { if (typeof value === `object` && value !== null) { - if (value[VERSION] === version) - return value; - + if (value[VERSION] === version) return value; + const clone = cloneValue(value); clone[VERSION] = version; @@ -45,32 +44,27 @@ function cloneValueDeep(value: any, filter: TrackingFilter): any { } else if (value instanceof Set) { const clone = new Set(); - for (const subValue of value.values()) - clone.add(cloneValueDeep(subValue, filter)); + for (const subValue of value.values()) clone.add(cloneValueDeep(subValue, filter)); return clone; } else if (value instanceof Map) { const clone = new Map(); - for (const [key, subValue] of value) - clone.set(key, cloneValueDeep(subValue, filter)); + for (const [key, subValue] of value) clone.set(key, cloneValueDeep(subValue, filter)); return clone; } else { const clone = cloneObject(value); for (const key of Object.keys(clone)) { - if (filter !== true && !filter[key]) - continue; - - const nextFilter = filter !== true - ? filter[key] - : true; - + if (filter !== true && !filter[key]) continue; + + const nextFilter = filter !== true ? filter[key] : true; + // @ts-ignore clone[key] = cloneValueDeep(clone[key], nextFilter); } - + return clone; } } else { @@ -84,55 +78,37 @@ function compareValuesDeep(a: any, b: any): boolean { } else if ((a == null) !== (b == null)) { return false; } else if (Array.isArray(a)) { - if (!Array.isArray(b)) - return false; - if (a.length !== b.length) - return false; - - for (let t = 0, T = a.length; t < T; ++t) - if (!compareValuesDeep(a[t], b[t])) - return false; - + if (!Array.isArray(b)) return false; + if (a.length !== b.length) return false; + + for (let t = 0, T = a.length; t < T; ++t) if (!compareValuesDeep(a[t], b[t])) return false; + return true; } else if (a instanceof Set) { - if (!(b instanceof Set)) - return false; - if (a.size !== b.size) - return false; - - for (const key of a.entries()) - if (!b.has(key)) - return false; - + if (!(b instanceof Set)) return false; + if (a.size !== b.size) return false; + + for (const key of a.entries()) if (!b.has(key)) return false; + return true; } else if (a instanceof Map) { - if (!(b instanceof Map)) - return false; - if (a.size !== b.size) - return false; - - for (const [key, value] of a.entries()) - if (!compareValuesDeep(value, b.get(key))) - return false; - + if (!(b instanceof Map)) return false; + if (a.size !== b.size) return false; + + for (const [key, value] of a.entries()) if (!compareValuesDeep(value, b.get(key))) return false; + return true; } else if (a.constructor === Object) { - if (b.constructor !== Object) - return false; - + if (b.constructor !== Object) return false; + const aKeys = Object.keys(a); const bKeys = Object.keys(b); - - if (aKeys.length !== bKeys.length) - return false; - - for (let t = 0, T = aKeys.length; t < T; ++t) - if (aKeys[t] !== bKeys[t]) - return false; - - for (let t = 0, T = aKeys.length; t < T; ++t) - if (!compareValuesDeep(a[aKeys[t]], b[bKeys[t]])) - return false; + + if (aKeys.length !== bKeys.length) return false; + + for (let t = 0, T = aKeys.length; t < T; ++t) if (aKeys[t] !== bKeys[t]) return false; + + for (let t = 0, T = aKeys.length; t < T; ++t) if (!compareValuesDeep(a[aKeys[t]], b[bKeys[t]])) return false; return true; } else { @@ -143,74 +119,83 @@ function compareValuesDeep(a: any, b: any): boolean { const proxyHandlerSet = (version: TrackingVersion, filter: TrackingFilter, ensureCloning: () => Set) => ({ get(source: Set, prop: string | number | symbol): any { switch (prop) { - case `clear`: return () => { - const clonedParent = ensureCloning(); - clonedParent.clear(); + case `clear`: + return () => { + const clonedParent = ensureCloning(); + clonedParent.clear(); - source.clear(); - }; + source.clear(); + }; - case `delete`: return (key: any) => { - const clonedParent = ensureCloning(); - clonedParent.delete(key); + case `delete`: + return (key: any) => { + const clonedParent = ensureCloning(); + clonedParent.delete(key); - source.delete(key); - }; + source.delete(key); + }; - case `add`: return (key: any) => { - const clonedParent = ensureCloning(); - clonedParent.add(key); + case `add`: + return (key: any) => { + const clonedParent = ensureCloning(); + clonedParent.add(key); - source.add(key); - }; + source.add(key); + }; - // @ts-ignore - default: return source[prop]; + default: + // @ts-ignore + return source[prop]; } - } + }, }); const proxyHandlerMap = (version: TrackingVersion, filter: TrackingFilter, ensureCloning: () => Map) => ({ get(source: Map, prop: string | number | symbol): any { switch (prop) { - case `clear`: return () => { - const clonedParent = ensureCloning(); - clonedParent.clear(); + case `clear`: + return () => { + const clonedParent = ensureCloning(); + clonedParent.clear(); - source.clear(); - }; + source.clear(); + }; - case `delete`: return (key: any) => { - const clonedParent = ensureCloning(); - clonedParent.delete(key); + case `delete`: + return (key: any) => { + const clonedParent = ensureCloning(); + clonedParent.delete(key); - source.delete(key); - }; + source.delete(key); + }; - case `set`: return (key: any, value: any) => { - const clonedParent = ensureCloning(); - clonedParent.set(key, value); + case `set`: + return (key: any, value: any) => { + const clonedParent = ensureCloning(); + clonedParent.set(key, value); - source.set(key, value); - }; + source.set(key, value); + }; - case `get`: return (key: any) => { - const value = source.get(key); + case `get`: + return (key: any) => { + const value = source.get(key); - return makeValueObservable(value, version, filter, () => { - const clonedParent = ensureCloning(); + return makeValueObservable(value, version, filter, () => { + const clonedParent = ensureCloning(); - const immutableValue = clonedParent.get(key); - const clonedValue = cloneValueChecked(immutableValue, version); + const immutableValue = clonedParent.get(key); + const clonedValue = cloneValueChecked(immutableValue, version); - clonedParent.set(key, clonedValue); + clonedParent.set(key, clonedValue); - return clonedParent; - }); - }; + return clonedParent; + }); + }; - // @ts-ignore - default: return source[prop]; + default: + // @ts-ignore + return source[prop]; } }, }); @@ -221,15 +206,11 @@ const proxyHandlerObject = (version: TrackingVersion, filter: TrackingFilter, en const value = source[prop]; // Typescript doesn't allow symbol in its index types - if (typeof prop === `symbol`) - return value; + if (typeof prop === `symbol`) return value; - if (filter !== true && !filter[prop]) - return value; + if (filter !== true && !filter[prop]) return value; - const nextFilter = filter !== true - ? filter[prop] - : true; + const nextFilter = filter !== true ? filter[prop] : true; return makeValueObservable(value, version, nextFilter, () => { const clonedParent = ensureCloning(); @@ -260,10 +241,15 @@ const proxyHandlerObject = (version: TrackingVersion, filter: TrackingFilter, en source[prop] = value; return true; - } + }, }); -function makeValueObservable(value: any, version: TrackingVersion, filter: TrackingFilter, ensureCloning: () => any): any { +function makeValueObservable( + value: any, + version: TrackingVersion, + filter: TrackingFilter, + ensureCloning: () => any, +): any { if (typeof value === `object` && value !== null) { if (value instanceof Set) { return new Proxy(value, proxyHandlerSet(version, filter, ensureCloning)); @@ -279,7 +265,9 @@ function makeValueObservable(value: any, version: TrackingVersion, filter: Track export type TrackingVersion = Object; export type TrackingFilter = true | TrackingFilterObject; -interface TrackingFilterObject {[key: string]: TrackingFilter} +interface TrackingFilterObject { + [key: string]: TrackingFilter; +} export type Tracker = (cb: (value: T) => void) => T; @@ -291,13 +279,15 @@ export function makeTracker(value: T, filter: TrackingFilter = true) { // A value guaranteed to be different from everything except itself const version = {}; - cb(makeValueObservable(value, version, filter, () => { - tracker.immutable = cloneValueChecked(tracker.immutable, version); - return tracker.immutable; - })); + cb( + makeValueObservable(value, version, filter, () => { + tracker.immutable = cloneValueChecked(tracker.immutable, version); + return tracker.immutable; + }), + ); return tracker.immutable; - } + }, }; return tracker; diff --git a/packages/berry-json-proxy/sources/makeUpdater.ts b/packages/berry-json-proxy/sources/makeUpdater.ts index 018d2ad0a9d7..8687f5e06965 100644 --- a/packages/berry-json-proxy/sources/makeUpdater.ts +++ b/packages/berry-json-proxy/sources/makeUpdater.ts @@ -1,4 +1,4 @@ -import {xfs} from '@berry/fslib'; +import {xfs} from '@berry/fslib'; import {makeTracker} from './makeTracker'; @@ -10,14 +10,12 @@ export async function makeUpdater(filename: string) { const content = await xfs.readFilePromise(filename, `utf8`); const indentMatch = content.match(/^[ \t]+/m); - if (indentMatch) - indent = indentMatch[0]; + if (indentMatch) indent = indentMatch[0]; obj = JSON.parse(content || `{}`); } - if (!obj) - obj = {}; + if (!obj) obj = {}; const tracker = makeTracker(obj); const initial = tracker.immutable; @@ -27,12 +25,11 @@ export async function makeUpdater(filename: string) { tracker.open(cb); }, async save() { - if (tracker.immutable === initial) - return; + if (tracker.immutable === initial) return; const data = JSON.stringify(tracker.immutable, null, indent) + `\n`; await xfs.writeFilePromise(filename, data); - } + }, }; } diff --git a/packages/berry-libzip/sources/index.ts b/packages/berry-libzip/sources/index.ts index a7310ca9932e..60447d1c2a23 100644 --- a/packages/berry-libzip/sources/index.ts +++ b/packages/berry-libzip/sources/index.ts @@ -8,8 +8,12 @@ const number64 = [ // eslint-disable-next-line arca/no-default-export export default { // Those are getters because they can change after memory growth - get HEAP8() { return libzip.HEAP8 }, - get HEAPU8() { return libzip.HEAPU8 }, + get HEAP8() { + return libzip.HEAP8; + }, + get HEAPU8() { + return libzip.HEAPU8; + }, ZIP_CHECKCONS: 4, ZIP_CREATE: 1, @@ -74,8 +78,20 @@ export default { file: { add: libzip.cwrap(`zip_file_add`, `number`, [`number`, `string`, `number`, `number`]), getError: libzip.cwrap(`zip_file_get_error`, `number`, [`number`]), - getExternalAttributes: libzip.cwrap(`zip_file_get_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), - setExternalAttributes: libzip.cwrap(`zip_file_set_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), + getExternalAttributes: libzip.cwrap(`zip_file_get_external_attributes`, `number`, [ + `number`, + ...number64, + `number`, + `number`, + `number`, + ]), + setExternalAttributes: libzip.cwrap(`zip_file_set_external_attributes`, `number`, [ + `number`, + ...number64, + `number`, + `number`, + `number`, + ]), setMtime: libzip.cwrap(`zip_file_set_mtime`, `number`, [`number`, ...number64, `number`, `number`]), }, diff --git a/packages/berry-parsers/sources/resolution.ts b/packages/berry-parsers/sources/resolution.ts index a90183d11a2d..74c7bba103d4 100644 --- a/packages/berry-parsers/sources/resolution.ts +++ b/packages/berry-parsers/sources/resolution.ts @@ -5,7 +5,10 @@ export function parseResolution(source: string) { return parse(source); } catch (error) { if (error.location) - error.message = error.message.replace(/(\.)?$/, ` (line ${error.location.start.line}, column ${error.location.start.column})$1`); + error.message = error.message.replace( + /(\.)?$/, + ` (line ${error.location.start.line}, column ${error.location.start.column})$1`, + ); throw error; } } diff --git a/packages/berry-parsers/sources/shell.ts b/packages/berry-parsers/sources/shell.ts index 72bbffc9982f..413304d3e7a8 100644 --- a/packages/berry-parsers/sources/shell.ts +++ b/packages/berry-parsers/sources/shell.ts @@ -5,7 +5,10 @@ export function parseShell(source: string) { return parse(source); } catch (error) { if (error.location) - error.message = error.message.replace(/(\.)?$/, ` (line ${error.location.start.line}, column ${error.location.start.column})$1`); + error.message = error.message.replace( + /(\.)?$/, + ` (line ${error.location.start.line}, column ${error.location.start.column})$1`, + ); throw error; } } diff --git a/packages/berry-parsers/sources/syml.ts b/packages/berry-parsers/sources/syml.ts index cc0316da1a1b..86082145c1dc 100644 --- a/packages/berry-parsers/sources/syml.ts +++ b/packages/berry-parsers/sources/syml.ts @@ -4,7 +4,15 @@ const simpleStringPattern = /^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{ // The following keys will always be stored at the top of the object, in the // specified order. It's not fair but life isn't fair either. -const specialObjectKeys = [`__metadata`, `version`, `resolution`, `dependencies`, `peerDependencies`, `dependenciesMeta`, `peerDependenciesMeta`]; +const specialObjectKeys = [ + `__metadata`, + `version`, + `resolution`, + `dependencies`, + `peerDependencies`, + `dependenciesMeta`, + `peerDependenciesMeta`, +]; function stringifyString(value: string): string { if (value.match(simpleStringPattern)) { @@ -42,9 +50,11 @@ function stringifyValue(value: any, indentLevel: number): string { if (Array.isArray(value)) { const indent = ` `.repeat(indentLevel); - return value.map(sub => { - return `\n${indent}-${stringifyValue(sub, indentLevel + 1)}`; - }).join(``); + return value + .map(sub => { + return `\n${indent}-${stringifyValue(sub, indentLevel + 1)}`; + }) + .join(``); } if (typeof value === `object` && value) { @@ -54,21 +64,21 @@ function stringifyValue(value: any, indentLevel: number): string { const aIndex = specialObjectKeys.indexOf(a); const bIndex = specialObjectKeys.indexOf(b); - if (aIndex === -1 && bIndex === -1) - return a < b ? -1 : a > b ? +1 : 0; - if (aIndex !== -1 && bIndex === -1) - return -1; - if (aIndex === -1 && bIndex !== -1) - return +1; - + if (aIndex === -1 && bIndex === -1) return a < b ? -1 : a > b ? +1 : 0; + if (aIndex !== -1 && bIndex === -1) return -1; + if (aIndex === -1 && bIndex !== -1) return +1; + return aIndex - bIndex; }); - const fields = keys.filter(key => { - return value[key] !== undefined; - }).map(key => { - return `${indent}${stringifyString(key)}:${stringifyValue(value[key], indentLevel + 1)}`; - }).join(indentLevel === 0 ? `\n\n` : `\n`); + const fields = keys + .filter(key => { + return value[key] !== undefined; + }) + .map(key => { + return `${indent}${stringifyString(key)}:${stringifyValue(value[key], indentLevel + 1)}`; + }) + .join(indentLevel === 0 ? `\n\n` : `\n`); if (indentLevel === 0) { return fields ? `${fields}\n` : ``; @@ -89,7 +99,10 @@ export function parseSyml(source: string) { return parse(source.endsWith(`\n`) ? source : `${source}\n`); } catch (error) { if (error.location) - error.message = error.message.replace(/(\.)?$/, ` (line ${error.location.start.line}, column ${error.location.start.column})$1`); + error.message = error.message.replace( + /(\.)?$/, + ` (line ${error.location.start.line}, column ${error.location.start.column})$1`, + ); throw error; } } diff --git a/packages/berry-pnp/sources/generatePnpScript.ts b/packages/berry-pnp/sources/generatePnpScript.ts index 1f0bd28ef8ad..188add04e074 100644 --- a/packages/berry-pnp/sources/generatePnpScript.ts +++ b/packages/berry-pnp/sources/generatePnpScript.ts @@ -1,15 +1,15 @@ // @ts-ignore -import template from '@berry/pnp/bundles/hook'; -import {readFileSync} from 'fs'; +import template from '@berry/pnp/bundles/hook'; +import {readFileSync} from 'fs'; import {generateSerializedState} from './generateSerializedState'; -import {SerializedState} from './types'; -import {PnpSettings} from './types'; +import {SerializedState} from './types'; +import {PnpSettings} from './types'; function generateLoader(shebang: string | null | undefined, loader: string) { return [ shebang ? `${shebang}\n\n` : ``, - `try {\n`, + `try {\n`, ` Object.freeze({}).detectStrictMode = true;\n`, `} catch (error) {\n`, ` throw new Error(\`The whole PnP file got strict-mode-ified, which is known to break (Emscripten libraries aren't strict mode). This usually happens when the file goes through Babel.\`);\n`, @@ -30,9 +30,7 @@ function generateJsonString(data: SerializedState) { } function generateInlinedSetup(data: SerializedState) { - return [ - `return hydrateRuntimeState(${generateJsonString(data)}, {basePath: __dirname});\n`, - ].join(``); + return [`return hydrateRuntimeState(${generateJsonString(data)}, {basePath: __dirname});\n`].join(``); } function generateSplitSetup(dataLocation: string) { @@ -51,11 +49,13 @@ export function generateInlinedScript(settings: PnpSettings): string { return loaderFile; } -export function generateSplitScript(settings: PnpSettings & {dataLocation: string}): {dataFile: string, loaderFile: string} { +export function generateSplitScript( + settings: PnpSettings & {dataLocation: string}, +): {dataFile: string; loaderFile: string} { const data = generateSerializedState(settings); const setup = generateSplitSetup(settings.dataLocation); const loaderFile = generateLoader(settings.shebang, setup); - + return {dataFile: generateJsonString(data), loaderFile}; } diff --git a/packages/berry-pnp/sources/generateSerializedState.ts b/packages/berry-pnp/sources/generateSerializedState.ts index a5ecfcc367de..a37429e7ba20 100644 --- a/packages/berry-pnp/sources/generateSerializedState.ts +++ b/packages/berry-pnp/sources/generateSerializedState.ts @@ -1,18 +1,16 @@ import {LocationBlacklistData, LocationLengthData, PackageRegistryData} from './types'; -import {PackageStoreData, PnpSettings, SerializedState} from './types'; +import {PackageStoreData, PnpSettings, SerializedState} from './types'; // Keep this function is sync with its implementation in: // @berry/core/sources/miscUtils.ts export function sortMap(values: Iterable, mappers: ((value: T) => string) | Array<(value: T) => string>) { const asArray = Array.from(values); - if (!Array.isArray(mappers)) - mappers = [mappers]; + if (!Array.isArray(mappers)) mappers = [mappers]; const stringified: Array> = []; - for (const mapper of mappers) - stringified.push(asArray.map(value => mapper(value))); + for (const mapper of mappers) stringified.push(asArray.map(value => mapper(value))); const indices = asArray.map((_, index) => index); @@ -36,23 +34,34 @@ export function sortMap(values: Iterable, mappers: ((value: T) => string) function generatePackageRegistryData(settings: PnpSettings): PackageRegistryData { const packageRegistryData: PackageRegistryData = []; - for (const [packageName, packageStore] of sortMap(settings.packageRegistry, ([packageName]) => packageName === null ? `0` : `1${packageName}`)) { + for (const [packageName, packageStore] of sortMap(settings.packageRegistry, ([packageName]) => + packageName === null ? `0` : `1${packageName}`, + )) { const packageStoreData: PackageStoreData = []; packageRegistryData.push([packageName, packageStoreData]); - for (const [packageReference, {packageLocation, packageDependencies}] of sortMap(packageStore, ([packageReference]) => packageReference === null ? `0` : `1${packageReference}`)) { + for (const [packageReference, {packageLocation, packageDependencies}] of sortMap( + packageStore, + ([packageReference]) => (packageReference === null ? `0` : `1${packageReference}`), + )) { const normalizedDependencies: Array<[string, string]> = []; if (packageName !== null && packageReference !== null && !packageDependencies.has(packageName)) normalizedDependencies.push([packageName, packageReference]); - for (const [dependencyName, dependencyReference] of sortMap(packageDependencies.entries(), ([dependencyName]) => dependencyName)) + for (const [dependencyName, dependencyReference] of sortMap( + packageDependencies.entries(), + ([dependencyName]) => dependencyName, + )) normalizedDependencies.push([dependencyName, dependencyReference]); - packageStoreData.push([packageReference, { - packageLocation, - packageDependencies: normalizedDependencies, - }]); + packageStoreData.push([ + packageReference, + { + packageLocation, + packageDependencies: normalizedDependencies, + }, + ]); } } @@ -68,8 +77,7 @@ function generateLocationLengthData(settings: PnpSettings): LocationLengthData { for (const packageInformationStore of settings.packageRegistry.values()) for (const {packageLocation} of packageInformationStore.values()) - if (packageLocation !== null) - lengths.add(packageLocation.length); + if (packageLocation !== null) lengths.add(packageLocation.length); return Array.from(lengths).sort((a, b) => b - a); } @@ -90,4 +98,4 @@ export function generateSerializedState(settings: PnpSettings): SerializedState data.locationLengthData = generateLocationLengthData(settings); return data; -} \ No newline at end of file +} diff --git a/packages/berry-pnp/sources/hydratePnpApi.ts b/packages/berry-pnp/sources/hydratePnpApi.ts index 5e08d7f83640..54d729a7f5f5 100644 --- a/packages/berry-pnp/sources/hydratePnpApi.ts +++ b/packages/berry-pnp/sources/hydratePnpApi.ts @@ -1,11 +1,11 @@ -import {FakeFS} from '@berry/fslib'; -import {readFile} from 'fs'; -import {dirname} from 'path'; -import {promisify} from 'util'; +import {FakeFS} from '@berry/fslib'; +import {readFile} from 'fs'; +import {dirname} from 'path'; +import {promisify} from 'util'; import {hydrateRuntimeState} from './loader/hydrateRuntimeState'; -import {makeApi} from './loader/makeApi'; -import {SerializedState} from './types'; +import {makeApi} from './loader/makeApi'; +import {SerializedState} from './types'; const readFileP = promisify(readFile); @@ -28,7 +28,10 @@ const readFileP = promisify(readFile); // real use case is to access the PnP API without running the risk of executing // third-party Javascript code. -export async function hydratePnpFile(location: string, {fakeFs, pnpapiResolution}: {fakeFs: FakeFS, pnpapiResolution: string}) { +export async function hydratePnpFile( + location: string, + {fakeFs, pnpapiResolution}: {fakeFs: FakeFS; pnpapiResolution: string}, +) { const source = await readFileP(location, `utf8`); return hydratePnpSource(source, { @@ -38,7 +41,10 @@ export async function hydratePnpFile(location: string, {fakeFs, pnpapiResolution }); } -export function hydratePnpSource(source: string, {basePath, fakeFs, pnpapiResolution}: {basePath: string, fakeFs: FakeFS, pnpapiResolution: string}) { +export function hydratePnpSource( + source: string, + {basePath, fakeFs, pnpapiResolution}: {basePath: string; fakeFs: FakeFS; pnpapiResolution: string}, +) { const data = JSON.parse(source) as SerializedState; const runtimeState = hydrateRuntimeState(data, { diff --git a/packages/berry-pnp/sources/types.ts b/packages/berry-pnp/sources/types.ts index f81f51108a54..42b2b5572d44 100644 --- a/packages/berry-pnp/sources/types.ts +++ b/packages/berry-pnp/sources/types.ts @@ -4,10 +4,10 @@ // Apart from that, note that the "Data"-suffixed types are the ones stored // within the state files (hence why they only use JSON datatypes). -export type PackageLocator = {name: string, reference: string} | {name: null, reference: null}; +export type PackageLocator = {name: string; reference: string} | {name: null; reference: null}; -export type PackageInformation = {packageLocation: string, packageDependencies: Map}; -export type PackageInformationData = {packageLocation: string, packageDependencies: Array<[string, string]>}; +export type PackageInformation = {packageLocation: string; packageDependencies: Map}; +export type PackageInformationData = {packageLocation: string; packageDependencies: Array<[string, string]>}; export type PackageStore = Map; export type PackageStoreData = Array<[string | null, PackageInformationData]>; @@ -19,35 +19,39 @@ export type LocationBlacklistData = Array; export type LocationLengthData = Array; export type SerializedState = { - ignorePatternData: string | null, - packageRegistryData: PackageRegistryData, - locationBlacklistData: LocationBlacklistData, - locationLengthData: LocationLengthData, + ignorePatternData: string | null; + packageRegistryData: PackageRegistryData; + locationBlacklistData: LocationBlacklistData; + locationLengthData: LocationLengthData; }; export type RuntimeState = { - basePath: string, - ignorePattern: RegExp | null, - packageRegistry: PackageRegistry, + basePath: string; + ignorePattern: RegExp | null; + packageRegistry: PackageRegistry; packageLocatorsByLocations: Map; - packageLocationLengths: Array, + packageLocationLengths: Array; }; export type PnpSettings = { - shebang?: string | null, - ignorePattern?: string | null, - blacklistedLocations?: Iterable, - packageRegistry: PackageRegistry, + shebang?: string | null; + ignorePattern?: string | null; + blacklistedLocations?: Iterable; + packageRegistry: PackageRegistry; }; export type PnpApi = { - VERSIONS: {std: number, [key: string]: number}, - topLevel: {name: null, reference: null}, - - getPackageInformation: (locator: PackageLocator) => PackageInformation | null, - findPackageLocator: (location: string) => PackageLocator | null, - - resolveToUnqualified: (request: string, issuer: string | null, opts?: {considerBuiltins?: boolean}) => string | null, - resolveUnqualified: (unqualified: string, opts?: {extensions?: Array}) => string, - resolveRequest: (request: string, issuer: string | null, opts?: {considerBuiltins?: boolean, extensions?: Array}) => string | null, + VERSIONS: {std: number; [key: string]: number}; + topLevel: {name: null; reference: null}; + + getPackageInformation: (locator: PackageLocator) => PackageInformation | null; + findPackageLocator: (location: string) => PackageLocator | null; + + resolveToUnqualified: (request: string, issuer: string | null, opts?: {considerBuiltins?: boolean}) => string | null; + resolveUnqualified: (unqualified: string, opts?: {extensions?: Array}) => string; + resolveRequest: ( + request: string, + issuer: string | null, + opts?: {considerBuiltins?: boolean; extensions?: Array}, + ) => string | null; }; diff --git a/packages/berry-shell/sources/index.ts b/packages/berry-shell/sources/index.ts index 52a8df06c03e..c8adc65b7c4b 100644 --- a/packages/berry-shell/sources/index.ts +++ b/packages/berry-shell/sources/index.ts @@ -1,88 +1,102 @@ -import {xfs, NodeFS} from '@berry/fslib'; +import {xfs, NodeFS} from '@berry/fslib'; import {CommandSegment, CommandChain, CommandLine, ShellLine, parseShell} from '@berry/parsers'; -import {posix} from 'path'; -import {PassThrough, Readable, Stream, Writable} from 'stream'; +import {posix} from 'path'; +import {PassThrough, Readable, Stream, Writable} from 'stream'; -import {Handle, ProtectedStream, Stdio, start, makeBuiltin, makeProcess} from './pipe'; +import {Handle, ProtectedStream, Stdio, start, makeBuiltin, makeProcess} from './pipe'; export type UserOptions = { - builtins: {[key: string]: ShellBuiltin}, - cwd: string, - env: {[key: string]: string | undefined}, - stdin: Readable | null, - stdout: Writable, - stderr: Writable, - variables: {[key: string]: string}, + builtins: {[key: string]: ShellBuiltin}; + cwd: string; + env: {[key: string]: string | undefined}; + stdin: Readable | null; + stdout: Writable; + stderr: Writable; + variables: {[key: string]: string}; }; -export type ShellBuiltin = ( - args: Array, - opts: ShellOptions, - state: ShellState, -) => Promise; +export type ShellBuiltin = (args: Array, opts: ShellOptions, state: ShellState) => Promise; export type ShellOptions = { - args: Array, - builtins: Map, - initialStdin: Readable, - initialStdout: Writable, - initialStderr: Writable, + args: Array; + builtins: Map; + initialStdin: Readable; + initialStdout: Writable; + initialStderr: Writable; }; export type ShellState = { - cwd: string, - environment: {[key: string]: string}, - exitCode: number | null, - stdin: Readable, - stdout: Writable, - stderr: Writable, - variables: {[key: string]: string}, + cwd: string; + environment: {[key: string]: string}; + exitCode: number | null; + stdin: Readable; + stdout: Writable; + stderr: Writable; + variables: {[key: string]: string}; }; function cloneState(state: ShellState, mergeWith: Partial = {}) { - const newState = {... state, ... mergeWith}; + const newState = {...state, ...mergeWith}; - newState.environment = {... state.environment, ... mergeWith.environment }; - newState.variables = {... state.variables, ... mergeWith.variables }; + newState.environment = {...state.environment, ...mergeWith.environment}; + newState.variables = {...state.variables, ...mergeWith.variables}; return newState; } const BUILTINS = new Map([ - [`cd`, async ([target, ... rest]: Array, opts: ShellOptions, state: ShellState) => { - const resolvedTarget = posix.resolve(state.cwd, NodeFS.toPortablePath(target)); - const stat = await xfs.statPromise(resolvedTarget); + [ + `cd`, + async ([target, ...rest]: Array, opts: ShellOptions, state: ShellState) => { + const resolvedTarget = posix.resolve(state.cwd, NodeFS.toPortablePath(target)); + const stat = await xfs.statPromise(resolvedTarget); + + if (!stat.isDirectory()) { + state.stderr.write(`cd: not a directory\n`); + return 1; + } else { + state.cwd = target; + return 0; + } + }, + ], - if (!stat.isDirectory()) { - state.stderr.write(`cd: not a directory\n`); - return 1; - } else { - state.cwd = target; + [ + `pwd`, + async (args: Array, opts: ShellOptions, state: ShellState) => { + state.stdout.write(`${NodeFS.fromPortablePath(state.cwd)}\n`); return 0; - } - }], - - [`pwd`, async (args: Array, opts: ShellOptions, state: ShellState) => { - state.stdout.write(`${NodeFS.fromPortablePath(state.cwd)}\n`); - return 0; - }], - - [`true`, async (args: Array, opts: ShellOptions, state: ShellState) => { - return 0; - }], + }, + ], - [`false`, async (args: Array, opts: ShellOptions, state: ShellState) => { - return 1; - }], - - [`exit`, async ([code, ... rest]: Array, opts: ShellOptions, state: ShellState) => { - return state.exitCode = parseInt(code, 10); - }], + [ + `true`, + async (args: Array, opts: ShellOptions, state: ShellState) => { + return 0; + }, + ], - [`echo`, async (args: Array, opts: ShellOptions, state: ShellState) => { - state.stdout.write(`${args.join(` `)}\n`); - return 0; - }], + [ + `false`, + async (args: Array, opts: ShellOptions, state: ShellState) => { + return 1; + }, + ], + + [ + `exit`, + async ([code, ...rest]: Array, opts: ShellOptions, state: ShellState) => { + return (state.exitCode = parseInt(code, 10)); + }, + ], + + [ + `echo`, + async (args: Array, opts: ShellOptions, state: ShellState) => { + state.stdout.write(`${args.join(` `)}\n`); + return 0; + }, + ], ]); async function executeBufferedSubshell(ast: ShellLine, opts: ShellOptions, state: ShellState) { @@ -92,7 +106,9 @@ async function executeBufferedSubshell(ast: ShellLine, opts: ShellOptions, state stdout.on(`data`, chunk => chunks.push(chunk)); await executeShellLine(ast, opts, cloneState(state, {stdout})); - return Buffer.concat(chunks).toString().replace(/[\r\n]+$/, ``); + return Buffer.concat(chunks) + .toString() + .replace(/[\r\n]+$/, ``); } async function interpolateArguments(commandArgs: Array>, opts: ShellOptions, state: ShellState) { @@ -108,8 +124,7 @@ async function interpolateArguments(commandArgs: Array>, o }; const close = () => { - if (interpolatedSegments.length > 0) - interpolated.push(interpolatedSegments.join(``)); + if (interpolatedSegments.length > 0) interpolated.push(interpolatedSegments.join(``)); interpolatedSegments = []; }; @@ -120,81 +135,85 @@ async function interpolateArguments(commandArgs: Array>, o for (const commandArg of commandArgs) { for (const segment of commandArg) { - if (typeof segment === 'string') { - push(segment); - } else { - switch (segment.type) { - - case `shell`: { - const raw = await executeBufferedSubshell(segment.shell, opts, state); - if (segment.quoted) { - push(raw); - } else { - for (const part of split(raw)) { - pushAndClose(part); + case `shell`: + { + const raw = await executeBufferedSubshell(segment.shell, opts, state); + if (segment.quoted) { + push(raw); + } else { + for (const part of split(raw)) { + pushAndClose(part); + } } } - } break; - - case `variable`: { - switch (segment.name) { - - case `#`: { - push(String(opts.args.length)); - } break; - - case `@`: { - if (segment.quoted) { - for (const raw of opts.args) { - pushAndClose(raw); + break; + + case `variable`: + { + switch (segment.name) { + case `#`: + { + push(String(opts.args.length)); } - } else { - for (const raw of opts.args) { - for (const part of split(raw)) { - pushAndClose(part); + break; + + case `@`: + { + if (segment.quoted) { + for (const raw of opts.args) { + pushAndClose(raw); + } + } else { + for (const raw of opts.args) { + for (const part of split(raw)) { + pushAndClose(part); + } + } } } - } - } break; - - case `*`: { - const raw = opts.args.join(` `); - if (segment.quoted) { - push(raw); - } else { - for (const part of split(raw)) { - pushAndClose(part); - } - } - } break; - - default: { - const argIndex = parseInt(segment.name, 10); - - if (Number.isFinite(argIndex)) { - if (!(argIndex >= 0 && argIndex < opts.args.length)) { - throw new Error(`Unbound argument #${argIndex}`); - } else { - push(opts.args[argIndex]); + break; + + case `*`: + { + const raw = opts.args.join(` `); + if (segment.quoted) { + push(raw); + } else { + for (const part of split(raw)) { + pushAndClose(part); + } + } } - } else { - if (!(segment.name in state.variables)) { - throw new Error(`Unbound variable "${segment.name}"`); - } else { - push(state.variables[segment.name]); + break; + + default: + { + const argIndex = parseInt(segment.name, 10); + + if (Number.isFinite(argIndex)) { + if (!(argIndex >= 0 && argIndex < opts.args.length)) { + throw new Error(`Unbound argument #${argIndex}`); + } else { + push(opts.args[argIndex]); + } + } else { + if (!(segment.name in state.variables)) { + throw new Error(`Unbound variable "${segment.name}"`); + } else { + push(state.variables[segment.name]); + } + } } - } - } break; - + break; + } } - } break; + break; } } - } close(); @@ -211,10 +230,9 @@ async function interpolateArguments(commandArgs: Array>, o */ function makeCommandAction(args: Array, opts: ShellOptions, state: ShellState) { - if (!opts.builtins.has(args[0])) - args = [`command`, ... args]; + if (!opts.builtins.has(args[0])) args = [`command`, ...args]; - const [name, ... rest] = args; + const [name, ...rest] = args; if (name === `command`) { return makeProcess(rest[0], rest.slice(1), { cwd: NodeFS.fromPortablePath(state.cwd), @@ -223,8 +241,7 @@ function makeCommandAction(args: Array, opts: ShellOptions, state: Shell } const builtin = opts.builtins.get(name); - if (typeof builtin === `undefined`) - throw new Error(`Assertion failed: A builtin should exist for "${name}"`) + if (typeof builtin === `undefined`) throw new Error(`Assertion failed: A builtin should exist for "${name}"`); return makeBuiltin(async ({stdin, stdout, stderr}) => { state.stdin = stdin; @@ -255,25 +272,26 @@ async function executeCommandChain(node: CommandChain, opts: ShellOptions, state while (current) { // Only the final segment is allowed to modify the shell state; all the // other ones are isolated - const activeState = current.then - ? {... state} - : state; + const activeState = current.then ? {...state} : state; let action; switch (current.type) { - case `command`: { - action = makeCommandAction(await interpolateArguments(current.args, opts, state), opts, activeState); - } break; - - case `subshell`: { - // We don't interpolate the subshell because it will be recursively - // interpolated within its own context - action = makeSubshellAction(current.subshell, opts, activeState); - } break; + case `command`: + { + action = makeCommandAction(await interpolateArguments(current.args, opts, state), opts, activeState); + } + break; + + case `subshell`: + { + // We don't interpolate the subshell because it will be recursively + // interpolated within its own context + action = makeSubshellAction(current.subshell, opts, activeState); + } + break; } - if (typeof action === `undefined`) - throw new Error(`Assertion failed: An action should have been generated`); + if (typeof action === `undefined`) throw new Error(`Assertion failed: An action should have been generated`); if (pipeType === null) { // If we're processing the left-most segment of the command, we start a @@ -284,19 +302,22 @@ async function executeCommandChain(node: CommandChain, opts: ShellOptions, state stderr: new ProtectedStream(activeState.stderr), }); } else { - if (execution === null) - throw new Error(`The execution pipeline should have been setup`); + if (execution === null) throw new Error(`The execution pipeline should have been setup`); // Otherwise, depending on the exaxct pipe type, we either pipe stdout // only or stdout and stderr switch (pipeType) { - case `|`: { - execution = execution.pipeTo(action); - } break; + case `|`: + { + execution = execution.pipeTo(action); + } + break; - case `|&`: { - execution = execution.pipeTo(action); - } break; + case `|&`: + { + execution = execution.pipeTo(action); + } + break; } } @@ -308,8 +329,7 @@ async function executeCommandChain(node: CommandChain, opts: ShellOptions, state } } - if (execution === null) - throw new Error(`Assertion failed: The execution pipeline should have been setup`); + if (execution === null) throw new Error(`Assertion failed: The execution pipeline should have been setup`); return await execution.run(); } @@ -319,39 +339,43 @@ async function executeCommandChain(node: CommandChain, opts: ShellOptions, state * together thanks to the use of either of the `||` or `&&` operators. */ async function executeCommandLine(node: CommandLine, opts: ShellOptions, state: ShellState): Promise { - if (!node.then) - return await executeCommandChain(node.chain, opts, state); + if (!node.then) return await executeCommandChain(node.chain, opts, state); const code = await executeCommandChain(node.chain, opts, state); // If the execution aborted (usually through "exit"), we must bailout - if (state.exitCode !== null) - return state.exitCode; + if (state.exitCode !== null) return state.exitCode; // We must update $?, which always contains the exit code from // the right-most command state.variables[`?`] = String(code); switch (node.then.type) { - case `&&`: { - if (code === 0) { - return await executeCommandLine(node.then.line, opts, state); - } else { - return code; + case `&&`: + { + if (code === 0) { + return await executeCommandLine(node.then.line, opts, state); + } else { + return code; + } } - } break; - - case `||`: { - if (code !== 0) { - return await executeCommandLine(node.then.line, opts, state); - } else { - return code; + break; + + case `||`: + { + if (code !== 0) { + return await executeCommandLine(node.then.line, opts, state); + } else { + return code; + } } - } break; + break; - default: { - throw new Error(`Unsupported command type: "${node.then.type}"`); - } break; + default: + { + throw new Error(`Unsupported command type: "${node.then.type}"`); + } + break; } } @@ -362,8 +386,7 @@ async function executeShellLine(node: ShellLine, opts: ShellOptions, state: Shel rightMostExitCode = await executeCommandLine(command, opts, state); // If the execution aborted (usually through "exit"), we must bailout - if (state.exitCode !== null) - return state.exitCode; + if (state.exitCode !== null) return state.exitCode; // We must update $?, which always contains the exit code from // the right-most command @@ -382,45 +405,56 @@ function locateArgsVariable(node: ShellLine): boolean { let hasArgs; switch (chain.type) { - case `subshell`: { - hasArgs = locateArgsVariable(chain.subshell); - } break; - - case `command`: { - hasArgs = chain.args.some(arg => { - return arg.some(segment => { - if (typeof segment === 'string') - return false; - - switch (segment.type) { - case `variable`: { - return segment.name === `@` || segment.name === `#` || segment.name === `*` || Number.isFinite(parseInt(segment.name, 10)); - } break; - - case `shell`: { - return locateArgsVariable(segment.shell); - } break; - - default: { - return false; - } break; - } + case `subshell`: + { + hasArgs = locateArgsVariable(chain.subshell); + } + break; + + case `command`: + { + hasArgs = chain.args.some(arg => { + return arg.some(segment => { + if (typeof segment === 'string') return false; + + switch (segment.type) { + case `variable`: + { + return ( + segment.name === `@` || + segment.name === `#` || + segment.name === `*` || + Number.isFinite(parseInt(segment.name, 10)) + ); + } + break; + + case `shell`: + { + return locateArgsVariable(segment.shell); + } + break; + + default: + { + return false; + } + break; + } + }); }); - }); - } break; + } + break; } - if (hasArgs) - return true; + if (hasArgs) return true; - if (!chain.then) - break; + if (!chain.then) break; chain = chain.then.chain; } - if (!command.then) - break; + if (!command.then) break; command = command.then.line; } @@ -429,23 +463,24 @@ function locateArgsVariable(node: ShellLine): boolean { }); } -export async function execute(command: string, args: Array = [], { - builtins = {}, - cwd = process.cwd(), - env = process.env, - stdin = process.stdin, - stdout = process.stdout, - stderr = process.stderr, - variables = {}, -}: Partial = {}) { +export async function execute( + command: string, + args: Array = [], + { + builtins = {}, + cwd = process.cwd(), + env = process.env, + stdin = process.stdin, + stdout = process.stdout, + stderr = process.stderr, + variables = {}, + }: Partial = {}, +) { const normalizedEnv: {[key: string]: string} = {}; - for (const [key, value] of Object.entries(env)) - if (typeof value !== `undefined`) - normalizedEnv[key] = value; + for (const [key, value] of Object.entries(env)) if (typeof value !== `undefined`) normalizedEnv[key] = value; const normalizedBuiltins = new Map(BUILTINS); - for (const [key, builtin] of Object.entries(builtins)) - normalizedBuiltins.set(key, builtin); + for (const [key, builtin] of Object.entries(builtins)) normalizedBuiltins.set(key, builtin); // This is meant to be the equivalent of /dev/null if (stdin === null) { @@ -459,35 +494,39 @@ export async function execute(command: string, args: Array = [], { // right-most command if (!locateArgsVariable(ast) && ast.length > 0) { let command = ast[ast.length - 1]; - while (command.then) - command = command.then.line; + while (command.then) command = command.then.line; let chain = command.chain; - while (chain.then) - chain = chain.then.chain; + while (chain.then) chain = chain.then.chain; if (chain.type === `command`) { - chain.args = chain.args.concat(args.map(arg => { - return [arg]; - })); + chain.args = chain.args.concat( + args.map(arg => { + return [arg]; + }), + ); } } - return await executeShellLine(ast, { - args, - builtins: normalizedBuiltins, - initialStdin: stdin, - initialStdout: stdout, - initialStderr: stderr, - }, { - cwd, - environment: normalizedEnv, - exitCode: null, - stdin, - stdout, - stderr, - variables: Object.assign(Object.create(variables), { - [`?`]: 0, - }), - }); + return await executeShellLine( + ast, + { + args, + builtins: normalizedBuiltins, + initialStdin: stdin, + initialStdout: stdout, + initialStderr: stderr, + }, + { + cwd, + environment: normalizedEnv, + exitCode: null, + stdin, + stdout, + stderr, + variables: Object.assign(Object.create(variables), { + [`?`]: 0, + }), + }, + ); } diff --git a/packages/berry-shell/sources/pipe.ts b/packages/berry-shell/sources/pipe.ts index a8df986311c6..d4bf0df6c080 100644 --- a/packages/berry-shell/sources/pipe.ts +++ b/packages/berry-shell/sources/pipe.ts @@ -1,23 +1,19 @@ -import crossSpawn from 'cross-spawn'; -import EventEmitter from 'events'; +import crossSpawn from 'cross-spawn'; +import EventEmitter from 'events'; import {PassThrough, Readable, Writable} from 'stream'; enum Pipe { STDOUT = 0b01, STDERR = 0b10, -}; +} -export type Stdio = [ - any, - any, - any -]; +export type Stdio = [any, any, any]; type ProcessImplementation = ( stdio: Stdio, ) => { - stdin: Writable, - promise: Promise, + stdin: Writable; + promise: Promise; }; function nextTick() { @@ -28,30 +24,17 @@ function nextTick() { export function makeProcess(name: string, args: Array, opts: any): ProcessImplementation { return (stdio: Stdio) => { - const stdin = stdio[0] instanceof PassThrough - ? `pipe` - : stdio[0]; + const stdin = stdio[0] instanceof PassThrough ? `pipe` : stdio[0]; - const stdout = stdio[1] instanceof PassThrough - ? `pipe` - : stdio[1]; + const stdout = stdio[1] instanceof PassThrough ? `pipe` : stdio[1]; - const stderr = stdio[2] instanceof PassThrough - ? `pipe` - : stdio[2]; + const stderr = stdio[2] instanceof PassThrough ? `pipe` : stdio[2]; - const child = crossSpawn(name, args, {... opts, stdio: [ - stdin, - stdout, - stderr, - ]}); + const child = crossSpawn(name, args, {...opts, stdio: [stdin, stdout, stderr]}); - if (stdio[0] instanceof PassThrough) - stdio[0].pipe(child.stdin); - if (stdio[1] instanceof PassThrough) - child.stdout.pipe(stdio[1]); - if (stdio[2] instanceof PassThrough) - child.stderr.pipe(stdio[2]); + if (stdio[0] instanceof PassThrough) stdio[0].pipe(child.stdin); + if (stdio[1] instanceof PassThrough) child.stdout.pipe(stdio[1]); + if (stdio[2] instanceof PassThrough) child.stderr.pipe(stdio[2]); return { stdin: child.stdin, @@ -59,21 +42,27 @@ export function makeProcess(name: string, args: Array, opts: any): Proce child.on(`error`, error => { // @ts-ignore switch (error.code) { - case `ENOENT`: { - stdio[2].write(`command not found: ${name}\n`); - resolve(127); - } break; - case `EACCESS`: { - stdio[2].write(`permission denied: ${name}\n`); - resolve(128); - } break; - default: { - stdio[2].write(`uncaught error: ${error.message}\n`); - resolve(1); - } break; + case `ENOENT`: + { + stdio[2].write(`command not found: ${name}\n`); + resolve(127); + } + break; + case `EACCESS`: + { + stdio[2].write(`permission denied: ${name}\n`); + resolve(128); + } + break; + default: + { + stdio[2].write(`uncaught error: ${error.message}\n`); + resolve(1); + } + break; } }); - + child.on(`exit`, code => { if (code !== null) { resolve(code); @@ -88,17 +77,17 @@ export function makeProcess(name: string, args: Array, opts: any): Proce export function makeBuiltin(builtin: (opts: any) => Promise): ProcessImplementation { return (stdio: Stdio) => { - const stdin = stdio[0] === `pipe` - ? new PassThrough() - : stdio[0]; + const stdin = stdio[0] === `pipe` ? new PassThrough() : stdio[0]; return { stdin, - promise: nextTick().then(() => builtin({ - stdin, - stdout: stdio[1], - stderr: stdio[2], - })), + promise: nextTick().then(() => + builtin({ + stdin, + stdout: stdio[1], + stderr: stdio[2], + }), + ), }; }; } @@ -149,9 +138,9 @@ class PipeStream implements StreamLock { } type StartOptions = { - stdin: StreamLock, - stdout: StreamLock, - stderr: StreamLock, + stdin: StreamLock; + stdout: StreamLock; + stderr: StreamLock; }; export class Handle { @@ -170,8 +159,8 @@ export class Handle { chain.stdin = stdin; chain.stdout = stdout; chain.stderr = stderr; - - return chain; + + return chain; } constructor(ancestor: Handle | null, implementation: ProcessImplementation) { @@ -188,25 +177,17 @@ export class Handle { next.stdout = this.stdout; next.stderr = this.stderr; - if ((source & Pipe.STDOUT) === Pipe.STDOUT) - this.stdout = pipe; - else if (this.ancestor !== null) - this.stderr = this.ancestor.stdout; + if ((source & Pipe.STDOUT) === Pipe.STDOUT) this.stdout = pipe; + else if (this.ancestor !== null) this.stderr = this.ancestor.stdout; - if ((source & Pipe.STDERR) === Pipe.STDERR) - this.stderr = pipe; - else if (this.ancestor !== null) - this.stderr = this.ancestor.stderr; + if ((source & Pipe.STDERR) === Pipe.STDERR) this.stderr = pipe; + else if (this.ancestor !== null) this.stderr = this.ancestor.stderr; return next; } async exec() { - const stdio: Stdio = [ - `ignore`, - `ignore`, - `ignore`, - ]; + const stdio: Stdio = [`ignore`, `ignore`, `ignore`]; if (this.pipe) { stdio[0] = `pipe`; @@ -236,8 +217,7 @@ export class Handle { const child = this.implementation(stdio); - if (this.pipe) - this.pipe.attach(child.stdin); + if (this.pipe) this.pipe.attach(child.stdin); return await child.promise.then(code => { stdoutLock.close(); @@ -249,8 +229,7 @@ export class Handle { async run() { const promises = []; - for (let handle: Handle | null = this; handle; handle = handle.ancestor) - promises.push(handle.exec()); + for (let handle: Handle | null = this; handle; handle = handle.ancestor) promises.push(handle.exec()); const exitCodes = await Promise.all(promises); return exitCodes[0]; diff --git a/packages/berry-ui/sources/DirtyScreen.ts b/packages/berry-ui/sources/DirtyScreen.ts index fbb6e3af69ed..a8eafcea5ca0 100644 --- a/packages/berry-ui/sources/DirtyScreen.ts +++ b/packages/berry-ui/sources/DirtyScreen.ts @@ -1,32 +1,30 @@ import {Rect} from './Rect'; type DirtySegment = { - start: number, - end: number, + start: number; + end: number; }; class DirtyRow { private segments: Array = []; add(start: number, end: number) { - if (end <= start) - return; + if (end <= start) return; let startIndex = 0; // Find the index of the first segment that doesn't end before our starting point - while (startIndex < this.segments.length && start > this.segments[startIndex].end) - startIndex += 1; + while (startIndex < this.segments.length && start > this.segments[startIndex].end) startIndex += 1; // If all segments end before we even start, we can just push the new segment at the end of the list if (startIndex === this.segments.length) { - this.segments.push({ start, end }); + this.segments.push({start, end}); } else { const startSegment = this.segments[startIndex]; // If the segment we found starts only after we even end, we just have to insert ourselves before it (we've already proven that the previous segment ends before we start, so no merge) if (startSegment.start > end) { - this.segments.splice(startIndex, 0, { start, end }); + this.segments.splice(startIndex, 0, {start, end}); } else { startSegment.start = Math.min(startSegment.start, start); startSegment.end = Math.max(startSegment.end, end); @@ -35,7 +33,10 @@ class DirtyRow { let spliceSize = 0; // Find the number of segments that are fully covered by our new segment ... - while (spliceIndex + spliceSize < this.segments.length && this.segments[spliceIndex + spliceSize].end <= startSegment.end) + while ( + spliceIndex + spliceSize < this.segments.length && + this.segments[spliceIndex + spliceSize].end <= startSegment.end + ) spliceSize += 1; // ... and remove them (since they have been merged) @@ -59,12 +60,11 @@ export class DirtyScreen { private rows: Map = new Map(); addCoordinates(left: number, top: number, width: number, height: number) { - if (width === 0 || height === 0) - return; + if (width === 0 || height === 0) return; for (let y = top; y < top + height; ++y) { let row = this.rows.get(y); - if (!row) this.rows.set(y, row = new DirtyRow()); + if (!row) this.rows.set(y, (row = new DirtyRow())); row.add(left, left + width); } @@ -84,18 +84,14 @@ export class DirtyScreen { *viewport(rect: Rect) { for (const [y, row] of this.rows.entries()) { - if (y < rect.top || y >= rect.top + rect.height) - continue; + if (y < rect.top || y >= rect.top + rect.height) continue; for (let {start, end} of row) { - if (start < rect.left) - start = rect.left; + if (start < rect.left) start = rect.left; - if (end > rect.left + rect.width) - end = rect.left + rect.width; + if (end > rect.left + rect.width) end = rect.left + rect.width; - if (start === end) - continue; + if (start === end) continue; yield {left: start, top: y, width: end - start, height: 1}; } diff --git a/packages/berry-ui/sources/Div.ts b/packages/berry-ui/sources/Div.ts index 708d2425dfdc..090ac29ad833 100644 --- a/packages/berry-ui/sources/Div.ts +++ b/packages/berry-ui/sources/Div.ts @@ -1,4 +1,4 @@ -import React from 'react'; +import React from 'react'; import {NodeElement} from './NodeElement'; @@ -12,88 +12,93 @@ export enum StyleFlexDirectionEnum { } export type StyleProp = Partial<{ - position: StylePositionEnum, + position: StylePositionEnum; - left: number | string, - right: number | string, - top: number | string, - bottom: number | string, + left: number | string; + right: number | string; + top: number | string; + bottom: number | string; - flexDirection: StyleFlexDirectionEnum, - flexGrow: number, - flexShrink: number, - flex: number, + flexDirection: StyleFlexDirectionEnum; + flexGrow: number; + flexShrink: number; + flex: number; - marginLeft: number | string, - marginRight: number | string, - marginTop: number | string, - marginBottom: number | string, + marginLeft: number | string; + marginRight: number | string; + marginTop: number | string; + marginBottom: number | string; - minWidth: number | string, - minHeight: number | string, + minWidth: number | string; + minHeight: number | string; - maxWidth: number | string, - maxHeight: number | string, + maxWidth: number | string; + maxHeight: number | string; - width: number | string, - height: number | string, + width: number | string; + height: number | string; - paddingLeft: number | string, - paddingRight: number | string, - paddingTop: number | string, - paddingBottom: number | string, + paddingLeft: number | string; + paddingRight: number | string; + paddingTop: number | string; + paddingBottom: number | string; - backgroundColor: string, + backgroundColor: string; - backgroundBackColor: string, - backgroundFrontColor: string, + backgroundBackColor: string; + backgroundFrontColor: string; - borderBackColor: string, - borderFrontColor: string, + borderBackColor: string; + borderFrontColor: string; - contentFrontColor: string, - contentBackColor: string, + contentFrontColor: string; + contentBackColor: string; }>; export type ShortcutProp = { - [sequence: string]: (e: any) => void | null, + [sequence: string]: (e: any) => void | null; }; export type DivProps = { - caret?: {x: number, y: number} | null, - globalShortcuts?: ShortcutProp, - renderFn?: ((row: number, left: number, width: number, renderText: (text: string) => string, renderBackground: (width: number) => string) => string) | null, - style?: StyleProp, - shortcuts?: ShortcutProp, - tabIndex?: number | null, - - onBlur?: ((event: any) => void) | null, - onFocus?: ((event: any) => void) | null, - - onData?: ((event: any) => void) | null, - - onWheel?: ((event: any) => void) | null, - onShortcut?: ((event: any) => void) | null, - - onResize?: ((event: any) => void) | null, + caret?: {x: number; y: number} | null; + globalShortcuts?: ShortcutProp; + renderFn?: + | (( + row: number, + left: number, + width: number, + renderText: (text: string) => string, + renderBackground: (width: number) => string, + ) => string) + | null; + style?: StyleProp; + shortcuts?: ShortcutProp; + tabIndex?: number | null; + + onBlur?: ((event: any) => void) | null; + onFocus?: ((event: any) => void) | null; + + onData?: ((event: any) => void) | null; + + onWheel?: ((event: any) => void) | null; + onShortcut?: ((event: any) => void) | null; + + onResize?: ((event: any) => void) | null; }; export class Div extends React.Component { private mainRef: NodeElement | null = null; markDirtyRender() { - if (!this.mainRef) - return; - + if (!this.mainRef) return; + this.mainRef.markDirtyRender(); } triggerFocus() { - if (!this.mainRef) - return; - - if (!this.mainRef.rootNode) - throw new Error(`Assertion failed: This element should belong to a tree`); + if (!this.mainRef) return; + + if (!this.mainRef.rootNode) throw new Error(`Assertion failed: This element should belong to a tree`); this.mainRef.rootNode.focus(this.mainRef); } @@ -103,6 +108,6 @@ export class Div extends React.Component { }; render() { - return React.createElement(`div`, {ref: this.handleRef, ... this.props}); + return React.createElement(`div`, {ref: this.handleRef, ...this.props}); } -}; +} diff --git a/packages/berry-ui/sources/Environment.ts b/packages/berry-ui/sources/Environment.ts index 9d35eed8353d..7e8b789676ed 100644 --- a/packages/berry-ui/sources/Environment.ts +++ b/packages/berry-ui/sources/Environment.ts @@ -1,4 +1,4 @@ export type Environment = { - textLayout: any, - yoga: any, + textLayout: any; + yoga: any; }; diff --git a/packages/berry-ui/sources/KeySequence.ts b/packages/berry-ui/sources/KeySequence.ts index 363966563e1d..85fbce63f543 100644 --- a/packages/berry-ui/sources/KeySequence.ts +++ b/packages/berry-ui/sources/KeySequence.ts @@ -1,8 +1,8 @@ type KeySequenceOptions = { - ctrl: boolean, - alt: boolean, - shift: boolean, - meta: boolean, + ctrl: boolean; + alt: boolean; + shift: boolean; + meta: boolean; }; class KeySequenceEntry { @@ -30,31 +30,41 @@ class KeySequenceEntry { if (t !== parts.length - 1) { switch (part.toLowerCase()) { case `ctrl`: - case `c`: { - ctrl = true; - } break; + case `c`: + { + ctrl = true; + } + break; case `alt`: - case `a`: { - alt = true; - } break; + case `a`: + { + alt = true; + } + break; case `shift`: - case `s`: { - shift = true; - } break; + case `s`: + { + shift = true; + } + break; case `meta`: - case `m`: { - meta = true; - } break; - - default: { - throw new Error(`Failed to parse shortcut descriptor: Invalid modifier "${part}".`); - } break; + case `m`: + { + meta = true; + } + break; + + default: + { + throw new Error(`Failed to parse shortcut descriptor: Invalid modifier "${part}".`); + } + break; } } else { - key = part.toLowerCase(); + key = part.toLowerCase(); } } @@ -69,33 +79,24 @@ class KeySequenceEntry { this.key = key; - if (ctrl) - this.name += `ctrl-`; - if (alt) - this.name += `alt-`; - if (shift) - this.name += `shift-`; - if (meta) - this.name += `meta-`; + if (ctrl) this.name += `ctrl-`; + if (alt) this.name += `alt-`; + if (shift) this.name += `shift-`; + if (meta) this.name += `meta-`; this.name += key; } check(key: any) { - if (this.shift !== key.shift) - return false; + if (this.shift !== key.shift) return false; - if (this.alt !== key.alt) - return false; + if (this.alt !== key.alt) return false; - if (this.ctrl !== key.ctrl) - return false; + if (this.ctrl !== key.ctrl) return false; - if (this.meta !== key.meta) - return false; + if (this.meta !== key.meta) return false; - if (this.key !== key.name) - return false; + if (this.key !== key.name) return false; return true; } @@ -115,10 +116,13 @@ export class KeySequence { constructor(descriptor: string) { this.descriptor = descriptor; - this.entries = String(this.descriptor).trim().toLowerCase().split(/\s+/g).map(descriptor => KeySequenceEntry.parse(descriptor.trim())); + this.entries = String(this.descriptor) + .trim() + .toLowerCase() + .split(/\s+/g) + .map(descriptor => KeySequenceEntry.parse(descriptor.trim())); - for (const entry of this.entries) - this.name += entry.name.charAt(0).toUpperCase() + entry.name.slice(1); + for (const entry of this.entries) this.name += entry.name.charAt(0).toUpperCase() + entry.name.slice(1); this.name = this.name.charAt(0).toLowerCase() + this.name.slice(1); } @@ -131,15 +135,11 @@ export class KeySequence { this.keyBuffer.splice(0, this.keyBuffer.length - this.entries.length); // Early return if we haven't bufferized enough keys to match anyway - if (this.keyBuffer.length < this.entries.length) - return false; + if (this.keyBuffer.length < this.entries.length) return false; // Check that every buffered key match its corresponding entry - for (let t = 0, T = this.entries.length; t < T; ++t) - if (!this.entries[t].check(this.keyBuffer[t])) - return false; + for (let t = 0, T = this.entries.length; t < T; ++t) if (!this.entries[t].check(this.keyBuffer[t])) return false; return true; } - } diff --git a/packages/berry-ui/sources/Node.ts b/packages/berry-ui/sources/Node.ts index b81d1b05d2d3..67264f572d1d 100644 --- a/packages/berry-ui/sources/Node.ts +++ b/packages/berry-ui/sources/Node.ts @@ -1,10 +1,10 @@ -import {DirtyScreen} from './DirtyScreen'; -import {Environment} from './Environment'; -import {NodeElement} from './NodeElement'; -import {NodeTree} from './NodeTree'; -import {Rect} from './Rect'; -import {StyleManager} from './StyleManager'; -import {getColorEntry} from './colors'; +import {DirtyScreen} from './DirtyScreen'; +import {Environment} from './Environment'; +import {NodeElement} from './NodeElement'; +import {NodeTree} from './NodeTree'; +import {Rect} from './Rect'; +import {StyleManager} from './StyleManager'; +import {getColorEntry} from './colors'; import {computeInPlaceIntersectingRect} from './geometryUtils'; enum Flags { @@ -78,8 +78,7 @@ export abstract class Node { } prependChild(node: Node) { - if (node.parentNode) - throw new Error(`Assertion failed: A node cannot be reparented`); + if (node.parentNode) throw new Error(`Assertion failed: A node cannot be reparented`); node.parentNode = this; @@ -99,15 +98,13 @@ export abstract class Node { this.childNodes.unshift(node); } - if (this.rootNode) - node.linkRecursive(); + if (this.rootNode) node.linkRecursive(); node.markDirtyLayout(); } appendChild(node: Node) { - if (node.parentNode) - throw new Error(`Assertion failed: A node cannot be reparented`); + if (node.parentNode) throw new Error(`Assertion failed: A node cannot be reparented`); node.parentNode = this; @@ -129,31 +126,26 @@ export abstract class Node { node.style.refreshInheritedProperties(); - if (this.rootNode) - node.linkRecursive(); + if (this.rootNode) node.linkRecursive(); node.markDirtyLayout(); } insertBefore(node: Node, before: Node | null) { - if (before === null) - return this.appendChild(node); + if (before === null) return this.appendChild(node); - if (before.parentNode !== this) - throw new Error(`Assertion failed: Cannot locate a node that isn't owned`); + if (before.parentNode !== this) throw new Error(`Assertion failed: Cannot locate a node that isn't owned`); const index = this.childNodes.indexOf(before); - if (index === -1) - throw new Error(`Assertion failed: Cannot locate a node that's been removed`); + if (index === -1) throw new Error(`Assertion failed: Cannot locate a node that's been removed`); - if (index === 0) - return this.prependChild(node); + if (index === 0) return this.prependChild(node); - if (node.parentNode) - throw new Error(`Assertion failed: A node cannot be reparented`); + if (node.parentNode) throw new Error(`Assertion failed: A node cannot be reparented`); - if (!before.previousSibling) // required to help typescript figure out this is true + if (!before.previousSibling) + // required to help typescript figure out this is true throw new Error(`Assertion failed: There should be a previous sibling`); node.parentNode = this; @@ -169,41 +161,33 @@ export abstract class Node { node.style.refreshInheritedProperties(); - if (this.rootNode) - node.linkRecursive(); + if (this.rootNode) node.linkRecursive(); this.markDirtyLayout(); } removeChild(node: Node) { - if (node.parentNode !== this) - throw new Error(`Assertion failed: Cannot remove a node that isn't owned`); + if (node.parentNode !== this) throw new Error(`Assertion failed: Cannot remove a node that isn't owned`); const index = this.childNodes.indexOf(node); - if (index === -1) - throw new Error(`Assertion failed: Cannot remove a node twice`); + if (index === -1) throw new Error(`Assertion failed: Cannot remove a node twice`); const previousSibling = node.previousSibling; const nextSibling = node.nextSibling; - + this.yoga.removeChild(node.yoga); this.childNodes.splice(index, 1); - if (previousSibling) - previousSibling.nextSibling = nextSibling; + if (previousSibling) previousSibling.nextSibling = nextSibling; - if (nextSibling) - nextSibling.previousSibling = previousSibling; + if (nextSibling) nextSibling.previousSibling = previousSibling; - if (this.firstChild === node) - this.firstChild = nextSibling; + if (this.firstChild === node) this.firstChild = nextSibling; - if (this.lastChild === node) - this.lastChild = previousSibling; + if (this.lastChild === node) this.lastChild = previousSibling; - if (node.rootNode) - node.unlinkRecursive(); + if (node.rootNode) node.unlinkRecursive(); this.markDirtyLayout(); } @@ -212,22 +196,19 @@ export abstract class Node { const eventSources: Array = []; for (let eventSource: Node | null = this; eventSource; eventSource = eventSource.parentNode) - if (eventSource instanceof NodeElement) - eventSources.push(eventSource); + if (eventSource instanceof NodeElement) eventSources.push(eventSource); event.target = this; for (let t = eventSources.length - 1; t >= 0; --t) { const eventSource = eventSources[t]; - if (event.propagationStopped) - break; + if (event.propagationStopped) break; const handlerName = `on${event.name.charAt(0).toUpperCase()}${event.name.slice(1)}Capture`; const handler = eventSource.props[handlerName]; - if (!handler) - continue; + if (!handler) continue; event.currentTarget = eventSource; handler.call(null, event); @@ -236,14 +217,12 @@ export abstract class Node { for (let t = 0, T = eventSources.length; t < T; ++t) { const eventSource = eventSources[t]; - if (event.propagationStopped) - break; + if (event.propagationStopped) break; let handlerName = `on${event.name.charAt(0).toUpperCase()}${event.name.slice(1)}`; let handler = eventSource.props[handlerName]; - if (!handler) - continue; + if (!handler) continue; event.currentTarget = eventSource; handler.call(null, event); @@ -269,14 +248,12 @@ export abstract class Node { this.flags |= Flags.NODE_HAS_DIRTY_LAYOUT | Flags.NODE_HAS_DIRTY_LAYOUT_CHILDREN; for (let parent = this.parentNode; parent; parent = parent.parentNode) { - if (parent.flags & Flags.NODE_HAS_DIRTY_LAYOUT_CHILDREN) - break; + if (parent.flags & Flags.NODE_HAS_DIRTY_LAYOUT_CHILDREN) break; parent.flags |= Flags.NODE_HAS_DIRTY_LAYOUT_CHILDREN; } - for (const child of this.childNodes) - child.flags |= Flags.NODE_HAS_DIRTY_LAYOUT; - + for (const child of this.childNodes) child.flags |= Flags.NODE_HAS_DIRTY_LAYOUT; + if (this.rootNode) { this.rootNode.markDirtyRenderList(); } @@ -286,11 +263,10 @@ export abstract class Node { this.flags |= Flags.NODE_HAS_DIRTY_LAYOUT; for (let parent = this.parentNode; parent; parent = parent.parentNode) { - if (parent.flags & Flags.NODE_HAS_DIRTY_LAYOUT_CHILDREN) - break; + if (parent.flags & Flags.NODE_HAS_DIRTY_LAYOUT_CHILDREN) break; parent.flags |= Flags.NODE_HAS_DIRTY_LAYOUT_CHILDREN; } - + if (this.rootNode) { this.rootNode.markDirtyRenderList(); } @@ -300,8 +276,7 @@ export abstract class Node { this.flags |= Flags.NODE_HAS_DIRTY_CLIPPING; for (let parent = this.parentNode; parent; parent = parent.parentNode) { - if (parent.flags & Flags.NODE_HAS_DIRTY_CLIPPING_CHILDREN) - break; + if (parent.flags & Flags.NODE_HAS_DIRTY_CLIPPING_CHILDREN) break; parent.flags |= Flags.NODE_HAS_DIRTY_CLIPPING_CHILDREN; } } @@ -310,46 +285,43 @@ export abstract class Node { this.flags |= Flags.NODE_HAS_DIRTY_RENDER; for (let parent = this.parentNode; parent; parent = parent.parentNode) { - if (parent.flags & Flags.NODE_HAS_DIRTY_RENDER_CHILDREN) - break; + if (parent.flags & Flags.NODE_HAS_DIRTY_RENDER_CHILDREN) break; parent.flags |= Flags.NODE_HAS_DIRTY_RENDER_CHILDREN; } } - applyTextStyle(text: string, { backColor = this.style.get(`contentBackColor`) || this.style.get(`backgroundBackColor`), frontColor = this.style.get(`contentFrontColor`) }: {backColor?: string, frontColor?: string} = {}) { - const backColorEntry = backColor - ? getColorEntry(backColor) - : null; + applyTextStyle( + text: string, + { + backColor = this.style.get(`contentBackColor`) || this.style.get(`backgroundBackColor`), + frontColor = this.style.get(`contentFrontColor`), + }: {backColor?: string; frontColor?: string} = {}, + ) { + const backColorEntry = backColor ? getColorEntry(backColor) : null; - if (backColorEntry) - text = backColorEntry.back.in + text + backColorEntry.back.out; + if (backColorEntry) text = backColorEntry.back.in + text + backColorEntry.back.out; - const frontColorEntry = frontColor - ? getColorEntry(frontColor) - : null; + const frontColorEntry = frontColor ? getColorEntry(frontColor) : null; - if (frontColorEntry) - text = frontColorEntry.front.in + text + frontColorEntry.front.out; + if (frontColorEntry) text = frontColorEntry.front.in + text + frontColorEntry.front.out; return text; } propagateLayout(dirtyRects: DirtyScreen) { - if (this.parentNode) - throw new Error(`Assertion failed: Cannot call propagateLayout from a non-tree node`); - - if (this.rootNode !== this as Node) + if (this.parentNode) throw new Error(`Assertion failed: Cannot call propagateLayout from a non-tree node`); + + if (this.rootNode !== (this as Node)) throw new Error(`Assertion failed: Cannot call propagateLayout from a non-tree node`); - + const thisRoot = this.rootNode; const removedRects = thisRoot.removedRects; thisRoot.removedRects = []; - + // Don't forget to redraw the parts of the screen where something has disappeared - for (const rect of removedRects) - dirtyRects.addRect(rect); - + for (const rect of removedRects) dirtyRects.addRect(rect); + this.yoga.calculateLayout(); //console.group(`layout`); @@ -378,8 +350,7 @@ export abstract class Node { this.elementRect.height = layout.height; } - for (const child of this.childNodes) - child.cascadeLayout(dirtyScreen, true); + for (const child of this.childNodes) child.cascadeLayout(dirtyScreen, true); if (true || this.yoga.hasNewLayout) { const preferredScrollSize = this.getPreferredScrollSize(); @@ -392,27 +363,24 @@ export abstract class Node { this.scrollRect.height = Math.max(this.scrollRect.height, child.elementRect.top + child.elementRect.height); } - this.contentRect.left = 0;//this.yoga.getComputedBorder(this.env.yoga.EDGE_LEFT) + this.yoga.getComputedPadding(this.env.yoga.EDGE_LEFT); - this.contentRect.top = 0;//this.yoga.getComputedBorder(this.env.yoga.EDGE_TOP) + this.yoga.getComputedPadding(this.env.yoga.EDGE_TOP); + this.contentRect.left = 0; //this.yoga.getComputedBorder(this.env.yoga.EDGE_LEFT) + this.yoga.getComputedPadding(this.env.yoga.EDGE_LEFT); + this.contentRect.top = 0; //this.yoga.getComputedBorder(this.env.yoga.EDGE_TOP) + this.yoga.getComputedPadding(this.env.yoga.EDGE_TOP); - this.contentRect.width = this.scrollRect.width;// - this.contentRect.left - this.yoga.getComputedBorder(this.env.yoga.EDGE_RIGHT) - this.yoga.getComputedPadding(this.env.yoga.EDGE_RIGHT); - this.contentRect.height = this.scrollRect.height;// - this.contentRect.top - this.yoga.getComputedBorder(this.env.yoga.EDGE_BOTTOM) - this.yoga.getComputedPadding(this.env.yoga.EDGE_BOTTOM); + this.contentRect.width = this.scrollRect.width; // - this.contentRect.left - this.yoga.getComputedBorder(this.env.yoga.EDGE_RIGHT) - this.yoga.getComputedPadding(this.env.yoga.EDGE_RIGHT); + this.contentRect.height = this.scrollRect.height; // - this.contentRect.top - this.yoga.getComputedBorder(this.env.yoga.EDGE_BOTTOM) - this.yoga.getComputedPadding(this.env.yoga.EDGE_BOTTOM); } - if (true || this.yoga.hasNewLayout) - this.markDirtyClipping(); + if (true || this.yoga.hasNewLayout) this.markDirtyClipping(); this.yoga.hasNewLayout = false; - + //console.groupEnd(); } private cascadeClipping(dirtyScreen: DirtyScreen, force: boolean, relativeClipRect: Rect | null) { //console.group(); - force = this.trackChanges(`relativeClipRect`, [ - relativeClipRect, - ]) || force; + force = this.trackChanges(`relativeClipRect`, [relativeClipRect]) || force; if (force || this.flags & (Flags.NODE_HAS_DIRTY_CLIPPING | Flags.NODE_HAS_DIRTY_CLIPPING_CHILDREN)) { if (force || this.flags & Flags.NODE_HAS_DIRTY_CLIPPING) { @@ -422,8 +390,12 @@ export abstract class Node { const parentScrollLeft = this.parentNode ? this.parentNode.scrollRect.left : 0; const parentScrollTop = this.parentNode ? this.parentNode.scrollRect.top : 0; - this.elementWorldRect.left = this.parentNode ? this.parentNode.elementWorldRect.left + this.elementRect.left - parentScrollLeft : 0; - this.elementWorldRect.top = this.parentNode ? this.parentNode.elementWorldRect.top + this.elementRect.top - parentScrollTop : 0; + this.elementWorldRect.left = this.parentNode + ? this.parentNode.elementWorldRect.left + this.elementRect.left - parentScrollLeft + : 0; + this.elementWorldRect.top = this.parentNode + ? this.parentNode.elementWorldRect.top + this.elementRect.top - parentScrollTop + : 0; this.elementWorldRect.width = this.elementRect.width; this.elementWorldRect.height = this.elementRect.height; @@ -480,23 +452,23 @@ export abstract class Node { if (doesClippingChange) { // If the clipping changes, we must redraw the previous location where the node was, since it doesn't cover it anymore - dirtyScreen.addCoordinates(prevElementClipLeft, prevElementClipTop, prevElementClipWidth, prevElementClipHeight); + dirtyScreen.addCoordinates( + prevElementClipLeft, + prevElementClipTop, + prevElementClipWidth, + prevElementClipHeight, + ); // We also have to redraw the new location where the node can be found, which be batch as a rendering (so that we don't perform the calculations twice if the node is dirty clipping + dirty rendering) this.markDirtyRender(); } } - if (!relativeClipRect) - relativeClipRect = this.elementClipRect; + if (!relativeClipRect) relativeClipRect = this.elementClipRect; - for (const child of this.childNodes) - child.cascadeClipping(dirtyScreen, force, relativeClipRect); + for (const child of this.childNodes) child.cascadeClipping(dirtyScreen, force, relativeClipRect); - this.flags &= ~( - Flags.NODE_HAS_DIRTY_CLIPPING | - Flags.NODE_HAS_DIRTY_CLIPPING_CHILDREN - ); + this.flags &= ~(Flags.NODE_HAS_DIRTY_CLIPPING | Flags.NODE_HAS_DIRTY_CLIPPING_CHILDREN); } //console.groupEnd(); @@ -506,16 +478,12 @@ export abstract class Node { //console.group(); if (force || this.flags & (Flags.NODE_HAS_DIRTY_RENDER | Flags.NODE_HAS_DIRTY_RENDER_CHILDREN)) { - if (force || (this.flags & Flags.NODE_HAS_DIRTY_RENDER)) - dirtyScreen.addRect(this.elementClipRect); + if (force || this.flags & Flags.NODE_HAS_DIRTY_RENDER) dirtyScreen.addRect(this.elementClipRect); for (const child of this.childNodes) child.cascadeRendering(dirtyScreen, force || Boolean(this.flags & Flags.NODE_HAS_DIRTY_RENDER)); - this.flags &= ~( - Flags.NODE_HAS_DIRTY_RENDER | - Flags.NODE_HAS_DIRTY_RENDER_CHILDREN - ); + this.flags &= ~(Flags.NODE_HAS_DIRTY_RENDER | Flags.NODE_HAS_DIRTY_RENDER_CHILDREN); } //console.groupEnd(); @@ -525,15 +493,11 @@ export abstract class Node { const previous = this.trackers.get(trackerName); this.trackers.set(trackerName, data); - if (!previous) - return true; + if (!previous) return true; - if (previous.length !== data.length) - return true; + if (previous.length !== data.length) return true; - for (let t = 0; t < data.length; ++t) - if (data[t] !== previous[t]) - return true; + for (let t = 0; t < data.length; ++t) if (data[t] !== previous[t]) return true; return false; } @@ -542,8 +506,7 @@ export abstract class Node { if (!this.parentNode || !this.parentNode.rootNode) throw new Error(`Assertion failed: linkRecursive called on a node that hasn't been correctly setup`); - if (this.rootNode) - throw new Error(`Assertion failed: linkRecursive called on a node that's already been linked`); + if (this.rootNode) throw new Error(`Assertion failed: linkRecursive called on a node that's already been linked`); this.rootNode = this.parentNode.rootNode; this.linkSelf(this.rootNode, this.parentNode); @@ -558,15 +521,12 @@ export abstract class Node { throw new Error(`Assertion failed: unlinkRecursive called on a node that hasn't been correctly setup`); // If the node is focused, we need to unfocus it - if (this.rootNode && this.rootNode.activeElement === this as Node) - this.rootNode.focus(null); + if (this.rootNode && this.rootNode.activeElement === (this as Node)) this.rootNode.focus(null); // We'll need to refresh this part of the screen no matter what - if (this.rootNode) - this.rootNode.removedRects.push(this.elementClipRect); + if (this.rootNode) this.rootNode.removedRects.push(this.elementClipRect); - for (const child of this.childNodes) - child.unlinkRecursive(); + for (const child of this.childNodes) child.unlinkRecursive(); this.unlinkSelf(this.rootNode, this.parentNode); this.rootNode = null; diff --git a/packages/berry-ui/sources/NodeElement.ts b/packages/berry-ui/sources/NodeElement.ts index 3821fed3be4a..91bdb8daa33d 100644 --- a/packages/berry-ui/sources/NodeElement.ts +++ b/packages/berry-ui/sources/NodeElement.ts @@ -1,9 +1,9 @@ -import {Environment} from './Environment'; -import {KeySequence} from './KeySequence'; -import {NodeTree} from './NodeTree'; -import {Node, NodeType} from './Node'; +import {Environment} from './Environment'; +import {KeySequence} from './KeySequence'; +import {NodeTree} from './NodeTree'; +import {Node, NodeType} from './Node'; import {DEFAULT_COMPUTED_STYLES} from './StyleConfiguration'; -import {Props} from './types'; +import {Props} from './types'; export class NodeElement extends Node { public props: Props = {}; @@ -31,8 +31,7 @@ export class NodeElement extends Node { this.setShortcuts(null, props.shortcuts || {}); // Attach all the global shortcuts to the root node, under our namespace - if (this.rootNode) - this.rootNode.setShortcuts(this, props.globalShortcuts); + if (this.rootNode) this.rootNode.setShortcuts(this, props.globalShortcuts); // Updates the node style properties this.style.setProperties(new Map(Object.entries(props.style || {}))); @@ -58,14 +57,11 @@ export class NodeElement extends Node { // We need a second copy because the first one will get mutated const tempShortcuts = new Set(shortcuts.keys()); - for (const shortcut of oldShortcuts) - newShortcuts.delete(shortcut); - for (const shortcut of tempShortcuts) - oldShortcuts.delete(shortcut); + for (const shortcut of oldShortcuts) newShortcuts.delete(shortcut); + for (const shortcut of tempShortcuts) oldShortcuts.delete(shortcut); if (this.rootNode) { - for (const shortcut of newShortcuts) - this.rootNode.addShortcutReference(shortcut); + for (const shortcut of newShortcuts) this.rootNode.addShortcutReference(shortcut); for (const shortcut of oldShortcuts) { this.rootNode.removeShortcutReference(shortcut); } @@ -75,8 +71,7 @@ export class NodeElement extends Node { } linkSelf(rootNode: NodeTree, parentNode: Node) { - if (this.rootNode) - this.rootNode.setShortcuts(this, this.props.globalShortcuts); + if (this.rootNode) this.rootNode.setShortcuts(this, this.props.globalShortcuts); for (const shortcuts of this.shortcutStores.values()) { for (const shortcut of shortcuts.keys()) { @@ -102,31 +97,28 @@ export class NodeElement extends Node { const style: {[key: string]: any} = {}; for (const key of DEFAULT_COMPUTED_STYLES.keys()) - if (DEFAULT_COMPUTED_STYLES.get(key) !== this.style.get(key)) - style[key] = this.style.get(key); + if (DEFAULT_COMPUTED_STYLES.get(key) !== this.style.get(key)) style[key] = this.style.get(key); console.log(indent + `
`); - for (const child of this.childNodes) - child.dumpNode(depth + 1); + for (const child of this.childNodes) child.dumpNode(depth + 1); console.log(indent + `
`); } getLine(row: number, left: number, width: number) { - if (!(left >= 0 && left < this.elementWorldRect.width)) - throw new Error(`Out-of-bound segment start`); - if (!(width >= 0 && width <= this.elementWorldRect.width - left)) - throw new Error(`Invalid segment width`); - - if (!width) - return ``; + if (!(left >= 0 && left < this.elementWorldRect.width)) throw new Error(`Out-of-bound segment start`); + if (!(width >= 0 && width <= this.elementWorldRect.width - left)) throw new Error(`Invalid segment width`); + + if (!width) return ``; if (row === 0) { const borderTop = this.style.get(`borderTop`); if (borderTop) { - let prefix = ``, center = ``, suffix = ``; + let prefix = ``, + center = ``, + suffix = ``; if (this.elementWorldRect.width >= 2) { if (left === 0) { @@ -160,7 +152,9 @@ export class NodeElement extends Node { const borderBottom = this.style.get(`borderBottom`); if (borderBottom) { - let prefix = ``, center = ``, suffix = ``; + let prefix = ``, + center = ``, + suffix = ``; if (this.elementWorldRect.width >= 2) { if (left === 0) { @@ -190,7 +184,8 @@ export class NodeElement extends Node { } } - let prefix = ``, suffix = ``; + let prefix = ``, + suffix = ``; if (left === 0) { const borderLeft = this.style.get(`borderLeft`); diff --git a/packages/berry-ui/sources/NodeText.ts b/packages/berry-ui/sources/NodeText.ts index eefa26aac75f..18d8010a20b2 100644 --- a/packages/berry-ui/sources/NodeText.ts +++ b/packages/berry-ui/sources/NodeText.ts @@ -1,7 +1,7 @@ -import {TextLayout} from '@manaflair/text-layout'; +import {TextLayout} from '@manaflair/text-layout'; -import {Environment} from './Environment'; -import {NodeTree} from './NodeTree'; +import {Environment} from './Environment'; +import {NodeTree} from './NodeTree'; import {Node, NodeType} from './Node'; export class NodeText extends Node { @@ -18,8 +18,7 @@ export class NodeText extends Node { this.textLayout.setSoftWrap(true); this.yoga.setMeasureFunc((widthHint: number, widthMode: any, heightHint: number, heightMode: any) => { - if (this.textLayout.setColumns(widthHint)) - this.textLayout.clearSource(); + if (this.textLayout.setColumns(widthHint)) this.textLayout.clearSource(); const width = this.textLayout.getColumnCount(); const height = this.textLayout.getRowCount(); @@ -40,9 +39,8 @@ export class NodeText extends Node { let leftMostTextNode = this.previousSibling; - while (leftMostTextNode.previousSibling instanceof NodeText) - leftMostTextNode = leftMostTextNode.previousSibling; - + while (leftMostTextNode.previousSibling instanceof NodeText) leftMostTextNode = leftMostTextNode.previousSibling; + leftMostTextNode.clearTextLayout(); } } @@ -56,12 +54,11 @@ export class NodeText extends Node { } } else { this.activate(); - + let leftMostTextNode = this.previousSibling; - while (leftMostTextNode.previousSibling instanceof NodeText) - leftMostTextNode = leftMostTextNode.previousSibling; - + while (leftMostTextNode.previousSibling instanceof NodeText) leftMostTextNode = leftMostTextNode.previousSibling; + leftMostTextNode.clearTextLayout(); } } @@ -71,8 +68,7 @@ export class NodeText extends Node { let activeTextNode: NodeText = this; - while (activeTextNode.previousSibling instanceof NodeText) - activeTextNode = activeTextNode.previousSibling; + while (activeTextNode.previousSibling instanceof NodeText) activeTextNode = activeTextNode.previousSibling; activeTextNode.clearTextLayout(); } @@ -106,7 +102,12 @@ export class NodeText extends Node { const pad = background.repeat(Math.ceil((width - line.length) / background.length)).substr(0, width - line.length); const formattedLine = this.applyTextStyle(line); - const formattedPad = pad ? this.applyTextStyle(pad, {backColor: this.style.get(`backgroundBackColor`), frontColor: this.style.get(`backgroundFrontColor`)}) : ``; + const formattedPad = pad + ? this.applyTextStyle(pad, { + backColor: this.style.get(`backgroundBackColor`), + frontColor: this.style.get(`backgroundFrontColor`), + }) + : ``; return formattedLine + formattedPad; } diff --git a/packages/berry-ui/sources/NodeTree.ts b/packages/berry-ui/sources/NodeTree.ts index 5bead30992b5..5e856bf76336 100644 --- a/packages/berry-ui/sources/NodeTree.ts +++ b/packages/berry-ui/sources/NodeTree.ts @@ -1,12 +1,12 @@ // @ts-ignore -import {Key} from '@manaflair/term-strings/parse'; - -import {DirtyScreen} from './DirtyScreen'; -import {Environment} from './Environment'; -import {KeySequence} from './KeySequence'; -import {NodeElement} from './NodeElement'; -import {Node} from './Node'; -import {Rect} from './Rect'; +import {Key} from '@manaflair/term-strings/parse'; + +import {DirtyScreen} from './DirtyScreen'; +import {Environment} from './Environment'; +import {KeySequence} from './KeySequence'; +import {NodeElement} from './NodeElement'; +import {Node} from './Node'; +import {Rect} from './Rect'; import {SyntheticEvent} from './SyntheticEvent'; export class NodeTree extends NodeElement { @@ -25,7 +25,7 @@ export class NodeTree extends NodeElement { private mouseOverElement: NodeElement | null = null; private mouseEnterElements: Array = []; - private readonly monitoredShortcuts: Map = new Map(); + private readonly monitoredShortcuts: Map = new Map(); constructor(env: Environment, renderFn: () => void, shutdownFn: () => void) { super(env); @@ -58,17 +58,13 @@ export class NodeTree extends NodeElement { } getElementAt(x: number, y: number) { - if (!this.renderList) - throw new Error(`Assertion failed: the render list should be available`); + if (!this.renderList) throw new Error(`Assertion failed: the render list should be available`); for (const node of this.renderList) { - if (!(node instanceof NodeElement)) - continue; + if (!(node instanceof NodeElement)) continue; - if (x < node.elementClipRect.left || x >= node.elementClipRect.left + node.elementClipRect.width) - continue; - if (y < node.elementClipRect.top || y >= node.elementClipRect.top + node.elementClipRect.height) - continue; + if (x < node.elementClipRect.left || x >= node.elementClipRect.left + node.elementClipRect.width) continue; + if (y < node.elementClipRect.top || y >= node.elementClipRect.top + node.elementClipRect.height) continue; return node; } @@ -77,24 +73,20 @@ export class NodeTree extends NodeElement { } focus(element: NodeElement | null) { - if (element && element.props.tabIndex === null) - element = null; - + if (element && element.props.tabIndex === null) element = null; + if (!element) { - if (!this.activeElement) - return; + if (!this.activeElement) return; const previousElement = this.activeElement; - this.activeElement = null; + this.activeElement = null; previousElement.dispatchEvent(new SyntheticEvent(`blur`)); } else { - if (this.activeElement === element) - return; + if (this.activeElement === element) return; // Don't forget to trigger the blur event on the currently active node - if (this.activeElement) - this.focus(null); - + if (this.activeElement) this.focus(null); + // If the blur event caused something else to get the focus, we // effectively cancel the focus action we were about to execute if (!this.activeElement) { @@ -111,8 +103,7 @@ export class NodeTree extends NodeElement { let monitorEntry = this.monitoredShortcuts.get(keySequenceName); // Register the sequence if it doesn't exist yet - if (!monitorEntry) - this.monitoredShortcuts.set(keySequenceName, monitorEntry = {keySequence, refCount: 0}); + if (!monitorEntry) this.monitoredShortcuts.set(keySequenceName, (monitorEntry = {keySequence, refCount: 0})); monitorEntry.refCount += 1; } @@ -123,8 +114,7 @@ export class NodeTree extends NodeElement { const monitorEntry = this.monitoredShortcuts.get(keySequenceName); - if (!monitorEntry) - throw new Error(`Assertion failed: the specified shortcut isn't referenced`); + if (!monitorEntry) throw new Error(`Assertion failed: the specified shortcut isn't referenced`); // Remove the sequence if nothing references it anymore if ((monitorEntry.refCount -= 1) === 0) { @@ -135,8 +125,7 @@ export class NodeTree extends NodeElement { emitMouse(mouse: any) { const targetElement = this.getElementAt(mouse.x, mouse.y); - if (!targetElement) - return; + if (!targetElement) return; if (mouse.name === `wheel`) { targetElement.dispatchEvent(new SyntheticEvent(`wheel`, {bubbles: true}, {mouse})); @@ -144,20 +133,17 @@ export class NodeTree extends NodeElement { if (mouse.start) { targetElement.dispatchEvent(new SyntheticEvent(`mouseDown`, {bubbles: true}, {mouse})); - if (mouse.name === `left`) - targetElement.dispatchEvent(new SyntheticEvent(`click`, {bubbles: true}, {mouse})); + if (mouse.name === `left`) targetElement.dispatchEvent(new SyntheticEvent(`click`, {bubbles: true}, {mouse})); let focusElement: NodeElement | null = null; for (let node: Node | null = targetElement; !focusElement && node; node = node.parentNode) - if (node instanceof NodeElement && node.props.tabIndex != null) - focusElement = node; + if (node instanceof NodeElement && node.props.tabIndex != null) focusElement = node; this.focus(focusElement); } - if (mouse.end) - targetElement.dispatchEvent(new SyntheticEvent(`mouseUp`, {bubbles: true}, {mouse})); + if (mouse.end) targetElement.dispatchEvent(new SyntheticEvent(`mouseUp`, {bubbles: true}, {mouse})); if (!mouse.start && !mouse.end) { this.emitMouseOver(mouse); @@ -171,14 +157,12 @@ export class NodeTree extends NodeElement { private emitMouseOver(mouse: any) { const targetElement = this.getElementAt(mouse.x, mouse.y); - if (targetElement === this.mouseOverElement) - return; + if (targetElement === this.mouseOverElement) return; const previousElement = this.mouseOverElement; - const currentElement = this.mouseOverElement = targetElement; + const currentElement = (this.mouseOverElement = targetElement); - if (previousElement) - previousElement.dispatchEvent(new SyntheticEvent(`mouseOut`, {bubbles: true}, {mouse})); + if (previousElement) previousElement.dispatchEvent(new SyntheticEvent(`mouseOut`, {bubbles: true}, {mouse})); if (currentElement) { currentElement.dispatchEvent(new SyntheticEvent(`mouseOver`, {bubbles: true}, {mouse})); @@ -188,9 +172,7 @@ export class NodeTree extends NodeElement { private emitMouseEnter(mouse: any) { const targetElement = this.getElementAt(mouse.x, mouse.y); - const index = targetElement - ? this.mouseEnterElements.indexOf(targetElement) - : -1; + const index = targetElement ? this.mouseEnterElements.indexOf(targetElement) : -1; let removedElements = []; const addedElements = []; @@ -202,8 +184,7 @@ export class NodeTree extends NodeElement { let currentIndex = index; while (currentNode && currentIndex === -1) { - if (currentNode instanceof NodeElement) - addedElements.unshift(currentNode); + if (currentNode instanceof NodeElement) addedElements.unshift(currentNode); currentNode = currentNode.parentNode; @@ -235,10 +216,15 @@ export class NodeTree extends NodeElement { for (let monitoredShortcut of this.monitoredShortcuts.values()) if (monitoredShortcut.keySequence.add(key)) - shortcutEvents.push(new SyntheticEvent(`shortcut`, {bubbles: true, cancelable: true}, {shortcut: monitoredShortcut.keySequence.name})); + shortcutEvents.push( + new SyntheticEvent( + `shortcut`, + {bubbles: true, cancelable: true}, + {shortcut: monitoredShortcut.keySequence.name}, + ), + ); - for (let event of shortcutEvents) - targetElement.dispatchEvent(event); + for (let event of shortcutEvents) targetElement.dispatchEvent(event); targetElement.dispatchEvent(new SyntheticEvent(`key`, {}, {key})); } @@ -261,11 +247,16 @@ export class NodeTree extends NodeElement { for (let monitoredShortcut of this.monitoredShortcuts.values()) if (monitoredShortcut.keySequence.add(key)) - shortcutEvents.push(new SyntheticEvent(`shortcut`, {bubbles: true, cancelable: true}, {shortcut: monitoredShortcut.keySequence.name})); + shortcutEvents.push( + new SyntheticEvent( + `shortcut`, + {bubbles: true, cancelable: true}, + {shortcut: monitoredShortcut.keySequence.name}, + ), + ); + + for (let event of shortcutEvents) targetElement.dispatchEvent(event); - for (let event of shortcutEvents) - targetElement.dispatchEvent(event); - if (shortcutEvents.some(event => event.defaultPrevented)) { return; } @@ -275,10 +266,9 @@ export class NodeTree extends NodeElement { } refreshRenderList() { - if (this.renderList) - return this.renderList; + if (this.renderList) return this.renderList; - const renderList: Array = this.renderList = [this]; + const renderList: Array = (this.renderList = [this]); const contexts: Array = [this]; @@ -300,9 +290,13 @@ export class NodeTree extends NodeElement { } } - contexts.splice(0, 0, ...subContexts.sort((a, b) => { - return a.layerIndex - b.layerIndex; - })); + contexts.splice( + 0, + 0, + ...subContexts.sort((a, b) => { + return a.layerIndex - b.layerIndex; + }), + ); } return renderList; @@ -323,4 +317,4 @@ export class NodeTree extends NodeElement { }, }); } -}; +} diff --git a/packages/berry-ui/sources/StyleConfiguration.ts b/packages/berry-ui/sources/StyleConfiguration.ts index 2c0021568727..6be3716a90d7 100644 --- a/packages/berry-ui/sources/StyleConfiguration.ts +++ b/packages/berry-ui/sources/StyleConfiguration.ts @@ -1,6 +1,6 @@ import {NodeElement} from './NodeElement'; -import {NodeText} from './NodeText'; -import {Node} from './Node'; +import {NodeText} from './NodeText'; +import {Node} from './Node'; /** * This symbol is meant to be used when a property must be inherited from its parent node styles. @@ -15,13 +15,16 @@ export const INHERITED_STYLE_PROPERTY = Symbol(`INHERITED_STYLE_PROPERTY`); export type StyleConverter = (value: any) => any; export const STYLE_CONVERTERS: Map = new Map([ - [ `zIndex`, (value: any) => { - if (value === null) { - return null; - } else { - return Number(value); - } - }], + [ + `zIndex`, + (value: any) => { + if (value === null) { + return null; + } else { + return Number(value); + } + }, + ], ]); /** @@ -119,198 +122,318 @@ export const DEFAULT_COMPUTED_STYLES: Map = new Map([ export type StyleTrigger = (node: Node, value: any) => void; export const STYLE_TRIGGERS: Map = new Map([ - [`display`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.display = getYogaEnum(element.env.yoga, `display`, value); - element.markDirtyLayout(); - })], - - [`position`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.position = getYogaEnum(element.env.yoga, `position`, value); - element.markDirtyLayout(); - })], - - [`left`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.left = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`right`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.right = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`top`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.top = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`bottom`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.bottom = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`zIndex`, elementsOnly((element: NodeElement, value: any) => { - element.markDirtyRender(); - })], - - [`flexDirection`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.flexDirection = getYogaEnum(element.env.yoga, `flexDirection`, value); - element.markDirtyLayout(); - })], - - [`flexWrap`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.flexWrap = getYogaEnum(element.env.yoga, `wrap`, value); - element.markDirtyLayout(); - })], - - [`alignContent`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.alignContent = getYogaEnum(element.env.yoga, `align`, value); - element.markDirtyLayout(); - })], - - [`alignSelf`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.alignSelf = getYogaEnum(element.env.yoga, `align`, value); - element.markDirtyLayout(); - })], - - [`alignItems`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.alignItems = getYogaEnum(element.env.yoga, `align`, value); - element.markDirtyLayout(); - })], - - [`justifyContent`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.justifyContent = getYogaEnum(element.env.yoga, `justify`, value); - element.markDirtyLayout(); - })], - - [`flexGrow`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.flexGrow = value; - element.markDirtyLayout(); - })], - - [`flexShrink`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.flexShrink = value; - element.markDirtyLayout(); - })], - - [`flexBasis`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.flexBasis = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`width`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.width = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`height`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.height = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`minWidth`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.minWidth = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`minHeight`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.minHeight = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`maxWidth`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.maxWidth = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`maxHeight`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.maxHeight = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`marginLeft`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.marginLeft = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`marginRight`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.marginRight = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`marginTop`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.marginTop = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`marginBottom`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.marginBottom = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`borderLeft`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.borderLeft = value ? 1 : 0; - element.markDirtyLayout(); - })], - - [`borderRight`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.borderRight = value ? 1 : 0; - element.markDirtyLayout(); - })], - - [`borderTop`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.borderTop = value ? 1 : 0; - element.markDirtyLayout(); - })], - - [`borderBottom`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.borderBottom = value ? 1 : 0; - element.markDirtyLayout(); - })], - - [`paddingLeft`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.paddingLeft = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`paddingRight`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.paddingRight = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`paddingTop`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.paddingTop = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`paddingBottom`, elementsOnly((element: NodeElement, value: any) => { - element.yoga.paddingBottom = getYogaUnit(element.env.yoga, value); - element.markDirtyLayout(); - })], - - [`borderBackColor`, (node: Node, value: any) => { - node.markDirtyRender(); - }], - - [`borderFrontColor`, (node: Node, value: any) => { - node.markDirtyRender(); - }], - - [`backgroundBackColor`, (node: Node, value: any) => { - node.markDirtyRender(); - }], - - [`backgroundFrontColor`, (node: Node, value: any) => { - node.markDirtyRender(); - }], - - [`contentBackColor`, (node: Node, value: any) => { - node.markDirtyRender(); - }], - - [`contentFrontColor`, (node: Node, value: any) => { - node.markDirtyRender(); - }], + [ + `display`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.display = getYogaEnum(element.env.yoga, `display`, value); + element.markDirtyLayout(); + }), + ], + + [ + `position`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.position = getYogaEnum(element.env.yoga, `position`, value); + element.markDirtyLayout(); + }), + ], + + [ + `left`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.left = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `right`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.right = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `top`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.top = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `bottom`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.bottom = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `zIndex`, + elementsOnly((element: NodeElement, value: any) => { + element.markDirtyRender(); + }), + ], + + [ + `flexDirection`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.flexDirection = getYogaEnum(element.env.yoga, `flexDirection`, value); + element.markDirtyLayout(); + }), + ], + + [ + `flexWrap`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.flexWrap = getYogaEnum(element.env.yoga, `wrap`, value); + element.markDirtyLayout(); + }), + ], + + [ + `alignContent`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.alignContent = getYogaEnum(element.env.yoga, `align`, value); + element.markDirtyLayout(); + }), + ], + + [ + `alignSelf`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.alignSelf = getYogaEnum(element.env.yoga, `align`, value); + element.markDirtyLayout(); + }), + ], + + [ + `alignItems`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.alignItems = getYogaEnum(element.env.yoga, `align`, value); + element.markDirtyLayout(); + }), + ], + + [ + `justifyContent`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.justifyContent = getYogaEnum(element.env.yoga, `justify`, value); + element.markDirtyLayout(); + }), + ], + + [ + `flexGrow`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.flexGrow = value; + element.markDirtyLayout(); + }), + ], + + [ + `flexShrink`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.flexShrink = value; + element.markDirtyLayout(); + }), + ], + + [ + `flexBasis`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.flexBasis = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `width`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.width = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `height`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.height = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `minWidth`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.minWidth = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `minHeight`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.minHeight = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `maxWidth`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.maxWidth = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `maxHeight`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.maxHeight = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `marginLeft`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.marginLeft = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `marginRight`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.marginRight = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `marginTop`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.marginTop = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `marginBottom`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.marginBottom = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `borderLeft`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.borderLeft = value ? 1 : 0; + element.markDirtyLayout(); + }), + ], + + [ + `borderRight`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.borderRight = value ? 1 : 0; + element.markDirtyLayout(); + }), + ], + + [ + `borderTop`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.borderTop = value ? 1 : 0; + element.markDirtyLayout(); + }), + ], + + [ + `borderBottom`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.borderBottom = value ? 1 : 0; + element.markDirtyLayout(); + }), + ], + + [ + `paddingLeft`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.paddingLeft = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `paddingRight`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.paddingRight = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `paddingTop`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.paddingTop = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `paddingBottom`, + elementsOnly((element: NodeElement, value: any) => { + element.yoga.paddingBottom = getYogaUnit(element.env.yoga, value); + element.markDirtyLayout(); + }), + ], + + [ + `borderBackColor`, + (node: Node, value: any) => { + node.markDirtyRender(); + }, + ], + + [ + `borderFrontColor`, + (node: Node, value: any) => { + node.markDirtyRender(); + }, + ], + + [ + `backgroundBackColor`, + (node: Node, value: any) => { + node.markDirtyRender(); + }, + ], + + [ + `backgroundFrontColor`, + (node: Node, value: any) => { + node.markDirtyRender(); + }, + ], + + [ + `contentBackColor`, + (node: Node, value: any) => { + node.markDirtyRender(); + }, + ], + + [ + `contentFrontColor`, + (node: Node, value: any) => { + node.markDirtyRender(); + }, + ], ]); function elementsOnly(trigger: (element: NodeElement, value: any) => void) { @@ -322,8 +445,7 @@ function elementsOnly(trigger: (element: NodeElement, value: any) => void) { } function getYogaEnum(yoga: any, type: string, value: any) { - if (typeof value !== `string`) - throw new Error(`Invalid value type (${typeof value})`); + if (typeof value !== `string`) throw new Error(`Invalid value type (${typeof value})`); if (!Object.prototype.hasOwnProperty.call(yoga.Constants, type)) throw new Error(`Invalid enumeration type ("${type}")`); if (!Object.prototype.hasOwnProperty.call(yoga.Constants[type], value)) @@ -351,57 +473,87 @@ function getYogaUnit(yoga: any, value: any) { */ const FLEX_SHORTHANDS: Map = new Map([ - [`initial`, { - flexGrow: 0, - flexShrink: 1, - }], - - [`none`, { - flexGrow: 0, - flexShrink: 0, - }], - - [`auto`, { - flexGrow: 1, - flexShrink: 1, - }], + [ + `initial`, + { + flexGrow: 0, + flexShrink: 1, + }, + ], + + [ + `none`, + { + flexGrow: 0, + flexShrink: 0, + }, + ], + + [ + `auto`, + { + flexGrow: 1, + flexShrink: 1, + }, + ], ]); export type CompositeStyle = (value: any) => {[key: string]: any}; export const COMPOSITE_STYLES: Map = new Map([ - [`borderColor`, (value: any) => { - return { borderFrontColor: value }; - }], - - [`backgroundColor`, (value: any) => { - return { backgroundBackColor: value }; - }], - - [`color`, (value: any) => { - return { contentFrontColor: value }; - }], - - [`margin`, (value: any) => { - return handleEdgeShorthand(`margin`, value); - }], - - [`padding`, (value: any) => { - return handleEdgeShorthand(`padding`, value); - }], - - [`border`, (value: any) => { - return handleBorderShorthand(value); - }], - - [`flex`, (value: any) => { - const shorthand = FLEX_SHORTHANDS.get(value); - if (shorthand) { - return shorthand; - } else { - return { flexGrow: value, flexShrink: 1, flexBasis: 0 }; - } - }], + [ + `borderColor`, + (value: any) => { + return {borderFrontColor: value}; + }, + ], + + [ + `backgroundColor`, + (value: any) => { + return {backgroundBackColor: value}; + }, + ], + + [ + `color`, + (value: any) => { + return {contentFrontColor: value}; + }, + ], + + [ + `margin`, + (value: any) => { + return handleEdgeShorthand(`margin`, value); + }, + ], + + [ + `padding`, + (value: any) => { + return handleEdgeShorthand(`padding`, value); + }, + ], + + [ + `border`, + (value: any) => { + return handleBorderShorthand(value); + }, + ], + + [ + `flex`, + (value: any) => { + const shorthand = FLEX_SHORTHANDS.get(value); + if (shorthand) { + return shorthand; + } else { + return {flexGrow: value, flexShrink: 1, flexBasis: 0}; + } + }, + ], ]); /** @@ -409,10 +561,8 @@ export const COMPOSITE_STYLES: Map = new Map([ */ function handleEdgeShorthand(base: string, n: any) { - if (typeof n === `number` || typeof n === `string`) - n = [n, n]; - if (n.length === 2) - n = [n[0], n[1], n[0], n[1]]; + if (typeof n === `number` || typeof n === `string`) n = [n, n]; + if (n.length === 2) n = [n[0], n[1], n[0], n[1]]; return { [`${base}Top`]: n[0], @@ -436,17 +586,12 @@ const BUILTIN_BORDERS = new Map([ function handleBorderShorthand(n: any) { const builtin = BUILTIN_BORDERS.get(n); - if (builtin) - n = builtin; - - if (typeof n === `string`) - n = [n]; - if (n.length === 1) - n = [n[0], n[0]]; - if (n.length === 2) - n = [n[0], n[1], n[0], n[1]]; - if (n.length === 6) - n = [n[0], n[1], n[0], n[1], n[2], n[3], n[4], n[5]]; + if (builtin) n = builtin; + + if (typeof n === `string`) n = [n]; + if (n.length === 1) n = [n[0], n[0]]; + if (n.length === 2) n = [n[0], n[1], n[0], n[1]]; + if (n.length === 6) n = [n[0], n[1], n[0], n[1], n[2], n[3], n[4], n[5]]; return { borderTop: n[0], diff --git a/packages/berry-ui/sources/StyleManager.ts b/packages/berry-ui/sources/StyleManager.ts index 776f75f511a9..fadf4ee0092c 100644 --- a/packages/berry-ui/sources/StyleManager.ts +++ b/packages/berry-ui/sources/StyleManager.ts @@ -1,12 +1,11 @@ -import {Node} from './Node'; +import {Node} from './Node'; import {DEFAULT_COMPUTED_STYLES, DEFAULT_INHERITED_STYLES, COMPOSITE_STYLES} from './StyleConfiguration'; -import {STYLE_CONVERTERS, STYLE_TRIGGERS} from './StyleConfiguration'; -import {INHERITED_STYLE_PROPERTY} from './StyleConfiguration'; +import {STYLE_CONVERTERS, STYLE_TRIGGERS} from './StyleConfiguration'; +import {INHERITED_STYLE_PROPERTY} from './StyleConfiguration'; export type StyleMap = Map; export class StyleManager { - private readonly node: Node; private readonly computed: Map = new Map(); @@ -29,8 +28,7 @@ export class StyleManager { refreshInheritedProperties() { const inheritedProperties: StyleMap = new Map(); - for (const inherited of this.inherited) - inheritedProperties.set(inherited, INHERITED_STYLE_PROPERTY); + for (const inherited of this.inherited) inheritedProperties.set(inherited, INHERITED_STYLE_PROPERTY); this.applyProperties(inheritedProperties); } @@ -55,12 +53,9 @@ export class StyleManager { } }; - for (let [key, value] of mappedSource.entries()) - traverseStyleProperty(key, value); + for (let [key, value] of mappedSource.entries()) traverseStyleProperty(key, value); - for (let key of this.computed.keys()) - if (!comprehensiveSource.has(key)) - comprehensiveSource.set(key, undefined); + for (let key of this.computed.keys()) if (!comprehensiveSource.has(key)) comprehensiveSource.set(key, undefined); this.applyProperties(comprehensiveSource); } @@ -93,8 +88,7 @@ export class StyleManager { } }; - for (const [key, value] of source.entries()) - applyStyleProperty(key, value); + for (const [key, value] of source.entries()) applyStyleProperty(key, value); this.applyComputedProperties(computedProperties); } @@ -105,19 +99,15 @@ export class StyleManager { for (let [key, value] of source.entries()) { const defaultValue: any = DEFAULT_COMPUTED_STYLES.get(key); - if (value === undefined) - value = DEFAULT_INHERITED_STYLES.has(key) ? INHERITED_STYLE_PROPERTY : defaultValue; + if (value === undefined) value = DEFAULT_INHERITED_STYLES.has(key) ? INHERITED_STYLE_PROPERTY : defaultValue; - if (value === INHERITED_STYLE_PROPERTY) - this.inherited.add(key); - else - this.inherited.delete(key); + if (value === INHERITED_STYLE_PROPERTY) this.inherited.add(key); + else this.inherited.delete(key); if (value === INHERITED_STYLE_PROPERTY) value = this.node.parentNode ? this.node.parentNode.style.get(key) : defaultValue; - if (value === this.get(key)) - continue; + if (value === this.get(key)) continue; dirtyKeys.add(key); @@ -140,8 +130,7 @@ export class StyleManager { const inheritedComputedProperties: StyleMap = new Map(); for (let key of child.style.inherited) - if (dirtyKeys.has(key)) - inheritedComputedProperties.set(key, INHERITED_STYLE_PROPERTY); + if (dirtyKeys.has(key)) inheritedComputedProperties.set(key, INHERITED_STYLE_PROPERTY); child.style.applyComputedProperties(inheritedComputedProperties); } diff --git a/packages/berry-ui/sources/SyntheticEvent.ts b/packages/berry-ui/sources/SyntheticEvent.ts index bccabc34ae50..60a278c5dd8f 100644 --- a/packages/berry-ui/sources/SyntheticEvent.ts +++ b/packages/berry-ui/sources/SyntheticEvent.ts @@ -3,12 +3,12 @@ import {Node} from './Node'; export type EventDefault = () => void; export type EventOptions = { - bubbles: boolean, - cancelable: boolean, + bubbles: boolean; + cancelable: boolean; }; export type EventData = { - [key: string]: any, + [key: string]: any; }; export class SyntheticEvent { @@ -62,8 +62,7 @@ export class SyntheticEvent { } preventDefault() { - if (!this.cancelable) - throw new Error(`Failed to execute 'preventDefault': Event is not cancelable.`); + if (!this.cancelable) throw new Error(`Failed to execute 'preventDefault': Event is not cancelable.`); this.defaultPrevented = true; } diff --git a/packages/berry-ui/sources/TermInput.ts b/packages/berry-ui/sources/TermInput.ts index b1b3bcc95098..5032b810a0aa 100644 --- a/packages/berry-ui/sources/TermInput.ts +++ b/packages/berry-ui/sources/TermInput.ts @@ -1,8 +1,8 @@ // @ts-ignore -import {Key, Mouse, parseTerminalInputs} from '@manaflair/term-strings/parse'; -import EventEmitter from 'eventemitter3'; -import {Readable} from 'stream'; -import {ReadStream as ReadableTTY} from 'tty'; +import {Key, Mouse, parseTerminalInputs} from '@manaflair/term-strings/parse'; +import EventEmitter from 'eventemitter3'; +import {Readable} from 'stream'; +import {ReadStream as ReadableTTY} from 'tty'; export class TermInput extends EventEmitter { private readonly stdin: Readable | ReadableTTY; @@ -18,29 +18,27 @@ export class TermInput extends EventEmitter { } open() { - if (this.opened) - throw new Error(`Instance already opened`); + if (this.opened) throw new Error(`Instance already opened`); this.subscription = parseTerminalInputs(this.stdin, { throttleMouseMoveEvents: 1000 / 60, }).subscribe({ next: (input: any) => { if (input instanceof Key) { - this.emit(`key`, { key: input }); + this.emit(`key`, {key: input}); } else if (input instanceof Mouse) { - this.emit(`mouse`, { mouse: input }); + this.emit(`mouse`, {mouse: input}); } else { - this.emit(`data`, { buffer: input }); + this.emit(`data`, {buffer: input}); } - } + }, }); this.opened = true; } close() { - if (!this.opened) - throw new Error(`Instance isn't open`); + if (!this.opened) throw new Error(`Instance isn't open`); this.subscription.unsubscribe(); this.subscription = null; @@ -49,8 +47,7 @@ export class TermInput extends EventEmitter { } setRawMode(mode: boolean) { - if (!this.subscription) - throw new Error(`Instance isn't open`); + if (!this.subscription) throw new Error(`Instance isn't open`); if (this.stdin instanceof ReadableTTY) { this.stdin.setRawMode(mode); diff --git a/packages/berry-ui/sources/TermOutput.ts b/packages/berry-ui/sources/TermOutput.ts index 3774b5309237..20e3bcd15266 100644 --- a/packages/berry-ui/sources/TermOutput.ts +++ b/packages/berry-ui/sources/TermOutput.ts @@ -1,10 +1,10 @@ -import EventEmitter from 'eventemitter3'; -import {Writable} from 'stream'; +import EventEmitter from 'eventemitter3'; +import {Writable} from 'stream'; import {WriteStream as WritableTTY} from 'tty'; export type OutputOptions = { - isDebug: boolean, - isInline: boolean, + isDebug: boolean; + isInline: boolean; }; export class TermOutput extends EventEmitter { @@ -44,8 +44,7 @@ export class TermOutput extends EventEmitter { } open() { - if (this.opened) - throw new Error(`Instance already open`); + if (this.opened) throw new Error(`Instance already open`); // @ts-ignore: `resize` is a valid event this.stdout.addListener(`resize`, this.handleResize); @@ -54,8 +53,7 @@ export class TermOutput extends EventEmitter { } close() { - if (!this.opened) - throw new Error(`Instance isn't open`); + if (!this.opened) throw new Error(`Instance isn't open`); // @ts-ignore: `resize` is a valid event this.stdout.removeListener(`resize`, this.handleResize); @@ -64,8 +62,7 @@ export class TermOutput extends EventEmitter { } buffer(fn: () => void) { - if (!this.opened) - throw new Error(`Instance isn't open`); + if (!this.opened) throw new Error(`Instance isn't open`); this.bufferDepth += 1; let result; @@ -86,11 +83,9 @@ export class TermOutput extends EventEmitter { } writeMeta(data: any) { - if (!this.opened) - throw new Error(`Instance isn't open`); + if (!this.opened) throw new Error(`Instance isn't open`); - if (this.isDebug) - return; + if (this.isDebug) return; if (this.bufferDepth > 0) { this.bufferData += String(data); @@ -101,11 +96,9 @@ export class TermOutput extends EventEmitter { } write(data: any) { - if (!this.opened) - throw new Error(`Instance isn't open`); + if (!this.opened) throw new Error(`Instance isn't open`); - if (this.isDebug) - return; + if (this.isDebug) return; if (this.bufferDepth > 0) { this.bufferData += String(data); @@ -116,11 +109,9 @@ export class TermOutput extends EventEmitter { } writeDebug(data: any) { - if (!this.opened) - throw new Error(`Instance isn't open`); + if (!this.opened) throw new Error(`Instance isn't open`); - if (!this.isDebug) - return; + if (!this.isDebug) return; if (this.bufferDepth > 0) { this.bufferData += String(data); @@ -135,5 +126,5 @@ export class TermOutput extends EventEmitter { columns: this.columns, rows: this.rows, }); - } + }; } diff --git a/packages/berry-ui/sources/TermRenderer.ts b/packages/berry-ui/sources/TermRenderer.ts index 80b14e5c1e31..500ea555cf2a 100644 --- a/packages/berry-ui/sources/TermRenderer.ts +++ b/packages/berry-ui/sources/TermRenderer.ts @@ -1,12 +1,12 @@ // @ts-ignore -import {feature, screen, cursor, style} from '@manaflair/term-strings'; - -import {DirtyScreen} from './DirtyScreen'; -import {NodeTree} from './NodeTree'; -import {Node} from './Node'; -import {Segment} from './Segment'; -import {TermInput} from './TermInput'; -import {TermOutput} from './TermOutput'; +import {feature, screen, cursor, style} from '@manaflair/term-strings'; + +import {DirtyScreen} from './DirtyScreen'; +import {NodeTree} from './NodeTree'; +import {Node} from './Node'; +import {Segment} from './Segment'; +import {TermInput} from './TermInput'; +import {TermOutput} from './TermOutput'; import {findOverlapingSegment, removeSegment} from './geometryUtils'; function getCaretX(caret: any) { @@ -18,7 +18,6 @@ function getCaretY(caret: any) { } export class TermRenderer { - private readonly termInput: TermInput; private readonly termOutput: TermOutput; @@ -32,8 +31,7 @@ export class TermRenderer { } open() { - if (this.opened) - return; + if (this.opened) return; this.termInput.open(); this.termOutput.open(); @@ -46,8 +44,7 @@ export class TermRenderer { this.termOutput.buffer(() => { // Enter the alternate screen - if (!this.termOutput.isInline) - this.termOutput.writeMeta(screen.alternateScreen.in); + if (!this.termOutput.isInline) this.termOutput.writeMeta(screen.alternateScreen.in); // Disable the terminal soft wrapping this.termOutput.writeMeta(screen.noWrap.in); @@ -61,8 +58,7 @@ export class TermRenderer { this.termOutput.writeMeta(feature.enableExtendedCoordinates.in); // Clear the current font style so that we aren't polluted by previous applications - if (!this.termOutput.isInline) - this.termOutput.writeMeta(style.clear); + if (!this.termOutput.isInline) this.termOutput.writeMeta(style.clear); // Ensure we capture as much things as possible from the keyboard (like ^C) this.termInput.setRawMode(true); @@ -72,8 +68,7 @@ export class TermRenderer { } close() { - if (!this.opened) - return; + if (!this.opened) return; process.removeListener(`uncaughtException`, this.handleException); process.removeListener(`exit`, this.handleExit); @@ -99,8 +94,7 @@ export class TermRenderer { this.termOutput.writeMeta(screen.noWrap.out); // Exit the alternate screen - if (!this.termOutput.isInline) - this.termOutput.writeMeta(screen.alternateScreen.out); + if (!this.termOutput.isInline) this.termOutput.writeMeta(screen.alternateScreen.out); if (this.termOutput.isInline) { this.termOutput.write(cursor.moveTo({x: 0, y: this.inlineTop})); @@ -115,12 +109,10 @@ export class TermRenderer { } render(tree: NodeTree) { - if (!this.opened) - return; + if (!this.opened) return; this.termOutput.buffer(() => { - if (!this.opened) - this.open(); + if (!this.opened) this.open(); const oldHeight = tree.elementRect.height; @@ -139,14 +131,14 @@ export class TermRenderer { // If we detect that we haven't enough space to print the interface, we reserve a few more lines by outputting line returns if (this.termOutput.rows - this.inlineTop < tree.elementRect.height) { - this.termOutput.write(cursor.moveTo({ x: 0, y: this.inlineTop })); + this.termOutput.write(cursor.moveTo({x: 0, y: this.inlineTop})); this.termOutput.write(`\n`.repeat(tree.elementRect.height - 1)); this.inlineTop = this.termOutput.rows - tree.elementRect.height; } // If the display shrinked, we must clear the lines below if (oldHeight > tree.elementRect.height) { - this.termOutput.write(cursor.moveTo({x: 0, y: this.inlineTop + tree.elementRect.height })); + this.termOutput.write(cursor.moveTo({x: 0, y: this.inlineTop + tree.elementRect.height})); this.termOutput.write(screen.clearBelow); } @@ -161,8 +153,7 @@ export class TermRenderer { left += getCaretX(tree.activeElement.props.caret); top += getCaretY(tree.activeElement.props.caret); - if (this.termOutput.isInline) - top += this.inlineTop; + if (this.termOutput.isInline) top += this.inlineTop; this.termOutput.write(cursor.moveTo({x: left, y: top})); this.termOutput.write(cursor.normal); @@ -175,31 +166,35 @@ export class TermRenderer { for (const node of renderList) { // We can skip the node entirely if it is not on the same line than the one we're processing - if (node.elementClipRect.top > y || node.elementClipRect.top + node.elementClipRect.height <= y) - continue; + if (node.elementClipRect.top > y || node.elementClipRect.top + node.elementClipRect.height <= y) continue; let nextSegments: Array = []; for (const segment of segments) { const overlap = findOverlapingSegment(segment, { - left: node.elementClipRect.left, width: node.elementClipRect.width, + left: node.elementClipRect.left, + width: node.elementClipRect.width, }); // Detects which parts of the segment won't be covered by the node - if (!overlap) - nextSegments.push(segment); - else - nextSegments = nextSegments.concat(removeSegment(overlap, segment)); + if (!overlap) nextSegments.push(segment); + else nextSegments = nextSegments.concat(removeSegment(overlap, segment)); // Generates the rendering code by asking the node if (overlap) { let top = y; - if (this.termOutput.isInline) - top += this.inlineTop; + if (this.termOutput.isInline) top += this.inlineTop; - const prefix = (``/*/+Date.now()/**/).substr(0, overlap.width); - const line = prefix + node.getLine(y - node.elementWorldRect.top, overlap.left - node.elementWorldRect.left, Math.max(0, overlap.width - prefix.length)); + const prefix = `` /*/+Date.now()/**/ + .substr(0, overlap.width); + const line = + prefix + + node.getLine( + y - node.elementWorldRect.top, + overlap.left - node.elementWorldRect.left, + Math.max(0, overlap.width - prefix.length), + ); this.termOutput.write(cursor.moveTo({x: overlap.left, y: top})); this.termOutput.write(line); @@ -211,7 +206,9 @@ export class TermRenderer { if (segments.length > 0) { // We can only reach this code if there's no element located over some part of the scanline, not even the root. This doesn't happen under normal circumstances - throw new Error(`Expected all segments to have been covered (not covered on line ${y}: ${JSON.stringify(segments)})`); + throw new Error( + `Expected all segments to have been covered (not covered on line ${y}: ${JSON.stringify(segments)})`, + ); } } @@ -222,15 +219,15 @@ export class TermRenderer { process.stdout.write(exception.stack || exception.message || exception); process.exitCode = 1; - } + }; handleExitSignal = () => { this.close(); process.exitCode = 1; - } + }; handleExit = () => { this.close(); - } + }; } diff --git a/packages/berry-ui/sources/colors.ts b/packages/berry-ui/sources/colors.ts index f5746f6cf9cf..a069d2590300 100644 --- a/packages/berry-ui/sources/colors.ts +++ b/packages/berry-ui/sources/colors.ts @@ -1,13 +1,12 @@ // @ts-ignore import {style} from '@manaflair/term-strings'; -const colorCache: Map = new Map(); +const colorCache: Map = new Map(); export function getColorEntry(name: string) { let colorEntry = colorCache.get(name); - if (!colorEntry) - colorCache.set(name, colorEntry = style.color(name)); + if (!colorEntry) colorCache.set(name, (colorEntry = style.color(name))); return colorEntry; } diff --git a/packages/berry-ui/sources/geometryUtils.ts b/packages/berry-ui/sources/geometryUtils.ts index 635a5266a170..911c5a957106 100644 --- a/packages/berry-ui/sources/geometryUtils.ts +++ b/packages/berry-ui/sources/geometryUtils.ts @@ -1,4 +1,4 @@ -import {Rect} from './Rect'; +import {Rect} from './Rect'; import {Segment} from './Segment'; /** @@ -21,8 +21,7 @@ export function findOverlapingSegment(a: Segment, b: Segment) { const left = Math.max(a.left, b.left); const width = Math.min(a.left + a.width, b.left + b.width) - left; - if (width <= 0) - return null; + if (width <= 0) return null; return {left, width}; } @@ -33,16 +32,14 @@ export function findOverlapingSegment(a: Segment, b: Segment) { export function removeSegment(a: Segment, b: Segment) { const overlap = findOverlapingSegment(a, b); - if (!overlap) - return [b]; + if (!overlap) return [b]; const remains = []; - if (overlap.left > b.left) - remains.push({ left: b.left, width: overlap.left - b.left }); + if (overlap.left > b.left) remains.push({left: b.left, width: overlap.left - b.left}); if (overlap.left + overlap.width < b.left + b.width) - remains.push({ left: overlap.left + overlap.width, width: b.left + b.width - overlap.left - overlap.width }); + remains.push({left: overlap.left + overlap.width, width: b.left + b.width - overlap.left - overlap.width}); return remains; } diff --git a/packages/berry-ui/sources/index.ts b/packages/berry-ui/sources/index.ts index 34735674ed21..72fdd4b35472 100644 --- a/packages/berry-ui/sources/index.ts +++ b/packages/berry-ui/sources/index.ts @@ -1,29 +1,28 @@ -import TextLayout from '@manaflair/text-layout'; +import TextLayout from '@manaflair/text-layout'; // @ts-ignore -import makeReconciler from 'react-reconciler'; -import React from 'react'; +import makeReconciler from 'react-reconciler'; +import React from 'react'; // @ts-ignore -import reopenTty from 'reopen-tty'; -import {Readable, Writable} from 'stream'; +import reopenTty from 'reopen-tty'; +import {Readable, Writable} from 'stream'; import {ReadStream as ReadableTTY, WriteStream as WritableTTY} from 'tty'; // @ts-ignore -import YogaDom from 'yoga-dom'; - -import {Div} from './Div'; -import {NodeElement} from './NodeElement'; -import {NodeText} from './NodeText'; -import {NodeTree} from './NodeTree'; -import {Node} from './Node'; -import {TermInput} from './TermInput'; -import {TermOutput} from './TermOutput'; -import {TermRenderer} from './TermRenderer'; -import {Props} from './types'; +import YogaDom from 'yoga-dom'; + +import {Div} from './Div'; +import {NodeElement} from './NodeElement'; +import {NodeText} from './NodeText'; +import {NodeTree} from './NodeTree'; +import {Node} from './Node'; +import {TermInput} from './TermInput'; +import {TermOutput} from './TermOutput'; +import {TermRenderer} from './TermRenderer'; +import {Props} from './types'; // Reexport the Div component export * from './Div'; -type HostContext = { -}; +type HostContext = {}; const Reconciler = makeReconciler({ useSyncScheduling: true, @@ -87,8 +86,7 @@ const Reconciler = makeReconciler({ supportsMutation: true, supportsPersistence: false, - commitMount(element: NodeElement, type: string, newProps: Props) { - }, + commitMount(element: NodeElement, type: string, newProps: Props) {}, commitUpdate(element: NodeElement, updatePayload: any, type: string, oldProps: Props, newProps: Props) { element.setProps(newProps); @@ -152,16 +150,14 @@ function openStdout() { } export type Options = { - stdin?: Readable | ReadableTTY | null, - stdout?: Writable | WritableTTY | null, - inline?: boolean, + stdin?: Readable | ReadableTTY | null; + stdout?: Writable | WritableTTY | null; + inline?: boolean; }; export async function render(app: any, {stdin = null, stdout = null, inline = false}: Options = {}) { - if (stdin === null) - stdin = await openStdin(); - if (stdout === null) - stdout = await openStdout(); + if (stdin === null) stdin = await openStdin(); + if (stdout === null) stdout = await openStdout(); // Not sure why we have to do this, but the ".default" is needed when adding "browser" field support const realYogaDom = YogaDom.default || YogaDom; @@ -169,11 +165,9 @@ export async function render(app: any, {stdin = null, stdout = null, inline = fa const env = {yoga: await realYogaDom, textLayout: await TextLayout}; return new Promise((resolve, reject) => { - if (!stdin) - throw new Error(`Assertion failed: missing stdin`); - if (!stdout) - throw new Error(`Assertion failed: missing stdout`); - + if (!stdin) throw new Error(`Assertion failed: missing stdin`); + if (!stdout) throw new Error(`Assertion failed: missing stdout`); + const termInput = new TermInput(stdin); const termOutput = new TermOutput(stdout, {isInline: inline, isDebug: false}); @@ -208,8 +202,7 @@ export async function render(app: any, {stdin = null, stdout = null, inline = fa nodeTree.resize(columns, rows); }); - if (termOutput.isDebug) - console.log(`Debug`); + if (termOutput.isDebug) console.log(`Debug`); termRenderer.open(); @@ -230,7 +223,7 @@ export async function render(app: any, {stdin = null, stdout = null, inline = fa Reconciler.unbatchedUpdates(() => { Reconciler.updateContainer(React.createElement(Div), container, null, null); }); - + resolve(); } diff --git a/packages/berry-ui/sources/tools.ts b/packages/berry-ui/sources/tools.ts index ab011434bf24..653148ba1d76 100644 --- a/packages/berry-ui/sources/tools.ts +++ b/packages/berry-ui/sources/tools.ts @@ -10,8 +10,7 @@ export function iterate(source: any, cb: (value: any, index: number, virtualInde } } - if (elements.length === 0) - return ifEmpty; - + if (elements.length === 0) return ifEmpty; + return elements; } diff --git a/packages/berry-ui/sources/types.ts b/packages/berry-ui/sources/types.ts index 6bd2d9ca32d3..197194795d4c 100644 --- a/packages/berry-ui/sources/types.ts +++ b/packages/berry-ui/sources/types.ts @@ -1,3 +1,3 @@ export type Props = { - [key: string]: any, + [key: string]: any; }; diff --git a/packages/plugin-constraints/sources/Constraints.ts b/packages/plugin-constraints/sources/Constraints.ts index 8e118ab8d883..fd8c12b8e894 100644 --- a/packages/plugin-constraints/sources/Constraints.ts +++ b/packages/plugin-constraints/sources/Constraints.ts @@ -1,19 +1,19 @@ import {Ident, Locator, Project, Workspace} from '@berry/core'; -import {miscUtils, structUtils} from '@berry/core'; -import {xfs} from '@berry/fslib'; -import {posix} from 'path'; -import pl from 'tau-prolog'; +import {miscUtils, structUtils} from '@berry/core'; +import {xfs} from '@berry/fslib'; +import {posix} from 'path'; +import pl from 'tau-prolog'; -import {linkProjectToSession} from './tauModule'; +import {linkProjectToSession} from './tauModule'; export type DependencyMismatch = { - packageLocator: Locator, - dependencyIdent: Ident, - expectedResolution: string, + packageLocator: Locator; + dependencyIdent: Ident; + expectedResolution: string; }; export type ConstraintReport = { - mismatchingDependencies: Array, + mismatchingDependencies: Array; }; export const enum DependencyType { @@ -22,16 +22,11 @@ export const enum DependencyType { PeerDependencies = 'peerDependencies', } -const DEPENDENCY_TYPES = [ - DependencyType.Dependencies, - DependencyType.DevDependencies, - DependencyType.PeerDependencies, -]; +const DEPENDENCY_TYPES = [DependencyType.Dependencies, DependencyType.DevDependencies, DependencyType.PeerDependencies]; // Node 8 doesn't have Symbol.asyncIterator // https://github.com/Microsoft/TypeScript/issues/14151#issuecomment-280812617 -if (Symbol.asyncIterator == null) - (Symbol as any).asyncIterator = Symbol.for('Symbol.asyncIterator'); +if (Symbol.asyncIterator == null) (Symbol as any).asyncIterator = Symbol.for('Symbol.asyncIterator'); class Session { private readonly session: pl.type.Session; @@ -57,15 +52,14 @@ class Session { while (true) { const answer = await this.fetchNextAnswer(); - if (!answer) - break; + if (!answer) break; yield answer; } } } -function parseLink(link: pl.Link): string|null { +function parseLink(link: pl.Link): string | null { if (link.id === `null`) { return null; } else { @@ -93,19 +87,22 @@ export class Constraints { getProjectDatabase() { let database = ``; - for (const dependencyType of DEPENDENCY_TYPES) - database += `dependency_type(${dependencyType}).\n` + for (const dependencyType of DEPENDENCY_TYPES) database += `dependency_type(${dependencyType}).\n`; for (const workspace of this.project.workspacesByCwd.values()) { const relativeCwd = workspace.relativeCwd; database += `workspace(${escape(relativeCwd)}).\n`; - database += `workspace_ident(${escape(relativeCwd)}, ${escape(structUtils.stringifyIdent(workspace.locator))}).\n` - database += `workspace_version(${escape(relativeCwd)}, ${escape(workspace.manifest.version)}).\n` + database += `workspace_ident(${escape(relativeCwd)}, ${escape( + structUtils.stringifyIdent(workspace.locator), + )}).\n`; + database += `workspace_version(${escape(relativeCwd)}, ${escape(workspace.manifest.version)}).\n`; for (const dependencyType of DEPENDENCY_TYPES) { for (const dependency of workspace.manifest[dependencyType].values()) { - database += `workspace_has_dependency(${escape(relativeCwd)}, ${escape(structUtils.stringifyIdent(dependency))}, ${escape(dependency.range)}, ${dependencyType}).\n`; + database += `workspace_has_dependency(${escape(relativeCwd)}, ${escape( + structUtils.stringifyIdent(dependency), + )}, ${escape(dependency.range)}, ${dependencyType}).\n`; } } } @@ -147,54 +144,54 @@ export class Constraints { const session = this.createSession(); let enforcedDependencyRanges: Array<{ - workspace: Workspace, - dependencyIdent: Ident, - dependencyRange: string | null, - dependencyType: DependencyType, + workspace: Workspace; + dependencyIdent: Ident; + dependencyRange: string | null; + dependencyType: DependencyType; }> = []; - for await (const answer of session.makeQuery(`workspace(WorkspaceCwd), dependency_type(DependencyType), gen_enforced_dependency_range(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType).`)) { - if (answer.id === `throw`) - throw new Error(pl.format_answer(answer)); + for await (const answer of session.makeQuery( + `workspace(WorkspaceCwd), dependency_type(DependencyType), gen_enforced_dependency_range(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType).`, + )) { + if (answer.id === `throw`) throw new Error(pl.format_answer(answer)); const workspaceCwd = posix.resolve(this.project.cwd, parseLink(answer.links.WorkspaceCwd)); const dependencyRawIdent = parseLink(answer.links.DependencyIdent); const dependencyRange = parseLink(answer.links.DependencyRange); const dependencyType = parseLink(answer.links.DependencyType) as DependencyType; - if (workspaceCwd === null || dependencyRawIdent === null) - throw new Error(`Invalid rule`); + if (workspaceCwd === null || dependencyRawIdent === null) throw new Error(`Invalid rule`); const workspace = this.project.getWorkspaceByCwd(workspaceCwd); const dependencyIdent = structUtils.parseIdent(dependencyRawIdent); - + enforcedDependencyRanges.push({workspace, dependencyIdent, dependencyRange, dependencyType}); } enforcedDependencyRanges = miscUtils.sortMap(enforcedDependencyRanges, [ - ({dependencyRange}) => dependencyRange !== null ? `0` : `1`, + ({dependencyRange}) => (dependencyRange !== null ? `0` : `1`), ({workspace}) => structUtils.stringifyIdent(workspace.locator), ({dependencyIdent}) => structUtils.stringifyIdent(dependencyIdent), ]); let invalidDependencies: Array<{ - workspace: Workspace, - dependencyIdent: Ident, - dependencyType: DependencyType, - reason: string | null, + workspace: Workspace; + dependencyIdent: Ident; + dependencyType: DependencyType; + reason: string | null; }> = []; - for await (const answer of session.makeQuery(`workspace(WorkspaceCwd), dependency_type(DependencyType), gen_invalid_dependency(WorkspaceCwd, DependencyIdent, DependencyType, Reason).`)) { - if (answer.id === `throw`) - throw new Error(pl.format_answer(answer)); + for await (const answer of session.makeQuery( + `workspace(WorkspaceCwd), dependency_type(DependencyType), gen_invalid_dependency(WorkspaceCwd, DependencyIdent, DependencyType, Reason).`, + )) { + if (answer.id === `throw`) throw new Error(pl.format_answer(answer)); const workspaceCwd = posix.resolve(this.project.cwd, parseLink(answer.links.WorkspaceCwd)); const dependencyRawIdent = parseLink(answer.links.DependencyIdent); const dependencyType = parseLink(answer.links.DependencyType) as DependencyType; const reason = parseLink(answer.links.Reason); - if (workspaceCwd === null || dependencyRawIdent === null) - throw new Error(`Invalid rule`); + if (workspaceCwd === null || dependencyRawIdent === null) throw new Error(`Invalid rule`); const workspace = this.project.getWorkspaceByCwd(workspaceCwd); const dependencyIdent = structUtils.parseIdent(dependencyRawIdent); @@ -214,10 +211,9 @@ export class Constraints { const session = this.createSession(); for await (const answer of session.makeQuery(query)) { - if (answer.id === `throw`) - throw new Error(pl.format_answer(answer)); + if (answer.id === `throw`) throw new Error(pl.format_answer(answer)); - const parsedLinks: Record = {}; + const parsedLinks: Record = {}; for (const [variable, value] of Object.entries(answer.links)) { if (variable !== `_`) { diff --git a/packages/plugin-constraints/sources/index.ts b/packages/plugin-constraints/sources/index.ts index 769ddc1ddb6d..fe4836e299a9 100644 --- a/packages/plugin-constraints/sources/index.ts +++ b/packages/plugin-constraints/sources/index.ts @@ -1,17 +1,12 @@ -import {Plugin} from '@berry/core'; +import {Plugin} from '@berry/core'; -import checkConstraints from './commands/constraints/check'; -import fixConstraints from './commands/constraints/fix'; -import queryConstraints from './commands/constraints/query'; +import checkConstraints from './commands/constraints/check'; +import fixConstraints from './commands/constraints/fix'; +import queryConstraints from './commands/constraints/query'; import sourceConstraints from './commands/constraints/source'; const plugin: Plugin = { - commands: [ - fixConstraints, - checkConstraints, - queryConstraints, - sourceConstraints, - ], + commands: [fixConstraints, checkConstraints, queryConstraints, sourceConstraints], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-constraints/sources/tauModule.ts b/packages/plugin-constraints/sources/tauModule.ts index d005f8d21e6d..f68667a62886 100644 --- a/packages/plugin-constraints/sources/tauModule.ts +++ b/packages/plugin-constraints/sources/tauModule.ts @@ -1,17 +1,11 @@ import {Project} from '@berry/core'; -import getPath from 'lodash.get'; -import pl from 'tau-prolog'; +import getPath from 'lodash.get'; +import pl from 'tau-prolog'; const {is_atom} = pl.type; function prependGoals(thread: pl.type.Thread, point: pl.type.State, goals: pl.type.Term[]): void { - thread.prepend(goals.map( - goal => new pl.type.State( - point.goal.replace(goal), - point.substitution, - point, - ), - )); + thread.prepend(goals.map(goal => new pl.type.State(point.goal.replace(goal), point.substitution, point))); } const projects = new WeakMap(); @@ -25,38 +19,35 @@ function getProject(thread: pl.type.Thread): Project { return project; } -const tauModule = new pl.type.Module(`constraints`, { - [`workspace_field/3`]: (thread, point, atom) => { - const [workspaceCwd, fieldName, fieldValue] = atom.args; +const tauModule = new pl.type.Module( + `constraints`, + { + [`workspace_field/3`]: (thread, point, atom) => { + const [workspaceCwd, fieldName, fieldValue] = atom.args; - if (!is_atom(workspaceCwd) || !is_atom(fieldName)) { - thread.throwError(pl.error.instantiation(atom.indicator)); - return; - } + if (!is_atom(workspaceCwd) || !is_atom(fieldName)) { + thread.throwError(pl.error.instantiation(atom.indicator)); + return; + } - const project = getProject(thread); - const workspace = project.tryWorkspaceByCwd(workspaceCwd.id); + const project = getProject(thread); + const workspace = project.tryWorkspaceByCwd(workspaceCwd.id); - // Workspace not found => this predicate can never match - // We might want to throw here? We can be pretty sure the user did - // something wrong at this point - if (workspace == null) - return; + // Workspace not found => this predicate can never match + // We might want to throw here? We can be pretty sure the user did + // something wrong at this point + if (workspace == null) return; - const value = getPath(workspace.manifest.raw!, fieldName.id); + const value = getPath(workspace.manifest.raw!, fieldName.id); - // Field is not present => this predicate can never match - if (typeof value === `undefined`) - return; + // Field is not present => this predicate can never match + if (typeof value === `undefined`) return; - prependGoals(thread, point, [new pl.type.Term(`=`, [ - fieldValue, - new pl.type.Term(String(value)), - ])]); + prependGoals(thread, point, [new pl.type.Term(`=`, [fieldValue, new pl.type.Term(String(value))])]); + }, }, -}, [ - `workspace_field/3`, -]); + [`workspace_field/3`], +); export function linkProjectToSession(session: pl.type.Session, project: Project) { projects.set(session, project); diff --git a/packages/plugin-dlx/sources/index.ts b/packages/plugin-dlx/sources/index.ts index 139760638993..8afe92eba6ea 100644 --- a/packages/plugin-dlx/sources/index.ts +++ b/packages/plugin-dlx/sources/index.ts @@ -1,11 +1,9 @@ import {Plugin, SettingsType} from '@berry/core'; -import dlx from './commands/dlx'; +import dlx from './commands/dlx'; const plugin: Plugin = { - commands: [ - dlx, - ], + commands: [dlx], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-essentials/sources/index.ts b/packages/plugin-essentials/sources/index.ts index b9e08cb59309..30a1c12e2b52 100644 --- a/packages/plugin-essentials/sources/index.ts +++ b/packages/plugin-essentials/sources/index.ts @@ -1,25 +1,25 @@ import {Descriptor, Plugin, SettingsType} from '@berry/core'; -import {Workspace} from '@berry/core'; +import {Workspace} from '@berry/core'; -import entry from './commands/_entry'; -import add from './commands/add'; -import bin from './commands/bin'; -import cleanCache from './commands/cache/clean'; -import setConfig from './commands/config/set'; -import config from './commands/config'; -import help from './commands/help'; -import install from './commands/install'; -import link from './commands/link'; -import node from './commands/node'; -import remove from './commands/remove'; -import run from './commands/run'; -import setResolutionPolicy from './commands/set/resolution'; -import setVersionPolicy from './commands/set/version'; -import up from './commands/up'; -import why from './commands/why'; -import foreachWorkspaces from './commands/workspaces/foreach'; -import listWorkspaces from './commands/workspaces/list'; -import * as suggestUtils from './suggestUtils'; +import entry from './commands/_entry'; +import add from './commands/add'; +import bin from './commands/bin'; +import cleanCache from './commands/cache/clean'; +import setConfig from './commands/config/set'; +import config from './commands/config'; +import help from './commands/help'; +import install from './commands/install'; +import link from './commands/link'; +import node from './commands/node'; +import remove from './commands/remove'; +import run from './commands/run'; +import setResolutionPolicy from './commands/set/resolution'; +import setVersionPolicy from './commands/set/version'; +import up from './commands/up'; +import why from './commands/why'; +import foreachWorkspaces from './commands/workspaces/foreach'; +import listWorkspaces from './commands/workspaces/list'; +import * as suggestUtils from './suggestUtils'; export {suggestUtils}; @@ -28,7 +28,7 @@ export interface Hooks { workspace: Workspace, target: suggestUtils.Target, descriptor: Descriptor, - ) => Promise, + ) => Promise; afterWorkspaceDependencyReplacement?: ( workspace: Workspace, @@ -41,8 +41,8 @@ export interface Hooks { workspace: Workspace, target: suggestUtils.Target, descriptor: Descriptor, - ) => Promise, -}; + ) => Promise; +} const plugin: Plugin = { configuration: { diff --git a/packages/plugin-essentials/sources/suggestUtils.ts b/packages/plugin-essentials/sources/suggestUtils.ts index f85ee426e5dd..1fa95238707e 100644 --- a/packages/plugin-essentials/sources/suggestUtils.ts +++ b/packages/plugin-essentials/sources/suggestUtils.ts @@ -1,24 +1,34 @@ -import {Cache, DescriptorHash, Descriptor, Ident, Locator, Manifest, Project, ThrowReport, Workspace} from '@berry/core'; -import {structUtils} from '@berry/core'; -import {posix} from 'path'; -import semver from 'semver'; +import { + Cache, + DescriptorHash, + Descriptor, + Ident, + Locator, + Manifest, + Project, + ThrowReport, + Workspace, +} from '@berry/core'; +import {structUtils} from '@berry/core'; +import {posix} from 'path'; +import semver from 'semver'; export type Suggestion = { - descriptor: Descriptor, - reason: string, + descriptor: Descriptor; + reason: string; }; export enum Target { REGULAR = 'dependencies', DEVELOPMENT = 'devDependencies', PEER = 'peerDependencies', -}; +} export enum Modifier { CARET = '^', TILDE = '~', EXACT = '', -}; +} export enum Strategy { KEEP = 'keep', @@ -26,31 +36,36 @@ export enum Strategy { PROJECT = 'project', LATEST = 'latest', CACHE = 'cache', -}; +} export function applyModifier(descriptor: Descriptor, modifier: Modifier) { let {protocol, source, selector} = structUtils.parseRange(descriptor.range); - if (semver.valid(selector)) - selector = `${modifier}${descriptor.range}`; + if (semver.valid(selector)) selector = `${modifier}${descriptor.range}`; return structUtils.makeDescriptor(descriptor, structUtils.makeRange({protocol, source, selector})); } -export async function findProjectDescriptors(ident: Ident, {project, target}: {project: Project, target: Target}) { - const matches: Map, - }> = new Map(); +export async function findProjectDescriptors(ident: Ident, {project, target}: {project: Project; target: Target}) { + const matches: Map< + DescriptorHash, + { + descriptor: Descriptor; + locators: Array; + } + > = new Map(); const getDescriptorEntry = (descriptor: Descriptor) => { let entry = matches.get(descriptor.descriptorHash); if (!entry) { - matches.set(descriptor.descriptorHash, entry = { - descriptor, - locators: [], - }); + matches.set( + descriptor.descriptorHash, + (entry = { + descriptor, + locators: [], + }), + ); } return entry; @@ -86,15 +101,19 @@ export async function findProjectDescriptors(ident: Ident, {project, target}: {p return matches; } -export async function extractDescriptorFromPath(path: string, {cache, cwd, workspace}: {cache: Cache, cwd: string, workspace: Workspace}) { - if (!posix.isAbsolute(path)) - path = posix.resolve(cwd, path); +export async function extractDescriptorFromPath( + path: string, + {cache, cwd, workspace}: {cache: Cache; cwd: string; workspace: Workspace}, +) { + if (!posix.isAbsolute(path)) path = posix.resolve(cwd, path); const project = workspace.project; - const descriptor = await fetchDescriptorFrom(structUtils.makeIdent(null, `archive`), path, {project: workspace.project, cache}); - if (!descriptor) - throw new Error(`Assertion failed: The descriptor should have been found`); + const descriptor = await fetchDescriptorFrom(structUtils.makeIdent(null, `archive`), path, { + project: workspace.project, + cache, + }); + if (!descriptor) throw new Error(`Assertion failed: The descriptor should have been found`); const report = new ThrowReport(); @@ -112,96 +131,141 @@ export async function extractDescriptorFromPath(path: string, {cache, cwd, works const fetchResult = await fetcher.fetch(locator, resolverOptions); const manifest = await Manifest.find(fetchResult.prefixPath, {baseFs: fetchResult.packageFs}); - if (!manifest.name) - throw new Error(`Target path doesn't have a name`); + if (!manifest.name) throw new Error(`Target path doesn't have a name`); return structUtils.makeDescriptor(manifest.name, path); } -export async function getSuggestedDescriptors(request: Descriptor, previous: Descriptor | null, {project, cache, target, modifier, strategies, maxResults = Infinity}: {project: Project, cache: Cache, target: Target, modifier: Modifier, strategies: Array, maxResults?: number}) { - if (!(maxResults >= 0)) - throw new Error(`Invalid maxResults (${maxResults})`); +export async function getSuggestedDescriptors( + request: Descriptor, + previous: Descriptor | null, + { + project, + cache, + target, + modifier, + strategies, + maxResults = Infinity, + }: { + project: Project; + cache: Cache; + target: Target; + modifier: Modifier; + strategies: Array; + maxResults?: number; + }, +) { + if (!(maxResults >= 0)) throw new Error(`Invalid maxResults (${maxResults})`); const suggested = []; for (const strategy of strategies) { - if (suggested.length >= maxResults) - break; + if (suggested.length >= maxResults) break; switch (strategy) { - case Strategy.KEEP: { - if (previous) { - const reason = `Keep ${structUtils.prettyDescriptor(project.configuration, previous)} (no changes)`; - suggested.push({descriptor: previous, reason}); + case Strategy.KEEP: + { + if (previous) { + const reason = `Keep ${structUtils.prettyDescriptor(project.configuration, previous)} (no changes)`; + suggested.push({descriptor: previous, reason}); + } } - } break; - - case Strategy.REUSE: { - for (const {descriptor, locators} of (await findProjectDescriptors(request, {project, target})).values()) { - let reason = `Reuse ${structUtils.prettyDescriptor(project.configuration, descriptor)} (originally used by ${structUtils.prettyLocator(project.configuration, locators[0])}` + break; - reason += locators.length > 1 - ? ` and ${locators.length - 1} other${locators.length > 2 ? `s` : ``})` - : `)`; + case Strategy.REUSE: + { + for (const {descriptor, locators} of (await findProjectDescriptors(request, {project, target})).values()) { + let reason = `Reuse ${structUtils.prettyDescriptor( + project.configuration, + descriptor, + )} (originally used by ${structUtils.prettyLocator(project.configuration, locators[0])}`; - suggested.push({descriptor, reason}); - } - } break; + reason += locators.length > 1 ? ` and ${locators.length - 1} other${locators.length > 2 ? `s` : ``})` : `)`; - case Strategy.CACHE: { - for (const descriptor of project.storedDescriptors.values()) { - if (descriptor.identHash === request.identHash) { - const reason = `Reuse ${structUtils.prettyDescriptor(project.configuration, descriptor)} (already used somewhere in the lockfile)`; suggested.push({descriptor, reason}); } } - } break; - - case Strategy.PROJECT: { - for (const workspace of project.workspacesByIdent.get(request.identHash) || []) { - const reason = `Attach ${structUtils.prettyWorkspace(project.configuration, workspace)} (local workspace at ${workspace.cwd})`; - - if (workspace.manifest.version) { - suggested.push({descriptor: workspace.anchoredDescriptor, reason}); - } else { - suggested.push({descriptor: workspace.anchoredDescriptor, reason}) + break; + + case Strategy.CACHE: + { + for (const descriptor of project.storedDescriptors.values()) { + if (descriptor.identHash === request.identHash) { + const reason = `Reuse ${structUtils.prettyDescriptor( + project.configuration, + descriptor, + )} (already used somewhere in the lockfile)`; + suggested.push({descriptor, reason}); + } } } - } break; - - case Strategy.LATEST: { - if (request.range !== `unknown`) { - const reason = `Use ${structUtils.prettyRange(project.configuration, request.range)} (explicit range requested)`; - suggested.push({descriptor: request, reason}) - } else if (target === Target.PEER) { - const reason = `Use * (catch-all peer dependency pattern)`; - suggested.push({descriptor: structUtils.makeDescriptor(request, `*`), reason}) - } else if (!project.configuration.get(`enableNetwork`)) { - const reason = `Resolve from latest ${project.configuration.format(`(unavailable because enableNetwork is toggled off)`, `grey`)}`; - suggested.push({descriptor: null, reason}); - } else { - let latest; - try { - latest = await fetchDescriptorFrom(request, `latest`, {project, cache}); - } catch (error) { - // Just ignore errors + break; + + case Strategy.PROJECT: + { + for (const workspace of project.workspacesByIdent.get(request.identHash) || []) { + const reason = `Attach ${structUtils.prettyWorkspace( + project.configuration, + workspace, + )} (local workspace at ${workspace.cwd})`; + + if (workspace.manifest.version) { + suggested.push({descriptor: workspace.anchoredDescriptor, reason}); + } else { + suggested.push({descriptor: workspace.anchoredDescriptor, reason}); + } } - - if (latest) { - latest = applyModifier(latest, modifier); - - const reason = `Use ${structUtils.prettyDescriptor(project.configuration, latest)} (resolved from latest)`; - suggested.push({descriptor: latest, reason}); + } + break; + + case Strategy.LATEST: + { + if (request.range !== `unknown`) { + const reason = `Use ${structUtils.prettyRange( + project.configuration, + request.range, + )} (explicit range requested)`; + suggested.push({descriptor: request, reason}); + } else if (target === Target.PEER) { + const reason = `Use * (catch-all peer dependency pattern)`; + suggested.push({descriptor: structUtils.makeDescriptor(request, `*`), reason}); + } else if (!project.configuration.get(`enableNetwork`)) { + const reason = `Resolve from latest ${project.configuration.format( + `(unavailable because enableNetwork is toggled off)`, + `grey`, + )}`; + suggested.push({descriptor: null, reason}); + } else { + let latest; + try { + latest = await fetchDescriptorFrom(request, `latest`, {project, cache}); + } catch (error) { + // Just ignore errors + } + + if (latest) { + latest = applyModifier(latest, modifier); + + const reason = `Use ${structUtils.prettyDescriptor( + project.configuration, + latest, + )} (resolved from latest)`; + suggested.push({descriptor: latest, reason}); + } } } - } break; + break; } } return suggested.slice(0, maxResults); } -export async function fetchDescriptorFrom(ident: Ident, range: string, {project, cache}: {project: Project, cache: Cache}) { +export async function fetchDescriptorFrom( + ident: Ident, + range: string, + {project, cache}: {project: Project; cache: Cache}, +) { const latestDescriptor = structUtils.makeDescriptor(ident, range); const report = new ThrowReport(); @@ -218,15 +282,13 @@ export async function fetchDescriptorFrom(ident: Ident, range: string, {project, return null; } - if (candidateLocators.length === 0) - return null; + if (candidateLocators.length === 0) return null; // Per the requirements exposed in Resolver.ts, the best is the first one const bestLocator = candidateLocators[0]; let {protocol, source, selector} = structUtils.parseRange(bestLocator.reference); - if (protocol === project.configuration.get(`defaultProtocol`)) - protocol = null; + if (protocol === project.configuration.get(`defaultProtocol`)) protocol = null; return structUtils.makeDescriptor(bestLocator, structUtils.makeRange({protocol, source, selector})); } diff --git a/packages/plugin-exec/sources/ExecFetcher.ts b/packages/plugin-exec/sources/ExecFetcher.ts index 2869301ffb4f..dd454c1e1239 100644 --- a/packages/plugin-exec/sources/ExecFetcher.ts +++ b/packages/plugin-exec/sources/ExecFetcher.ts @@ -1,17 +1,16 @@ -import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {Locator, MessageName} from '@berry/core'; +import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; +import {Locator, MessageName} from '@berry/core'; import {execUtils, miscUtils, scriptUtils, structUtils, tgzUtils} from '@berry/core'; -import {NodeFS, xfs} from '@berry/fslib'; -import {posix} from 'path'; -import querystring from 'querystring'; -import {dirSync, tmpNameSync} from 'tmp'; +import {NodeFS, xfs} from '@berry/fslib'; +import {posix} from 'path'; +import querystring from 'querystring'; +import {dirSync, tmpNameSync} from 'tmp'; -import {PROTOCOL} from './constants'; +import {PROTOCOL} from './constants'; export class ExecFetcher implements Fetcher { supports(locator: Locator, opts: MinimalFetchOptions) { - if (!locator.reference.startsWith(PROTOCOL)) - return false; + if (!locator.reference.startsWith(PROTOCOL)) return false; return true; } @@ -19,8 +18,7 @@ export class ExecFetcher implements Fetcher { getLocalPath(locator: Locator, opts: FetchOptions) { const {parentLocator, execPath} = this.parseLocator(locator); - if (posix.isAbsolute(execPath)) - return execPath; + if (posix.isAbsolute(execPath)) return execPath; const parentLocalPath = opts.fetcher.getLocalPath(parentLocator, opts); @@ -38,7 +36,13 @@ export class ExecFetcher implements Fetcher { locator, expectedChecksum, async () => { - opts.report.reportInfoOnce(MessageName.FETCH_NOT_CACHED, `${structUtils.prettyLocator(opts.project.configuration, locator)} can't be found in the cache and will be fetched from the disk`); + opts.report.reportInfoOnce( + MessageName.FETCH_NOT_CACHED, + `${structUtils.prettyLocator( + opts.project.configuration, + locator, + )} can't be found in the cache and will be fetched from the disk`, + ); return await this.fetchFromDisk(locator, opts); }, ); @@ -68,18 +72,19 @@ export class ExecFetcher implements Fetcher { : parentFetch; // Discard the parent fs unless we really need it to access the files - if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) - parentFetch.releaseFs(); + if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) parentFetch.releaseFs(); const generatorFs = effectiveParentFetch.packageFs; - const generatorPath = posix.resolve(posix.resolve(generatorFs.getRealPath(), effectiveParentFetch.prefixPath), execPath); + const generatorPath = posix.resolve( + posix.resolve(generatorFs.getRealPath(), effectiveParentFetch.prefixPath), + execPath, + ); // Execute the specified script in the temporary directory const cwd = await this.generatePackage(locator, generatorPath, opts); // Make sure the script generated the package - if (!xfs.existsSync(`${cwd}/build`)) - throw new Error(`The script should have generated a build directory`); + if (!xfs.existsSync(`${cwd}/build`)) throw new Error(`The script should have generated a build directory`); return await tgzUtils.makeArchiveFromDirectory(`${cwd}/build`, { prefixPath: `/sources`, @@ -99,10 +104,16 @@ export class ExecFetcher implements Fetcher { const stdout = xfs.createWriteStream(logFile); const stderr = stdout; - stdout.write(`# This file contains the result of Yarn generating a package (${structUtils.stringifyLocator(locator)})\n`); + stdout.write( + `# This file contains the result of Yarn generating a package (${structUtils.stringifyLocator(locator)})\n`, + ); stdout.write(`\n`); - const {code} = await execUtils.pipevp(process.execPath, [NodeFS.fromPortablePath(generatorPath), structUtils.stringifyIdent(locator)], {cwd, env, stdin, stdout, stderr}); + const {code} = await execUtils.pipevp( + process.execPath, + [NodeFS.fromPortablePath(generatorPath), structUtils.stringifyIdent(locator)], + {cwd, env, stdin, stdout, stderr}, + ); if (code !== 0) throw new Error(`Package generation failed (exit code ${code}, logs can be found here: ${logFile})`); @@ -112,14 +123,12 @@ export class ExecFetcher implements Fetcher { private parseLocator(locator: Locator) { const qsIndex = locator.reference.indexOf(`?`); - if (qsIndex === -1) - throw new Error(`Invalid file-type locator`); + if (qsIndex === -1) throw new Error(`Invalid file-type locator`); const execPath = posix.normalize(locator.reference.slice(PROTOCOL.length, qsIndex)); const queryString = querystring.parse(locator.reference.slice(qsIndex + 1)); - if (typeof queryString.locator !== `string`) - throw new Error(`Invalid file-type locator`); + if (typeof queryString.locator !== `string`) throw new Error(`Invalid file-type locator`); const parentLocator = structUtils.parseLocator(queryString.locator, true); diff --git a/packages/plugin-exec/sources/ExecResolver.ts b/packages/plugin-exec/sources/ExecResolver.ts index afa875dc4588..aced7bfa24a1 100644 --- a/packages/plugin-exec/sources/ExecResolver.ts +++ b/packages/plugin-exec/sources/ExecResolver.ts @@ -1,23 +1,21 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {Descriptor, Locator, Manifest} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {miscUtils, structUtils} from '@berry/core'; -import {NodeFS} from '@berry/fslib'; -import querystring from 'querystring'; +import {Descriptor, Locator, Manifest} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {miscUtils, structUtils} from '@berry/core'; +import {NodeFS} from '@berry/fslib'; +import querystring from 'querystring'; -import {PROTOCOL} from './constants'; +import {PROTOCOL} from './constants'; export class ExecResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!descriptor.range.startsWith(PROTOCOL)) - return false; + if (!descriptor.range.startsWith(PROTOCOL)) return false; return true; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!locator.reference.startsWith(PROTOCOL)) - return false; + if (!locator.reference.startsWith(PROTOCOL)) return false; return true; } @@ -27,19 +25,20 @@ export class ExecResolver implements Resolver { } bindDescriptor(descriptor: Descriptor, fromLocator: Locator, opts: MinimalResolveOptions) { - if (descriptor.range.includes(`?`)) - return descriptor; - - return structUtils.makeDescriptor(descriptor, `${descriptor.range}?${querystring.stringify({ - locator: structUtils.stringifyLocator(fromLocator), - })}`); + if (descriptor.range.includes(`?`)) return descriptor; + + return structUtils.makeDescriptor( + descriptor, + `${descriptor.range}?${querystring.stringify({ + locator: structUtils.stringifyLocator(fromLocator), + })}`, + ); } async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { let path = descriptor.range; - if (path.startsWith(PROTOCOL)) - path = path.slice(PROTOCOL.length); + if (path.startsWith(PROTOCOL)) path = path.slice(PROTOCOL.length); return [structUtils.makeLocator(descriptor, `${PROTOCOL}${NodeFS.toPortablePath(path)}`)]; } @@ -52,13 +51,13 @@ export class ExecResolver implements Resolver { }, packageFetch.releaseFs); return { - ... locator, + ...locator, version: manifest.version || `0.0.0`, - + languageName: opts.project.configuration.get(`defaultLanguageName`), linkType: LinkType.HARD, - + dependencies: manifest.dependencies, peerDependencies: manifest.peerDependencies, diff --git a/packages/plugin-exec/sources/index.ts b/packages/plugin-exec/sources/index.ts index ff74687e9a9d..7ec49cefd161 100644 --- a/packages/plugin-exec/sources/index.ts +++ b/packages/plugin-exec/sources/index.ts @@ -1,15 +1,11 @@ -import {Plugin} from '@berry/core'; +import {Plugin} from '@berry/core'; -import {ExecFetcher} from './ExecFetcher'; +import {ExecFetcher} from './ExecFetcher'; import {ExecResolver} from './ExecResolver'; const plugin: Plugin = { - fetchers: [ - ExecFetcher, - ], - resolvers: [ - ExecResolver, - ], + fetchers: [ExecFetcher], + resolvers: [ExecResolver], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-file/sources/FileFetcher.ts b/packages/plugin-file/sources/FileFetcher.ts index 73602781a9ff..befd6956c984 100644 --- a/packages/plugin-file/sources/FileFetcher.ts +++ b/packages/plugin-file/sources/FileFetcher.ts @@ -1,16 +1,15 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {Locator, MessageName} from '@berry/core'; -import {miscUtils, structUtils, tgzUtils} from '@berry/core'; -import {NodeFS} from '@berry/fslib'; -import {posix} from 'path'; -import querystring from 'querystring'; +import {Locator, MessageName} from '@berry/core'; +import {miscUtils, structUtils, tgzUtils} from '@berry/core'; +import {NodeFS} from '@berry/fslib'; +import {posix} from 'path'; +import querystring from 'querystring'; -import {PROTOCOL} from './constants'; +import {PROTOCOL} from './constants'; export class FileFetcher implements Fetcher { supports(locator: Locator, opts: MinimalFetchOptions) { - if (!locator.reference.startsWith(PROTOCOL)) - return false; + if (!locator.reference.startsWith(PROTOCOL)) return false; return true; } @@ -18,9 +17,8 @@ export class FileFetcher implements Fetcher { getLocalPath(locator: Locator, opts: FetchOptions) { const {parentLocator, filePath} = this.parseLocator(locator); - if (posix.isAbsolute(filePath)) - return filePath; - + if (posix.isAbsolute(filePath)) return filePath; + const parentLocalPath = opts.fetcher.getLocalPath(parentLocator, opts); if (parentLocalPath !== null) { @@ -37,7 +35,13 @@ export class FileFetcher implements Fetcher { locator, expectedChecksum, async () => { - opts.report.reportInfoOnce(MessageName.FETCH_NOT_CACHED, `${structUtils.prettyLocator(opts.project.configuration, locator)} can't be found in the cache and will be fetched from the disk`); + opts.report.reportInfoOnce( + MessageName.FETCH_NOT_CACHED, + `${structUtils.prettyLocator( + opts.project.configuration, + locator, + )} can't be found in the cache and will be fetched from the disk`, + ); return await this.fetchFromDisk(locator, opts); }, ); @@ -67,8 +71,7 @@ export class FileFetcher implements Fetcher { : parentFetch; // Discard the parent fs unless we really need it to access the files - if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) - parentFetch.releaseFs(); + if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) parentFetch.releaseFs(); const sourceFs = effectiveParentFetch.packageFs; const sourcePath = posix.resolve(effectiveParentFetch.prefixPath, filePath); @@ -84,14 +87,12 @@ export class FileFetcher implements Fetcher { private parseLocator(locator: Locator) { const qsIndex = locator.reference.indexOf(`?`); - if (qsIndex === -1) - throw new Error(`Invalid file-type locator`); + if (qsIndex === -1) throw new Error(`Invalid file-type locator`); const filePath = posix.normalize(locator.reference.slice(PROTOCOL.length, qsIndex)); const queryString = querystring.parse(locator.reference.slice(qsIndex + 1)); - if (typeof queryString.locator !== `string`) - throw new Error(`Invalid file-type locator`); + if (typeof queryString.locator !== `string`) throw new Error(`Invalid file-type locator`); const parentLocator = structUtils.parseLocator(queryString.locator, true); diff --git a/packages/plugin-file/sources/FileResolver.ts b/packages/plugin-file/sources/FileResolver.ts index a06e44946c72..0912653c741a 100644 --- a/packages/plugin-file/sources/FileResolver.ts +++ b/packages/plugin-file/sources/FileResolver.ts @@ -1,26 +1,23 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {Descriptor, Locator, Manifest} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {miscUtils, structUtils} from '@berry/core'; -import {NodeFS} from '@berry/fslib'; -import querystring from 'querystring'; +import {Descriptor, Locator, Manifest} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {miscUtils, structUtils} from '@berry/core'; +import {NodeFS} from '@berry/fslib'; +import querystring from 'querystring'; -import {FILE_REGEXP, PROTOCOL} from './constants'; +import {FILE_REGEXP, PROTOCOL} from './constants'; export class FileResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (descriptor.range.match(FILE_REGEXP)) - return true; + if (descriptor.range.match(FILE_REGEXP)) return true; - if (!descriptor.range.startsWith(PROTOCOL)) - return false; + if (!descriptor.range.startsWith(PROTOCOL)) return false; return true; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!locator.reference.startsWith(PROTOCOL)) - return false; + if (!locator.reference.startsWith(PROTOCOL)) return false; return true; } @@ -33,19 +30,20 @@ export class FileResolver implements Resolver { if (FILE_REGEXP.test(descriptor.range)) descriptor = structUtils.makeDescriptor(descriptor, `file:${descriptor.range}`); - if (descriptor.range.includes(`?`)) - throw new Error(`File-type dependencies cannot contain the character "?"`); + if (descriptor.range.includes(`?`)) throw new Error(`File-type dependencies cannot contain the character "?"`); - return structUtils.makeDescriptor(descriptor, `${descriptor.range}?${querystring.stringify({ - locator: structUtils.stringifyLocator(fromLocator), - })}`); + return structUtils.makeDescriptor( + descriptor, + `${descriptor.range}?${querystring.stringify({ + locator: structUtils.stringifyLocator(fromLocator), + })}`, + ); } async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { let path = descriptor.range; - if (path.startsWith(PROTOCOL)) - path = path.slice(PROTOCOL.length); + if (path.startsWith(PROTOCOL)) path = path.slice(PROTOCOL.length); return [structUtils.makeLocator(descriptor, `${PROTOCOL}${NodeFS.toPortablePath(path)}`)]; } @@ -58,13 +56,13 @@ export class FileResolver implements Resolver { }, packageFetch.releaseFs); return { - ... locator, + ...locator, version: manifest.version || `0.0.0`, - + languageName: opts.project.configuration.get(`defaultLanguageName`), linkType: LinkType.HARD, - + dependencies: manifest.dependencies, peerDependencies: manifest.peerDependencies, diff --git a/packages/plugin-file/sources/TarballFileFetcher.ts b/packages/plugin-file/sources/TarballFileFetcher.ts index 259bd214abbf..604fd5a15ed5 100644 --- a/packages/plugin-file/sources/TarballFileFetcher.ts +++ b/packages/plugin-file/sources/TarballFileFetcher.ts @@ -1,21 +1,19 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {Locator, MessageName} from '@berry/core'; -import {miscUtils, structUtils, tgzUtils} from '@berry/core'; -import {NodeFS} from '@berry/fslib'; -import {posix} from 'path'; -import querystring from 'querystring'; +import {Locator, MessageName} from '@berry/core'; +import {miscUtils, structUtils, tgzUtils} from '@berry/core'; +import {NodeFS} from '@berry/fslib'; +import {posix} from 'path'; +import querystring from 'querystring'; -import {TARBALL_REGEXP, PROTOCOL} from './constants'; +import {TARBALL_REGEXP, PROTOCOL} from './constants'; export class TarballFileFetcher implements Fetcher { static mountPoint: string = `cached-fetchers`; supports(locator: Locator, opts: MinimalFetchOptions) { - if (!TARBALL_REGEXP.test(locator.reference)) - return false; + if (!TARBALL_REGEXP.test(locator.reference)) return false; - if (locator.reference.startsWith(PROTOCOL)) - return true; + if (locator.reference.startsWith(PROTOCOL)) return true; return false; } @@ -31,7 +29,13 @@ export class TarballFileFetcher implements Fetcher { locator, expectedChecksum, async () => { - opts.report.reportInfoOnce(MessageName.FETCH_NOT_CACHED, `${structUtils.prettyLocator(opts.project.configuration, locator)} can't be found in the cache and will be fetched from the disk`); + opts.report.reportInfoOnce( + MessageName.FETCH_NOT_CACHED, + `${structUtils.prettyLocator( + opts.project.configuration, + locator, + )} can't be found in the cache and will be fetched from the disk`, + ); return await this.fetchFromDisk(locator, opts); }, ); @@ -60,8 +64,7 @@ export class TarballFileFetcher implements Fetcher { : parentFetch; // Discard the parent fs unless we really need it to access the files - if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) - parentFetch.releaseFs(); + if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) parentFetch.releaseFs(); const sourceFs = effectiveParentFetch.packageFs; const sourcePath = posix.resolve(effectiveParentFetch.prefixPath, filePath); @@ -78,14 +81,12 @@ export class TarballFileFetcher implements Fetcher { private parseLocator(locator: Locator) { const qsIndex = locator.reference.indexOf(`?`); - if (qsIndex === -1) - throw new Error(`Invalid file-type locator`); + if (qsIndex === -1) throw new Error(`Invalid file-type locator`); const filePath = locator.reference.slice(PROTOCOL.length, qsIndex); const queryString = querystring.parse(locator.reference.slice(qsIndex + 1)); - if (typeof queryString.locator !== `string`) - throw new Error(`Invalid file-type locator`); + if (typeof queryString.locator !== `string`) throw new Error(`Invalid file-type locator`); const parentLocator = structUtils.parseLocator(queryString.locator, true); diff --git a/packages/plugin-file/sources/TarballFileResolver.ts b/packages/plugin-file/sources/TarballFileResolver.ts index 70c572dfbf00..1f22936a8000 100644 --- a/packages/plugin-file/sources/TarballFileResolver.ts +++ b/packages/plugin-file/sources/TarballFileResolver.ts @@ -1,32 +1,27 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {Descriptor, Locator, Manifest} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {miscUtils, structUtils} from '@berry/core'; -import {NodeFS} from '@berry/fslib'; -import querystring from 'querystring'; +import {Descriptor, Locator, Manifest} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {miscUtils, structUtils} from '@berry/core'; +import {NodeFS} from '@berry/fslib'; +import querystring from 'querystring'; -import {FILE_REGEXP, TARBALL_REGEXP, PROTOCOL} from './constants'; +import {FILE_REGEXP, TARBALL_REGEXP, PROTOCOL} from './constants'; export class TarballFileResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!TARBALL_REGEXP.test(descriptor.range)) - return false; + if (!TARBALL_REGEXP.test(descriptor.range)) return false; - if (descriptor.range.startsWith(PROTOCOL)) - return true; + if (descriptor.range.startsWith(PROTOCOL)) return true; - if (FILE_REGEXP.test(descriptor.range)) - return true; + if (FILE_REGEXP.test(descriptor.range)) return true; return false; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!TARBALL_REGEXP.test(locator.reference)) - return false; + if (!TARBALL_REGEXP.test(locator.reference)) return false; - if (locator.reference.startsWith(PROTOCOL)) - return true; + if (locator.reference.startsWith(PROTOCOL)) return true; return false; } @@ -39,19 +34,20 @@ export class TarballFileResolver implements Resolver { if (FILE_REGEXP.test(descriptor.range)) descriptor = structUtils.makeDescriptor(descriptor, `file:${descriptor.range}`); - if (descriptor.range.includes(`?`)) - throw new Error(`File-type dependencies cannot contain the character "?"`); + if (descriptor.range.includes(`?`)) throw new Error(`File-type dependencies cannot contain the character "?"`); - return structUtils.makeDescriptor(descriptor, `${descriptor.range}?${querystring.stringify({ - locator: structUtils.stringifyLocator(fromLocator), - })}`); + return structUtils.makeDescriptor( + descriptor, + `${descriptor.range}?${querystring.stringify({ + locator: structUtils.stringifyLocator(fromLocator), + })}`, + ); } async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { let path = descriptor.range; - if (path.startsWith(PROTOCOL)) - path = path.slice(PROTOCOL.length); + if (path.startsWith(PROTOCOL)) path = path.slice(PROTOCOL.length); return [structUtils.makeLocator(descriptor, `${PROTOCOL}${NodeFS.toPortablePath(path)}`)]; } @@ -64,7 +60,7 @@ export class TarballFileResolver implements Resolver { }, packageFetch.releaseFs); return { - ... locator, + ...locator, version: manifest.version || `0.0.0`, diff --git a/packages/plugin-file/sources/index.ts b/packages/plugin-file/sources/index.ts index c119489235a7..6ce18ffc2f2b 100644 --- a/packages/plugin-file/sources/index.ts +++ b/packages/plugin-file/sources/index.ts @@ -1,19 +1,13 @@ -import {Plugin} from '@berry/core'; +import {Plugin} from '@berry/core'; -import {FileFetcher} from './FileFetcher'; -import {FileResolver} from './FileResolver'; -import {TarballFileFetcher} from './TarballFileFetcher'; +import {FileFetcher} from './FileFetcher'; +import {FileResolver} from './FileResolver'; +import {TarballFileFetcher} from './TarballFileFetcher'; import {TarballFileResolver} from './TarballFileResolver'; const plugin: Plugin = { - fetchers: [ - TarballFileFetcher, - FileFetcher, - ], - resolvers: [ - TarballFileResolver, - FileResolver, - ], + fetchers: [TarballFileFetcher, FileFetcher], + resolvers: [TarballFileResolver, FileResolver], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-github/sources/GithubFetcher.ts b/packages/plugin-github/sources/GithubFetcher.ts index 1e33a5ff7b3d..d2a2412bce11 100644 --- a/packages/plugin-github/sources/GithubFetcher.ts +++ b/packages/plugin-github/sources/GithubFetcher.ts @@ -1,13 +1,12 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {Locator, MessageName} from '@berry/core'; -import {httpUtils, structUtils, tgzUtils} from '@berry/core'; +import {Locator, MessageName} from '@berry/core'; +import {httpUtils, structUtils, tgzUtils} from '@berry/core'; -import * as githubUtils from './githubUtils'; +import * as githubUtils from './githubUtils'; export class GithubFetcher implements Fetcher { supports(locator: Locator, opts: MinimalFetchOptions) { - if (!githubUtils.isGithubUrl(locator.reference)) - return false; + if (!githubUtils.isGithubUrl(locator.reference)) return false; return true; } @@ -23,7 +22,13 @@ export class GithubFetcher implements Fetcher { locator, expectedChecksum, async () => { - opts.report.reportInfoOnce(MessageName.FETCH_NOT_CACHED, `${structUtils.prettyLocator(opts.project.configuration, locator)} can't be found in the cache and will be fetched from the remote repository`); + opts.report.reportInfoOnce( + MessageName.FETCH_NOT_CACHED, + `${structUtils.prettyLocator( + opts.project.configuration, + locator, + )} can't be found in the cache and will be fetched from the remote repository`, + ); return await this.fetchFromNetwork(locator, opts); }, ); diff --git a/packages/plugin-github/sources/GithubResolver.ts b/packages/plugin-github/sources/GithubResolver.ts index 029ba0e2ad94..aced51700c4c 100644 --- a/packages/plugin-github/sources/GithubResolver.ts +++ b/packages/plugin-github/sources/GithubResolver.ts @@ -1,9 +1,9 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {httpUtils, miscUtils, structUtils} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {Ident, Descriptor, Locator, Manifest, Package} from '@berry/core'; +import {httpUtils, miscUtils, structUtils} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {Ident, Descriptor, Locator, Manifest, Package} from '@berry/core'; -import * as githubUtils from './githubUtils'; +import * as githubUtils from './githubUtils'; export class GithubResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { @@ -34,13 +34,13 @@ export class GithubResolver implements Resolver { }, packageFetch.releaseFs); return { - ... locator, + ...locator, version: manifest.version || `0.0.0`, - + languageName: opts.project.configuration.get(`defaultLanguageName`), linkType: LinkType.HARD, - + dependencies: manifest.dependencies, peerDependencies: manifest.peerDependencies, diff --git a/packages/plugin-github/sources/githubUtils.ts b/packages/plugin-github/sources/githubUtils.ts index 5b506c951157..72ff36676001 100644 --- a/packages/plugin-github/sources/githubUtils.ts +++ b/packages/plugin-github/sources/githubUtils.ts @@ -19,8 +19,7 @@ export function parseGithubUrl(string: string) { } } - if (!match) - throw new Error(`Input cannot be parsed as a valid Github URL ('${string}')`); + if (!match) throw new Error(`Input cannot be parsed as a valid Github URL ('${string}')`); const [, username, reponame, branch] = match; return {username, reponame, branch: branch ? branch : undefined}; diff --git a/packages/plugin-github/sources/index.ts b/packages/plugin-github/sources/index.ts index cb03df9cfdf5..6d7d109cea9b 100644 --- a/packages/plugin-github/sources/index.ts +++ b/packages/plugin-github/sources/index.ts @@ -1,15 +1,11 @@ -import {Plugin} from '@berry/core'; +import {Plugin} from '@berry/core'; -import {GithubFetcher} from './GithubFetcher'; +import {GithubFetcher} from './GithubFetcher'; import {GithubResolver} from './GithubResolver'; const plugin: Plugin = { - fetchers: [ - GithubFetcher, - ], - resolvers: [ - GithubResolver, - ], + fetchers: [GithubFetcher], + resolvers: [GithubResolver], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-http/sources/TarballHttpFetcher.ts b/packages/plugin-http/sources/TarballHttpFetcher.ts index 00b8070dffbd..7128211be6e1 100644 --- a/packages/plugin-http/sources/TarballHttpFetcher.ts +++ b/packages/plugin-http/sources/TarballHttpFetcher.ts @@ -1,16 +1,14 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {Locator, MessageName} from '@berry/core'; -import {httpUtils, structUtils, tgzUtils} from '@berry/core'; +import {Locator, MessageName} from '@berry/core'; +import {httpUtils, structUtils, tgzUtils} from '@berry/core'; -import {TARBALL_REGEXP, PROTOCOL_REGEXP} from './constants'; +import {TARBALL_REGEXP, PROTOCOL_REGEXP} from './constants'; export class TarballHttpFetcher implements Fetcher { supports(locator: Locator, opts: MinimalFetchOptions) { - if (!TARBALL_REGEXP.test(locator.reference)) - return false; + if (!TARBALL_REGEXP.test(locator.reference)) return false; - if (PROTOCOL_REGEXP.test(locator.reference)) - return true; + if (PROTOCOL_REGEXP.test(locator.reference)) return true; return false; } @@ -26,7 +24,13 @@ export class TarballHttpFetcher implements Fetcher { locator, expectedChecksum, async () => { - opts.report.reportInfoOnce(MessageName.FETCH_NOT_CACHED, `${structUtils.prettyLocator(opts.project.configuration, locator)} can't be found in the cache and will be fetched from the remote server`); + opts.report.reportInfoOnce( + MessageName.FETCH_NOT_CACHED, + `${structUtils.prettyLocator( + opts.project.configuration, + locator, + )} can't be found in the cache and will be fetched from the remote server`, + ); return await this.fetchFromNetwork(locator, opts); }, ); diff --git a/packages/plugin-http/sources/TarballHttpResolver.ts b/packages/plugin-http/sources/TarballHttpResolver.ts index 6e2975a87c0e..4fdef7c3e7b1 100644 --- a/packages/plugin-http/sources/TarballHttpResolver.ts +++ b/packages/plugin-http/sources/TarballHttpResolver.ts @@ -1,27 +1,23 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {Descriptor, Locator, Manifest} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {miscUtils, structUtils} from '@berry/core'; +import {Descriptor, Locator, Manifest} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {miscUtils, structUtils} from '@berry/core'; -import {PROTOCOL_REGEXP, TARBALL_REGEXP} from './constants'; +import {PROTOCOL_REGEXP, TARBALL_REGEXP} from './constants'; export class TarballHttpResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!TARBALL_REGEXP.test(descriptor.range)) - return false; + if (!TARBALL_REGEXP.test(descriptor.range)) return false; - if (PROTOCOL_REGEXP.test(descriptor.range)) - return true; + if (PROTOCOL_REGEXP.test(descriptor.range)) return true; return false; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!TARBALL_REGEXP.test(locator.reference)) - return false; + if (!TARBALL_REGEXP.test(locator.reference)) return false; - if (PROTOCOL_REGEXP.test(locator.reference)) - return true; + if (PROTOCOL_REGEXP.test(locator.reference)) return true; return false; } @@ -46,7 +42,7 @@ export class TarballHttpResolver implements Resolver { }, packageFetch.releaseFs); return { - ... locator, + ...locator, version: manifest.version || `0.0.0`, diff --git a/packages/plugin-http/sources/index.ts b/packages/plugin-http/sources/index.ts index 2e05c89f335f..2430f8e48a78 100644 --- a/packages/plugin-http/sources/index.ts +++ b/packages/plugin-http/sources/index.ts @@ -1,15 +1,11 @@ -import {Plugin} from '@berry/core'; +import {Plugin} from '@berry/core'; -import {TarballHttpFetcher} from './TarballHttpFetcher'; +import {TarballHttpFetcher} from './TarballHttpFetcher'; import {TarballHttpResolver} from './TarballHttpResolver'; const plugin: Plugin = { - fetchers: [ - TarballHttpFetcher, - ], - resolvers: [ - TarballHttpResolver, - ], + fetchers: [TarballHttpFetcher], + resolvers: [TarballHttpResolver], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-hub/sources/index.ts b/packages/plugin-hub/sources/index.ts index 9ae17b469b32..11ed98c1a8cd 100644 --- a/packages/plugin-hub/sources/index.ts +++ b/packages/plugin-hub/sources/index.ts @@ -1,11 +1,9 @@ -import {Plugin} from '@berry/core'; +import {Plugin} from '@berry/core'; import hubCommand from './commands/hub'; const plugin: Plugin = { - commands: [ - hubCommand, - ], + commands: [hubCommand], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-init/sources/index.ts b/packages/plugin-init/sources/index.ts index 8a90fcde7fa5..8e1a37d8a140 100644 --- a/packages/plugin-init/sources/index.ts +++ b/packages/plugin-init/sources/index.ts @@ -1,6 +1,6 @@ import {Plugin, SettingsType} from '@berry/core'; -import init from './commands/init'; +import init from './commands/init'; const plugin: Plugin = { configuration: { @@ -20,9 +20,7 @@ const plugin: Plugin = { default: null, }, }, - commands: [ - init, - ], + commands: [init], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-link/sources/LinkFetcher.ts b/packages/plugin-link/sources/LinkFetcher.ts index 0fad3d2799a6..5cebe027a814 100644 --- a/packages/plugin-link/sources/LinkFetcher.ts +++ b/packages/plugin-link/sources/LinkFetcher.ts @@ -1,16 +1,15 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {Locator} from '@berry/core'; -import {structUtils} from '@berry/core'; -import {JailFS, NodeFS} from '@berry/fslib'; -import {posix} from 'path'; -import querystring from 'querystring'; +import {Locator} from '@berry/core'; +import {structUtils} from '@berry/core'; +import {JailFS, NodeFS} from '@berry/fslib'; +import {posix} from 'path'; +import querystring from 'querystring'; -import {LINK_PROTOCOL} from './constants'; +import {LINK_PROTOCOL} from './constants'; export class LinkFetcher implements Fetcher { supports(locator: Locator, opts: MinimalFetchOptions) { - if (!locator.reference.startsWith(LINK_PROTOCOL)) - return false; + if (!locator.reference.startsWith(LINK_PROTOCOL)) return false; return true; } @@ -18,9 +17,8 @@ export class LinkFetcher implements Fetcher { getLocalPath(locator: Locator, opts: FetchOptions) { const {parentLocator, linkPath} = this.parseLocator(locator); - if (posix.isAbsolute(linkPath)) - return linkPath; - + if (posix.isAbsolute(linkPath)) return linkPath; + const parentLocalPath = opts.fetcher.getLocalPath(parentLocator, opts); if (parentLocalPath !== null) { @@ -44,32 +42,38 @@ export class LinkFetcher implements Fetcher { const effectiveParentFetch = parentFetch.localPath ? {packageFs: new NodeFS(), prefixPath: parentFetch.localPath} : parentFetch; - + // Discard the parent fs unless we really need it to access the files - if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) - parentFetch.releaseFs(); + if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) parentFetch.releaseFs(); const sourceFs = effectiveParentFetch.packageFs; const sourcePath = posix.resolve(effectiveParentFetch.prefixPath, linkPath); if (parentFetch.localPath) { - return {packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), releaseFs: effectiveParentFetch.releaseFs, prefixPath: `/`, localPath: sourcePath}; + return { + packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), + releaseFs: effectiveParentFetch.releaseFs, + prefixPath: `/`, + localPath: sourcePath, + }; } else { - return {packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), releaseFs: effectiveParentFetch.releaseFs, prefixPath: `/`}; + return { + packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), + releaseFs: effectiveParentFetch.releaseFs, + prefixPath: `/`, + }; } } private parseLocator(locator: Locator) { const qsIndex = locator.reference.indexOf(`?`); - if (qsIndex === -1) - throw new Error(`Invalid link-type locator`); + if (qsIndex === -1) throw new Error(`Invalid link-type locator`); const linkPath = posix.normalize(locator.reference.slice(LINK_PROTOCOL.length, qsIndex)); const queryString = querystring.parse(locator.reference.slice(qsIndex + 1)); - if (typeof queryString.locator !== `string`) - throw new Error(`Invalid link-type locator`); + if (typeof queryString.locator !== `string`) throw new Error(`Invalid link-type locator`); const parentLocator = structUtils.parseLocator(queryString.locator, true); diff --git a/packages/plugin-link/sources/LinkResolver.ts b/packages/plugin-link/sources/LinkResolver.ts index 5101725cb752..d1b22735180d 100644 --- a/packages/plugin-link/sources/LinkResolver.ts +++ b/packages/plugin-link/sources/LinkResolver.ts @@ -1,23 +1,21 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {Descriptor, Locator, Manifest} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {miscUtils, structUtils} from '@berry/core'; -import {NodeFS} from '@berry/fslib'; -import querystring from 'querystring'; +import {Descriptor, Locator, Manifest} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {miscUtils, structUtils} from '@berry/core'; +import {NodeFS} from '@berry/fslib'; +import querystring from 'querystring'; -import {LINK_PROTOCOL} from './constants'; +import {LINK_PROTOCOL} from './constants'; export class LinkResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!descriptor.range.startsWith(LINK_PROTOCOL)) - return false; + if (!descriptor.range.startsWith(LINK_PROTOCOL)) return false; return true; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!locator.reference.startsWith(LINK_PROTOCOL)) - return false; + if (!locator.reference.startsWith(LINK_PROTOCOL)) return false; return true; } @@ -27,12 +25,14 @@ export class LinkResolver implements Resolver { } bindDescriptor(descriptor: Descriptor, fromLocator: Locator, opts: MinimalResolveOptions) { - if (descriptor.range.includes(`?`)) - throw new Error(`Link-type dependencies cannot contain the character "?"`); - - return structUtils.makeDescriptor(descriptor, `${descriptor.range}?${querystring.stringify({ - locator: structUtils.stringifyLocator(fromLocator), - })}`); + if (descriptor.range.includes(`?`)) throw new Error(`Link-type dependencies cannot contain the character "?"`); + + return structUtils.makeDescriptor( + descriptor, + `${descriptor.range}?${querystring.stringify({ + locator: structUtils.stringifyLocator(fromLocator), + })}`, + ); } async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { @@ -49,7 +49,7 @@ export class LinkResolver implements Resolver { }, packageFetch.releaseFs); return { - ... locator, + ...locator, version: manifest.version || `0.0.0`, diff --git a/packages/plugin-link/sources/RawLinkFetcher.ts b/packages/plugin-link/sources/RawLinkFetcher.ts index 73f6bfd2128a..e7901c84c133 100644 --- a/packages/plugin-link/sources/RawLinkFetcher.ts +++ b/packages/plugin-link/sources/RawLinkFetcher.ts @@ -1,16 +1,15 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {Locator} from '@berry/core'; -import {structUtils} from '@berry/core'; -import {JailFS, NodeFS} from '@berry/fslib'; -import {posix} from 'path'; -import querystring from 'querystring'; +import {Locator} from '@berry/core'; +import {structUtils} from '@berry/core'; +import {JailFS, NodeFS} from '@berry/fslib'; +import {posix} from 'path'; +import querystring from 'querystring'; -import {RAW_LINK_PROTOCOL} from './constants'; +import {RAW_LINK_PROTOCOL} from './constants'; export class RawLinkFetcher implements Fetcher { supports(locator: Locator, opts: MinimalFetchOptions) { - if (!locator.reference.startsWith(RAW_LINK_PROTOCOL)) - return false; + if (!locator.reference.startsWith(RAW_LINK_PROTOCOL)) return false; return true; } @@ -18,9 +17,8 @@ export class RawLinkFetcher implements Fetcher { getLocalPath(locator: Locator, opts: FetchOptions) { const {parentLocator, linkPath} = this.parseLocator(locator); - if (posix.isAbsolute(linkPath)) - return linkPath; - + if (posix.isAbsolute(linkPath)) return linkPath; + const parentLocalPath = opts.fetcher.getLocalPath(parentLocator, opts); if (parentLocalPath !== null) { @@ -46,30 +44,36 @@ export class RawLinkFetcher implements Fetcher { : parentFetch; // Discard the parent fs unless we really need it to access the files - if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) - parentFetch.releaseFs(); + if (parentFetch !== effectiveParentFetch && parentFetch.releaseFs) parentFetch.releaseFs(); const sourceFs = effectiveParentFetch.packageFs; const sourcePath = posix.resolve(effectiveParentFetch.prefixPath, linkPath); if (parentFetch.localPath) { - return {packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), releaseFs: effectiveParentFetch.releaseFs, prefixPath: `/`, localPath: sourcePath}; + return { + packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), + releaseFs: effectiveParentFetch.releaseFs, + prefixPath: `/`, + localPath: sourcePath, + }; } else { - return {packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), releaseFs: effectiveParentFetch.releaseFs, prefixPath: `/`}; + return { + packageFs: new JailFS(sourcePath, {baseFs: sourceFs}), + releaseFs: effectiveParentFetch.releaseFs, + prefixPath: `/`, + }; } } private parseLocator(locator: Locator) { const qsIndex = locator.reference.indexOf(`?`); - if (qsIndex === -1) - throw new Error(`Invalid link-type locator`); + if (qsIndex === -1) throw new Error(`Invalid link-type locator`); const linkPath = locator.reference.slice(RAW_LINK_PROTOCOL.length, qsIndex); const queryString = querystring.parse(locator.reference.slice(qsIndex + 1)); - if (typeof queryString.locator !== `string`) - throw new Error(`Invalid link-type locator`); + if (typeof queryString.locator !== `string`) throw new Error(`Invalid link-type locator`); const parentLocator = structUtils.parseLocator(queryString.locator, true); diff --git a/packages/plugin-link/sources/RawLinkResolver.ts b/packages/plugin-link/sources/RawLinkResolver.ts index 99ff6b13c805..4aed7dfbe576 100644 --- a/packages/plugin-link/sources/RawLinkResolver.ts +++ b/packages/plugin-link/sources/RawLinkResolver.ts @@ -1,23 +1,21 @@ import {Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {Descriptor, Locator} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {structUtils} from '@berry/core'; -import {NodeFS} from '@berry/fslib'; -import querystring from 'querystring'; +import {Descriptor, Locator} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {structUtils} from '@berry/core'; +import {NodeFS} from '@berry/fslib'; +import querystring from 'querystring'; -import {RAW_LINK_PROTOCOL} from './constants'; +import {RAW_LINK_PROTOCOL} from './constants'; export class RawLinkResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!descriptor.range.startsWith(RAW_LINK_PROTOCOL)) - return false; + if (!descriptor.range.startsWith(RAW_LINK_PROTOCOL)) return false; return true; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!locator.reference.startsWith(RAW_LINK_PROTOCOL)) - return false; + if (!locator.reference.startsWith(RAW_LINK_PROTOCOL)) return false; return true; } @@ -27,12 +25,14 @@ export class RawLinkResolver implements Resolver { } bindDescriptor(descriptor: Descriptor, fromLocator: Locator, opts: MinimalResolveOptions) { - if (descriptor.range.includes(`?`)) - throw new Error(`Link-type dependencies cannot contain the character "?"`); - - return structUtils.makeDescriptor(descriptor, `${descriptor.range}?${querystring.stringify({ - locator: structUtils.stringifyLocator(fromLocator), - })}`); + if (descriptor.range.includes(`?`)) throw new Error(`Link-type dependencies cannot contain the character "?"`); + + return structUtils.makeDescriptor( + descriptor, + `${descriptor.range}?${querystring.stringify({ + locator: structUtils.stringifyLocator(fromLocator), + })}`, + ); } async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { @@ -43,7 +43,7 @@ export class RawLinkResolver implements Resolver { async resolve(locator: Locator, opts: ResolveOptions) { return { - ... locator, + ...locator, version: `0.0.0`, diff --git a/packages/plugin-link/sources/index.ts b/packages/plugin-link/sources/index.ts index c039deb75f69..9e1a94c3f896 100644 --- a/packages/plugin-link/sources/index.ts +++ b/packages/plugin-link/sources/index.ts @@ -1,19 +1,13 @@ -import {Plugin} from '@berry/core'; +import {Plugin} from '@berry/core'; -import {LinkFetcher} from './LinkFetcher'; -import {LinkResolver} from './LinkResolver'; -import {RawLinkFetcher} from './RawLinkFetcher'; +import {LinkFetcher} from './LinkFetcher'; +import {LinkResolver} from './LinkResolver'; +import {RawLinkFetcher} from './RawLinkFetcher'; import {RawLinkResolver} from './RawLinkResolver'; const plugin: Plugin = { - fetchers: [ - RawLinkFetcher, - LinkFetcher, - ], - resolvers: [ - RawLinkResolver, - LinkResolver, - ], + fetchers: [RawLinkFetcher, LinkFetcher], + resolvers: [RawLinkResolver, LinkResolver], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-npm/sources/NpmFetcher.ts b/packages/plugin-npm/sources/NpmFetcher.ts index 873d8dd05651..899b7d569f6d 100644 --- a/packages/plugin-npm/sources/NpmFetcher.ts +++ b/packages/plugin-npm/sources/NpmFetcher.ts @@ -1,17 +1,15 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@berry/core'; -import {httpUtils, structUtils, tgzUtils} from '@berry/core'; -import {Locator, MessageName} from '@berry/core'; -import semver from 'semver'; +import {httpUtils, structUtils, tgzUtils} from '@berry/core'; +import {Locator, MessageName} from '@berry/core'; +import semver from 'semver'; -import {PROTOCOL} from './constants'; +import {PROTOCOL} from './constants'; export class NpmFetcher implements Fetcher { supports(locator: Locator, opts: MinimalFetchOptions) { - if (!locator.reference.startsWith(PROTOCOL)) - return false; + if (!locator.reference.startsWith(PROTOCOL)) return false; - if (!semver.valid(locator.reference.slice(PROTOCOL.length))) - return false; + if (!semver.valid(locator.reference.slice(PROTOCOL.length))) return false; return true; } @@ -27,7 +25,13 @@ export class NpmFetcher implements Fetcher { locator, expectedChecksum, async () => { - opts.report.reportInfoOnce(MessageName.FETCH_NOT_CACHED, `${structUtils.prettyLocator(opts.project.configuration, locator)} can't be found in the cache and will be fetched from the remote registry`); + opts.report.reportInfoOnce( + MessageName.FETCH_NOT_CACHED, + `${structUtils.prettyLocator( + opts.project.configuration, + locator, + )} can't be found in the cache and will be fetched from the remote registry`, + ); return await this.fetchFromNetwork(locator, opts); }, ); diff --git a/packages/plugin-npm/sources/NpmRemapResolver.ts b/packages/plugin-npm/sources/NpmRemapResolver.ts index 2a288cddf56e..c33e02f47376 100644 --- a/packages/plugin-npm/sources/NpmRemapResolver.ts +++ b/packages/plugin-npm/sources/NpmRemapResolver.ts @@ -1,15 +1,13 @@ import {Descriptor, Locator, MinimalResolveOptions, ResolveOptions, Resolver} from '@berry/core'; -import {structUtils} from '@berry/core'; +import {structUtils} from '@berry/core'; -import {PROTOCOL} from './constants'; +import {PROTOCOL} from './constants'; export class NpmRemapResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!descriptor.range.startsWith(PROTOCOL)) - return false; - - if (!structUtils.tryParseDescriptor(descriptor.range.slice(PROTOCOL.length), true)) - return false; + if (!descriptor.range.startsWith(PROTOCOL)) return false; + + if (!structUtils.tryParseDescriptor(descriptor.range.slice(PROTOCOL.length), true)) return false; return true; } diff --git a/packages/plugin-npm/sources/NpmSemverResolver.ts b/packages/plugin-npm/sources/NpmSemverResolver.ts index 4a67296c1d08..3d0ec52eef23 100644 --- a/packages/plugin-npm/sources/NpmSemverResolver.ts +++ b/packages/plugin-npm/sources/NpmSemverResolver.ts @@ -1,30 +1,26 @@ import {ReportError, MessageName, Resolver, ResolveOptions, MinimalResolveOptions, Manifest} from '@berry/core'; -import {Ident, Descriptor, Locator} from '@berry/core'; -import {LinkType} from '@berry/core'; -import {httpUtils, structUtils} from '@berry/core'; -import semver from 'semver'; +import {Ident, Descriptor, Locator} from '@berry/core'; +import {LinkType} from '@berry/core'; +import {httpUtils, structUtils} from '@berry/core'; +import semver from 'semver'; -import {PROTOCOL} from './constants'; +import {PROTOCOL} from './constants'; const NODE_GYP_IDENT = structUtils.makeIdent(null, `node-gyp`); export class NpmSemverResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!descriptor.range.startsWith(PROTOCOL)) - return false; + if (!descriptor.range.startsWith(PROTOCOL)) return false; - if (!semver.validRange(descriptor.range.slice(PROTOCOL.length))) - return false; + if (!semver.validRange(descriptor.range.slice(PROTOCOL.length))) return false; return true; } supportsLocator(locator: Locator, opts: MinimalResolveOptions) { - if (!locator.reference.startsWith(PROTOCOL)) - return false; + if (!locator.reference.startsWith(PROTOCOL)) return false; - if (!semver.valid(locator.reference.slice(PROTOCOL.length))) - return false; + if (!semver.valid(locator.reference.slice(PROTOCOL.length))) return false; return true; } @@ -40,8 +36,7 @@ export class NpmSemverResolver implements Resolver { async getCandidates(descriptor: Descriptor, opts: ResolveOptions) { const range = descriptor.range.slice(PROTOCOL.length); - if (semver.valid(range)) - return [structUtils.convertDescriptorToLocator(descriptor)]; + if (semver.valid(range)) return [structUtils.convertDescriptorToLocator(descriptor)]; const httpResponse = await httpUtils.get(this.getIdentUrl(descriptor, opts), opts.project.configuration); @@ -64,7 +59,10 @@ export class NpmSemverResolver implements Resolver { const registryData = JSON.parse(httpResponse.toString()); if (!Object.prototype.hasOwnProperty.call(registryData, `versions`)) - throw new ReportError(MessageName.REMOTE_INVALID, `Registry returned invalid data for - missing "versions" field`); + throw new ReportError( + MessageName.REMOTE_INVALID, + `Registry returned invalid data for - missing "versions" field`, + ); if (!Object.prototype.hasOwnProperty.call(registryData.versions, version)) throw new ReportError(MessageName.REMOTE_NOT_FOUND, `Registry failed to return reference "${version}"`); @@ -76,10 +74,13 @@ export class NpmSemverResolver implements Resolver { // This is because the npm registry will automatically add a `node-gyp rebuild` install script // in the metadata if there is not already an install script and a binding.gyp file exists. // Also, node-gyp is not always set as a dependency in packages, so it will also be added if used in scripts. - if (!manifest.dependencies.has(NODE_GYP_IDENT.identHash) && !manifest.peerDependencies.has(NODE_GYP_IDENT.identHash)) { + if ( + !manifest.dependencies.has(NODE_GYP_IDENT.identHash) && + !manifest.peerDependencies.has(NODE_GYP_IDENT.identHash) + ) { for (const value of manifest.scripts.values()) { if (value.includes(`node-gyp`)) { - manifest.dependencies.set(NODE_GYP_IDENT.identHash, structUtils.makeDescriptor(NODE_GYP_IDENT, `*`)); + manifest.dependencies.set(NODE_GYP_IDENT.identHash, structUtils.makeDescriptor(NODE_GYP_IDENT, `*`)); opts.report.reportWarning(MessageName.NODE_GYP_INJECTED, `Implicit dependencies on node-gyp are discouraged`); break; } @@ -87,7 +88,7 @@ export class NpmSemverResolver implements Resolver { } return { - ... locator, + ...locator, version, diff --git a/packages/plugin-npm/sources/NpmTagResolver.ts b/packages/plugin-npm/sources/NpmTagResolver.ts index 1ebef5c85f54..3f306b84354a 100644 --- a/packages/plugin-npm/sources/NpmTagResolver.ts +++ b/packages/plugin-npm/sources/NpmTagResolver.ts @@ -1,18 +1,16 @@ import {ReportError, MessageName, Resolver, ResolveOptions, MinimalResolveOptions} from '@berry/core'; -import {httpUtils, structUtils} from '@berry/core'; -import {Ident, Descriptor, Locator, Package} from '@berry/core'; +import {httpUtils, structUtils} from '@berry/core'; +import {Ident, Descriptor, Locator, Package} from '@berry/core'; -import {PROTOCOL} from './constants'; +import {PROTOCOL} from './constants'; export const TAG_REGEXP = /^[a-z]+$/; export class NpmTagResolver implements Resolver { supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) { - if (!descriptor.range.startsWith(PROTOCOL)) - return false; + if (!descriptor.range.startsWith(PROTOCOL)) return false; - if (!TAG_REGEXP.test(descriptor.range.slice(PROTOCOL.length))) - return false; + if (!TAG_REGEXP.test(descriptor.range.slice(PROTOCOL.length))) return false; return true; } @@ -41,7 +39,7 @@ export class NpmTagResolver implements Resolver { throw new ReportError(MessageName.REMOTE_INVALID, `Registry returned invalid data - missing "dist-tags" field`); const distTags = registryData[`dist-tags`]; - + if (!Object.prototype.hasOwnProperty.call(distTags, tag)) throw new ReportError(MessageName.REMOTE_NOT_FOUND, `Registry failed to return tag "${tag}"`); diff --git a/packages/plugin-npm/sources/index.ts b/packages/plugin-npm/sources/index.ts index e1ed10bab87c..d118ee1df9cc 100644 --- a/packages/plugin-npm/sources/index.ts +++ b/packages/plugin-npm/sources/index.ts @@ -1,9 +1,9 @@ import {Plugin, SettingsType} from '@berry/core'; -import {NpmFetcher} from './NpmFetcher'; -import {NpmRemapResolver} from './NpmRemapResolver'; -import {NpmSemverResolver} from './NpmSemverResolver'; -import {NpmTagResolver} from './NpmTagResolver'; +import {NpmFetcher} from './NpmFetcher'; +import {NpmRemapResolver} from './NpmRemapResolver'; +import {NpmSemverResolver} from './NpmSemverResolver'; +import {NpmTagResolver} from './NpmTagResolver'; const plugin: Plugin = { configuration: { @@ -13,14 +13,8 @@ const plugin: Plugin = { default: `https://registry.yarnpkg.com`, }, }, - fetchers: [ - NpmFetcher, - ], - resolvers: [ - NpmRemapResolver, - NpmSemverResolver, - NpmTagResolver, - ], + fetchers: [NpmFetcher], + resolvers: [NpmRemapResolver, NpmSemverResolver, NpmTagResolver], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-pack/sources/index.ts b/packages/plugin-pack/sources/index.ts index 92ea3beea7b5..df3853518c4e 100644 --- a/packages/plugin-pack/sources/index.ts +++ b/packages/plugin-pack/sources/index.ts @@ -1,11 +1,9 @@ import {Plugin} from '@berry/core'; -import pack from './commands/pack'; +import pack from './commands/pack'; const plugin: Plugin = { - commands: [ - pack, - ], + commands: [pack], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-pnp/sources/PnpLinker.ts b/packages/plugin-pnp/sources/PnpLinker.ts index 5ac912b40cc6..0090a1fb9289 100644 --- a/packages/plugin-pnp/sources/PnpLinker.ts +++ b/packages/plugin-pnp/sources/PnpLinker.ts @@ -1,9 +1,18 @@ -import {Installer, Linker, LinkOptions, MinimalLinkOptions, Manifest, LinkType, MessageName, DependencyMeta} from '@berry/core'; -import {FetchResult, Ident, Locator, Package, BuildDirective, BuildType} from '@berry/core'; -import {miscUtils, structUtils} from '@berry/core'; -import {CwdFS, FakeFS, NodeFS, xfs} from '@berry/fslib'; -import {PackageRegistry, generateInlinedScript, generateSplitScript} from '@berry/pnp'; -import {posix} from 'path'; +import { + Installer, + Linker, + LinkOptions, + MinimalLinkOptions, + Manifest, + LinkType, + MessageName, + DependencyMeta, +} from '@berry/core'; +import {FetchResult, Ident, Locator, Package, BuildDirective, BuildType} from '@berry/core'; +import {miscUtils, structUtils} from '@berry/core'; +import {CwdFS, FakeFS, NodeFS, xfs} from '@berry/fslib'; +import {PackageRegistry, generateInlinedScript, generateSplitScript} from '@berry/pnp'; +import {posix} from 'path'; // Some packages do weird stuff and MUST be unplugged. I don't like them. const FORCED_UNPLUG_PACKAGES = new Set([ @@ -31,7 +40,12 @@ export class PnpLinker implements Linker { const packageInformation = pnpFile.getPackageInformation(packageLocator); if (!packageInformation) - throw new Error(`Couldn't find ${structUtils.prettyLocator(opts.project.configuration, locator)} in the currently installed pnp map`); + throw new Error( + `Couldn't find ${structUtils.prettyLocator( + opts.project.configuration, + locator, + )} in the currently installed pnp map`, + ); return NodeFS.toPortablePath(packageInformation.packageLocation); } @@ -46,8 +60,7 @@ export class PnpLinker implements Linker { delete require.cache[physicalPath]; const locator = pnpFile.findPackageLocator(NodeFS.fromPortablePath(location)); - if (!locator) - return null; + if (!locator) return null; return structUtils.makeLocator(structUtils.parseIdent(locator.name), locator.reference); } @@ -74,25 +87,44 @@ class PnpInstaller implements Installer { const buildScripts = await this.getBuildScripts(fetchResult); if (buildScripts.length > 0 && !this.opts.project.configuration.get(`enableScripts`)) { - this.opts.report.reportWarning(MessageName.DISABLED_BUILD_SCRIPTS, `${structUtils.prettyLocator(this.opts.project.configuration, pkg)} lists build scripts, but all build scripts have been disabled.`); + this.opts.report.reportWarning( + MessageName.DISABLED_BUILD_SCRIPTS, + `${structUtils.prettyLocator( + this.opts.project.configuration, + pkg, + )} lists build scripts, but all build scripts have been disabled.`, + ); buildScripts.length = 0; } if (buildScripts.length > 0 && pkg.linkType !== LinkType.HARD && !this.opts.project.tryWorkspaceByLocator(pkg)) { - this.opts.report.reportWarning(MessageName.SOFT_LINK_BUILD, `${structUtils.prettyLocator(this.opts.project.configuration, pkg)} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`); + this.opts.report.reportWarning( + MessageName.SOFT_LINK_BUILD, + `${structUtils.prettyLocator( + this.opts.project.configuration, + pkg, + )} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`, + ); buildScripts.length = 0; } const dependencyMeta = this.opts.project.getDependencyMeta(pkg, pkg.version); if (buildScripts.length > 0 && dependencyMeta && dependencyMeta.built === false) { - this.opts.report.reportInfo(MessageName.BUILD_DISABLED, `${structUtils.prettyLocator(this.opts.project.configuration, pkg)} lists build scripts, but its build has been explicitly disabled through configuration.`); + this.opts.report.reportInfo( + MessageName.BUILD_DISABLED, + `${structUtils.prettyLocator( + this.opts.project.configuration, + pkg, + )} lists build scripts, but its build has been explicitly disabled through configuration.`, + ); buildScripts.length = 0; } - const packageFs = pkg.linkType !== LinkType.SOFT && (buildScripts.length > 0 || this.isUnplugged(pkg, dependencyMeta)) - ? await this.unplugPackage(pkg, fetchResult.packageFs) - : fetchResult.packageFs; + const packageFs = + pkg.linkType !== LinkType.SOFT && (buildScripts.length > 0 || this.isUnplugged(pkg, dependencyMeta)) + ? await this.unplugPackage(pkg, fetchResult.packageFs) + : fetchResult.packageFs; const packageRawLocation = posix.resolve(packageFs.getRealPath(), posix.relative(`/`, fetchResult.prefixPath)); @@ -104,7 +136,7 @@ class PnpInstaller implements Installer { return { packageLocation, - buildDirective: buildScripts.length > 0 ? buildScripts as BuildDirective[] : null, + buildDirective: buildScripts.length > 0 ? (buildScripts as BuildDirective[]) : null, }; } @@ -125,11 +157,15 @@ class PnpInstaller implements Installer { async finalizeInstall() { if (await this.shouldWarnNodeModules()) - this.opts.report.reportWarning(MessageName.DANGEROUS_NODE_MODULES, `One or more node_modules have been detected; they risk hiding legitimate problems until your application reaches production.`); + this.opts.report.reportWarning( + MessageName.DANGEROUS_NODE_MODULES, + `One or more node_modules have been detected; they risk hiding legitimate problems until your application reaches production.`, + ); - this.packageRegistry.set(null, new Map([ - [null, this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)], - ])); + this.packageRegistry.set( + null, + new Map([[null, this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]), + ); const shebang = this.opts.project.configuration.get(`pnpShebang`); const ignorePattern = this.opts.project.configuration.get(`pnpIgnorePattern`); @@ -150,7 +186,7 @@ class PnpInstaller implements Installer { await xfs.removePromise(pnpDataPath); } else { const dataLocation = posix.relative(posix.dirname(pnpPath), pnpDataPath); - const {dataFile, loaderFile} = generateSplitScript({... pnpSettings, dataLocation}); + const {dataFile, loaderFile} = generateSplitScript({...pnpSettings, dataLocation}); await xfs.changeFilePromise(pnpPath, loaderFile); await xfs.chmodPromise(pnpPath, 0o755); @@ -175,8 +211,7 @@ class PnpInstaller implements Installer { private getPackageStore(key: string) { let packageStore = this.packageRegistry.get(key); - if (!packageStore) - this.packageRegistry.set(key, packageStore = new Map()); + if (!packageStore) this.packageRegistry.set(key, (packageStore = new Map())); return packageStore; } @@ -187,11 +222,21 @@ class PnpInstaller implements Installer { const packageInformationStore = this.packageRegistry.get(key1); if (!packageInformationStore) - throw new Error(`Assertion failed: The package information store should have been available (for ${structUtils.prettyIdent(this.opts.project.configuration, locator)})`); + throw new Error( + `Assertion failed: The package information store should have been available (for ${structUtils.prettyIdent( + this.opts.project.configuration, + locator, + )})`, + ); const packageInformation = packageInformationStore.get(key2); if (!packageInformation) - throw new Error(`Assertion failed: The package information should have been available (for ${structUtils.prettyLocator(this.opts.project.configuration, locator)})`); + throw new Error( + `Assertion failed: The package information should have been available (for ${structUtils.prettyLocator( + this.opts.project.configuration, + locator, + )})`, + ); return packageInformation; } @@ -203,10 +248,13 @@ class PnpInstaller implements Installer { let diskInformation = packageStore.get(normalizedPath); if (!diskInformation) { - packageStore.set(normalizedPath, diskInformation = { - packageLocation: normalizedPath, - packageDependencies: new Map(), - }); + packageStore.set( + normalizedPath, + (diskInformation = { + packageLocation: normalizedPath, + packageDependencies: new Map(), + }), + ); } return diskInformation; @@ -215,12 +263,10 @@ class PnpInstaller implements Installer { private async shouldWarnNodeModules() { for (const workspace of this.opts.project.workspaces) { const nodeModulesPath = `${workspace.cwd}/node_modules`; - if (!xfs.existsSync(nodeModulesPath)) - continue; + if (!xfs.existsSync(nodeModulesPath)) continue; const directoryListing = await xfs.readdirPromise(nodeModulesPath); - if (directoryListing.every(entry => entry.startsWith(`.`))) - continue; + if (directoryListing.every(entry => entry.startsWith(`.`))) continue; return true; } @@ -231,8 +277,7 @@ class PnpInstaller implements Installer { private normalizeDirectoryPath(folder: string) { let relativeFolder = posix.relative(this.opts.project.cwd, folder); - if (!relativeFolder.match(/^\.{0,2}\//)) - relativeFolder = `./${relativeFolder}`; + if (!relativeFolder.match(/^\.{0,2}\//)) relativeFolder = `./${relativeFolder}`; return relativeFolder.replace(/\/?$/, '/'); } @@ -242,8 +287,7 @@ class PnpInstaller implements Installer { const {scripts} = await Manifest.find(fetchResult.prefixPath, {baseFs: fetchResult.packageFs}); for (const scriptName of [`preinstall`, `install`, `postinstall`]) - if (scripts.has(scriptName)) - buildScripts.push([BuildType.SCRIPT, scriptName]); + if (scripts.has(scriptName)) buildScripts.push([BuildType.SCRIPT, scriptName]); // Detect cases where a package has a binding.gyp but no install script const bindingFilePath = posix.resolve(fetchResult.prefixPath, `binding.gyp`); @@ -254,7 +298,10 @@ class PnpInstaller implements Installer { } private getUnpluggedPath(locator: Locator) { - return posix.resolve(this.opts.project.configuration.get(`pnpUnpluggedFolder`), structUtils.slugifyLocator(locator)); + return posix.resolve( + this.opts.project.configuration.get(`pnpUnpluggedFolder`), + structUtils.slugifyLocator(locator), + ); } private async unplugPackage(locator: Locator, packageFs: FakeFS) { @@ -268,11 +315,9 @@ class PnpInstaller implements Installer { } private isUnplugged(ident: Ident, dependencyMeta: DependencyMeta) { - if (dependencyMeta.unplugged) - return true; + if (dependencyMeta.unplugged) return true; - if (FORCED_UNPLUG_PACKAGES.has(ident.identHash)) - return true; + if (FORCED_UNPLUG_PACKAGES.has(ident.identHash)) return true; return false; } diff --git a/packages/plugin-pnp/sources/index.ts b/packages/plugin-pnp/sources/index.ts index 55e1db5ce6e4..1874e25ee1a4 100644 --- a/packages/plugin-pnp/sources/index.ts +++ b/packages/plugin-pnp/sources/index.ts @@ -1,11 +1,15 @@ import {Hooks as CoreHooks, Plugin, Project, SettingsType} from '@berry/core'; -import {NodeFS, xfs} from '@berry/fslib'; -import {Hooks as StageHooks} from '@berry/plugin-stage'; +import {NodeFS, xfs} from '@berry/fslib'; +import {Hooks as StageHooks} from '@berry/plugin-stage'; -import {PnpLinker} from './PnpLinker'; -import unplug from './commands/unplug'; +import {PnpLinker} from './PnpLinker'; +import unplug from './commands/unplug'; -async function setupScriptEnvironment(project: Project, env: {[key: string]: string}, makePathWrapper: (name: string, argv0: string, args: Array) => Promise) { +async function setupScriptEnvironment( + project: Project, + env: {[key: string]: string}, + makePathWrapper: (name: string, argv0: string, args: Array) => Promise, +) { const pnpPath = NodeFS.fromPortablePath(project.configuration.get(`pnpPath`)); const pnpRequire = `--require ${pnpPath}`; @@ -29,10 +33,7 @@ const plugin: Plugin = { hooks: { populateYarnPaths, setupScriptEnvironment, - } as ( - CoreHooks & - StageHooks - ), + } as CoreHooks & StageHooks, configuration: { pnpShebang: { description: `String to prepend to the generated PnP script`, @@ -65,12 +66,8 @@ const plugin: Plugin = { default: `./.pnp.js`, }, }, - linkers: [ - PnpLinker, - ], - commands: [ - unplug, - ], + linkers: [PnpLinker], + commands: [unplug], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-stage/sources/index.ts b/packages/plugin-stage/sources/index.ts index e65522f15330..94dfb2955c6a 100644 --- a/packages/plugin-stage/sources/index.ts +++ b/packages/plugin-stage/sources/index.ts @@ -1,18 +1,13 @@ import {Plugin, Project} from '@berry/core'; -import stage from './commands/stage'; +import stage from './commands/stage'; export interface Hooks { - populateYarnPaths?: ( - project: Project, - definePath: (path: string | null) => void, - ) => Promise, + populateYarnPaths?: (project: Project, definePath: (path: string | null) => void) => Promise; } const plugin: Plugin = { - commands: [ - stage, - ], + commands: [stage], }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/plugin-stage/sources/stageUtils.ts b/packages/plugin-stage/sources/stageUtils.ts index fd908a4eca60..4e9eefdd2073 100644 --- a/packages/plugin-stage/sources/stageUtils.ts +++ b/packages/plugin-stage/sources/stageUtils.ts @@ -1,4 +1,4 @@ -import {xfs} from '@berry/fslib'; +import {xfs} from '@berry/fslib'; import {posix} from 'path'; export async function findVcsRoot(cwd: string, {marker}: {marker: string}) { @@ -13,9 +13,8 @@ export async function findVcsRoot(cwd: string, {marker}: {marker: string}) { return null; } -export function isYarnFile(path: string, {roots, names}: {roots: Set, names: Set}) { - if (names.has(posix.basename(path))) - return true; +export function isYarnFile(path: string, {roots, names}: {roots: Set; names: Set}) { + if (names.has(posix.basename(path))) return true; do { if (!roots.has(path)) { @@ -52,7 +51,8 @@ export function expandDirectory(initialCwd: string) { } export function checkConsensus(lines: Array, regex: RegExp) { - let yes = 0, no = 0; + let yes = 0, + no = 0; for (const line of lines) { if (regex.test(line)) { @@ -78,23 +78,11 @@ export function findConsensus(lines: Array) { } export function genCommitMessage(lines: Array) { - const { - useThirdPerson, - useUpperCase, - useComponent, - } = findConsensus(lines); - - const prefix = useComponent - ? `chore(yarn): ` - : ``; - - const verb = useThirdPerson - ? useUpperCase - ? `Updates` - : `updates` - : useUpperCase - ? `Update` - : `update`; + const {useThirdPerson, useUpperCase, useComponent} = findConsensus(lines); + + const prefix = useComponent ? `chore(yarn): ` : ``; + + const verb = useThirdPerson ? (useUpperCase ? `Updates` : `updates`) : useUpperCase ? `Update` : `update`; return `${prefix}${verb} the project settings`; } diff --git a/packages/plugin-typescript/sources/index.ts b/packages/plugin-typescript/sources/index.ts index 87a034373dc8..46b054775aa9 100644 --- a/packages/plugin-typescript/sources/index.ts +++ b/packages/plugin-typescript/sources/index.ts @@ -1,51 +1,47 @@ import {Cache, Descriptor, Plugin, Workspace} from '@berry/core'; -import {httpUtils, structUtils} from '@berry/core'; -import {Hooks as EssentialsHooks} from '@berry/plugin-essentials'; -import {suggestUtils} from '@berry/plugin-essentials'; +import {httpUtils, structUtils} from '@berry/core'; +import {Hooks as EssentialsHooks} from '@berry/plugin-essentials'; +import {suggestUtils} from '@berry/plugin-essentials'; const afterWorkspaceDependencyAddition = async ( workspace: Workspace, dependencyTarget: suggestUtils.Target, descriptor: Descriptor, ) => { - if (descriptor.scope === `types`) - return; + if (descriptor.scope === `types`) return; const project = workspace.project; const configuration = project.configuration; const cache = await Cache.find(configuration); - const typesName = descriptor.scope - ? `${descriptor.scope}__${descriptor.name}` - : `${descriptor.name}`; + const typesName = descriptor.scope ? `${descriptor.scope}__${descriptor.name}` : `${descriptor.name}`; const target = suggestUtils.Target.REGULAR; const modifier = suggestUtils.Modifier.EXACT; const strategies = [suggestUtils.Strategy.LATEST]; const request = structUtils.makeDescriptor(structUtils.makeIdent(`types`, typesName), `unknown`); - const suggestions = await suggestUtils.getSuggestedDescriptors(request, null, {project, cache, target, modifier, strategies}); + const suggestions = await suggestUtils.getSuggestedDescriptors(request, null, { + project, + cache, + target, + modifier, + strategies, + }); const nonNullSuggestions = suggestions.filter(suggestion => suggestion.descriptor !== null); - if (nonNullSuggestions.length === 0) - return; + if (nonNullSuggestions.length === 0) return; const selected = nonNullSuggestions[0].descriptor; - if (selected === null) - return; + if (selected === null) return; - workspace.manifest[target].set( - selected.identHash, - selected, - ); + workspace.manifest[target].set(selected.identHash, selected); }; const plugin: Plugin = { hooks: { afterWorkspaceDependencyAddition, - } as ( - EssentialsHooks - ), + } as (EssentialsHooks), }; // eslint-disable-next-line arca/no-default-export diff --git a/packages/vscode-zipfs/sources/ZipFSProvider.ts b/packages/vscode-zipfs/sources/ZipFSProvider.ts index c8e65840338d..8731b24bc376 100644 --- a/packages/vscode-zipfs/sources/ZipFSProvider.ts +++ b/packages/vscode-zipfs/sources/ZipFSProvider.ts @@ -1,76 +1,80 @@ import {ZipOpenFS} from '@berry/fslib'; -import {posix} from 'path'; +import {posix} from 'path'; import * as vscode from 'vscode'; export class ZipFSProvider implements vscode.FileSystemProvider { - private readonly zipFs = new ZipOpenFS({useCache: false}); + private readonly zipFs = new ZipOpenFS({useCache: false}); - stat(uri: vscode.Uri): vscode.FileStat { - const stat: any = this.zipFs.statSync(uri.path); + stat(uri: vscode.Uri): vscode.FileStat { + const stat: any = this.zipFs.statSync(uri.path); - switch (true) { - case stat.isDirectory(): { - stat.type = vscode.FileType.Directory; - } break; - - case stat.isFile(): { - stat.type = vscode.FileType.File; - } break; + switch (true) { + case stat.isDirectory(): + { + stat.type = vscode.FileType.Directory; + } + break; - default: { - stat.type = vscode.FileType.Unknown; - } break; + case stat.isFile(): + { + stat.type = vscode.FileType.File; } + break; - return stat; + default: + { + stat.type = vscode.FileType.Unknown; + } + break; } - readDirectory(uri: vscode.Uri): [string, vscode.FileType][] { - const listing = this.zipFs.readdirSync(uri.path); - const results = []; + return stat; + } - for (const entry of listing) { - const entryStat = this.zipFs.statSync(posix.join(uri.path, entry)); + readDirectory(uri: vscode.Uri): [string, vscode.FileType][] { + const listing = this.zipFs.readdirSync(uri.path); + const results = []; - if (entryStat.isDirectory()) { - results.push([entry, vscode.FileType.Directory] as [string, vscode.FileType]); - } else { - results.push([entry, vscode.FileType.File] as [string, vscode.FileType]) - } - } + for (const entry of listing) { + const entryStat = this.zipFs.statSync(posix.join(uri.path, entry)); - return results; + if (entryStat.isDirectory()) { + results.push([entry, vscode.FileType.Directory] as [string, vscode.FileType]); + } else { + results.push([entry, vscode.FileType.File] as [string, vscode.FileType]); + } } - readFile(uri: vscode.Uri): Uint8Array { - return this.zipFs.readFileSync(uri.path) as any as Buffer; - } + return results; + } - writeFile(uri: vscode.Uri, content: Uint8Array, options: {create: boolean, overwrite: boolean}): void { - if (!options.create && !this.zipFs.existsSync(uri.path)) - throw new Error(``); - if (options.create && !options.overwrite && this.zipFs.existsSync(uri.path)) - throw new Error(``); - - this.zipFs.writeFileSync(uri.path, new Buffer(content)); - } + readFile(uri: vscode.Uri): Uint8Array { + return (this.zipFs.readFileSync(uri.path) as any) as Buffer; + } - rename(oldUri: vscode.Uri, newUri: vscode.Uri, options: { overwrite: boolean }): void { - throw new Error(`Not supported`); - } + writeFile(uri: vscode.Uri, content: Uint8Array, options: {create: boolean; overwrite: boolean}): void { + if (!options.create && !this.zipFs.existsSync(uri.path)) throw new Error(``); + if (options.create && !options.overwrite && this.zipFs.existsSync(uri.path)) throw new Error(``); - delete(uri: vscode.Uri): void { - throw new Error(`Not supported`); - } + this.zipFs.writeFileSync(uri.path, new Buffer(content)); + } - createDirectory(uri: vscode.Uri): void { - this.zipFs.mkdirSync(uri.path); - } + rename(oldUri: vscode.Uri, newUri: vscode.Uri, options: {overwrite: boolean}): void { + throw new Error(`Not supported`); + } - private _emitter = new vscode.EventEmitter(); - readonly onDidChangeFile = this._emitter.event; + delete(uri: vscode.Uri): void { + throw new Error(`Not supported`); + } - watch(resource: vscode.Uri, opts: any): vscode.Disposable { - return new vscode.Disposable(() => {}); - } + createDirectory(uri: vscode.Uri): void { + this.zipFs.mkdirSync(uri.path); + } + + private _emitter = new vscode.EventEmitter(); + readonly onDidChangeFile = this._emitter.event; + + watch(resource: vscode.Uri, opts: any): vscode.Disposable { + return new vscode.Disposable(() => {}); + } } diff --git a/packages/vscode-zipfs/sources/index.ts b/packages/vscode-zipfs/sources/index.ts index 7fc28569efc0..b0f34985dfb4 100644 --- a/packages/vscode-zipfs/sources/index.ts +++ b/packages/vscode-zipfs/sources/index.ts @@ -1,5 +1,5 @@ -import {posix} from 'path'; -import * as vscode from 'vscode'; +import {posix} from 'path'; +import * as vscode from 'vscode'; import {ZipFSProvider} from './ZipFSProvider'; @@ -15,15 +15,21 @@ function mount(uri: vscode.Uri) { } export function activate(context: vscode.ExtensionContext) { - context.subscriptions.push(vscode.workspace.registerFileSystemProvider('zip', new ZipFSProvider(), { - isCaseSensitive: true, - })); + context.subscriptions.push( + vscode.workspace.registerFileSystemProvider('zip', new ZipFSProvider(), { + isCaseSensitive: true, + }), + ); - context.subscriptions.push(vscode.commands.registerCommand('zipfs.mountZipFile', (uri: vscode.Uri) => { - mount(uri); - })); + context.subscriptions.push( + vscode.commands.registerCommand('zipfs.mountZipFile', (uri: vscode.Uri) => { + mount(uri); + }), + ); - context.subscriptions.push(vscode.commands.registerCommand('zipfs.mountZipEditor', () => { - mount(vscode.window.activeTextEditor!.document.uri); - })); + context.subscriptions.push( + vscode.commands.registerCommand('zipfs.mountZipEditor', () => { + mount(vscode.window.activeTextEditor!.document.uri); + }), + ); } diff --git a/yarn.lock b/yarn.lock index 2bd5194fda65..5218b5c8ca00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1640,6 +1640,7 @@ __metadata: "@types/dateformat": "npm:^1.0.1" "@types/emscripten": "npm:^0.0.31" "@types/eslint": "npm:4.16.6" + "@types/eslint-plugin-prettier": "npm:2.2.0" "@types/eventemitter3": "npm:^2.0.2" "@types/execa": "npm:^0.9.0" "@types/faker": "npm:^4.1.4" @@ -1654,6 +1655,7 @@ __metadata: "@types/node": "npm:^10.12.0" "@types/node-emoji": "npm:^1.8.0" "@types/node-fetch": "npm:^2.1.2" + "@types/prettier": "npm:1.16.3" "@types/react": "npm:^16.4.14" "@types/react-redux": "npm:^6.0.9" "@types/redux-saga": "npm:^0.10.5" @@ -1670,9 +1672,11 @@ __metadata: babel-jest: "npm:^24.5.0" eslint: "npm:^5.16.0" eslint-plugin-arca: "npm:^0.8.1" + eslint-plugin-prettier: "npm:^3.0.1" jest: "npm:^24.5.0" jest-environment-node: "npm:^24.5.0" jest-junit: "npm:^5.2.0" + prettier: "npm:^1.17.0" ts-node: "npm:^7.0.1" typescript: "npm:^3.3.3333" dependenciesMeta: @@ -2893,6 +2897,13 @@ __metadata: languageName: node linkType: hard +"@types/eslint-plugin-prettier@npm:2.2.0": + version: 2.2.0 + resolution: "@types/eslint-plugin-prettier@npm:2.2.0" + checksum: 5a79264fb324af83ffd411cc1fd2509eb9f344f9b2dfa76710b464044d838eaed134081c4eedd2f729cabbdce8c0d29a4d4a70fca73d0a28f8835ccb04965dc9 + languageName: node + linkType: hard + "@types/eslint@npm:4.16.6": version: 4.16.6 resolution: "@types/eslint@npm:4.16.6" @@ -3122,6 +3133,13 @@ __metadata: languageName: node linkType: hard +"@types/prettier@npm:1.16.3": + version: 1.16.3 + resolution: "@types/prettier@npm:1.16.3" + checksum: 54c9c8db2c20cf81da1177d1a40c692fe7b442d124828fffd63221533f724b02cf18330e2111066a083b5d60dbd8f35142cd9b1d7fddad023430fc70477a2cb7 + languageName: node + linkType: hard + "@types/prop-types@npm:*": version: 15.5.8 resolution: "@types/prop-types@npm:15.5.8" @@ -8163,6 +8181,18 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-prettier@npm:^3.0.1": + version: 3.0.1 + resolution: "eslint-plugin-prettier@npm:3.0.1" + dependencies: + prettier-linter-helpers: "npm:^1.0.0" + peerDependencies: + eslint: ">= 5.0.0" + prettier: ">= 1.13.0" + checksum: bf958f3fbb1ff5a55c7bd811c79c102345e83c9b7f42e19742d669202a2f84170eefa89f0bf704eba8eb693638a1def864de0ffc7980332213e968893744a288 + languageName: node + linkType: hard + "eslint-plugin-react@npm:^7.8.2": version: 7.12.4 resolution: "eslint-plugin-react@npm:7.12.4" @@ -8830,6 +8860,13 @@ __metadata: languageName: node linkType: hard +"fast-diff@npm:^1.1.2": + version: 1.2.0 + resolution: "fast-diff@npm:1.2.0" + checksum: d8332a974440fa82f20d87c91df8140865bb43f8e462d0c7c7ce1167e342ff4e1922dd2fd509d4e2d9f6ae8c23c9aa664b5f9fc799e27517a2eef02fdbed6445 + languageName: node + linkType: hard + "fast-glob@npm:^2.0.2, fast-glob@npm:^2.2.2": version: 2.2.6 resolution: "fast-glob@npm:2.2.6" @@ -16792,6 +16829,15 @@ __metadata: languageName: node linkType: hard +"prettier-linter-helpers@npm:^1.0.0": + version: 1.0.0 + resolution: "prettier-linter-helpers@npm:1.0.0" + dependencies: + fast-diff: "npm:^1.1.2" + checksum: 40f6522372d74398a1e71b6809988545e499825401d04035fd09f8c54ce184e7c7f2e4e2da267a974d3e24e4ece1f937870797d6cd6716225b9ddc7136bf61f6 + languageName: node + linkType: hard + "prettier@npm:^1.16.0": version: 1.16.4 resolution: "prettier@npm:1.16.4" @@ -16799,6 +16845,13 @@ __metadata: languageName: node linkType: hard +"prettier@npm:^1.17.0": + version: 1.17.0 + resolution: "prettier@npm:1.17.0" + checksum: 00fb1a7cd03427a816ca3ba2c80417a402be75da8b56f0d87f22bbabc0469bdb87cf5cc7800c119758a05df3ffc4f3879610c83f2e3adbf3a1fe221424c9c2df + languageName: node + linkType: hard + "pretty-bytes@npm:^4.0.2": version: 4.0.2 resolution: "pretty-bytes@npm:4.0.2"