@backstage/cli-node
Advanced tools
| 'use strict'; | ||
| var fs = require('fs-extra'); | ||
| var path = require('node:path'); | ||
| var cliCommon = require('@backstage/cli-common'); | ||
| function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } | ||
| var fs__default = /*#__PURE__*/_interopDefaultCompat(fs); | ||
| const DEFAULT_CACHE_BASE_PATH = "node_modules/.cache/backstage-cli"; | ||
| const CACHE_MAX_AGE_MS = 7 * 24 * 36e5; | ||
| class SuccessCache { | ||
| #path; | ||
| /** | ||
| * Trim any occurrences of the workspace root path from the input string. This | ||
| * is useful to ensure stable hashes that don't vary based on the workspace | ||
| * location. | ||
| */ | ||
| static trimPaths(input) { | ||
| return input.replaceAll(cliCommon.targetPaths.rootDir, ""); | ||
| } | ||
| static create(options) { | ||
| return new SuccessCache(options); | ||
| } | ||
| constructor(options) { | ||
| this.#path = path.resolve( | ||
| options.basePath ?? DEFAULT_CACHE_BASE_PATH, | ||
| options.name | ||
| ); | ||
| } | ||
| async read() { | ||
| try { | ||
| const stat = await fs__default.default.stat(this.#path); | ||
| if (!stat.isDirectory()) { | ||
| await fs__default.default.rm(this.#path); | ||
| return /* @__PURE__ */ new Set(); | ||
| } | ||
| } catch (error) { | ||
| if (error.code === "ENOENT") { | ||
| return /* @__PURE__ */ new Set(); | ||
| } | ||
| throw error; | ||
| } | ||
| const items = await fs__default.default.readdir(this.#path); | ||
| const returned = /* @__PURE__ */ new Set(); | ||
| const removed = /* @__PURE__ */ new Set(); | ||
| const now = Date.now(); | ||
| for (const item of items) { | ||
| const split = item.split("_"); | ||
| if (split.length !== 2) { | ||
| removed.add(item); | ||
| continue; | ||
| } | ||
| const createdAt = parseInt(split[0], 10); | ||
| if (Number.isNaN(createdAt) || now - createdAt > CACHE_MAX_AGE_MS) { | ||
| removed.add(item); | ||
| } else { | ||
| returned.add(split[1]); | ||
| } | ||
| } | ||
| for (const item of removed) { | ||
| await fs__default.default.unlink(path.resolve(this.#path, item)); | ||
| } | ||
| return returned; | ||
| } | ||
| async write(newEntries) { | ||
| const now = Date.now(); | ||
| await fs__default.default.ensureDir(this.#path); | ||
| const existingItems = await fs__default.default.readdir(this.#path); | ||
| const empty = Buffer.alloc(0); | ||
| for (const key of newEntries) { | ||
| const trimmedItems = existingItems.filter( | ||
| (item) => item.endsWith(`_${key}`) | ||
| ); | ||
| for (const trimmedItem of trimmedItems) { | ||
| await fs__default.default.unlink(path.resolve(this.#path, trimmedItem)); | ||
| } | ||
| await fs__default.default.writeFile(path.resolve(this.#path, `${now}_${key}`), empty); | ||
| } | ||
| } | ||
| } | ||
| exports.SuccessCache = SuccessCache; | ||
| //# sourceMappingURL=SuccessCache.cjs.js.map |
| {"version":3,"file":"SuccessCache.cjs.js","sources":["../../src/cache/SuccessCache.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs-extra';\nimport { resolve as resolvePath } from 'node:path';\nimport { targetPaths } from '@backstage/cli-common';\n\nconst DEFAULT_CACHE_BASE_PATH = 'node_modules/.cache/backstage-cli';\n\nconst CACHE_MAX_AGE_MS = 7 * 24 * 3600_000;\n\n/**\n * A file-system-based cache that tracks successful operations by storing\n * timestamped marker files.\n *\n * @public\n */\nexport class SuccessCache {\n readonly #path: string;\n\n /**\n * Trim any occurrences of the workspace root path from the input string. This\n * is useful to ensure stable hashes that don't vary based on the workspace\n * location.\n */\n static trimPaths(input: string) {\n return input.replaceAll(targetPaths.rootDir, '');\n }\n\n static create(options: { name: string; basePath?: string }): SuccessCache {\n return new SuccessCache(options);\n }\n\n private constructor(options: { name: string; basePath?: string }) {\n this.#path = resolvePath(\n options.basePath ?? DEFAULT_CACHE_BASE_PATH,\n options.name,\n );\n }\n\n async read(): Promise<Set<string>> {\n try {\n const stat = await fs.stat(this.#path);\n if (!stat.isDirectory()) {\n await fs.rm(this.#path);\n return new Set();\n }\n } catch (error) {\n if (error.code === 'ENOENT') {\n return new Set();\n }\n throw error;\n }\n\n const items = await fs.readdir(this.#path);\n\n const returned = new Set<string>();\n const removed = new Set<string>();\n\n const now = Date.now();\n\n for (const item of items) {\n const split = item.split('_');\n if (split.length !== 2) {\n removed.add(item);\n continue;\n }\n const createdAt = parseInt(split[0], 10);\n if (Number.isNaN(createdAt) || now - createdAt > CACHE_MAX_AGE_MS) {\n removed.add(item);\n } else {\n returned.add(split[1]);\n }\n }\n\n for (const item of removed) {\n await fs.unlink(resolvePath(this.#path, item));\n }\n\n return returned;\n }\n\n async write(newEntries: Iterable<string>): Promise<void> {\n const now = Date.now();\n\n await fs.ensureDir(this.#path);\n\n const existingItems = await fs.readdir(this.#path);\n\n const empty = Buffer.alloc(0);\n for (const key of newEntries) {\n const trimmedItems = existingItems.filter(item =>\n item.endsWith(`_${key}`),\n );\n for (const trimmedItem of trimmedItems) {\n await fs.unlink(resolvePath(this.#path, trimmedItem));\n }\n\n await fs.writeFile(resolvePath(this.#path, `${now}_${key}`), empty);\n }\n }\n}\n"],"names":["targetPaths","resolvePath","fs"],"mappings":"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"} |
| 'use strict'; | ||
| var fs = require('fs-extra'); | ||
| var path = require('node:path'); | ||
| var yaml = require('yaml'); | ||
| var z = require('zod'); | ||
| var cliCommon = require('@backstage/cli-common'); | ||
| function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } | ||
| var fs__default = /*#__PURE__*/_interopDefaultCompat(fs); | ||
| var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml); | ||
| var z__default = /*#__PURE__*/_interopDefaultCompat(z); | ||
| const yarnRcSchema = z__default.default.object({ | ||
| plugins: z__default.default.array( | ||
| z__default.default.object({ | ||
| path: z__default.default.string() | ||
| }) | ||
| ).optional() | ||
| }); | ||
| async function hasBackstageYarnPlugin(workspaceDir) { | ||
| const yarnRcPath = path.resolve( | ||
| workspaceDir ?? cliCommon.targetPaths.rootDir, | ||
| ".yarnrc.yml" | ||
| ); | ||
| const yarnRcContent = await fs__default.default.readFile(yarnRcPath, "utf-8").catch((e) => { | ||
| if (e.code === "ENOENT") { | ||
| return ""; | ||
| } | ||
| throw e; | ||
| }); | ||
| if (!yarnRcContent) { | ||
| return false; | ||
| } | ||
| const parseResult = yarnRcSchema.safeParse(yaml__default.default.parse(yarnRcContent)); | ||
| if (!parseResult.success) { | ||
| throw new Error( | ||
| `Unexpected content in .yarnrc.yml: ${parseResult.error.toString()}` | ||
| ); | ||
| } | ||
| const yarnRc = parseResult.data; | ||
| const backstagePlugin = yarnRc.plugins?.some( | ||
| (plugin) => plugin.path === ".yarn/plugins/@yarnpkg/plugin-backstage.cjs" | ||
| ); | ||
| return Boolean(backstagePlugin); | ||
| } | ||
| exports.hasBackstageYarnPlugin = hasBackstageYarnPlugin; | ||
| //# sourceMappingURL=yarnPlugin.cjs.js.map |
| {"version":3,"file":"yarnPlugin.cjs.js","sources":["../../src/yarn/yarnPlugin.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs-extra';\nimport { resolve as resolvePath } from 'node:path';\nimport yaml from 'yaml';\nimport z from 'zod';\nimport { targetPaths } from '@backstage/cli-common';\n\nconst yarnRcSchema = z.object({\n plugins: z\n .array(\n z.object({\n path: z.string(),\n }),\n )\n .optional(),\n});\n\n/**\n * Detects whether the Backstage Yarn plugin is installed in the given workspace directory.\n *\n * @param workspaceDir - The workspace root directory to check. Defaults to the target root.\n * @returns Promise resolving to true if the plugin is installed, false otherwise\n * @public\n */\nexport async function hasBackstageYarnPlugin(\n workspaceDir?: string,\n): Promise<boolean> {\n const yarnRcPath = resolvePath(\n workspaceDir ?? targetPaths.rootDir,\n '.yarnrc.yml',\n );\n const yarnRcContent = await fs.readFile(yarnRcPath, 'utf-8').catch(e => {\n if (e.code === 'ENOENT') {\n return '';\n }\n throw e;\n });\n\n if (!yarnRcContent) {\n return false;\n }\n\n const parseResult = yarnRcSchema.safeParse(yaml.parse(yarnRcContent));\n\n if (!parseResult.success) {\n throw new Error(\n `Unexpected content in .yarnrc.yml: ${parseResult.error.toString()}`,\n );\n }\n\n const yarnRc = parseResult.data;\n\n const backstagePlugin = yarnRc.plugins?.some(\n plugin => plugin.path === '.yarn/plugins/@yarnpkg/plugin-backstage.cjs',\n );\n\n return Boolean(backstagePlugin);\n}\n"],"names":["z","resolvePath","targetPaths","fs","yaml"],"mappings":";;;;;;;;;;;;;;AAsBA,MAAM,YAAA,GAAeA,mBAAE,MAAA,CAAO;AAAA,EAC5B,SAASA,kBAAA,CACN,KAAA;AAAA,IACCA,mBAAE,MAAA,CAAO;AAAA,MACP,IAAA,EAAMA,mBAAE,MAAA;AAAO,KAChB;AAAA,IAEF,QAAA;AACL,CAAC,CAAA;AASD,eAAsB,uBACpB,YAAA,EACkB;AAClB,EAAA,MAAM,UAAA,GAAaC,YAAA;AAAA,IACjB,gBAAgBC,qBAAA,CAAY,OAAA;AAAA,IAC5B;AAAA,GACF;AACA,EAAA,MAAM,aAAA,GAAgB,MAAMC,mBAAA,CAAG,QAAA,CAAS,YAAY,OAAO,CAAA,CAAE,MAAM,CAAA,CAAA,KAAK;AACtE,IAAA,IAAI,CAAA,CAAE,SAAS,QAAA,EAAU;AACvB,MAAA,OAAO,EAAA;AAAA,IACT;AACA,IAAA,MAAM,CAAA;AAAA,EACR,CAAC,CAAA;AAED,EAAA,IAAI,CAAC,aAAA,EAAe;AAClB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAc,YAAA,CAAa,SAAA,CAAUC,qBAAA,CAAK,KAAA,CAAM,aAAa,CAAC,CAAA;AAEpE,EAAA,IAAI,CAAC,YAAY,OAAA,EAAS;AACxB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,mCAAA,EAAsC,WAAA,CAAY,KAAA,CAAM,QAAA,EAAU,CAAA;AAAA,KACpE;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,WAAA,CAAY,IAAA;AAE3B,EAAA,MAAM,eAAA,GAAkB,OAAO,OAAA,EAAS,IAAA;AAAA,IACtC,CAAA,MAAA,KAAU,OAAO,IAAA,KAAS;AAAA,GAC5B;AAEA,EAAA,OAAO,QAAQ,eAAe,CAAA;AAChC;;;;"} |
+12
-0
| # @backstage/cli-node | ||
| ## 0.2.19-next.1 | ||
| ### Patch Changes | ||
| - 61cb976: Added `toString()` method to `Lockfile` for serializing lockfiles back to string format. | ||
| - 3c811bf: Added `hasBackstageYarnPlugin` and `SuccessCache` exports, moved from `@backstage/cli`. | ||
| - a9d23c4: Properly support `package.json` `workspaces` field | ||
| - Updated dependencies | ||
| - @backstage/cli-common@0.2.0-next.1 | ||
| - @backstage/errors@1.2.7 | ||
| - @backstage/types@1.2.2 | ||
| ## 0.2.19-next.0 | ||
@@ -4,0 +16,0 @@ |
| 'use strict'; | ||
| var SuccessCache = require('./cache/SuccessCache.cjs.js'); | ||
| var runConcurrentTasks = require('./concurrency/runConcurrentTasks.cjs.js'); | ||
| var runWorkerQueueThreads = require('./concurrency/runWorkerQueueThreads.cjs.js'); | ||
| var GitUtils = require('./git/GitUtils.cjs.js'); | ||
@@ -7,8 +10,10 @@ var isMonoRepo = require('./monorepo/isMonoRepo.cjs.js'); | ||
| var Lockfile = require('./monorepo/Lockfile.cjs.js'); | ||
| var runConcurrentTasks = require('./concurrency/runConcurrentTasks.cjs.js'); | ||
| var runWorkerQueueThreads = require('./concurrency/runWorkerQueueThreads.cjs.js'); | ||
| var PackageRoles = require('./roles/PackageRoles.cjs.js'); | ||
| var yarnPlugin = require('./yarn/yarnPlugin.cjs.js'); | ||
| exports.SuccessCache = SuccessCache.SuccessCache; | ||
| exports.runConcurrentTasks = runConcurrentTasks.runConcurrentTasks; | ||
| exports.runWorkerQueueThreads = runWorkerQueueThreads.runWorkerQueueThreads; | ||
| exports.GitUtils = GitUtils.GitUtils; | ||
@@ -19,5 +24,4 @@ exports.isMonoRepo = isMonoRepo.isMonoRepo; | ||
| exports.Lockfile = Lockfile.Lockfile; | ||
| exports.runConcurrentTasks = runConcurrentTasks.runConcurrentTasks; | ||
| exports.runWorkerQueueThreads = runWorkerQueueThreads.runWorkerQueueThreads; | ||
| exports.PackageRoles = PackageRoles.PackageRoles; | ||
| exports.hasBackstageYarnPlugin = yarnPlugin.hasBackstageYarnPlugin; | ||
| //# sourceMappingURL=index.cjs.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"} | ||
| {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"} |
+95
-55
@@ -5,2 +5,83 @@ import { Package } from '@manypkg/get-packages'; | ||
| /** | ||
| * A file-system-based cache that tracks successful operations by storing | ||
| * timestamped marker files. | ||
| * | ||
| * @public | ||
| */ | ||
| declare class SuccessCache { | ||
| #private; | ||
| /** | ||
| * Trim any occurrences of the workspace root path from the input string. This | ||
| * is useful to ensure stable hashes that don't vary based on the workspace | ||
| * location. | ||
| */ | ||
| static trimPaths(input: string): string; | ||
| static create(options: { | ||
| name: string; | ||
| basePath?: string; | ||
| }): SuccessCache; | ||
| private constructor(); | ||
| read(): Promise<Set<string>>; | ||
| write(newEntries: Iterable<string>): Promise<void>; | ||
| } | ||
| /** | ||
| * Options for {@link runConcurrentTasks}. | ||
| * | ||
| * @public | ||
| */ | ||
| type ConcurrentTasksOptions<TItem> = { | ||
| /** | ||
| * Decides the number of concurrent workers by multiplying | ||
| * this with the configured concurrency. | ||
| * | ||
| * Defaults to 1. | ||
| */ | ||
| concurrencyFactor?: number; | ||
| items: Iterable<TItem>; | ||
| worker: (item: TItem) => Promise<void>; | ||
| }; | ||
| /** | ||
| * Runs items through a worker function concurrently across multiple async workers. | ||
| * | ||
| * @public | ||
| */ | ||
| declare function runConcurrentTasks<TItem>(options: ConcurrentTasksOptions<TItem>): Promise<void>; | ||
| /** | ||
| * Options for {@link runWorkerQueueThreads}. | ||
| * | ||
| * @public | ||
| */ | ||
| type WorkerQueueThreadsOptions<TItem, TResult, TContext> = { | ||
| /** The items to process */ | ||
| items: Iterable<TItem>; | ||
| /** | ||
| * A function that will be called within each worker thread at startup, | ||
| * which should return the worker function that will be called for each item. | ||
| * | ||
| * This function must be defined as an arrow function or using the | ||
| * function keyword, and must be entirely self contained, not referencing | ||
| * any variables outside of its scope. This is because the function source | ||
| * is stringified and evaluated in the worker thread. | ||
| * | ||
| * To pass data to the worker, use the `context` option and `items`, but | ||
| * note that they are both copied by value into the worker thread, except for | ||
| * types that are explicitly shareable across threads, such as `SharedArrayBuffer`. | ||
| */ | ||
| workerFactory: (context: TContext) => ((item: TItem) => Promise<TResult>) | Promise<(item: TItem) => Promise<TResult>>; | ||
| /** Context data supplied to each worker factory */ | ||
| context?: TContext; | ||
| }; | ||
| /** | ||
| * Spawns one or more worker threads using the `worker_threads` module. | ||
| * Each thread processes one item at a time from the provided `options.items`. | ||
| * | ||
| * @public | ||
| */ | ||
| declare function runWorkerQueueThreads<TItem, TResult, TContext>(options: WorkerQueueThreadsOptions<TItem, TResult, TContext>): Promise<{ | ||
| results: TResult[]; | ||
| }>; | ||
| /** | ||
| * Utilities for working with git. | ||
@@ -23,4 +104,7 @@ * | ||
| /** | ||
| * Returns try if the current project is a monorepo. | ||
| * Returns true if the current project is a monorepo. | ||
| * | ||
| * Uses a simple presence check on the `workspaces` field. Empty or invalid | ||
| * workspace config is treated as a monorepo; we do not validate patterns. | ||
| * | ||
| * @public | ||
@@ -291,2 +375,3 @@ */ | ||
| private readonly data; | ||
| private readonly legacy; | ||
| private constructor(); | ||
@@ -298,2 +383,6 @@ /** Returns the name of all packages available in the lockfile */ | ||
| /** | ||
| * Serialize the lockfile back to a string. | ||
| */ | ||
| toString(): string; | ||
| /** | ||
| * Creates a simplified dependency graph from the lockfile data, where each | ||
@@ -316,60 +405,11 @@ * key is a package, and the value is a set of all packages that it depends on | ||
| /** | ||
| * Options for {@link runConcurrentTasks}. | ||
| * Detects whether the Backstage Yarn plugin is installed in the given workspace directory. | ||
| * | ||
| * @param workspaceDir - The workspace root directory to check. Defaults to the target root. | ||
| * @returns Promise resolving to true if the plugin is installed, false otherwise | ||
| * @public | ||
| */ | ||
| type ConcurrentTasksOptions<TItem> = { | ||
| /** | ||
| * Decides the number of concurrent workers by multiplying | ||
| * this with the configured concurrency. | ||
| * | ||
| * Defaults to 1. | ||
| */ | ||
| concurrencyFactor?: number; | ||
| items: Iterable<TItem>; | ||
| worker: (item: TItem) => Promise<void>; | ||
| }; | ||
| /** | ||
| * Runs items through a worker function concurrently across multiple async workers. | ||
| * | ||
| * @public | ||
| */ | ||
| declare function runConcurrentTasks<TItem>(options: ConcurrentTasksOptions<TItem>): Promise<void>; | ||
| declare function hasBackstageYarnPlugin(workspaceDir?: string): Promise<boolean>; | ||
| /** | ||
| * Options for {@link runWorkerQueueThreads}. | ||
| * | ||
| * @public | ||
| */ | ||
| type WorkerQueueThreadsOptions<TItem, TResult, TContext> = { | ||
| /** The items to process */ | ||
| items: Iterable<TItem>; | ||
| /** | ||
| * A function that will be called within each worker thread at startup, | ||
| * which should return the worker function that will be called for each item. | ||
| * | ||
| * This function must be defined as an arrow function or using the | ||
| * function keyword, and must be entirely self contained, not referencing | ||
| * any variables outside of its scope. This is because the function source | ||
| * is stringified and evaluated in the worker thread. | ||
| * | ||
| * To pass data to the worker, use the `context` option and `items`, but | ||
| * note that they are both copied by value into the worker thread, except for | ||
| * types that are explicitly shareable across threads, such as `SharedArrayBuffer`. | ||
| */ | ||
| workerFactory: (context: TContext) => ((item: TItem) => Promise<TResult>) | Promise<(item: TItem) => Promise<TResult>>; | ||
| /** Context data supplied to each worker factory */ | ||
| context?: TContext; | ||
| }; | ||
| /** | ||
| * Spawns one or more worker threads using the `worker_threads` module. | ||
| * Each thread processes one item at a time from the provided `options.items`. | ||
| * | ||
| * @public | ||
| */ | ||
| declare function runWorkerQueueThreads<TItem, TResult, TContext>(options: WorkerQueueThreadsOptions<TItem, TResult, TContext>): Promise<{ | ||
| results: TResult[]; | ||
| }>; | ||
| export { GitUtils, Lockfile, PackageGraph, PackageRoles, isMonoRepo, packageFeatureType, runConcurrentTasks, runWorkerQueueThreads }; | ||
| export { GitUtils, Lockfile, PackageGraph, PackageRoles, SuccessCache, hasBackstageYarnPlugin, isMonoRepo, packageFeatureType, runConcurrentTasks, runWorkerQueueThreads }; | ||
| export type { BackstagePackage, BackstagePackageFeatureType, BackstagePackageJson, ConcurrentTasksOptions, LockfileDiff, LockfileDiffEntry, LockfileQueryEntry, PackageGraphNode, PackageOutputType, PackagePlatform, PackageRole, PackageRoleInfo, WorkerQueueThreadsOptions }; |
@@ -14,3 +14,3 @@ 'use strict'; | ||
| const pkg = await fs__default.default.readJson(rootPackageJsonPath); | ||
| return Boolean(pkg?.workspaces?.packages); | ||
| return Boolean(pkg?.workspaces); | ||
| } catch (error) { | ||
@@ -17,0 +17,0 @@ return false; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"isMonoRepo.cjs.js","sources":["../../src/monorepo/isMonoRepo.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { targetPaths } from '@backstage/cli-common';\nimport fs from 'fs-extra';\n\n/**\n * Returns try if the current project is a monorepo.\n *\n * @public\n */\nexport async function isMonoRepo(): Promise<boolean> {\n const rootPackageJsonPath = targetPaths.resolveRoot('package.json');\n try {\n const pkg = await fs.readJson(rootPackageJsonPath);\n return Boolean(pkg?.workspaces?.packages);\n } catch (error) {\n return false;\n }\n}\n"],"names":["targetPaths","fs"],"mappings":";;;;;;;;;AAwBA,eAAsB,UAAA,GAA+B;AACnD,EAAA,MAAM,mBAAA,GAAsBA,qBAAA,CAAY,WAAA,CAAY,cAAc,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAMC,mBAAA,CAAG,QAAA,CAAS,mBAAmB,CAAA;AACjD,IAAA,OAAO,OAAA,CAAQ,GAAA,EAAK,UAAA,EAAY,QAAQ,CAAA;AAAA,EAC1C,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;;"} | ||
| {"version":3,"file":"isMonoRepo.cjs.js","sources":["../../src/monorepo/isMonoRepo.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { targetPaths } from '@backstage/cli-common';\nimport fs from 'fs-extra';\n\n/**\n * Returns true if the current project is a monorepo.\n *\n * Uses a simple presence check on the `workspaces` field. Empty or invalid\n * workspace config is treated as a monorepo; we do not validate patterns.\n *\n * @public\n */\nexport async function isMonoRepo(): Promise<boolean> {\n const rootPackageJsonPath = targetPaths.resolveRoot('package.json');\n try {\n const pkg = await fs.readJson(rootPackageJsonPath);\n return Boolean(pkg?.workspaces);\n } catch (error) {\n return false;\n }\n}\n"],"names":["targetPaths","fs"],"mappings":";;;;;;;;;AA2BA,eAAsB,UAAA,GAA+B;AACnD,EAAA,MAAM,mBAAA,GAAsBA,qBAAA,CAAY,WAAA,CAAY,cAAc,CAAA;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAMC,mBAAA,CAAG,QAAA,CAAS,mBAAmB,CAAA;AACjD,IAAA,OAAO,OAAA,CAAQ,KAAK,UAAU,CAAA;AAAA,EAChC,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;;"} |
| 'use strict'; | ||
| var parsers = require('@yarnpkg/parsers'); | ||
| var lockfile = require('@yarnpkg/lockfile'); | ||
| var crypto = require('node:crypto'); | ||
@@ -13,2 +14,10 @@ var fs = require('fs-extra'); | ||
| const ENTRY_PATTERN = /^((?:@[^/]+\/)?[^@/]+)@(.+)$/; | ||
| const NEW_HEADER = `${[ | ||
| `# This file is generated by running "yarn install" inside your project. | ||
| `, | ||
| `# Manual changes might be lost - proceed with caution! | ||
| ` | ||
| ].join(``)} | ||
| `; | ||
| const LEGACY_REGEX = /^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i; | ||
| const SPECIAL_OBJECT_KEYS = [ | ||
@@ -38,2 +47,3 @@ `__metadata`, | ||
| static parse(content) { | ||
| const legacy = LEGACY_REGEX.test(content); | ||
| let data; | ||
@@ -67,9 +77,11 @@ try { | ||
| } | ||
| return new Lockfile(packages, data); | ||
| return new Lockfile(packages, data, legacy); | ||
| } | ||
| packages; | ||
| data; | ||
| constructor(packages, data) { | ||
| legacy; | ||
| constructor(packages, data, legacy = false) { | ||
| this.packages = packages; | ||
| this.data = data; | ||
| this.legacy = legacy; | ||
| } | ||
@@ -85,2 +97,8 @@ /** Returns the name of all packages available in the lockfile */ | ||
| /** | ||
| * Serialize the lockfile back to a string. | ||
| */ | ||
| toString() { | ||
| return this.legacy ? lockfile.stringify(this.data) : NEW_HEADER + parsers.stringifySyml(this.data); | ||
| } | ||
| /** | ||
| * Creates a simplified dependency graph from the lockfile data, where each | ||
@@ -87,0 +105,0 @@ * key is a package, and the value is a set of all packages that it depends on |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"Lockfile.cjs.js","sources":["../../src/monorepo/Lockfile.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseSyml } from '@yarnpkg/parsers';\nimport crypto from 'node:crypto';\nimport fs from 'fs-extra';\n\nconst ENTRY_PATTERN = /^((?:@[^/]+\\/)?[^@/]+)@(.+)$/;\n\n/** @internal */\ntype LockfileData = {\n [entry: string]: {\n version: string;\n resolved?: string;\n integrity?: string /* old */;\n checksum?: string /* new */;\n dependencies?: { [name: string]: string };\n peerDependencies?: { [name: string]: string };\n };\n};\n\n/**\n * A single entry in a {@link Lockfile}.\n *\n * @public\n */\nexport type LockfileQueryEntry = {\n range: string;\n version: string;\n dataKey: string;\n};\n\n/**\n * An entry for a single difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiffEntry = {\n name: string;\n range: string;\n};\n\n/**\n * Represents the difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiff = {\n added: LockfileDiffEntry[];\n changed: LockfileDiffEntry[];\n removed: LockfileDiffEntry[];\n};\n\n// these are special top level yarn keys.\n// https://github.com/yarnpkg/berry/blob/9bd61fbffb83d0b8166a9cc26bec3a58743aa453/packages/yarnpkg-parsers/sources/syml.ts#L9\nconst SPECIAL_OBJECT_KEYS = [\n `__metadata`,\n `version`,\n `resolution`,\n `dependencies`,\n `peerDependencies`,\n `dependenciesMeta`,\n `peerDependenciesMeta`,\n `binaries`,\n];\n\n/**\n * Represents a package manager lockfile.\n *\n * @public\n */\nexport class Lockfile {\n /**\n * Load a {@link Lockfile} from a file path.\n */\n static async load(path: string): Promise<Lockfile> {\n const lockfileContents = await fs.readFile(path, 'utf8');\n return Lockfile.parse(lockfileContents);\n }\n\n /**\n * Parse lockfile contents into a {@link Lockfile}.\n *\n * @public\n */\n static parse(content: string): Lockfile {\n let data: LockfileData;\n try {\n data = parseSyml(content);\n } catch (err) {\n throw new Error(`Failed yarn.lock parse, ${err}`);\n }\n\n const packages = new Map<string, LockfileQueryEntry[]>();\n\n for (const [key, value] of Object.entries(data)) {\n if (SPECIAL_OBJECT_KEYS.includes(key)) continue;\n\n const [, name, ranges] = ENTRY_PATTERN.exec(key) ?? [];\n if (!name) {\n throw new Error(`Failed to parse yarn.lock entry '${key}'`);\n }\n\n let queries = packages.get(name);\n if (!queries) {\n queries = [];\n packages.set(name, queries);\n }\n for (let range of ranges.split(/\\s*,\\s*/)) {\n if (range.startsWith(`${name}@`)) {\n range = range.slice(`${name}@`.length);\n }\n if (range.startsWith('npm:')) {\n range = range.slice('npm:'.length);\n }\n queries.push({ range, version: value.version, dataKey: key });\n }\n }\n\n return new Lockfile(packages, data);\n }\n\n private readonly packages: Map<string, LockfileQueryEntry[]>;\n private readonly data: LockfileData;\n\n private constructor(\n packages: Map<string, LockfileQueryEntry[]>,\n data: LockfileData,\n ) {\n this.packages = packages;\n this.data = data;\n }\n\n /** Returns the name of all packages available in the lockfile */\n get(name: string): LockfileQueryEntry[] | undefined {\n return this.packages.get(name);\n }\n\n /** Get the entries for a single package in the lockfile */\n keys(): IterableIterator<string> {\n return this.packages.keys();\n }\n\n /**\n * Creates a simplified dependency graph from the lockfile data, where each\n * key is a package, and the value is a set of all packages that it depends on\n * across all versions.\n */\n createSimplifiedDependencyGraph(): Map<string, Set<string>> {\n const graph = new Map<string, Set<string>>();\n\n for (const [name, entries] of this.packages) {\n const dependencies = new Set(\n entries.flatMap(e => {\n const data = this.data[e.dataKey];\n return [\n ...Object.keys(data?.dependencies ?? {}),\n ...Object.keys(data?.peerDependencies ?? {}),\n ];\n }),\n );\n graph.set(name, dependencies);\n }\n\n return graph;\n }\n\n /**\n * Diff with another lockfile, returning entries that have been\n * added, changed, and removed compared to the other lockfile.\n */\n diff(otherLockfile: Lockfile): LockfileDiff {\n const diff = {\n added: new Array<{ name: string; range: string }>(),\n changed: new Array<{ name: string; range: string }>(),\n removed: new Array<{ name: string; range: string }>(),\n };\n\n // Keeps track of packages that only exist in this lockfile\n const remainingOldNames = new Set(this.packages.keys());\n\n for (const [name, otherQueries] of otherLockfile.packages) {\n remainingOldNames.delete(name);\n\n const thisQueries = this.packages.get(name);\n // If the packages doesn't exist in this lockfile, add all entries\n if (!thisQueries) {\n diff.removed.push(...otherQueries.map(q => ({ name, range: q.range })));\n continue;\n }\n\n const remainingOldRanges = new Set(thisQueries.map(q => q.range));\n\n for (const otherQuery of otherQueries) {\n remainingOldRanges.delete(otherQuery.range);\n\n const thisQuery = thisQueries.find(q => q.range === otherQuery.range);\n if (!thisQuery) {\n diff.removed.push({ name, range: otherQuery.range });\n continue;\n }\n\n const otherPkg = otherLockfile.data[otherQuery.dataKey];\n const thisPkg = this.data[thisQuery.dataKey];\n if (otherPkg && thisPkg) {\n const thisCheck = thisPkg.integrity || thisPkg.checksum;\n const otherCheck = otherPkg.integrity || otherPkg.checksum;\n if (thisCheck !== otherCheck) {\n diff.changed.push({ name, range: otherQuery.range });\n }\n }\n }\n\n for (const thisRange of remainingOldRanges) {\n diff.added.push({ name, range: thisRange });\n }\n }\n\n for (const name of remainingOldNames) {\n const queries = this.packages.get(name) ?? [];\n diff.added.push(...queries.map(q => ({ name, range: q.range })));\n }\n\n return diff;\n }\n\n /**\n * Generates a sha1 hex hash of the dependency graph for a package.\n */\n getDependencyTreeHash(startName: string): string {\n if (!this.packages.has(startName)) {\n throw new Error(`Package '${startName}' not found in lockfile`);\n }\n\n const hash = crypto.createHash('sha1');\n\n const queue = [startName];\n const seen = new Set<string>();\n\n while (queue.length > 0) {\n const name = queue.pop()!;\n\n if (seen.has(name)) {\n continue;\n }\n seen.add(name);\n\n const entries = this.packages.get(name);\n if (!entries) {\n continue; // In case of missing optional peer dependencies\n }\n\n hash.update(`pkg:${name}`);\n hash.update('\\0');\n\n // TODO(Rugvip): This uses the same simplified lookup as createSimplifiedDependencyGraph()\n // we could match version queries to make the resulting tree a bit smaller.\n const deps = new Array<string>();\n for (const entry of entries) {\n // We're not being particular about stable ordering here. If the lockfile ordering changes, so will likely hash.\n hash.update(entry.version);\n\n const data = this.data[entry.dataKey];\n if (!data) {\n continue;\n }\n\n const checksum = data.checksum || data.integrity;\n if (checksum) {\n hash.update('#');\n hash.update(checksum);\n }\n\n hash.update(' ');\n\n deps.push(...Object.keys(data.dependencies ?? {}));\n deps.push(...Object.keys(data.peerDependencies ?? {}));\n }\n\n queue.push(...new Set(deps));\n }\n\n return hash.digest('hex');\n }\n}\n"],"names":["fs","parseSyml","crypto"],"mappings":";;;;;;;;;;;AAoBA,MAAM,aAAA,GAAgB,8BAAA;AAgDtB,MAAM,mBAAA,GAAsB;AAAA,EAC1B,CAAA,UAAA,CAAA;AAAA,EACA,CAAA,OAAA,CAAA;AAAA,EACA,CAAA,UAAA,CAAA;AAAA,EACA,CAAA,YAAA,CAAA;AAAA,EACA,CAAA,gBAAA,CAAA;AAAA,EACA,CAAA,gBAAA,CAAA;AAAA,EACA,CAAA,oBAAA,CAAA;AAAA,EACA,CAAA,QAAA;AACF,CAAA;AAOO,MAAM,QAAA,CAAS;AAAA;AAAA;AAAA;AAAA,EAIpB,aAAa,KAAK,IAAA,EAAiC;AACjD,IAAA,MAAM,gBAAA,GAAmB,MAAMA,mBAAA,CAAG,QAAA,CAAS,MAAM,MAAM,CAAA;AACvD,IAAA,OAAO,QAAA,CAAS,MAAM,gBAAgB,CAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,MAAM,OAAA,EAA2B;AACtC,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAOC,kBAAU,OAAO,CAAA;AAAA,IAC1B,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAG,CAAA,CAAE,CAAA;AAAA,IAClD;AAEA,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAkC;AAEvD,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AAC/C,MAAA,IAAI,mBAAA,CAAoB,QAAA,CAAS,GAAG,CAAA,EAAG;AAEvC,MAAA,MAAM,GAAG,IAAA,EAAM,MAAM,IAAI,aAAA,CAAc,IAAA,CAAK,GAAG,CAAA,IAAK,EAAC;AACrD,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,GAAG,CAAA,CAAA,CAAG,CAAA;AAAA,MAC5D;AAEA,MAAA,IAAI,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC/B,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAA,GAAU,EAAC;AACX,QAAA,QAAA,CAAS,GAAA,CAAI,MAAM,OAAO,CAAA;AAAA,MAC5B;AACA,MAAA,KAAA,IAAS,KAAA,IAAS,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACzC,QAAA,IAAI,KAAA,CAAM,UAAA,CAAW,CAAA,EAAG,IAAI,GAAG,CAAA,EAAG;AAChC,UAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,IAAI,IAAI,MAAM,CAAA;AAAA,QACvC;AACA,QAAA,IAAI,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,EAAG;AAC5B,UAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA;AAAA,QACnC;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,KAAA,EAAO,OAAA,EAAS,MAAM,OAAA,EAAS,OAAA,EAAS,KAAK,CAAA;AAAA,MAC9D;AAAA,IACF;AAEA,IAAA,OAAO,IAAI,QAAA,CAAS,QAAA,EAAU,IAAI,CAAA;AAAA,EACpC;AAAA,EAEiB,QAAA;AAAA,EACA,IAAA;AAAA,EAET,WAAA,CACN,UACA,IAAA,EACA;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,IAAA,EAAgD;AAClD,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAAA,EAC/B;AAAA;AAAA,EAGA,IAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,SAAS,IAAA,EAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,+BAAA,GAA4D;AAC1D,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAyB;AAE3C,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,OAAO,CAAA,IAAK,KAAK,QAAA,EAAU;AAC3C,MAAA,MAAM,eAAe,IAAI,GAAA;AAAA,QACvB,OAAA,CAAQ,QAAQ,CAAA,CAAA,KAAK;AACnB,UAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA;AAChC,UAAA,OAAO;AAAA,YACL,GAAG,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,YAAA,IAAgB,EAAE,CAAA;AAAA,YACvC,GAAG,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,gBAAA,IAAoB,EAAE;AAAA,WAC7C;AAAA,QACF,CAAC;AAAA,OACH;AACA,MAAA,KAAA,CAAM,GAAA,CAAI,MAAM,YAAY,CAAA;AAAA,IAC9B;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,aAAA,EAAuC;AAC1C,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,KAAA,EAAO,IAAI,KAAA,EAAuC;AAAA,MAClD,OAAA,EAAS,IAAI,KAAA,EAAuC;AAAA,MACpD,OAAA,EAAS,IAAI,KAAA;AAAuC,KACtD;AAGA,IAAA,MAAM,oBAAoB,IAAI,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA;AAEtD,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,YAAY,CAAA,IAAK,cAAc,QAAA,EAAU;AACzD,MAAA,iBAAA,CAAkB,OAAO,IAAI,CAAA;AAE7B,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAE1C,MAAA,IAAI,CAAC,WAAA,EAAa;AAChB,QAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,GAAG,YAAA,CAAa,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,CAAE,CAAC,CAAA;AACtE,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,kBAAA,GAAqB,IAAI,GAAA,CAAI,WAAA,CAAY,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA;AAEhE,MAAA,KAAA,MAAW,cAAc,YAAA,EAAc;AACrC,QAAA,kBAAA,CAAmB,MAAA,CAAO,WAAW,KAAK,CAAA;AAE1C,QAAA,MAAM,YAAY,WAAA,CAAY,IAAA,CAAK,OAAK,CAAA,CAAE,KAAA,KAAU,WAAW,KAAK,CAAA;AACpE,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,EAAE,MAAM,KAAA,EAAO,UAAA,CAAW,OAAO,CAAA;AACnD,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,QAAA,GAAW,aAAA,CAAc,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA;AACtD,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AAC3C,QAAA,IAAI,YAAY,OAAA,EAAS;AACvB,UAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,IAAa,OAAA,CAAQ,QAAA;AAC/C,UAAA,MAAM,UAAA,GAAa,QAAA,CAAS,SAAA,IAAa,QAAA,CAAS,QAAA;AAClD,UAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,YAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,EAAE,MAAM,KAAA,EAAO,UAAA,CAAW,OAAO,CAAA;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,aAAa,kBAAA,EAAoB;AAC1C,QAAA,IAAA,CAAK,MAAM,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,WAAW,CAAA;AAAA,MAC5C;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,QAAQ,iBAAA,EAAmB;AACpC,MAAA,MAAM,UAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,KAAK,EAAC;AAC5C,MAAA,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAG,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,CAAE,CAAC,CAAA;AAAA,IACjE;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,SAAA,EAA2B;AAC/C,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA,EAAG;AACjC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY,SAAS,CAAA,uBAAA,CAAyB,CAAA;AAAA,IAChE;AAEA,IAAA,MAAM,IAAA,GAAOC,uBAAA,CAAO,UAAA,CAAW,MAAM,CAAA;AAErC,IAAA,MAAM,KAAA,GAAQ,CAAC,SAAS,CAAA;AACxB,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,IAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,EAAI;AAEvB,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AAClB,QAAA;AAAA,MACF;AACA,MAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAEb,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AACtC,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA;AAAA,MACF;AAEA,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,IAAA,EAAO,IAAI,CAAA,CAAE,CAAA;AACzB,MAAA,IAAA,CAAK,OAAO,IAAI,CAAA;AAIhB,MAAA,MAAM,IAAA,GAAO,IAAI,KAAA,EAAc;AAC/B,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAE3B,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,OAAO,CAAA;AAEzB,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACpC,QAAA,IAAI,CAAC,IAAA,EAAM;AACT,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,SAAA;AACvC,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,IAAA,CAAK,OAAO,GAAG,CAAA;AACf,UAAA,IAAA,CAAK,OAAO,QAAQ,CAAA;AAAA,QACtB;AAEA,QAAA,IAAA,CAAK,OAAO,GAAG,CAAA;AAEf,QAAA,IAAA,CAAK,IAAA,CAAK,GAAG,MAAA,CAAO,IAAA,CAAK,KAAK,YAAA,IAAgB,EAAE,CAAC,CAAA;AACjD,QAAA,IAAA,CAAK,IAAA,CAAK,GAAG,MAAA,CAAO,IAAA,CAAK,KAAK,gBAAA,IAAoB,EAAE,CAAC,CAAA;AAAA,MACvD;AAEA,MAAA,KAAA,CAAM,IAAA,CAAK,GAAG,IAAI,GAAA,CAAI,IAAI,CAAC,CAAA;AAAA,IAC7B;AAEA,IAAA,OAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,EAC1B;AACF;;;;"} | ||
| {"version":3,"file":"Lockfile.cjs.js","sources":["../../src/monorepo/Lockfile.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseSyml, stringifySyml } from '@yarnpkg/parsers';\nimport { stringify as legacyStringifyLockfile } from '@yarnpkg/lockfile';\nimport crypto from 'node:crypto';\nimport fs from 'fs-extra';\n\nconst ENTRY_PATTERN = /^((?:@[^/]+\\/)?[^@/]+)@(.+)$/;\n\n// https://github.com/yarnpkg/berry/blob/0c5974f193a9397630e9aee2b3876cca62611149/packages/yarnpkg-core/sources/Project.ts#L1741-L1746\nconst NEW_HEADER = `${[\n `# This file is generated by running \"yarn install\" inside your project.\\n`,\n `# Manual changes might be lost - proceed with caution!\\n`,\n].join(``)}\\n`;\n\n// https://github.com/yarnpkg/berry/blob/0c5974f193a9397630e9aee2b3876cca62611149/packages/yarnpkg-parsers/sources/syml.ts#L136\nconst LEGACY_REGEX = /^(#.*(\\r?\\n))*?#\\s+yarn\\s+lockfile\\s+v1\\r?\\n/i;\n\n/** @internal */\ntype LockfileData = {\n [entry: string]: {\n version: string;\n resolved?: string;\n integrity?: string /* old */;\n checksum?: string /* new */;\n dependencies?: { [name: string]: string };\n peerDependencies?: { [name: string]: string };\n };\n};\n\n/**\n * A single entry in a {@link Lockfile}.\n *\n * @public\n */\nexport type LockfileQueryEntry = {\n range: string;\n version: string;\n dataKey: string;\n};\n\n/**\n * An entry for a single difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiffEntry = {\n name: string;\n range: string;\n};\n\n/**\n * Represents the difference between two {@link Lockfile}s.\n *\n * @public\n */\nexport type LockfileDiff = {\n added: LockfileDiffEntry[];\n changed: LockfileDiffEntry[];\n removed: LockfileDiffEntry[];\n};\n\n// these are special top level yarn keys.\n// https://github.com/yarnpkg/berry/blob/9bd61fbffb83d0b8166a9cc26bec3a58743aa453/packages/yarnpkg-parsers/sources/syml.ts#L9\nconst SPECIAL_OBJECT_KEYS = [\n `__metadata`,\n `version`,\n `resolution`,\n `dependencies`,\n `peerDependencies`,\n `dependenciesMeta`,\n `peerDependenciesMeta`,\n `binaries`,\n];\n\n/**\n * Represents a package manager lockfile.\n *\n * @public\n */\nexport class Lockfile {\n /**\n * Load a {@link Lockfile} from a file path.\n */\n static async load(path: string): Promise<Lockfile> {\n const lockfileContents = await fs.readFile(path, 'utf8');\n return Lockfile.parse(lockfileContents);\n }\n\n /**\n * Parse lockfile contents into a {@link Lockfile}.\n *\n * @public\n */\n static parse(content: string): Lockfile {\n const legacy = LEGACY_REGEX.test(content);\n\n let data: LockfileData;\n try {\n data = parseSyml(content);\n } catch (err) {\n throw new Error(`Failed yarn.lock parse, ${err}`);\n }\n\n const packages = new Map<string, LockfileQueryEntry[]>();\n\n for (const [key, value] of Object.entries(data)) {\n if (SPECIAL_OBJECT_KEYS.includes(key)) continue;\n\n const [, name, ranges] = ENTRY_PATTERN.exec(key) ?? [];\n if (!name) {\n throw new Error(`Failed to parse yarn.lock entry '${key}'`);\n }\n\n let queries = packages.get(name);\n if (!queries) {\n queries = [];\n packages.set(name, queries);\n }\n for (let range of ranges.split(/\\s*,\\s*/)) {\n if (range.startsWith(`${name}@`)) {\n range = range.slice(`${name}@`.length);\n }\n if (range.startsWith('npm:')) {\n range = range.slice('npm:'.length);\n }\n queries.push({ range, version: value.version, dataKey: key });\n }\n }\n\n return new Lockfile(packages, data, legacy);\n }\n\n private readonly packages: Map<string, LockfileQueryEntry[]>;\n private readonly data: LockfileData;\n private readonly legacy: boolean;\n\n private constructor(\n packages: Map<string, LockfileQueryEntry[]>,\n data: LockfileData,\n legacy: boolean = false,\n ) {\n this.packages = packages;\n this.data = data;\n this.legacy = legacy;\n }\n\n /** Returns the name of all packages available in the lockfile */\n get(name: string): LockfileQueryEntry[] | undefined {\n return this.packages.get(name);\n }\n\n /** Get the entries for a single package in the lockfile */\n keys(): IterableIterator<string> {\n return this.packages.keys();\n }\n\n /**\n * Serialize the lockfile back to a string.\n */\n toString(): string {\n return this.legacy\n ? legacyStringifyLockfile(this.data)\n : NEW_HEADER + stringifySyml(this.data);\n }\n\n /**\n * Creates a simplified dependency graph from the lockfile data, where each\n * key is a package, and the value is a set of all packages that it depends on\n * across all versions.\n */\n createSimplifiedDependencyGraph(): Map<string, Set<string>> {\n const graph = new Map<string, Set<string>>();\n\n for (const [name, entries] of this.packages) {\n const dependencies = new Set(\n entries.flatMap(e => {\n const data = this.data[e.dataKey];\n return [\n ...Object.keys(data?.dependencies ?? {}),\n ...Object.keys(data?.peerDependencies ?? {}),\n ];\n }),\n );\n graph.set(name, dependencies);\n }\n\n return graph;\n }\n\n /**\n * Diff with another lockfile, returning entries that have been\n * added, changed, and removed compared to the other lockfile.\n */\n diff(otherLockfile: Lockfile): LockfileDiff {\n const diff = {\n added: new Array<{ name: string; range: string }>(),\n changed: new Array<{ name: string; range: string }>(),\n removed: new Array<{ name: string; range: string }>(),\n };\n\n // Keeps track of packages that only exist in this lockfile\n const remainingOldNames = new Set(this.packages.keys());\n\n for (const [name, otherQueries] of otherLockfile.packages) {\n remainingOldNames.delete(name);\n\n const thisQueries = this.packages.get(name);\n // If the packages doesn't exist in this lockfile, add all entries\n if (!thisQueries) {\n diff.removed.push(...otherQueries.map(q => ({ name, range: q.range })));\n continue;\n }\n\n const remainingOldRanges = new Set(thisQueries.map(q => q.range));\n\n for (const otherQuery of otherQueries) {\n remainingOldRanges.delete(otherQuery.range);\n\n const thisQuery = thisQueries.find(q => q.range === otherQuery.range);\n if (!thisQuery) {\n diff.removed.push({ name, range: otherQuery.range });\n continue;\n }\n\n const otherPkg = otherLockfile.data[otherQuery.dataKey];\n const thisPkg = this.data[thisQuery.dataKey];\n if (otherPkg && thisPkg) {\n const thisCheck = thisPkg.integrity || thisPkg.checksum;\n const otherCheck = otherPkg.integrity || otherPkg.checksum;\n if (thisCheck !== otherCheck) {\n diff.changed.push({ name, range: otherQuery.range });\n }\n }\n }\n\n for (const thisRange of remainingOldRanges) {\n diff.added.push({ name, range: thisRange });\n }\n }\n\n for (const name of remainingOldNames) {\n const queries = this.packages.get(name) ?? [];\n diff.added.push(...queries.map(q => ({ name, range: q.range })));\n }\n\n return diff;\n }\n\n /**\n * Generates a sha1 hex hash of the dependency graph for a package.\n */\n getDependencyTreeHash(startName: string): string {\n if (!this.packages.has(startName)) {\n throw new Error(`Package '${startName}' not found in lockfile`);\n }\n\n const hash = crypto.createHash('sha1');\n\n const queue = [startName];\n const seen = new Set<string>();\n\n while (queue.length > 0) {\n const name = queue.pop()!;\n\n if (seen.has(name)) {\n continue;\n }\n seen.add(name);\n\n const entries = this.packages.get(name);\n if (!entries) {\n continue; // In case of missing optional peer dependencies\n }\n\n hash.update(`pkg:${name}`);\n hash.update('\\0');\n\n // TODO(Rugvip): This uses the same simplified lookup as createSimplifiedDependencyGraph()\n // we could match version queries to make the resulting tree a bit smaller.\n const deps = new Array<string>();\n for (const entry of entries) {\n // We're not being particular about stable ordering here. If the lockfile ordering changes, so will likely hash.\n hash.update(entry.version);\n\n const data = this.data[entry.dataKey];\n if (!data) {\n continue;\n }\n\n const checksum = data.checksum || data.integrity;\n if (checksum) {\n hash.update('#');\n hash.update(checksum);\n }\n\n hash.update(' ');\n\n deps.push(...Object.keys(data.dependencies ?? {}));\n deps.push(...Object.keys(data.peerDependencies ?? {}));\n }\n\n queue.push(...new Set(deps));\n }\n\n return hash.digest('hex');\n }\n}\n"],"names":["fs","parseSyml","legacyStringifyLockfile","stringifySyml","crypto"],"mappings":"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"} |
| 'use strict'; | ||
| var zod = require('zod'); | ||
| var z = require('zod'); | ||
@@ -63,22 +63,22 @@ const packageRoleInfos = [ | ||
| ]; | ||
| const readSchema = zod.z.object({ | ||
| name: zod.z.string().optional(), | ||
| backstage: zod.z.object({ | ||
| role: zod.z.string().optional() | ||
| const readSchema = z.z.object({ | ||
| name: z.z.string().optional(), | ||
| backstage: z.z.object({ | ||
| role: z.z.string().optional() | ||
| }).optional() | ||
| }); | ||
| const detectionSchema = zod.z.object({ | ||
| name: zod.z.string().optional(), | ||
| scripts: zod.z.object({ | ||
| start: zod.z.string().optional(), | ||
| build: zod.z.string().optional() | ||
| const detectionSchema = z.z.object({ | ||
| name: z.z.string().optional(), | ||
| scripts: z.z.object({ | ||
| start: z.z.string().optional(), | ||
| build: z.z.string().optional() | ||
| }).optional(), | ||
| publishConfig: zod.z.object({ | ||
| main: zod.z.string().optional(), | ||
| types: zod.z.string().optional(), | ||
| module: zod.z.string().optional() | ||
| publishConfig: z.z.object({ | ||
| main: z.z.string().optional(), | ||
| types: z.z.string().optional(), | ||
| module: z.z.string().optional() | ||
| }).optional(), | ||
| main: zod.z.string().optional(), | ||
| types: zod.z.string().optional(), | ||
| module: zod.z.string().optional() | ||
| main: z.z.string().optional(), | ||
| types: z.z.string().optional(), | ||
| module: z.z.string().optional() | ||
| }); | ||
@@ -85,0 +85,0 @@ class PackageRoles { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"PackageRoles.cjs.js","sources":["../../src/roles/PackageRoles.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from 'zod';\nimport { PackageRole, PackageRoleInfo } from './types';\n\nconst packageRoleInfos: PackageRoleInfo[] = [\n {\n role: 'frontend',\n platform: 'web',\n output: ['bundle'],\n },\n {\n role: 'backend',\n platform: 'node',\n output: ['bundle'],\n },\n {\n role: 'cli',\n platform: 'node',\n output: ['cjs'],\n },\n {\n role: 'web-library',\n platform: 'web',\n output: ['types', 'esm'],\n },\n {\n role: 'node-library',\n platform: 'node',\n output: ['types', 'cjs'],\n },\n {\n role: 'common-library',\n platform: 'common',\n output: ['types', 'esm', 'cjs'],\n },\n {\n role: 'frontend-plugin',\n platform: 'web',\n output: ['types', 'esm'],\n },\n {\n role: 'frontend-plugin-module',\n platform: 'web',\n output: ['types', 'esm'],\n },\n {\n role: 'frontend-dynamic-container' as PackageRole, // experimental\n platform: 'web',\n output: ['bundle'],\n },\n {\n role: 'backend-plugin',\n platform: 'node',\n output: ['types', 'cjs'],\n },\n {\n role: 'backend-plugin-module',\n platform: 'node',\n output: ['types', 'cjs'],\n },\n];\n\nconst readSchema = z.object({\n name: z.string().optional(),\n backstage: z\n .object({\n role: z.string().optional(),\n })\n .optional(),\n});\n\nconst detectionSchema = z.object({\n name: z.string().optional(),\n scripts: z\n .object({\n start: z.string().optional(),\n build: z.string().optional(),\n })\n .optional(),\n publishConfig: z\n .object({\n main: z.string().optional(),\n types: z.string().optional(),\n module: z.string().optional(),\n })\n .optional(),\n main: z.string().optional(),\n types: z.string().optional(),\n module: z.string().optional(),\n});\n\n/**\n * Utilities for working with Backstage package roles.\n *\n * @public\n */\nexport class PackageRoles {\n /**\n * Get the associated info for a package role.\n */\n static getRoleInfo(role: string): PackageRoleInfo {\n const roleInfo = packageRoleInfos.find(r => r.role === role);\n if (!roleInfo) {\n throw new Error(`Unknown package role '${role}'`);\n }\n return roleInfo;\n }\n\n /**\n * Given package JSON data, get the package role.\n */\n static getRoleFromPackage(pkgJson: unknown): PackageRole | undefined {\n const pkg = readSchema.parse(pkgJson);\n\n if (pkg.backstage) {\n const { role } = pkg.backstage;\n if (!role) {\n throw new Error(\n `Package ${pkg.name} must specify a role in the \"backstage\" field`,\n );\n }\n\n return this.getRoleInfo(role).role;\n }\n\n return undefined;\n }\n\n /**\n * Attempt to detect the role of a package from its package.json.\n */\n static detectRoleFromPackage(pkgJson: unknown): PackageRole | undefined {\n const pkg = detectionSchema.parse(pkgJson);\n\n if (pkg.scripts?.start?.includes('app:serve')) {\n return 'frontend';\n }\n if (pkg.scripts?.build?.includes('backend:bundle')) {\n return 'backend';\n }\n if (\n pkg.name?.includes('plugin-') &&\n pkg.name?.includes('-backend-module-')\n ) {\n return 'backend-plugin-module';\n }\n if (pkg.name?.includes('plugin-') && pkg.name?.includes('-module-')) {\n return 'frontend-plugin-module';\n }\n if (pkg.scripts?.start?.includes('plugin:serve')) {\n return 'frontend-plugin';\n }\n if (pkg.scripts?.start?.includes('backend:dev')) {\n return 'backend-plugin';\n }\n\n const mainEntry = pkg.publishConfig?.main || pkg.main;\n const moduleEntry = pkg.publishConfig?.module || pkg.module;\n const typesEntry = pkg.publishConfig?.types || pkg.types;\n if (typesEntry) {\n if (mainEntry && moduleEntry) {\n return 'common-library';\n }\n if (moduleEntry || mainEntry?.endsWith('.esm.js')) {\n return 'web-library';\n }\n if (mainEntry) {\n return 'node-library';\n }\n } else if (mainEntry) {\n return 'cli';\n }\n\n return undefined;\n }\n}\n"],"names":["z"],"mappings":"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"} | ||
| {"version":3,"file":"PackageRoles.cjs.js","sources":["../../src/roles/PackageRoles.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from 'zod';\nimport { PackageRole, PackageRoleInfo } from './types';\n\nconst packageRoleInfos: PackageRoleInfo[] = [\n {\n role: 'frontend',\n platform: 'web',\n output: ['bundle'],\n },\n {\n role: 'backend',\n platform: 'node',\n output: ['bundle'],\n },\n {\n role: 'cli',\n platform: 'node',\n output: ['cjs'],\n },\n {\n role: 'web-library',\n platform: 'web',\n output: ['types', 'esm'],\n },\n {\n role: 'node-library',\n platform: 'node',\n output: ['types', 'cjs'],\n },\n {\n role: 'common-library',\n platform: 'common',\n output: ['types', 'esm', 'cjs'],\n },\n {\n role: 'frontend-plugin',\n platform: 'web',\n output: ['types', 'esm'],\n },\n {\n role: 'frontend-plugin-module',\n platform: 'web',\n output: ['types', 'esm'],\n },\n {\n role: 'frontend-dynamic-container' as PackageRole, // experimental\n platform: 'web',\n output: ['bundle'],\n },\n {\n role: 'backend-plugin',\n platform: 'node',\n output: ['types', 'cjs'],\n },\n {\n role: 'backend-plugin-module',\n platform: 'node',\n output: ['types', 'cjs'],\n },\n];\n\nconst readSchema = z.object({\n name: z.string().optional(),\n backstage: z\n .object({\n role: z.string().optional(),\n })\n .optional(),\n});\n\nconst detectionSchema = z.object({\n name: z.string().optional(),\n scripts: z\n .object({\n start: z.string().optional(),\n build: z.string().optional(),\n })\n .optional(),\n publishConfig: z\n .object({\n main: z.string().optional(),\n types: z.string().optional(),\n module: z.string().optional(),\n })\n .optional(),\n main: z.string().optional(),\n types: z.string().optional(),\n module: z.string().optional(),\n});\n\n/**\n * Utilities for working with Backstage package roles.\n *\n * @public\n */\nexport class PackageRoles {\n /**\n * Get the associated info for a package role.\n */\n static getRoleInfo(role: string): PackageRoleInfo {\n const roleInfo = packageRoleInfos.find(r => r.role === role);\n if (!roleInfo) {\n throw new Error(`Unknown package role '${role}'`);\n }\n return roleInfo;\n }\n\n /**\n * Given package JSON data, get the package role.\n */\n static getRoleFromPackage(pkgJson: unknown): PackageRole | undefined {\n const pkg = readSchema.parse(pkgJson);\n\n if (pkg.backstage) {\n const { role } = pkg.backstage;\n if (!role) {\n throw new Error(\n `Package ${pkg.name} must specify a role in the \"backstage\" field`,\n );\n }\n\n return this.getRoleInfo(role).role;\n }\n\n return undefined;\n }\n\n /**\n * Attempt to detect the role of a package from its package.json.\n */\n static detectRoleFromPackage(pkgJson: unknown): PackageRole | undefined {\n const pkg = detectionSchema.parse(pkgJson);\n\n if (pkg.scripts?.start?.includes('app:serve')) {\n return 'frontend';\n }\n if (pkg.scripts?.build?.includes('backend:bundle')) {\n return 'backend';\n }\n if (\n pkg.name?.includes('plugin-') &&\n pkg.name?.includes('-backend-module-')\n ) {\n return 'backend-plugin-module';\n }\n if (pkg.name?.includes('plugin-') && pkg.name?.includes('-module-')) {\n return 'frontend-plugin-module';\n }\n if (pkg.scripts?.start?.includes('plugin:serve')) {\n return 'frontend-plugin';\n }\n if (pkg.scripts?.start?.includes('backend:dev')) {\n return 'backend-plugin';\n }\n\n const mainEntry = pkg.publishConfig?.main || pkg.main;\n const moduleEntry = pkg.publishConfig?.module || pkg.module;\n const typesEntry = pkg.publishConfig?.types || pkg.types;\n if (typesEntry) {\n if (mainEntry && moduleEntry) {\n return 'common-library';\n }\n if (moduleEntry || mainEntry?.endsWith('.esm.js')) {\n return 'web-library';\n }\n if (mainEntry) {\n return 'node-library';\n }\n } else if (mainEntry) {\n return 'cli';\n }\n\n return undefined;\n }\n}\n"],"names":["z"],"mappings":"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"} |
+8
-5
| { | ||
| "name": "@backstage/cli-node", | ||
| "version": "0.2.19-next.0", | ||
| "version": "0.2.19-next.1", | ||
| "description": "Node.js library for Backstage CLIs", | ||
@@ -34,15 +34,18 @@ "backstage": { | ||
| "dependencies": { | ||
| "@backstage/cli-common": "0.2.0-next.0", | ||
| "@backstage/cli-common": "0.2.0-next.1", | ||
| "@backstage/errors": "1.2.7", | ||
| "@backstage/types": "1.2.2", | ||
| "@manypkg/get-packages": "^1.1.3", | ||
| "@yarnpkg/lockfile": "^1.1.0", | ||
| "@yarnpkg/parsers": "^3.0.0", | ||
| "fs-extra": "^11.2.0", | ||
| "semver": "^7.5.3", | ||
| "yaml": "^2.0.0", | ||
| "zod": "^3.25.76" | ||
| }, | ||
| "devDependencies": { | ||
| "@backstage/backend-test-utils": "1.11.1-next.0", | ||
| "@backstage/cli": "0.35.5-next.0", | ||
| "@backstage/test-utils": "1.7.16-next.0" | ||
| "@backstage/backend-test-utils": "1.11.1-next.1", | ||
| "@backstage/cli": "0.36.0-next.1", | ||
| "@backstage/test-utils": "1.7.16-next.0", | ||
| "@types/yarnpkg__lockfile": "^1.1.4" | ||
| }, | ||
@@ -49,0 +52,0 @@ "typesVersions": { |
134981
14.83%26
18.18%1345
15.95%10
25%4
33.33%8
33.33%+ Added
+ Added
+ Added
+ Added
+ Added
- Removed