@backstage/cli-common
Advanced tools
+8
-0
| # @backstage/cli-common | ||
| ## 0.1.18-next.0 | ||
| ### Patch Changes | ||
| - 7455dae: Use node prefix on native imports | ||
| - Updated dependencies | ||
| - @backstage/errors@1.2.7 | ||
| ## 0.1.17 | ||
@@ -4,0 +12,0 @@ |
+1
-1
@@ -1,2 +0,2 @@ | ||
| import { SpawnOptions, ChildProcess } from 'child_process'; | ||
| import { SpawnOptions, ChildProcess } from 'node:child_process'; | ||
| import { CustomErrorBase } from '@backstage/errors'; | ||
@@ -3,0 +3,0 @@ |
+14
-14
| 'use strict'; | ||
| var path = require('path'); | ||
| var fs = require('fs'); | ||
| var node_path = require('node:path'); | ||
| var fs = require('node:fs'); | ||
| function resolveRealPath(path$1) { | ||
| function resolveRealPath(path) { | ||
| try { | ||
| return fs.realpathSync(path$1); | ||
| return fs.realpathSync(path); | ||
| } catch (ex) { | ||
@@ -15,4 +15,4 @@ if (ex.code !== "ENOENT") { | ||
| try { | ||
| if (fs.lstatSync(path$1).isSymbolicLink()) { | ||
| const target = path.resolve(path.dirname(path$1), fs.readlinkSync(path$1)); | ||
| if (fs.lstatSync(path).isSymbolicLink()) { | ||
| const target = node_path.resolve(node_path.dirname(path), fs.readlinkSync(path)); | ||
| return resolveRealPath(target); | ||
@@ -25,12 +25,12 @@ } | ||
| } | ||
| const parent = path.dirname(path$1); | ||
| if (parent === path$1) { | ||
| return path$1; | ||
| const parent = node_path.dirname(path); | ||
| if (parent === path) { | ||
| return path; | ||
| } | ||
| return path.resolve(resolveRealPath(parent), path.basename(path$1)); | ||
| return node_path.resolve(resolveRealPath(parent), node_path.basename(path)); | ||
| } | ||
| function isChildPath(base, path$1) { | ||
| function isChildPath(base, path) { | ||
| const resolvedBase = resolveRealPath(base); | ||
| const resolvedPath = resolveRealPath(path$1); | ||
| const relativePath = path.relative(resolvedBase, resolvedPath); | ||
| const resolvedPath = resolveRealPath(path); | ||
| const relativePath = node_path.relative(resolvedBase, resolvedPath); | ||
| if (relativePath === "") { | ||
@@ -40,3 +40,3 @@ return true; | ||
| const outsideBase = relativePath.startsWith(".."); | ||
| const differentDrive = path.isAbsolute(relativePath); | ||
| const differentDrive = node_path.isAbsolute(relativePath); | ||
| return !outsideBase && !differentDrive; | ||
@@ -43,0 +43,0 @@ } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"isChildPath.cjs.js","sources":["../src/isChildPath.ts"],"sourcesContent":["/*\n * Copyright 2021 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 {\n relative,\n isAbsolute,\n resolve as resolvePath,\n dirname,\n basename,\n} from 'path';\nimport { realpathSync, lstatSync, readlinkSync } from 'fs';\n\n// Resolves a path to its real location, following symlinks.\n// Handles cases where the final target doesn't exist by recursively\n// resolving parent directories.\nfunction resolveRealPath(path: string): string {\n try {\n return realpathSync(path);\n } catch (ex) {\n if (ex.code !== 'ENOENT') {\n throw ex;\n }\n }\n\n // Check if path itself is a dangling symlink - recursively resolve the target\n // to handle symlink chains (e.g., link1 -> link2 -> /outside)\n try {\n if (lstatSync(path).isSymbolicLink()) {\n const target = resolvePath(dirname(path), readlinkSync(path));\n return resolveRealPath(target);\n }\n } catch (ex) {\n if (ex.code !== 'ENOENT') {\n throw ex;\n }\n }\n\n // Path doesn't exist - walk up the tree until we find an existing path,\n // resolve it, then rebuild the non-existent portion on top\n const parent = dirname(path);\n if (parent === path) {\n return path; // Hit filesystem root\n }\n\n return resolvePath(resolveRealPath(parent), basename(path));\n}\n\n/**\n * Checks if path is the same as or a child path of base.\n *\n * @public\n */\nexport function isChildPath(base: string, path: string): boolean {\n const resolvedBase = resolveRealPath(base);\n const resolvedPath = resolveRealPath(path);\n\n const relativePath = relative(resolvedBase, resolvedPath);\n if (relativePath === '') {\n // The same directory\n return true;\n }\n\n const outsideBase = relativePath.startsWith('..'); // not outside base\n const differentDrive = isAbsolute(relativePath); // on Windows, this means dir is on a different drive from base.\n\n return !outsideBase && !differentDrive;\n}\n"],"names":["path","realpathSync","lstatSync","resolvePath","dirname","readlinkSync","basename","relative","isAbsolute"],"mappings":";;;;;AA4BA,SAAS,gBAAgBA,MAAA,EAAsB;AAC7C,EAAA,IAAI;AACF,IAAA,OAAOC,gBAAaD,MAAI,CAAA;AAAA,EAC1B,SAAS,EAAA,EAAI;AACX,IAAA,IAAI,EAAA,CAAG,SAAS,QAAA,EAAU;AACxB,MAAA,MAAM,EAAA;AAAA,IACR;AAAA,EACF;AAIA,EAAA,IAAI;AACF,IAAA,IAAIE,YAAA,CAAUF,MAAI,CAAA,CAAE,cAAA,EAAe,EAAG;AACpC,MAAA,MAAM,SAASG,YAAA,CAAYC,YAAA,CAAQJ,MAAI,CAAA,EAAGK,eAAA,CAAaL,MAAI,CAAC,CAAA;AAC5D,MAAA,OAAO,gBAAgB,MAAM,CAAA;AAAA,IAC/B;AAAA,EACF,SAAS,EAAA,EAAI;AACX,IAAA,IAAI,EAAA,CAAG,SAAS,QAAA,EAAU;AACxB,MAAA,MAAM,EAAA;AAAA,IACR;AAAA,EACF;AAIA,EAAA,MAAM,MAAA,GAASI,aAAQJ,MAAI,CAAA;AAC3B,EAAA,IAAI,WAAWA,MAAA,EAAM;AACnB,IAAA,OAAOA,MAAA;AAAA,EACT;AAEA,EAAA,OAAOG,aAAY,eAAA,CAAgB,MAAM,CAAA,EAAGG,aAAA,CAASN,MAAI,CAAC,CAAA;AAC5D;AAOO,SAAS,WAAA,CAAY,MAAcA,MAAA,EAAuB;AAC/D,EAAA,MAAM,YAAA,GAAe,gBAAgB,IAAI,CAAA;AACzC,EAAA,MAAM,YAAA,GAAe,gBAAgBA,MAAI,CAAA;AAEzC,EAAA,MAAM,YAAA,GAAeO,aAAA,CAAS,YAAA,EAAc,YAAY,CAAA;AACxD,EAAA,IAAI,iBAAiB,EAAA,EAAI;AAEvB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,YAAA,CAAa,UAAA,CAAW,IAAI,CAAA;AAChD,EAAA,MAAM,cAAA,GAAiBC,gBAAW,YAAY,CAAA;AAE9C,EAAA,OAAO,CAAC,eAAe,CAAC,cAAA;AAC1B;;;;"} | ||
| {"version":3,"file":"isChildPath.cjs.js","sources":["../src/isChildPath.ts"],"sourcesContent":["/*\n * Copyright 2021 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 {\n relative,\n isAbsolute,\n resolve as resolvePath,\n dirname,\n basename,\n} from 'node:path';\nimport { realpathSync, lstatSync, readlinkSync } from 'node:fs';\n\n// Resolves a path to its real location, following symlinks.\n// Handles cases where the final target doesn't exist by recursively\n// resolving parent directories.\nfunction resolveRealPath(path: string): string {\n try {\n return realpathSync(path);\n } catch (ex) {\n if (ex.code !== 'ENOENT') {\n throw ex;\n }\n }\n\n // Check if path itself is a dangling symlink - recursively resolve the target\n // to handle symlink chains (e.g., link1 -> link2 -> /outside)\n try {\n if (lstatSync(path).isSymbolicLink()) {\n const target = resolvePath(dirname(path), readlinkSync(path));\n return resolveRealPath(target);\n }\n } catch (ex) {\n if (ex.code !== 'ENOENT') {\n throw ex;\n }\n }\n\n // Path doesn't exist - walk up the tree until we find an existing path,\n // resolve it, then rebuild the non-existent portion on top\n const parent = dirname(path);\n if (parent === path) {\n return path; // Hit filesystem root\n }\n\n return resolvePath(resolveRealPath(parent), basename(path));\n}\n\n/**\n * Checks if path is the same as or a child path of base.\n *\n * @public\n */\nexport function isChildPath(base: string, path: string): boolean {\n const resolvedBase = resolveRealPath(base);\n const resolvedPath = resolveRealPath(path);\n\n const relativePath = relative(resolvedBase, resolvedPath);\n if (relativePath === '') {\n // The same directory\n return true;\n }\n\n const outsideBase = relativePath.startsWith('..'); // not outside base\n const differentDrive = isAbsolute(relativePath); // on Windows, this means dir is on a different drive from base.\n\n return !outsideBase && !differentDrive;\n}\n"],"names":["realpathSync","lstatSync","resolvePath","dirname","readlinkSync","basename","relative","isAbsolute"],"mappings":";;;;;AA4BA,SAAS,gBAAgB,IAAA,EAAsB;AAC7C,EAAA,IAAI;AACF,IAAA,OAAOA,gBAAa,IAAI,CAAA;AAAA,EAC1B,SAAS,EAAA,EAAI;AACX,IAAA,IAAI,EAAA,CAAG,SAAS,QAAA,EAAU;AACxB,MAAA,MAAM,EAAA;AAAA,IACR;AAAA,EACF;AAIA,EAAA,IAAI;AACF,IAAA,IAAIC,YAAA,CAAU,IAAI,CAAA,CAAE,cAAA,EAAe,EAAG;AACpC,MAAA,MAAM,SAASC,iBAAA,CAAYC,iBAAA,CAAQ,IAAI,CAAA,EAAGC,eAAA,CAAa,IAAI,CAAC,CAAA;AAC5D,MAAA,OAAO,gBAAgB,MAAM,CAAA;AAAA,IAC/B;AAAA,EACF,SAAS,EAAA,EAAI;AACX,IAAA,IAAI,EAAA,CAAG,SAAS,QAAA,EAAU;AACxB,MAAA,MAAM,EAAA;AAAA,IACR;AAAA,EACF;AAIA,EAAA,MAAM,MAAA,GAASD,kBAAQ,IAAI,CAAA;AAC3B,EAAA,IAAI,WAAW,IAAA,EAAM;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAOD,kBAAY,eAAA,CAAgB,MAAM,CAAA,EAAGG,kBAAA,CAAS,IAAI,CAAC,CAAA;AAC5D;AAOO,SAAS,WAAA,CAAY,MAAc,IAAA,EAAuB;AAC/D,EAAA,MAAM,YAAA,GAAe,gBAAgB,IAAI,CAAA;AACzC,EAAA,MAAM,YAAA,GAAe,gBAAgB,IAAI,CAAA;AAEzC,EAAA,MAAM,YAAA,GAAeC,kBAAA,CAAS,YAAA,EAAc,YAAY,CAAA;AACxD,EAAA,IAAI,iBAAiB,EAAA,EAAI;AAEvB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,YAAA,CAAa,UAAA,CAAW,IAAI,CAAA;AAChD,EAAA,MAAM,cAAA,GAAiBC,qBAAW,YAAY,CAAA;AAE9C,EAAA,OAAO,CAAC,eAAe,CAAC,cAAA;AAC1B;;;;"} |
+14
-14
| 'use strict'; | ||
| var fs = require('fs'); | ||
| var path = require('path'); | ||
| var fs = require('node:fs'); | ||
| var node_path = require('node:path'); | ||
@@ -11,14 +11,14 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } | ||
| function findRootPath(searchDir, filterFunc) { | ||
| let path$1 = searchDir; | ||
| let path = searchDir; | ||
| for (let i = 0; i < 1e3; i++) { | ||
| const packagePath = path.resolve(path$1, "package.json"); | ||
| const packagePath = node_path.resolve(path, "package.json"); | ||
| const exists = fs__default.default.existsSync(packagePath); | ||
| if (exists && filterFunc(packagePath)) { | ||
| return path$1; | ||
| return path; | ||
| } | ||
| const newPath = path.dirname(path$1); | ||
| if (newPath === path$1) { | ||
| const newPath = node_path.dirname(path); | ||
| if (newPath === path) { | ||
| return void 0; | ||
| } | ||
| path$1 = newPath; | ||
| path = newPath; | ||
| } | ||
@@ -39,3 +39,3 @@ throw new Error( | ||
| function findOwnRootDir(ownDir) { | ||
| const isLocal = fs__default.default.existsSync(path.resolve(ownDir, "src")); | ||
| const isLocal = fs__default.default.existsSync(node_path.resolve(ownDir, "src")); | ||
| if (!isLocal) { | ||
@@ -46,3 +46,3 @@ throw new Error( | ||
| } | ||
| return path.resolve(ownDir, "../.."); | ||
| return node_path.resolve(ownDir, "../.."); | ||
| } | ||
@@ -85,6 +85,6 @@ function findPaths(searchDir) { | ||
| }, | ||
| resolveOwn: (...paths) => path.resolve(ownDir, ...paths), | ||
| resolveOwnRoot: (...paths) => path.resolve(getOwnRoot(), ...paths), | ||
| resolveTarget: (...paths) => path.resolve(targetDir, ...paths), | ||
| resolveTargetRoot: (...paths) => path.resolve(getTargetRoot(), ...paths) | ||
| resolveOwn: (...paths) => node_path.resolve(ownDir, ...paths), | ||
| resolveOwnRoot: (...paths) => node_path.resolve(getOwnRoot(), ...paths), | ||
| resolveTarget: (...paths) => node_path.resolve(targetDir, ...paths), | ||
| resolveTargetRoot: (...paths) => node_path.resolve(getTargetRoot(), ...paths) | ||
| }; | ||
@@ -91,0 +91,0 @@ } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"paths.cjs.js","sources":["../src/paths.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';\nimport { dirname, resolve as resolvePath } from 'path';\n\n/**\n * A function that takes a set of path fragments and resolves them into a\n * single complete path, relative to some root.\n *\n * @public\n */\nexport type ResolveFunc = (...paths: string[]) => string;\n\n/**\n * Common paths and resolve functions used by the cli.\n * Currently assumes it is being executed within a monorepo.\n *\n * @public\n */\nexport type Paths = {\n // Root dir of the cli itself, containing package.json\n ownDir: string;\n\n // Monorepo root dir of the cli itself. Only accessible when running inside Backstage repo.\n ownRoot: string;\n\n // The location of the app that the cli is being executed in\n targetDir: string;\n\n // The monorepo root package of the app that the cli is being executed in.\n targetRoot: string;\n\n // Resolve a path relative to own repo\n resolveOwn: ResolveFunc;\n\n // Resolve a path relative to own monorepo root. Only accessible when running inside Backstage repo.\n resolveOwnRoot: ResolveFunc;\n\n // Resolve a path relative to the app\n resolveTarget: ResolveFunc;\n\n // Resolve a path relative to the app repo root\n resolveTargetRoot: ResolveFunc;\n};\n\n// Looks for a package.json with a workspace config to identify the root of the monorepo\nexport function findRootPath(\n searchDir: string,\n filterFunc: (pkgJsonPath: string) => boolean,\n): string | undefined {\n let path = searchDir;\n\n // Some confidence check to avoid infinite loop\n for (let i = 0; i < 1000; i++) {\n const packagePath = resolvePath(path, 'package.json');\n const exists = fs.existsSync(packagePath);\n if (exists && filterFunc(packagePath)) {\n return path;\n }\n\n const newPath = dirname(path);\n if (newPath === path) {\n return undefined;\n }\n path = newPath;\n }\n\n throw new Error(\n `Iteration limit reached when searching for root package.json at ${searchDir}`,\n );\n}\n\n// Finds the root of a given package\nexport function findOwnDir(searchDir: string) {\n const path = findRootPath(searchDir, () => true);\n if (!path) {\n throw new Error(\n `No package.json found while searching for package root of ${searchDir}`,\n );\n }\n return path;\n}\n\n// Finds the root of the monorepo that the package exists in. Only accessible when running inside Backstage repo.\nexport function findOwnRootDir(ownDir: string) {\n const isLocal = fs.existsSync(resolvePath(ownDir, 'src'));\n if (!isLocal) {\n throw new Error(\n 'Tried to access monorepo package root dir outside of Backstage repository',\n );\n }\n\n return resolvePath(ownDir, '../..');\n}\n\n/**\n * Find paths related to a package and its execution context.\n *\n * @public\n * @example\n *\n * const paths = findPaths(__dirname)\n */\nexport function findPaths(searchDir: string): Paths {\n const ownDir = findOwnDir(searchDir);\n // Drive letter can end up being lowercased here on Windows, bring back to uppercase for consistency\n const targetDir = fs\n .realpathSync(process.cwd())\n .replace(/^[a-z]:/, str => str.toLocaleUpperCase('en-US'));\n\n // Lazy load this as it will throw an error if we're not inside the Backstage repo.\n let ownRoot = '';\n const getOwnRoot = () => {\n if (!ownRoot) {\n ownRoot = findOwnRootDir(ownDir);\n }\n return ownRoot;\n };\n\n // We're not always running in a monorepo, so we lazy init this to only crash commands\n // that require a monorepo when we're not in one.\n let targetRoot = '';\n const getTargetRoot = () => {\n if (!targetRoot) {\n targetRoot =\n findRootPath(targetDir, path => {\n try {\n const content = fs.readFileSync(path, 'utf8');\n const data = JSON.parse(content);\n return Boolean(data.workspaces);\n } catch (error) {\n throw new Error(\n `Failed to parse package.json file while searching for root, ${error}`,\n );\n }\n }) ?? targetDir; // We didn't find any root package.json, assume we're not in a monorepo\n }\n return targetRoot;\n };\n\n return {\n ownDir,\n get ownRoot() {\n return getOwnRoot();\n },\n targetDir,\n get targetRoot() {\n return getTargetRoot();\n },\n resolveOwn: (...paths) => resolvePath(ownDir, ...paths),\n resolveOwnRoot: (...paths) => resolvePath(getOwnRoot(), ...paths),\n resolveTarget: (...paths) => resolvePath(targetDir, ...paths),\n resolveTargetRoot: (...paths) => resolvePath(getTargetRoot(), ...paths),\n };\n}\n\n/**\n * The name of the backstage's config file\n *\n * @public\n */\nexport const BACKSTAGE_JSON = 'backstage.json';\n"],"names":["path","resolvePath","fs","dirname"],"mappings":"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"} | ||
| {"version":3,"file":"paths.cjs.js","sources":["../src/paths.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 'node:fs';\nimport { dirname, resolve as resolvePath } from 'node:path';\n\n/**\n * A function that takes a set of path fragments and resolves them into a\n * single complete path, relative to some root.\n *\n * @public\n */\nexport type ResolveFunc = (...paths: string[]) => string;\n\n/**\n * Common paths and resolve functions used by the cli.\n * Currently assumes it is being executed within a monorepo.\n *\n * @public\n */\nexport type Paths = {\n // Root dir of the cli itself, containing package.json\n ownDir: string;\n\n // Monorepo root dir of the cli itself. Only accessible when running inside Backstage repo.\n ownRoot: string;\n\n // The location of the app that the cli is being executed in\n targetDir: string;\n\n // The monorepo root package of the app that the cli is being executed in.\n targetRoot: string;\n\n // Resolve a path relative to own repo\n resolveOwn: ResolveFunc;\n\n // Resolve a path relative to own monorepo root. Only accessible when running inside Backstage repo.\n resolveOwnRoot: ResolveFunc;\n\n // Resolve a path relative to the app\n resolveTarget: ResolveFunc;\n\n // Resolve a path relative to the app repo root\n resolveTargetRoot: ResolveFunc;\n};\n\n// Looks for a package.json with a workspace config to identify the root of the monorepo\nexport function findRootPath(\n searchDir: string,\n filterFunc: (pkgJsonPath: string) => boolean,\n): string | undefined {\n let path = searchDir;\n\n // Some confidence check to avoid infinite loop\n for (let i = 0; i < 1000; i++) {\n const packagePath = resolvePath(path, 'package.json');\n const exists = fs.existsSync(packagePath);\n if (exists && filterFunc(packagePath)) {\n return path;\n }\n\n const newPath = dirname(path);\n if (newPath === path) {\n return undefined;\n }\n path = newPath;\n }\n\n throw new Error(\n `Iteration limit reached when searching for root package.json at ${searchDir}`,\n );\n}\n\n// Finds the root of a given package\nexport function findOwnDir(searchDir: string) {\n const path = findRootPath(searchDir, () => true);\n if (!path) {\n throw new Error(\n `No package.json found while searching for package root of ${searchDir}`,\n );\n }\n return path;\n}\n\n// Finds the root of the monorepo that the package exists in. Only accessible when running inside Backstage repo.\nexport function findOwnRootDir(ownDir: string) {\n const isLocal = fs.existsSync(resolvePath(ownDir, 'src'));\n if (!isLocal) {\n throw new Error(\n 'Tried to access monorepo package root dir outside of Backstage repository',\n );\n }\n\n return resolvePath(ownDir, '../..');\n}\n\n/**\n * Find paths related to a package and its execution context.\n *\n * @public\n * @example\n *\n * const paths = findPaths(__dirname)\n */\nexport function findPaths(searchDir: string): Paths {\n const ownDir = findOwnDir(searchDir);\n // Drive letter can end up being lowercased here on Windows, bring back to uppercase for consistency\n const targetDir = fs\n .realpathSync(process.cwd())\n .replace(/^[a-z]:/, str => str.toLocaleUpperCase('en-US'));\n\n // Lazy load this as it will throw an error if we're not inside the Backstage repo.\n let ownRoot = '';\n const getOwnRoot = () => {\n if (!ownRoot) {\n ownRoot = findOwnRootDir(ownDir);\n }\n return ownRoot;\n };\n\n // We're not always running in a monorepo, so we lazy init this to only crash commands\n // that require a monorepo when we're not in one.\n let targetRoot = '';\n const getTargetRoot = () => {\n if (!targetRoot) {\n targetRoot =\n findRootPath(targetDir, path => {\n try {\n const content = fs.readFileSync(path, 'utf8');\n const data = JSON.parse(content);\n return Boolean(data.workspaces);\n } catch (error) {\n throw new Error(\n `Failed to parse package.json file while searching for root, ${error}`,\n );\n }\n }) ?? targetDir; // We didn't find any root package.json, assume we're not in a monorepo\n }\n return targetRoot;\n };\n\n return {\n ownDir,\n get ownRoot() {\n return getOwnRoot();\n },\n targetDir,\n get targetRoot() {\n return getTargetRoot();\n },\n resolveOwn: (...paths) => resolvePath(ownDir, ...paths),\n resolveOwnRoot: (...paths) => resolvePath(getOwnRoot(), ...paths),\n resolveTarget: (...paths) => resolvePath(targetDir, ...paths),\n resolveTargetRoot: (...paths) => resolvePath(getTargetRoot(), ...paths),\n };\n}\n\n/**\n * The name of the backstage's config file\n *\n * @public\n */\nexport const BACKSTAGE_JSON = 'backstage.json';\n"],"names":["resolvePath","fs","dirname"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"run.cjs.js","sources":["../src/run.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 { ChildProcess, SpawnOptions } from 'child_process';\nimport spawn from 'cross-spawn';\nimport { ExitCodeError } from './errors';\nimport { assertError } from '@backstage/errors';\n\n/**\n * Callback function that can be used to receive stdout or stderr data from a child process.\n *\n * @public\n */\nexport type RunOnOutput = (data: Buffer) => void;\n\n/**\n * Options for running a child process with {@link run} or related functions.\n *\n * @public\n */\nexport type RunOptions = Omit<SpawnOptions, 'env'> & {\n env?: Partial<NodeJS.ProcessEnv>;\n onStdout?: RunOnOutput;\n onStderr?: RunOnOutput;\n stdio?: SpawnOptions['stdio'];\n};\n\n/**\n * Child process handle returned by {@link run}.\n *\n * @public\n */\nexport interface RunChildProcess extends ChildProcess {\n /**\n * Waits for the child process to exit.\n *\n * @remarks\n *\n * Resolves when the process exits successfully (exit code 0) or is terminated by a signal.\n * If the process exits with a non-zero exit code, the promise is rejected with an {@link ExitCodeError}.\n *\n * @returns A promise that resolves when the process exits successfully or is terminated by a signal, or rejects on error.\n */\n waitForExit(): Promise<void>;\n}\n\n/**\n * Runs a command and returns a child process handle.\n *\n * @public\n */\nexport function run(args: string[], options: RunOptions = {}): RunChildProcess {\n if (args.length === 0) {\n throw new Error('run requires at least one argument');\n }\n\n const [name, ...cmdArgs] = args;\n\n const { onStdout, onStderr, stdio: customStdio, ...spawnOptions } = options;\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n FORCE_COLOR: 'true',\n ...(options.env ?? {}),\n };\n\n const stdio =\n customStdio ??\n ([\n 'inherit',\n onStdout ? 'pipe' : 'inherit',\n onStderr ? 'pipe' : 'inherit',\n ] as ('inherit' | 'pipe')[]);\n\n const child = spawn(name, cmdArgs, {\n ...spawnOptions,\n stdio,\n env,\n }) as RunChildProcess;\n\n if (onStdout && child.stdout) {\n child.stdout.on('data', onStdout);\n }\n if (onStderr && child.stderr) {\n child.stderr.on('data', onStderr);\n }\n\n const commandName = args.join(' ');\n\n let waitPromise: Promise<void> | undefined;\n\n child.waitForExit = async (): Promise<void> => {\n if (waitPromise) {\n return waitPromise;\n }\n\n waitPromise = new Promise<void>((resolve, reject) => {\n if (typeof child.exitCode === 'number') {\n if (child.exitCode) {\n reject(new ExitCodeError(child.exitCode, commandName));\n } else {\n resolve();\n }\n return;\n }\n\n function onError(error: Error) {\n cleanup();\n reject(error);\n }\n\n function onExit(code: number | null) {\n cleanup();\n if (code) {\n reject(new ExitCodeError(code, commandName));\n } else {\n resolve();\n }\n }\n\n function onSignal() {\n if (!child.killed && child.exitCode === null) {\n child.kill();\n }\n }\n\n function cleanup() {\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.removeListener(signal, onSignal);\n }\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n }\n\n child.once('error', onError);\n child.once('exit', onExit);\n\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.addListener(signal, onSignal);\n }\n });\n\n return waitPromise;\n };\n\n return child;\n}\n\n/**\n * Runs a command and returns the stdout.\n *\n * @remarks\n *\n * On error, both stdout and stderr are attached to the error object as properties.\n *\n * @public\n */\nexport async function runOutput(\n args: string[],\n options?: RunOptions,\n): Promise<string> {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n if (args.length === 0) {\n throw new Error('runOutput requires at least one argument');\n }\n\n try {\n await run(args, {\n ...options,\n onStdout: data => {\n stdoutChunks.push(data);\n options?.onStdout?.(data);\n },\n onStderr: data => {\n stderrChunks.push(data);\n options?.onStderr?.(data);\n },\n }).waitForExit();\n\n return Buffer.concat(stdoutChunks).toString().trim();\n } catch (error) {\n assertError(error);\n\n (error as Error & { stdout?: string }).stdout =\n Buffer.concat(stdoutChunks).toString();\n (error as Error & { stderr?: string }).stderr =\n Buffer.concat(stderrChunks).toString();\n\n throw error;\n }\n}\n\n/**\n * Runs a command and returns true if it exits with code 0, false otherwise.\n *\n * @public\n */\nexport async function runCheck(args: string[]): Promise<boolean> {\n try {\n await run(args).waitForExit();\n return true;\n } catch {\n return false;\n }\n}\n"],"names":["spawn","ExitCodeError","assertError"],"mappings":"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"} | ||
| {"version":3,"file":"run.cjs.js","sources":["../src/run.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 { ChildProcess, SpawnOptions } from 'node:child_process';\nimport spawn from 'cross-spawn';\nimport { ExitCodeError } from './errors';\nimport { assertError } from '@backstage/errors';\n\n/**\n * Callback function that can be used to receive stdout or stderr data from a child process.\n *\n * @public\n */\nexport type RunOnOutput = (data: Buffer) => void;\n\n/**\n * Options for running a child process with {@link run} or related functions.\n *\n * @public\n */\nexport type RunOptions = Omit<SpawnOptions, 'env'> & {\n env?: Partial<NodeJS.ProcessEnv>;\n onStdout?: RunOnOutput;\n onStderr?: RunOnOutput;\n stdio?: SpawnOptions['stdio'];\n};\n\n/**\n * Child process handle returned by {@link run}.\n *\n * @public\n */\nexport interface RunChildProcess extends ChildProcess {\n /**\n * Waits for the child process to exit.\n *\n * @remarks\n *\n * Resolves when the process exits successfully (exit code 0) or is terminated by a signal.\n * If the process exits with a non-zero exit code, the promise is rejected with an {@link ExitCodeError}.\n *\n * @returns A promise that resolves when the process exits successfully or is terminated by a signal, or rejects on error.\n */\n waitForExit(): Promise<void>;\n}\n\n/**\n * Runs a command and returns a child process handle.\n *\n * @public\n */\nexport function run(args: string[], options: RunOptions = {}): RunChildProcess {\n if (args.length === 0) {\n throw new Error('run requires at least one argument');\n }\n\n const [name, ...cmdArgs] = args;\n\n const { onStdout, onStderr, stdio: customStdio, ...spawnOptions } = options;\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n FORCE_COLOR: 'true',\n ...(options.env ?? {}),\n };\n\n const stdio =\n customStdio ??\n ([\n 'inherit',\n onStdout ? 'pipe' : 'inherit',\n onStderr ? 'pipe' : 'inherit',\n ] as ('inherit' | 'pipe')[]);\n\n const child = spawn(name, cmdArgs, {\n ...spawnOptions,\n stdio,\n env,\n }) as RunChildProcess;\n\n if (onStdout && child.stdout) {\n child.stdout.on('data', onStdout);\n }\n if (onStderr && child.stderr) {\n child.stderr.on('data', onStderr);\n }\n\n const commandName = args.join(' ');\n\n let waitPromise: Promise<void> | undefined;\n\n child.waitForExit = async (): Promise<void> => {\n if (waitPromise) {\n return waitPromise;\n }\n\n waitPromise = new Promise<void>((resolve, reject) => {\n if (typeof child.exitCode === 'number') {\n if (child.exitCode) {\n reject(new ExitCodeError(child.exitCode, commandName));\n } else {\n resolve();\n }\n return;\n }\n\n function onError(error: Error) {\n cleanup();\n reject(error);\n }\n\n function onExit(code: number | null) {\n cleanup();\n if (code) {\n reject(new ExitCodeError(code, commandName));\n } else {\n resolve();\n }\n }\n\n function onSignal() {\n if (!child.killed && child.exitCode === null) {\n child.kill();\n }\n }\n\n function cleanup() {\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.removeListener(signal, onSignal);\n }\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n }\n\n child.once('error', onError);\n child.once('exit', onExit);\n\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.addListener(signal, onSignal);\n }\n });\n\n return waitPromise;\n };\n\n return child;\n}\n\n/**\n * Runs a command and returns the stdout.\n *\n * @remarks\n *\n * On error, both stdout and stderr are attached to the error object as properties.\n *\n * @public\n */\nexport async function runOutput(\n args: string[],\n options?: RunOptions,\n): Promise<string> {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n if (args.length === 0) {\n throw new Error('runOutput requires at least one argument');\n }\n\n try {\n await run(args, {\n ...options,\n onStdout: data => {\n stdoutChunks.push(data);\n options?.onStdout?.(data);\n },\n onStderr: data => {\n stderrChunks.push(data);\n options?.onStderr?.(data);\n },\n }).waitForExit();\n\n return Buffer.concat(stdoutChunks).toString().trim();\n } catch (error) {\n assertError(error);\n\n (error as Error & { stdout?: string }).stdout =\n Buffer.concat(stdoutChunks).toString();\n (error as Error & { stderr?: string }).stderr =\n Buffer.concat(stderrChunks).toString();\n\n throw error;\n }\n}\n\n/**\n * Runs a command and returns true if it exits with code 0, false otherwise.\n *\n * @public\n */\nexport async function runCheck(args: string[]): Promise<boolean> {\n try {\n await run(args).waitForExit();\n return true;\n } catch {\n return false;\n }\n}\n"],"names":["spawn","ExitCodeError","assertError"],"mappings":"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"} |
+3
-3
| { | ||
| "name": "@backstage/cli-common", | ||
| "version": "0.1.17", | ||
| "version": "0.1.18-next.0", | ||
| "description": "Common functionality used by cli, backend, and create-app", | ||
@@ -38,3 +38,3 @@ "backstage": { | ||
| "dependencies": { | ||
| "@backstage/errors": "^1.2.7", | ||
| "@backstage/errors": "1.2.7", | ||
| "cross-spawn": "^7.0.3", | ||
@@ -45,3 +45,3 @@ "global-agent": "^3.0.0", | ||
| "devDependencies": { | ||
| "@backstage/cli": "^0.35.2", | ||
| "@backstage/cli": "0.35.3-next.0", | ||
| "@types/cross-spawn": "^6.0.2", | ||
@@ -48,0 +48,0 @@ "@types/node": "^22.13.14" |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
42291
0.55%6
-25%1
-50%Updated