|
1 | 1 | /* eslint-disable no-console */
|
2 | 2 |
|
3 |
| -import { stat } from 'node:fs/promises' |
4 |
| -import path from 'node:path' |
5 |
| - |
6 | 3 | import meow from 'meow'
|
7 | 4 | import ora from 'ora'
|
8 |
| -import { ErrorWithCause } from 'pony-cause' |
9 | 5 |
|
10 | 6 | import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
|
11 | 7 | import { ChalkOrMarkdown, logSymbols } from '../../utils/chalk-markdown.js'
|
12 |
| -import { InputError } from '../../utils/errors.js' |
13 | 8 | import { printFlagList } from '../../utils/formatting.js'
|
14 | 9 | import { createDebugLogger } from '../../utils/misc.js'
|
| 10 | +import { resolvePackagePaths } from '../../utils/path-resolve.js' |
15 | 11 | import { setupSdk } from '../../utils/sdk.js'
|
16 |
| -import { isErrnoException } from '../../utils/type-helpers.js' |
17 | 12 | import { fetchReportData, formatReportDataOutput } from './view.js'
|
18 | 13 |
|
19 | 14 | /** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */
|
@@ -210,113 +205,3 @@ function formatReportCreationOutput (data, { outputJson, outputMarkdown }) {
|
210 | 205 |
|
211 | 206 | console.log('\nNew report: ' + format.hyperlink(data.id, data.url, { fallbackToUrl: true }))
|
212 | 207 | }
|
213 |
| - |
214 |
| -// TODO: Add globbing support with support for ignoring, as a "./**/package.json" in a project also traverses eg. node_modules |
215 |
| -/** |
216 |
| - * Takes paths to folders and/or package.json / package-lock.json files and resolves to package.json + package-lock.json pairs (where feasible) |
217 |
| - * |
218 |
| - * @param {string} cwd |
219 |
| - * @param {string[]} inputPaths |
220 |
| - * @returns {Promise<string[]>} |
221 |
| - * @throws {InputError} |
222 |
| - */ |
223 |
| -async function resolvePackagePaths (cwd, inputPaths) { |
224 |
| - const packagePathLookups = inputPaths.map(async (filePath) => { |
225 |
| - const packagePath = await resolvePackagePath(cwd, filePath) |
226 |
| - return findComplementaryPackageFile(packagePath) |
227 |
| - }) |
228 |
| - |
229 |
| - const packagePaths = await Promise.all(packagePathLookups) |
230 |
| - |
231 |
| - const uniquePackagePaths = new Set(packagePaths.flat()) |
232 |
| - |
233 |
| - return [...uniquePackagePaths] |
234 |
| -} |
235 |
| - |
236 |
| -/** |
237 |
| - * Resolves a package.json / package-lock.json path from a relative folder / file path |
238 |
| - * |
239 |
| - * @param {string} cwd |
240 |
| - * @param {string} inputPath |
241 |
| - * @returns {Promise<string>} |
242 |
| - * @throws {InputError} |
243 |
| - */ |
244 |
| -async function resolvePackagePath (cwd, inputPath) { |
245 |
| - const filePath = path.resolve(cwd, inputPath) |
246 |
| - /** @type {string|undefined} */ |
247 |
| - let filePathAppended |
248 |
| - |
249 |
| - try { |
250 |
| - const fileStat = await stat(filePath) |
251 |
| - |
252 |
| - if (fileStat.isDirectory()) { |
253 |
| - filePathAppended = path.resolve(filePath, 'package.json') |
254 |
| - } |
255 |
| - } catch (err) { |
256 |
| - if (isErrnoException(err) && err.code === 'ENOENT') { |
257 |
| - throw new InputError(`Expected '${inputPath}' to point to an existing file or directory`) |
258 |
| - } |
259 |
| - throw new ErrorWithCause('Failed to resolve path to package.json', { cause: err }) |
260 |
| - } |
261 |
| - |
262 |
| - if (filePathAppended) { |
263 |
| - /** @type {import('node:fs').Stats} */ |
264 |
| - let filePathAppendedStat |
265 |
| - |
266 |
| - try { |
267 |
| - filePathAppendedStat = await stat(filePathAppended) |
268 |
| - } catch (err) { |
269 |
| - if (isErrnoException(err) && err.code === 'ENOENT') { |
270 |
| - throw new InputError(`Expected directory '${inputPath}' to contain a package.json file`) |
271 |
| - } |
272 |
| - throw new ErrorWithCause('Failed to resolve package.json in directory', { cause: err }) |
273 |
| - } |
274 |
| - |
275 |
| - if (!filePathAppendedStat.isFile()) { |
276 |
| - throw new InputError(`Expected '${filePathAppended}' to be a file`) |
277 |
| - } |
278 |
| - |
279 |
| - return filePathAppended |
280 |
| - } |
281 |
| - |
282 |
| - return filePath |
283 |
| -} |
284 |
| - |
285 |
| -/** |
286 |
| - * Finds any complementary file to a package.json or package-lock.json |
287 |
| - * |
288 |
| - * @param {string} packagePath |
289 |
| - * @returns {Promise<string[]>} |
290 |
| - * @throws {InputError} |
291 |
| - */ |
292 |
| -async function findComplementaryPackageFile (packagePath) { |
293 |
| - const basename = path.basename(packagePath) |
294 |
| - const dirname = path.dirname(packagePath) |
295 |
| - |
296 |
| - if (basename === 'package-lock.json') { |
297 |
| - // We need the package file as well |
298 |
| - return [ |
299 |
| - packagePath, |
300 |
| - path.resolve(dirname, 'package.json') |
301 |
| - ] |
302 |
| - } |
303 |
| - |
304 |
| - if (basename === 'package.json') { |
305 |
| - const lockfilePath = path.resolve(dirname, 'package-lock.json') |
306 |
| - try { |
307 |
| - const lockfileStat = await stat(lockfilePath) |
308 |
| - if (lockfileStat.isFile()) { |
309 |
| - return [packagePath, lockfilePath] |
310 |
| - } |
311 |
| - } catch (err) { |
312 |
| - if (isErrnoException(err) && err.code === 'ENOENT') { |
313 |
| - return [packagePath] |
314 |
| - } |
315 |
| - throw new ErrorWithCause(`Unexpected error when finding a lockfile for '${packagePath}'`, { cause: err }) |
316 |
| - } |
317 |
| - |
318 |
| - throw new InputError(`Encountered a non-file at lockfile path '${lockfilePath}'`) |
319 |
| - } |
320 |
| - |
321 |
| - throw new InputError(`Expected '${packagePath}' to point to a package.json or package-lock.json or to a folder containing a package.json`) |
322 |
| -} |
0 commit comments