diff --git a/code/addons/vitest/package.json b/code/addons/vitest/package.json index f94405d306a6..4ad7aa3cf5e5 100644 --- a/code/addons/vitest/package.json +++ b/code/addons/vitest/package.json @@ -85,9 +85,9 @@ "@vitest/browser": "^3.2.4", "@vitest/runner": "^3.2.4", "boxen": "^8.0.1", + "empathic": "^2.0.0", "es-toolkit": "^1.36.0", "execa": "^8.0.1", - "find-up": "^7.0.0", "istanbul-lib-report": "^3.0.1", "micromatch": "^4.0.8", "pathe": "^1.1.2", diff --git a/code/addons/vitest/src/node/vitest-manager.ts b/code/addons/vitest/src/node/vitest-manager.ts index 30c7f31d82d9..00363c295487 100644 --- a/code/addons/vitest/src/node/vitest-manager.ts +++ b/code/addons/vitest/src/node/vitest-manager.ts @@ -12,7 +12,7 @@ import type { import { getProjectRoot, resolvePathInStorybookCache } from 'storybook/internal/common'; import type { StoryId, StoryIndex, StoryIndexEntry } from 'storybook/internal/types'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import path, { dirname, join, normalize } from 'pathe'; import slash from 'slash'; @@ -64,12 +64,12 @@ export class VitestManager { : { enabled: false } ) as CoverageOptions; - const vitestWorkspaceConfig = await findUp( + const vitestWorkspaceConfig = find.any( [ ...VITEST_WORKSPACE_FILE_EXTENSION.map((ext) => `vitest.workspace.${ext}`), ...VITEST_CONFIG_FILE_EXTENSIONS.map((ext) => `vitest.config.${ext}`), ], - { stopAt: getProjectRoot() } + { last: getProjectRoot() } ); const projectName = 'storybook:' + process.env.STORYBOOK_CONFIG_DIR; diff --git a/code/addons/vitest/src/postinstall.ts b/code/addons/vitest/src/postinstall.ts index 1d131a11eec6..c5156707f108 100644 --- a/code/addons/vitest/src/postinstall.ts +++ b/code/addons/vitest/src/postinstall.ts @@ -19,9 +19,10 @@ import { experimental_loadStorybook } from 'storybook/internal/core-server'; import { readConfig, writeConfig } from 'storybook/internal/csf-tools'; import { logger } from 'storybook/internal/node-logger'; +import * as find from 'empathic/find'; +import * as pkg from 'empathic/package'; // eslint-disable-next-line depend/ban-dependencies import { execa } from 'execa'; -import { findUp } from 'find-up'; import { dirname, relative, resolve } from 'pathe'; import prompts from 'prompts'; import { coerce, satisfies } from 'semver'; @@ -60,10 +61,10 @@ const logErrors = (...args: Parameters) => { printError(...args); }; -const findFile = async (basename: string, extensions = EXTENSIONS) => - findUp( +const findFile = (basename: string, extensions = EXTENSIONS) => + find.any( extensions.map((ext) => basename + ext), - { stopAt: getProjectRoot() } + { last: getProjectRoot() } ); export default async function postInstall(options: PostinstallOptions) { @@ -320,7 +321,7 @@ export default async function postInstall(options: PostinstallOptions) { } const fileExtension = - allDeps.typescript || (await findFile('tsconfig', [...EXTENSIONS, '.json'])) ? 'ts' : 'js'; + allDeps.typescript || findFile('tsconfig', [...EXTENSIONS, '.json']) ? 'ts' : 'js'; const vitestSetupFile = resolve(options.configDir, `vitest.setup.${fileExtension}`); if (existsSync(vitestSetupFile)) { @@ -367,11 +368,11 @@ export default async function postInstall(options: PostinstallOptions) { ); const vitestWorkspaceFile = - (await findFile('vitest.workspace', ['.ts', '.js', '.json'])) || - (await findFile('vitest.projects', ['.ts', '.js', '.json'])); - const viteConfigFile = await findFile('vite.config'); - const vitestConfigFile = await findFile('vitest.config'); - const vitestShimFile = await findFile('vitest.shims.d'); + findFile('vitest.workspace', ['.ts', '.js', '.json']) || + findFile('vitest.projects', ['.ts', '.js', '.json']); + const viteConfigFile = findFile('vite.config'); + const vitestConfigFile = findFile('vitest.config'); + const vitestShimFile = findFile('vitest.shims.d'); const rootConfig = vitestConfigFile || viteConfigFile; const browserConfig = `{ @@ -576,10 +577,7 @@ async function getPackageNameFromPath(input: string): Promise { return path; } - const packageJsonPath = await findUp('package.json', { - cwd: path, - }); - + const packageJsonPath = pkg.up({ cwd: path }); if (!packageJsonPath) { throw new Error(`Could not find package.json in path: ${path}`); } diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index 5436a2eb4974..ba766f916ddc 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -52,10 +52,9 @@ "ts-dedent": "^2.0.0" }, "devDependencies": { - "@types/find-cache-dir": "^3.2.1", "@types/node": "^22.0.0", + "empathic": "^2.0.0", "es-module-lexer": "^1.5.0", - "find-cache-dir": "^3.0.0", "glob": "^10.0.0", "knitwork": "^1.1.0", "magic-string": "^0.30.0", diff --git a/code/builders/builder-vite/src/plugins/external-globals-plugin.ts b/code/builders/builder-vite/src/plugins/external-globals-plugin.ts index 2316ede7ac1c..aab1bd72c694 100644 --- a/code/builders/builder-vite/src/plugins/external-globals-plugin.ts +++ b/code/builders/builder-vite/src/plugins/external-globals-plugin.ts @@ -2,8 +2,8 @@ import { existsSync } from 'node:fs'; import { mkdir, writeFile } from 'node:fs/promises'; import { dirname, join } from 'node:path'; +import * as pkg from 'empathic/package'; import { init, parse } from 'es-module-lexer'; -import findCacheDirectory from 'find-cache-dir'; import MagicString from 'magic-string'; import type { Alias, Plugin } from 'vite'; @@ -52,10 +52,7 @@ export async function externalGlobalsPlugin(externals: Record): } const newAlias = mergeAlias([], config.resolve?.alias) as Alias[]; - const cachePath = findCacheDirectory({ - name: 'sb-vite-plugin-externals', - create: true, - }) as string; + const cachePath = pkg.cache('sb-vite-plugin-externals', { create: true })!; await Promise.all( (Object.keys(externals) as Array).map(async (externalKey) => { const externalCachePath = join(cachePath, `${externalKey}.js`); diff --git a/code/core/package.json b/code/core/package.json index a3d6b0f8946d..109a8956efa6 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -271,7 +271,6 @@ "@types/detect-port": "^1.3.0", "@types/diff": "^5.0.9", "@types/ejs": "^3.1.1", - "@types/find-cache-dir": "^5.0.0", "@types/js-yaml": "^4.0.5", "@types/node": "^22.0.0", "@types/npmlog": "^7.0.0", @@ -305,14 +304,12 @@ "diff": "^5.2.0", "downshift": "^9.0.4", "ejs": "^3.1.10", + "empathic": "^2.0.0", "es-toolkit": "^1.36.0", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", "execa": "^8.0.1", "exsolve": "^1.0.7", - "fd-package-json": "^1.2.0", "fetch-retry": "^6.0.0", - "find-cache-dir": "^5.0.0", - "find-up": "^7.0.0", "flush-promises": "^1.0.2", "fuse.js": "^3.6.1", "get-npm-tarball-url": "^2.0.3", @@ -348,7 +345,6 @@ "react-textarea-autosize": "^8.3.0", "react-transition-group": "^4.4.5", "require-from-string": "^2.0.2", - "resolve-from": "^5.0.0", "resolve.exports": "^2.0.3", "sirv": "^2.0.4", "slash": "^5.0.0", diff --git a/code/core/src/cli/detect.test.ts b/code/core/src/cli/detect.test.ts index ad58aac30d66..157ea39920f9 100644 --- a/code/core/src/cli/detect.test.ts +++ b/code/core/src/cli/detect.test.ts @@ -21,7 +21,7 @@ vi.mock(import('fs'), async (importOriginal) => { }); vi.mock('storybook/internal/node-logger'); -vi.mock('find-up'); +vi.mock('empathic/find'); const MOCK_FRAMEWORK_FILES: { name: string; diff --git a/code/core/src/cli/detect.ts b/code/core/src/cli/detect.ts index 8eac757bc3c6..c07dc8c119cc 100644 --- a/code/core/src/cli/detect.ts +++ b/code/core/src/cli/detect.ts @@ -5,7 +5,7 @@ import type { JsPackageManager, PackageJsonWithMaybeDeps } from 'storybook/inter import { HandledError, commandLog, getProjectRoot } from 'storybook/internal/common'; import { logger } from 'storybook/internal/node-logger'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import prompts from 'prompts'; import semver from 'semver'; @@ -112,8 +112,8 @@ export function detectFrameworkPreset( * @returns CoreBuilder */ export async function detectBuilder(packageManager: JsPackageManager, projectType: ProjectType) { - const viteConfig = findUpSync(viteConfigFiles, { stopAt: getProjectRoot() }); - const webpackConfig = findUpSync(webpackConfigFiles, { stopAt: getProjectRoot() }); + const viteConfig = find.any(viteConfigFiles, { last: getProjectRoot() }); + const webpackConfig = find.any(webpackConfigFiles, { last: getProjectRoot() }); const dependencies = packageManager.getAllDependencies(); if (viteConfig || (dependencies.vite && dependencies.webpack === undefined)) { @@ -171,7 +171,7 @@ export function isStorybookInstantiated(configDir = resolve(process.cwd(), '.sto } export async function detectPnp() { - return !!findUpSync(['.pnp.js', '.pnp.cjs']); + return !!find.any(['.pnp.js', '.pnp.cjs']); } export async function detectLanguage(packageManager: JsPackageManager) { diff --git a/code/core/src/cli/eslintPlugin.test.ts b/code/core/src/cli/eslintPlugin.test.ts index d8b125a55dde..793b17f86a17 100644 --- a/code/core/src/cli/eslintPlugin.test.ts +++ b/code/core/src/cli/eslintPlugin.test.ts @@ -2,7 +2,7 @@ import { readFile, writeFile } from 'node:fs/promises'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import { dedent } from 'ts-dedent'; import type { PackageJsonWithDepsAndDevDeps } from '../common'; @@ -14,8 +14,8 @@ import { normalizeExtends, } from './eslintPlugin'; -vi.mock('find-up', () => ({ - findUp: vi.fn(), +vi.mock('empathic/find', () => ({ + up: vi.fn(), })); vi.mock(import('node:fs/promises'), async (importOriginal) => { @@ -38,32 +38,32 @@ describe('extractEslintInfo', () => { } satisfies Partial; beforeEach(() => { - vi.mocked(findUp).mockClear(); + vi.mocked(find).up.mockClear(); mockPackageManager.getAllDependencies.mockClear(); }); it('should find ESLint config file with supported extension', async () => { - vi.mocked(findUp).mockImplementation(async (fileName) => { + vi.mocked(find).up.mockImplementation((fileName) => { return String(fileName) === '.eslintrc.js' ? String(fileName) : undefined; }); - const result = await findEslintFile(process.cwd()); + const result = findEslintFile(process.cwd()); expect(result).toBe('.eslintrc.js'); }); it('should return undefined if no ESLint config file is found', async () => { - vi.mocked(findUp).mockImplementation(async () => undefined); + vi.mocked(find).up.mockImplementation(() => undefined); - const result = await findEslintFile(process.cwd()); + const result = findEslintFile(process.cwd()); expect(result).toBeUndefined(); }); it('should throw error for unsupported ESLint config file extensions', async () => { - vi.mocked(findUp).mockImplementation(async () => { + vi.mocked(find).up.mockImplementation(() => { return '.eslintrc.yaml'; }); - await expect(findEslintFile(process.cwd())).rejects.toThrowError( + expect(() => findEslintFile(process.cwd())).toThrowError( 'Unsupported ESLint config extension: .yaml' ); }); @@ -72,7 +72,7 @@ describe('extractEslintInfo', () => { mockPackageManager.getAllDependencies.mockReturnValue({}); mockPackageManager.primaryPackageJson.packageJson = { dependencies: {}, devDependencies: {} }; - vi.mocked(findUp).mockImplementation(async () => undefined); + vi.mocked(find).up.mockImplementation(() => undefined); const result = await extractEslintInfo(mockPackageManager as any); @@ -96,7 +96,7 @@ describe('extractEslintInfo', () => { operationDir: '/some/path', }; - vi.mocked(findUp).mockImplementation(async (fileName) => + vi.mocked(find).up.mockImplementation((fileName) => String(fileName) === '.eslintrc.js' ? String(fileName) : undefined ); diff --git a/code/core/src/cli/eslintPlugin.ts b/code/core/src/cli/eslintPlugin.ts index a2aa2e594670..665c4fc84419 100644 --- a/code/core/src/cli/eslintPlugin.ts +++ b/code/core/src/cli/eslintPlugin.ts @@ -6,7 +6,7 @@ import { logger, prompt } from 'storybook/internal/node-logger'; import commentJson from 'comment-json'; import detectIndent from 'detect-indent'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import picocolors from 'picocolors'; import { dedent } from 'ts-dedent'; @@ -15,13 +15,13 @@ import { babelParse, recast, types as t, traverse } from '../babel'; export const SUPPORTED_ESLINT_EXTENSIONS = ['ts', 'mts', 'cts', 'mjs', 'js', 'cjs', 'json']; const UNSUPPORTED_ESLINT_EXTENSIONS = ['yaml', 'yml']; -export const findEslintFile = async (instanceDir: string) => { +export const findEslintFile = (instanceDir: string) => { const filePrefixes = ['eslint.config', '.eslintrc']; // Check for unsupported files for (const prefix of filePrefixes) { for (const ext of UNSUPPORTED_ESLINT_EXTENSIONS) { - const file = await findUp(`${prefix}.${ext}`, { cwd: instanceDir, stopAt: getProjectRoot() }); + const file = find.up(`${prefix}.${ext}`, { cwd: instanceDir, last: getProjectRoot() }); if (file) { throw new Error(`Unsupported ESLint config extension: .${ext}`); } @@ -31,7 +31,7 @@ export const findEslintFile = async (instanceDir: string) => { // Find supported ESLint config files for (const prefix of filePrefixes) { for (const ext of SUPPORTED_ESLINT_EXTENSIONS) { - const file = await findUp(`${prefix}.${ext}`, { cwd: instanceDir, stopAt: getProjectRoot() }); + const file = find.up(`${prefix}.${ext}`, { cwd: instanceDir, last: getProjectRoot() }); if (file) { return file; } @@ -157,7 +157,7 @@ export async function extractEslintInfo(packageManager: JsPackageManager): Promi let eslintConfigFile: string | undefined = undefined; try { - eslintConfigFile = await findEslintFile(packageManager.instanceDir); + eslintConfigFile = findEslintFile(packageManager.instanceDir); } catch (err) { if (err instanceof Error && err.message.includes('Unsupported ESLint')) { unsupportedExtension = String(err); diff --git a/code/core/src/cli/helpers.test.ts b/code/core/src/cli/helpers.test.ts index 04d0f1ae1687..ca8e6f7c8638 100644 --- a/code/core/src/cli/helpers.test.ts +++ b/code/core/src/cli/helpers.test.ts @@ -53,8 +53,8 @@ vi.mock('node:fs/promises', async (importOriginal) => { }; }); -vi.mock('find-up', () => ({ - sync: vi.fn(), +vi.mock('empathic/find', () => ({ + up: vi.fn(), })); vi.mock('path', async (importOriginal) => { diff --git a/code/core/src/cli/helpers.ts b/code/core/src/cli/helpers.ts index d07f05db54af..d529523fb352 100644 --- a/code/core/src/cli/helpers.ts +++ b/code/core/src/cli/helpers.ts @@ -5,15 +5,13 @@ import { join, resolve } from 'node:path'; import { type JsPackageManager, type PackageJson, - type PackageJsonWithDepsAndDevDeps, frameworkToRenderer, getProjectRoot, } from 'storybook/internal/common'; -import { versions as storybookMonorepoPackages } from 'storybook/internal/common'; import { logger } from 'storybook/internal/node-logger'; import type { SupportedFrameworks, SupportedRenderers } from 'storybook/internal/types'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import picocolors from 'picocolors'; import { coerce, satisfies } from 'semver'; import stripJsonComments from 'strip-json-comments'; @@ -261,7 +259,7 @@ export async function adjustTemplate(templatePath: string, templateData: Record< } export async function isNxProject() { - return findUpSync('nx.json', { stopAt: getProjectRoot() }); + return find.up('nx.json', { last: getProjectRoot() }); } export function coerceSemver(version: string) { diff --git a/code/core/src/common/js-package-manager/BUNProxy.ts b/code/core/src/common/js-package-manager/BUNProxy.ts index af9026eb85ae..8a8b9dcbd6fc 100644 --- a/code/core/src/common/js-package-manager/BUNProxy.ts +++ b/code/core/src/common/js-package-manager/BUNProxy.ts @@ -5,7 +5,7 @@ import { join } from 'node:path'; import { logger } from 'storybook/internal/node-logger'; import { FindPackageVersionsError } from 'storybook/internal/server-errors'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import sort from 'semver/functions/sort.js'; import { getProjectRoot } from '../utils/paths'; @@ -85,13 +85,8 @@ export class BUNProxy extends JsPackageManager { } public async getModulePackageJSON(packageName: string): Promise { - const packageJsonPath = findUpSync( - (dir) => { - const possiblePath = join(dir, 'node_modules', packageName, 'package.json'); - return existsSync(possiblePath) ? possiblePath : undefined; - }, - { cwd: this.cwd, stopAt: getProjectRoot() } - ); + const wantedPath = join('node_modules', packageName, 'package.json'); + const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() }); if (!packageJsonPath) { return null; diff --git a/code/core/src/common/js-package-manager/JsPackageManager.ts b/code/core/src/common/js-package-manager/JsPackageManager.ts index 0bf7834ae79c..ae1850a508d4 100644 --- a/code/core/src/common/js-package-manager/JsPackageManager.ts +++ b/code/core/src/common/js-package-manager/JsPackageManager.ts @@ -3,9 +3,9 @@ import { dirname, isAbsolute, join, resolve } from 'node:path'; import { logger, prompt } from 'storybook/internal/node-logger'; +import * as find from 'empathic/find'; // eslint-disable-next-line depend/ban-dependencies import { type CommonOptions, type ExecaChildProcess, execa, execaCommandSync } from 'execa'; -import { findUpMultipleSync, findUpSync } from 'find-up'; // eslint-disable-next-line depend/ban-dependencies import { globSync } from 'glob'; import picocolors from 'picocolors'; @@ -13,7 +13,7 @@ import { gt, satisfies } from 'semver'; import invariant from 'tiny-invariant'; import { HandledError } from '../utils/HandledError'; -import { getProjectRoot } from '../utils/paths'; +import { findFilesUp, getProjectRoot } from '../utils/paths'; import storybookPackagesVersions from '../versions'; import type { PackageJson, PackageJsonWithDepsAndDevDeps } from './PackageJson'; import type { InstallationMetadata } from './types'; @@ -109,15 +109,15 @@ export abstract class JsPackageManager { abstract getModulePackageJSON(packageName: string): Promise; isStorybookInMonorepo() { - const turboJsonPath = findUpSync(`turbo.json`, { stopAt: getProjectRoot() }); - const rushJsonPath = findUpSync(`rush.json`, { stopAt: getProjectRoot() }); - const nxJsonPath = findUpSync(`nx.json`, { stopAt: getProjectRoot() }); + const turboJsonPath = find.up(`turbo.json`, { last: getProjectRoot() }); + const rushJsonPath = find.up(`rush.json`, { last: getProjectRoot() }); + const nxJsonPath = find.up(`nx.json`, { last: getProjectRoot() }); if (turboJsonPath || rushJsonPath || nxJsonPath) { return true; } - const packageJsonPaths = findUpMultipleSync(`package.json`, { stopAt: getProjectRoot() }); + const packageJsonPaths = findFilesUp(['package.json']); if (packageJsonPaths.length === 0) { return false; } @@ -773,10 +773,7 @@ export abstract class JsPackageManager { /** List all package.json files starting from the given directory and stopping at the project root. */ static listAllPackageJsonPaths(instanceDir: string, storiesPaths?: string[]): string[] { - const packageJsonPaths = findUpMultipleSync('package.json', { - cwd: instanceDir, - stopAt: getProjectRoot(), - }); + const packageJsonPaths = findFilesUp(['package.json'], instanceDir); if (!storiesPaths) { return packageJsonPaths; diff --git a/code/core/src/common/js-package-manager/JsPackageManagerFactory.test.ts b/code/core/src/common/js-package-manager/JsPackageManagerFactory.test.ts index 6f2be018299e..6616d15b1ad2 100644 --- a/code/core/src/common/js-package-manager/JsPackageManagerFactory.test.ts +++ b/code/core/src/common/js-package-manager/JsPackageManagerFactory.test.ts @@ -3,7 +3,7 @@ import { join } from 'node:path'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { sync as spawnSync } from 'cross-spawn'; -import { findUpMultipleSync, findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import { BUNProxy } from './BUNProxy'; import { JsPackageManagerFactory } from './JsPackageManagerFactory'; @@ -15,14 +15,14 @@ import { Yarn2Proxy } from './Yarn2Proxy'; vi.mock('cross-spawn'); const spawnSyncMock = vi.mocked(spawnSync); -vi.mock('find-up'); -const findUpSyncMock = vi.mocked(findUpSync); -const findUpMultipleSyncMock = vi.mocked(findUpMultipleSync); +vi.mock('empathic/find'); +const findMock = vi.mocked(find); + describe('CLASS: JsPackageManagerFactory', () => { beforeEach(() => { JsPackageManagerFactory.clearCache(); - findUpSyncMock.mockReturnValue(undefined); - findUpMultipleSyncMock.mockReturnValue([]); + findMock.up.mockReturnValue(undefined); + findMock.any.mockReturnValue(undefined); spawnSyncMock.mockReturnValue({ status: 1 } as any); delete process.env.npm_config_user_agent; }); @@ -70,7 +70,7 @@ describe('CLASS: JsPackageManagerFactory', () => { }); // There is only a package-lock.json - findUpSyncMock.mockImplementation((filename) => { + findMock.up.mockImplementation((filename) => { if (typeof filename === 'string' && filename === 'package-lock.json') { return '/Users/johndoe/Documents/package-lock.json'; } @@ -123,7 +123,7 @@ describe('CLASS: JsPackageManagerFactory', () => { }); // There is only a pnpm-lock.yaml - findUpSyncMock.mockImplementation((filename) => { + findMock.up.mockImplementation((filename) => { if (typeof filename === 'string' && filename === 'pnpm-lock.yaml') { return '/Users/johndoe/Documents/pnpm-lock.yaml'; } @@ -134,9 +134,9 @@ describe('CLASS: JsPackageManagerFactory', () => { }); it('PNPM LOCK IF CLOSER: when a pnpm-lock.yaml file is closer than a yarn.lock', async () => { - // Allow find-up to work as normal, we'll set the cwd to our fixture package - findUpSyncMock.mockImplementation( - (await vi.importActual('find-up')).findUpSync + // Allow find to work as normal, we'll set the cwd to our fixture package + findMock.up.mockImplementation( + (await vi.importActual('empathic/find')).up ); spawnSyncMock.mockImplementation((command) => { @@ -211,7 +211,7 @@ describe('CLASS: JsPackageManagerFactory', () => { }); // there is a yarn.lock file - findUpSyncMock.mockImplementation((filename) => { + findMock.up.mockImplementation((filename) => { if (typeof filename === 'string' && filename === 'yarn.lock') { return '/Users/johndoe/Documents/yarn.lock'; } @@ -251,7 +251,7 @@ describe('CLASS: JsPackageManagerFactory', () => { }); // There is a yarn.lock - findUpSyncMock.mockImplementation((filename) => { + findMock.up.mockImplementation((filename) => { if (typeof filename === 'string' && filename === 'yarn.lock') { return '/Users/johndoe/Documents/yarn.lock'; } @@ -262,9 +262,9 @@ describe('CLASS: JsPackageManagerFactory', () => { }); it('when multiple lockfiles are in a project, prefers yarn', async () => { - // Allow find-up to work as normal, we'll set the cwd to our fixture package - findUpSyncMock.mockImplementation( - (await vi.importActual('find-up')).findUpSync + // Allow find to work as normal, we'll set the cwd to our fixture package + findMock.up.mockImplementation( + (await vi.importActual('empathic/find')).up ); spawnSyncMock.mockImplementation((command) => { @@ -338,7 +338,7 @@ describe('CLASS: JsPackageManagerFactory', () => { } as any; }); - findUpSyncMock.mockImplementation((filename) => { + findMock.up.mockImplementation((filename) => { if (typeof filename === 'string' && filename === 'yarn.lock') { return '/Users/johndoe/Documents/yarn.lock'; } @@ -385,7 +385,7 @@ describe('CLASS: JsPackageManagerFactory', () => { }); // There is a bun.lockb - findUpSyncMock.mockImplementation((filename) => { + findMock.up.mockImplementation((filename) => { if (typeof filename === 'string' && filename === 'bun.lockb') { return '/Users/johndoe/Documents/bun.lockb'; } diff --git a/code/core/src/common/js-package-manager/JsPackageManagerFactory.ts b/code/core/src/common/js-package-manager/JsPackageManagerFactory.ts index c74cf58603d1..d7917cb9909d 100644 --- a/code/core/src/common/js-package-manager/JsPackageManagerFactory.ts +++ b/code/core/src/common/js-package-manager/JsPackageManagerFactory.ts @@ -1,7 +1,7 @@ import { basename, parse, relative } from 'node:path'; import { sync as spawnSync } from 'cross-spawn'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import { getProjectRoot } from '../utils/paths'; import { BUNProxy } from './BUNProxy'; @@ -56,11 +56,11 @@ export class JsPackageManagerFactory { const root = getProjectRoot(); const lockFiles = [ - findUpSync(YARN_LOCKFILE, { cwd, stopAt: root }), - findUpSync(PNPM_LOCKFILE, { cwd, stopAt: root }), - findUpSync(NPM_LOCKFILE, { cwd, stopAt: root }), - findUpSync(BUN_LOCKFILE, { cwd, stopAt: root }), - findUpSync(BUN_LOCKFILE_BINARY, { cwd, stopAt: root }), + find.up(YARN_LOCKFILE, { cwd, last: root }), + find.up(PNPM_LOCKFILE, { cwd, last: root }), + find.up(NPM_LOCKFILE, { cwd, last: root }), + find.up(BUN_LOCKFILE, { cwd, last: root }), + find.up(BUN_LOCKFILE_BINARY, { cwd, last: root }), ] .filter(Boolean) .sort((a, b) => { diff --git a/code/core/src/common/js-package-manager/NPMProxy.ts b/code/core/src/common/js-package-manager/NPMProxy.ts index 28b27c46d38b..cad78dfc2471 100644 --- a/code/core/src/common/js-package-manager/NPMProxy.ts +++ b/code/core/src/common/js-package-manager/NPMProxy.ts @@ -1,11 +1,11 @@ -import { existsSync, readFileSync } from 'node:fs'; +import { readFileSync } from 'node:fs'; import { platform } from 'node:os'; import { join } from 'node:path'; import { logger, prompt } from 'storybook/internal/node-logger'; import { FindPackageVersionsError } from 'storybook/internal/server-errors'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import sort from 'semver/functions/sort.js'; import { getProjectRoot } from '../utils/paths'; @@ -77,13 +77,8 @@ export class NPMProxy extends JsPackageManager { } async getModulePackageJSON(packageName: string): Promise { - const packageJsonPath = findUpSync( - (dir) => { - const possiblePath = join(dir, 'node_modules', packageName, 'package.json'); - return existsSync(possiblePath) ? possiblePath : undefined; - }, - { cwd: this.primaryPackageJson.operationDir, stopAt: getProjectRoot() } - ); + const wantedPath = join('node_modules', packageName, 'package.json'); + const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() }); if (!packageJsonPath) { return null; diff --git a/code/core/src/common/js-package-manager/PNPMProxy.ts b/code/core/src/common/js-package-manager/PNPMProxy.ts index c5fddbdf6e50..8c7d83699480 100644 --- a/code/core/src/common/js-package-manager/PNPMProxy.ts +++ b/code/core/src/common/js-package-manager/PNPMProxy.ts @@ -5,7 +5,7 @@ import { pathToFileURL } from 'node:url'; import { prompt } from 'storybook/internal/node-logger'; import { FindPackageVersionsError } from 'storybook/internal/server-errors'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import { getProjectRoot } from '../utils/paths'; import { JsPackageManager } from './JsPackageManager'; @@ -143,9 +143,9 @@ export class PNPMProxy extends JsPackageManager { } public async getModulePackageJSON(packageName: string): Promise { - const pnpapiPath = findUpSync(['.pnp.js', '.pnp.cjs'], { + const pnpapiPath = find.any(['.pnp.js', '.pnp.cjs'], { cwd: this.primaryPackageJson.operationDir, - stopAt: getProjectRoot(), + last: getProjectRoot(), }); if (pnpapiPath) { @@ -172,13 +172,8 @@ export class PNPMProxy extends JsPackageManager { } } - const packageJsonPath = findUpSync( - (dir) => { - const possiblePath = join(dir, 'node_modules', packageName, 'package.json'); - return existsSync(possiblePath) ? possiblePath : undefined; - }, - { cwd: this.cwd, stopAt: getProjectRoot() } - ); + const wantedPath = join('node_modules', packageName, 'package.json'); + const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() }); if (!packageJsonPath) { return null; diff --git a/code/core/src/common/js-package-manager/Yarn1Proxy.ts b/code/core/src/common/js-package-manager/Yarn1Proxy.ts index f5f5019e70e9..c03c173b61c0 100644 --- a/code/core/src/common/js-package-manager/Yarn1Proxy.ts +++ b/code/core/src/common/js-package-manager/Yarn1Proxy.ts @@ -1,11 +1,11 @@ -import { existsSync, readFileSync } from 'node:fs'; +import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import process from 'node:process'; import { prompt } from 'storybook/internal/node-logger'; import { FindPackageVersionsError } from 'storybook/internal/server-errors'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import { getProjectRoot } from '../utils/paths'; import { JsPackageManager } from './JsPackageManager'; @@ -83,13 +83,8 @@ export class Yarn1Proxy extends JsPackageManager { } public async getModulePackageJSON(packageName: string): Promise { - const packageJsonPath = findUpSync( - (dir) => { - const possiblePath = join(dir, 'node_modules', packageName, 'package.json'); - return existsSync(possiblePath) ? possiblePath : undefined; - }, - { cwd: this.primaryPackageJson.operationDir, stopAt: getProjectRoot() } - ); + const wantedPath = join('node_modules', packageName, 'package.json'); + const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() }); if (!packageJsonPath) { return null; diff --git a/code/core/src/common/js-package-manager/Yarn2Proxy.ts b/code/core/src/common/js-package-manager/Yarn2Proxy.ts index 9ea3c474b885..d0eef925baa8 100644 --- a/code/core/src/common/js-package-manager/Yarn2Proxy.ts +++ b/code/core/src/common/js-package-manager/Yarn2Proxy.ts @@ -1,4 +1,4 @@ -import { existsSync, readFileSync } from 'node:fs'; +import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { pathToFileURL } from 'node:url'; @@ -7,7 +7,7 @@ import { FindPackageVersionsError } from 'storybook/internal/server-errors'; import { PosixFS, VirtualFS, ZipOpenFS } from '@yarnpkg/fslib'; import { getLibzipSync } from '@yarnpkg/libzip'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import { getProjectRoot } from '../utils/paths'; import { JsPackageManager } from './JsPackageManager'; @@ -150,9 +150,9 @@ export class Yarn2Proxy extends JsPackageManager { } async getModulePackageJSON(packageName: string): Promise { - const pnpapiPath = findUpSync(['.pnp.js', '.pnp.cjs'], { + const pnpapiPath = find.any(['.pnp.js', '.pnp.cjs'], { cwd: this.cwd, - stopAt: getProjectRoot(), + last: getProjectRoot(), }); if (pnpapiPath) { @@ -161,7 +161,7 @@ export class Yarn2Proxy extends JsPackageManager { This is a rather fragile way to access Yarn's PnP API, essentially manually loading it. The proper way to do this would be to just do await import('pnpapi'), as documented at https://yarnpkg.com/advanced/pnpapi#requirepnpapi - + However the 'pnpapi' module is only injected when the Node process is started via Yarn, which is not always the case for us, because we spawn child processes directly with Node, eg. when running automigrations. @@ -197,13 +197,11 @@ export class Yarn2Proxy extends JsPackageManager { } } - const packageJsonPath = findUpSync( - (dir) => { - const possiblePath = join(dir, 'node_modules', packageName, 'package.json'); - return existsSync(possiblePath) ? possiblePath : undefined; - }, - { cwd: this.primaryPackageJson.operationDir, stopAt: getProjectRoot() } - ); + const wantedPath = join('node_modules', packageName, 'package.json'); + const packageJsonPath = find.up(wantedPath, { + cwd: this.primaryPackageJson.operationDir, + last: getProjectRoot(), + }); if (!packageJsonPath) { return null; diff --git a/code/core/src/common/utils/__tests__/paths.test.ts b/code/core/src/common/utils/__tests__/paths.test.ts index e353aed6f36e..727987e3d6de 100644 --- a/code/core/src/common/utils/__tests__/paths.test.ts +++ b/code/core/src/common/utils/__tests__/paths.test.ts @@ -2,12 +2,12 @@ import { join, sep } from 'node:path'; import { describe, expect, it, vi } from 'vitest'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; import slash from 'slash'; import { getProjectRoot, normalizeStoryPath } from '../paths'; -vi.mock('find-up'); +vi.mock('empathic/find'); describe('paths - normalizeStoryPath()', () => { it('returns a path starting with "./" unchanged', () => { @@ -48,15 +48,15 @@ describe('paths - normalizeStoryPath()', () => { describe('getProjectRoot', () => { it('should return the root directory containing a .git directory', () => { - vi.mocked(findUpSync).mockImplementation((name) => - name === ('.git' as any) ? '/path/to/root' : undefined + vi.mocked(find.up).mockImplementation((name) => + name === '.git' ? '/path/to/root' : undefined ); expect(slash(getProjectRoot())).toBe('/path/to'); }); it('should return the root directory containing a .svn directory if there is no .git directory', () => { - vi.mocked(findUpSync).mockImplementation((name) => + vi.mocked(find.up).mockImplementation((name) => name === ('.svn' as any) ? '/path/to/root' : undefined ); @@ -64,7 +64,7 @@ describe('getProjectRoot', () => { }); it('should return the root directory containing a .yarn directory if there is no .git or .svn directory', () => { - vi.mocked(findUpSync).mockImplementation((name) => + vi.mocked(find.up).mockImplementation((name) => name === ('.yarn' as any) ? '/path/to/root' : undefined ); diff --git a/code/core/src/common/utils/get-storybook-refs.ts b/code/core/src/common/utils/get-storybook-refs.ts index 7772aa653fb7..457025541997 100644 --- a/code/core/src/common/utils/get-storybook-refs.ts +++ b/code/core/src/common/utils/get-storybook-refs.ts @@ -4,16 +4,13 @@ import { dirname, join } from 'node:path'; import { logger } from 'storybook/internal/node-logger'; import type { Options, Ref } from 'storybook/internal/types'; -import { findUp } from 'find-up'; -import resolveFrom from 'resolve-from'; +import * as pkg from 'empathic/package'; +import * as resolve from 'empathic/resolve'; import { getProjectRoot } from './paths'; export const getAutoRefs = async (options: Options): Promise> => { - const location = await findUp('package.json', { - cwd: options.configDir, - stopAt: getProjectRoot(), - }); + const location = pkg.up({ cwd: options.configDir, last: getProjectRoot() }); if (!location) { return {}; } @@ -26,7 +23,7 @@ export const getAutoRefs = async (options: Options): Promise const list = await Promise.all( deps.map(async (d) => { try { - const l = resolveFrom(directory, join(d, 'package.json')); + const l = resolve.from(directory, join(d, 'package.json')); const { storybook, name, version } = JSON.parse(await readFile(l, { encoding: 'utf8' })) || {}; diff --git a/code/core/src/common/utils/paths.ts b/code/core/src/common/utils/paths.ts index de29cb6d8c15..d35ee86ceb2d 100644 --- a/code/core/src/common/utils/paths.ts +++ b/code/core/src/common/utils/paths.ts @@ -1,6 +1,8 @@ import { join, relative, resolve, sep } from 'node:path'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; +import * as walk from 'empathic/walk'; +import { globSync } from 'tinyglobby'; import { LOCK_FILES } from '../js-package-manager/constants'; @@ -17,10 +19,7 @@ export const getProjectRoot = () => { } try { - const found = - findUpSync('.git', { type: 'directory' }) || - findUpSync('.svn', { type: 'directory' }) || - findUpSync('.hg', { type: 'directory' }); + const found = find.up('.git') || find.up('.svn') || find.up('.hg'); if (found) { projectRoot = join(found, '..'); return projectRoot; @@ -30,7 +29,7 @@ export const getProjectRoot = () => { } try { - const found = findUpSync(LOCK_FILES, { type: 'file' }); + const found = find.any(LOCK_FILES); if (found) { projectRoot = join(found, '..'); return projectRoot; @@ -61,6 +60,16 @@ export const invalidateProjectRootCache = () => { projectRoot = undefined; }; +/** Finds files in the directory tree up to the project root */ +export const findFilesUp = (matchers: string[], baseDir = process.cwd()) => { + const matchingFiles: string[] = []; + for (const directory of walk.up(baseDir, { last: getProjectRoot() })) { + matchingFiles.push(...globSync(matchers, { cwd: directory, absolute: true })); + } + + return matchingFiles; +}; + export const nodePathsToArray = (nodePath: string) => nodePath .split(process.platform === 'win32' ? ';' : ':') diff --git a/code/core/src/common/utils/resolve-path-in-sb-cache.ts b/code/core/src/common/utils/resolve-path-in-sb-cache.ts index 17dd62a4c212..a45cc73e99d8 100644 --- a/code/core/src/common/utils/resolve-path-in-sb-cache.ts +++ b/code/core/src/common/utils/resolve-path-in-sb-cache.ts @@ -1,6 +1,6 @@ import { join } from 'node:path'; -import findCacheDirectory from 'find-cache-dir'; +import * as pkg from 'empathic/package'; /** * Get the path of the file or directory with input name inside the Storybook cache directory: @@ -12,7 +12,7 @@ import findCacheDirectory from 'find-cache-dir'; * @returns {string} Absolute path to the file or directory */ export function resolvePathInStorybookCache(fileOrDirectoryName: string, sub = 'default'): string { - let cacheDirectory = findCacheDirectory({ name: 'storybook' }); + let cacheDirectory = pkg.cache('storybook'); cacheDirectory ||= join(process.cwd(), 'node_modules', '.cache', 'storybook'); return join(cacheDirectory, sub, fileOrDirectoryName); diff --git a/code/core/src/core-server/utils/StoryIndexGenerator.ts b/code/core/src/core-server/utils/StoryIndexGenerator.ts index 64841b4727a4..9a4be8f30d97 100644 --- a/code/core/src/core-server/utils/StoryIndexGenerator.ts +++ b/code/core/src/core-server/utils/StoryIndexGenerator.ts @@ -21,7 +21,7 @@ import type { Tag, } from 'storybook/internal/types'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import picocolors from 'picocolors'; import slash from 'slash'; import invariant from 'tiny-invariant'; @@ -414,9 +414,9 @@ export class StoryIndexGenerator { invariant(indexer, `No matching indexer found for ${absolutePath}`); const indexInputs = await indexer.createIndex(absolutePath, { makeTitle: defaultMakeTitle }); - const tsconfigPath = await findUp('tsconfig.json', { + const tsconfigPath = find.up('tsconfig.json', { cwd: this.options.workingDir, - stopAt: getProjectRoot(), + last: getProjectRoot(), }); const tsconfig = TsconfigPaths.loadConfig(tsconfigPath); let matchPath: TsconfigPaths.MatchPath | undefined; diff --git a/code/core/src/core-server/utils/__tests__/server-address.test.ts b/code/core/src/core-server/utils/__tests__/server-address.test.ts index d4da0d269849..9825cce6529d 100644 --- a/code/core/src/core-server/utils/__tests__/server-address.test.ts +++ b/code/core/src/core-server/utils/__tests__/server-address.test.ts @@ -1,28 +1,38 @@ import os, { type NetworkInterfaceInfoIPv4 } from 'node:os'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; import { getServerAddresses } from '../server-address'; -vi.mock('node:os'); +const mockedNetworkAddress: NetworkInterfaceInfoIPv4 = { + address: '192.168.0.5', + netmask: '255.255.255.0', + family: 'IPv4', + mac: '01:02:03:0a:0b:0c', + internal: false, + cidr: '192.168.0.5/24', +}; + +vi.mock( + 'node:os', + async (importOriginal): Promise => ({ + ...(await importOriginal()), + // We have to mock both the default export and named exports here for whatever reason + ['default' as never]: { + networkInterfaces: vi.fn(() => ({ + eth0: [mockedNetworkAddress], + })), + release: vi.fn(() => '10.0.26100'), + }, + networkInterfaces: vi.fn(() => ({ + eth0: [mockedNetworkAddress], + })), + release: vi.fn(() => '10.0.26100'), + }) +); const mockedOs = vi.mocked(os); describe('getServerAddresses', () => { - const mockedNetworkAddress: NetworkInterfaceInfoIPv4 = { - address: '192.168.0.5', - netmask: '255.255.255.0', - family: 'IPv4', - mac: '01:02:03:0a:0b:0c', - internal: false, - cidr: '192.168.0.5/24', - }; - - beforeEach(() => { - mockedOs.networkInterfaces.mockReturnValue({ - eth0: [mockedNetworkAddress], - }); - }); - it('builds addresses with a specified host', () => { const { address, networkAddress } = getServerAddresses(9009, '192.168.89.89', 'http'); expect(address).toEqual('http://localhost:9009/'); diff --git a/code/core/src/telemetry/package-json.ts b/code/core/src/telemetry/package-json.ts index 5c668e75af4c..26be7c3a171d 100644 --- a/code/core/src/telemetry/package-json.ts +++ b/code/core/src/telemetry/package-json.ts @@ -1,7 +1,6 @@ -import { readFile } from 'node:fs/promises'; import { fileURLToPath, pathToFileURL } from 'node:url'; -import { findUp } from 'find-up'; +import * as pkg from 'empathic/package'; import { join } from 'pathe'; import type { PackageJson } from 'type-fest'; @@ -31,7 +30,7 @@ export const getActualPackageJson = async ( packageName: string ): Promise => { try { - let resolvedPackageJsonPath = await findUp('package.json', { + let resolvedPackageJsonPath = pkg.up({ cwd: fileURLToPath(import.meta.resolve(packageName, process.cwd())), }); if (!resolvedPackageJsonPath) { diff --git a/code/core/src/telemetry/storybook-metadata.ts b/code/core/src/telemetry/storybook-metadata.ts index d7574d438d9a..2aafcbe5bac7 100644 --- a/code/core/src/telemetry/storybook-metadata.ts +++ b/code/core/src/telemetry/storybook-metadata.ts @@ -1,3 +1,4 @@ +import { readFile } from 'node:fs/promises'; import { dirname } from 'node:path'; import { @@ -10,7 +11,7 @@ import { import { readConfig } from 'storybook/internal/csf-tools'; import type { PackageJson, StorybookConfig } from 'storybook/internal/types'; -import { findPackage, findPackagePath } from 'fd-package-json'; +import * as pkg from 'empathic/package'; import { version } from '../../package.json'; import { globalSettings } from '../cli/globalSettings'; @@ -246,11 +247,11 @@ export const computeStorybookMetadata = async ({ }; async function getPackageJsonDetails() { - const packageJsonPath = await findPackagePath(process.cwd()); + const packageJsonPath = pkg.up(); if (packageJsonPath) { return { packageJsonPath, - packageJson: (await findPackage(packageJsonPath)) || {}, + packageJson: JSON.parse(await readFile(packageJsonPath, 'utf8')), }; } diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index 2b1cd3e9d030..78cb0435411c 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -83,8 +83,7 @@ "@angular/platform-browser-dynamic": "^19.1.1", "@storybook/core-webpack": "workspace:*", "@types/node": "^22.0.0", - "fd-package-json": "^1.2.0", - "find-up": "^7.0.0", + "empathic": "^2.0.0", "rimraf": "^6.0.1", "typescript": "^5.8.3", "webpack": "5", diff --git a/code/frameworks/angular/src/builders/build-storybook/index.spec.ts b/code/frameworks/angular/src/builders/build-storybook/index.spec.ts index 3b62deeb8c69..4a8a37ac9080 100644 --- a/code/frameworks/angular/src/builders/build-storybook/index.spec.ts +++ b/code/frameworks/angular/src/builders/build-storybook/index.spec.ts @@ -25,7 +25,7 @@ vi.doMock('storybook/internal/common', () => ({ storybook: 'x.x.x', }, })); -vi.doMock('find-up', () => ({ sync: () => './storybook/tsconfig.ts' })); +vi.doMock('empathic/find', () => ({ up: () => './storybook/tsconfig.ts' })); const mockRunScript = vi.fn(); diff --git a/code/frameworks/angular/src/builders/build-storybook/index.ts b/code/frameworks/angular/src/builders/build-storybook/index.ts index c1eaf8e7592c..b12b7cb99fe8 100644 --- a/code/frameworks/angular/src/builders/build-storybook/index.ts +++ b/code/frameworks/angular/src/builders/build-storybook/index.ts @@ -1,3 +1,5 @@ +import { readFileSync } from 'node:fs'; + import { getEnvConfig, getProjectRoot, versions } from 'storybook/internal/common'; import { buildStaticStandalone, withTelemetry } from 'storybook/internal/core-server'; import { addToGlobalContext } from 'storybook/internal/telemetry'; @@ -22,8 +24,8 @@ import type { StyleElement, } from '@angular-devkit/build-angular/src/builders/browser/schema'; import type { JsonObject } from '@angular-devkit/core'; -import { findPackageSync } from 'fd-package-json'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; +import * as pkg from 'empathic/package'; import { from, of, throwError } from 'rxjs'; import { catchError, map, mapTo, switchMap } from 'rxjs/operators'; @@ -72,9 +74,9 @@ const commandBuilder: BuilderHandlerFn = ( ): BuilderOutputLike => { const builder = from(setup(options, context)).pipe( switchMap(({ tsConfig }) => { - const docTSConfig = findUpSync('tsconfig.doc.json', { + const docTSConfig = find.up('tsconfig.doc.json', { cwd: options.configDir, - stopAt: getProjectRoot(), + last: getProjectRoot(), }); const runCompodoc$ = options.compodoc ? runCompodoc( @@ -114,8 +116,12 @@ const commandBuilder: BuilderHandlerFn = ( experimentalZoneless = false, } = options; + const packageJsonPath = pkg.up({ cwd: __dirname }); + const packageJson = + packageJsonPath != null ? JSON.parse(readFileSync(packageJsonPath, 'utf8')) : null; + const standaloneOptions: StandaloneBuildOptions = { - packageJson: findPackageSync(__dirname), + packageJson, configDir, ...(docs ? { docs } : {}), loglevel, @@ -169,7 +175,7 @@ async function setup(options: StorybookBuilderOptions, context: BuilderContext) return { tsConfig: options.tsConfig ?? - findUpSync('tsconfig.json', { cwd: options.configDir, stopAt: getProjectRoot() }) ?? + find.up('tsconfig.json', { cwd: options.configDir, last: getProjectRoot() }) ?? browserOptions.tsConfig, }; } diff --git a/code/frameworks/angular/src/builders/start-storybook/index.spec.ts b/code/frameworks/angular/src/builders/start-storybook/index.spec.ts index cdce7ad01f06..ace692f2758a 100644 --- a/code/frameworks/angular/src/builders/start-storybook/index.spec.ts +++ b/code/frameworks/angular/src/builders/start-storybook/index.spec.ts @@ -12,7 +12,7 @@ const buildMock = { withTelemetry: (_: string, __: any, fn: any) => fn(), }; vi.doMock('storybook/internal/core-server', () => buildMock); -vi.doMock('find-up', () => ({ sync: () => './storybook/tsconfig.ts' })); +vi.doMock('empathic/find', () => ({ up: () => './storybook/tsconfig.ts' })); const mockRunScript = vi.fn(); diff --git a/code/frameworks/angular/src/builders/start-storybook/index.ts b/code/frameworks/angular/src/builders/start-storybook/index.ts index 78c6ae221c0f..18f69daeb56e 100644 --- a/code/frameworks/angular/src/builders/start-storybook/index.ts +++ b/code/frameworks/angular/src/builders/start-storybook/index.ts @@ -1,3 +1,5 @@ +import { readFileSync } from 'node:fs'; + import { getEnvConfig, getProjectRoot, versions } from 'storybook/internal/common'; import { buildDevStandalone, withTelemetry } from 'storybook/internal/core-server'; import { addToGlobalContext } from 'storybook/internal/telemetry'; @@ -21,8 +23,8 @@ import type { StyleElement, } from '@angular-devkit/build-angular/src/builders/browser/schema'; import type { JsonObject } from '@angular-devkit/core'; -import { findPackageSync } from 'fd-package-json'; -import { findUpSync } from 'find-up'; +import * as find from 'empathic/find'; +import * as pkg from 'empathic/package'; import { Observable, from, of } from 'rxjs'; import { map, mapTo, switchMap } from 'rxjs/operators'; @@ -73,9 +75,9 @@ export type StorybookBuilderOutput = JsonObject & BuilderOutput & {}; const commandBuilder: BuilderHandlerFn = (options, context) => { const builder = from(setup(options, context)).pipe( switchMap(({ tsConfig }) => { - const docTSConfig = findUpSync('tsconfig.doc.json', { + const docTSConfig = find.up('tsconfig.doc.json', { cwd: options.configDir, - stopAt: getProjectRoot(), + last: getProjectRoot(), }); const runCompodoc$ = options.compodoc @@ -131,8 +133,12 @@ const commandBuilder: BuilderHandlerFn = (options, cont experimentalZoneless = false, } = options; + const packageJsonPath = pkg.up({ cwd: __dirname }); + const packageJson = + packageJsonPath != null ? JSON.parse(readFileSync(packageJsonPath, 'utf8')) : null; + const standaloneOptions: StandaloneOptions = { - packageJson: findPackageSync(__dirname), + packageJson, ci, configDir, ...(docs ? { docs } : {}), @@ -194,7 +200,7 @@ async function setup(options: StorybookBuilderOptions, context: BuilderContext) return { tsConfig: options.tsConfig ?? - findUpSync('tsconfig.json', { cwd: options.configDir }) ?? + find.up('tsconfig.json', { cwd: options.configDir }) ?? browserOptions.tsConfig, }; } diff --git a/code/frameworks/angular/src/server/framework-preset-angular-cli.test.ts b/code/frameworks/angular/src/server/framework-preset-angular-cli.test.ts index 700e2e865e74..89cdf948e543 100644 --- a/code/frameworks/angular/src/server/framework-preset-angular-cli.test.ts +++ b/code/frameworks/angular/src/server/framework-preset-angular-cli.test.ts @@ -34,9 +34,7 @@ vi.mock('@angular-devkit/architect', () => ({ targetFromTargetString: vi.fn(), })); -vi.mock('find-up', () => ({ - findUp: vi.fn(), -})); +vi.mock('empathic/find', () => ({ up: vi.fn() })); vi.mock('./utils/module-is-available', () => ({ moduleIsAvailable: vi.fn(), @@ -58,7 +56,7 @@ const mockedLogger = vi.mocked(logger); const mockedTargetFromTargetString = vi.mocked( await import('@angular-devkit/architect') ).targetFromTargetString; -const mockedFindUp = vi.mocked(await import('find-up')).findUp; +const mockedFindUp = vi.mocked(await import('empathic/find')).up; const mockedGetProjectRoot = vi.mocked(await import('storybook/internal/common')).getProjectRoot; describe('framework-preset-angular-cli', () => { @@ -77,7 +75,7 @@ describe('framework-preset-angular-cli', () => { beforeEach(() => { mockedGetProjectRoot.mockReturnValue('/test/project'); - mockedFindUp.mockResolvedValue('/test/tsconfig.json'); + mockedFindUp.mockReturnValue('/test/tsconfig.json'); }); it('should get browser target options when angularBrowserTarget is provided', async () => { @@ -164,7 +162,7 @@ describe('framework-preset-angular-cli', () => { expect(mockedFindUp).toHaveBeenCalledWith('tsconfig.json', { cwd: '/test/config', - stopAt: '/test/project', + last: '/test/project', }); expect(result.tsConfig).toBe('/test/tsconfig.json'); }); @@ -172,7 +170,7 @@ describe('framework-preset-angular-cli', () => { it('should use browser target tsConfig when no other tsConfig is available', async () => { const mockTarget = { project: 'test-project', target: 'build' }; mockedTargetFromTargetString.mockReturnValue(mockTarget); - mockedFindUp.mockResolvedValue(null); + mockedFindUp.mockReturnValue(null); const browserTargetOptions = { tsConfig: '/browser/tsconfig.json' }; vi.mocked(mockBuilderContext.getTargetOptions).mockResolvedValue(browserTargetOptions); diff --git a/code/frameworks/angular/src/server/framework-preset-angular-cli.ts b/code/frameworks/angular/src/server/framework-preset-angular-cli.ts index bf45e7600463..cd66ad4fc779 100644 --- a/code/frameworks/angular/src/server/framework-preset-angular-cli.ts +++ b/code/frameworks/angular/src/server/framework-preset-angular-cli.ts @@ -6,7 +6,7 @@ import type { BuilderContext } from '@angular-devkit/architect'; import { targetFromTargetString } from '@angular-devkit/architect'; import type { JsonObject } from '@angular-devkit/core'; import { logging } from '@angular-devkit/core'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import type webpack from 'webpack'; import { getWebpackConfig as getCustomWebpackConfig } from './angular-cli-webpack'; @@ -146,9 +146,8 @@ export async function getBuilderOptions(options: PresetOptions, builderContext: // Handle tsConfig separately to maintain existing logic builderOptions.tsConfig = options.tsConfig ?? - (await findUp('tsconfig.json', { cwd: options.configDir, stopAt: getProjectRoot() })) ?? + find.up('tsconfig.json', { cwd: options.configDir, last: getProjectRoot() }) ?? browserTargetOptions.tsConfig; - logger.info(`=> Using angular project with "tsConfig:${builderOptions.tsConfig}"`); return builderOptions; diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index fec7d95ab85e..69f99502000f 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -53,7 +53,7 @@ "@storybook/builder-webpack5": "workspace:*", "@storybook/global": "^5.0.0", "babel-loader": "9.1.3", - "find-up": "^7.0.0" + "empathic": "2.0.0" }, "devDependencies": { "ember-source": "~3.28.1", diff --git a/code/frameworks/ember/src/util.ts b/code/frameworks/ember/src/util.ts index 012b79b3fc97..926e94fe8213 100644 --- a/code/frameworks/ember/src/util.ts +++ b/code/frameworks/ember/src/util.ts @@ -2,10 +2,10 @@ import { dirname, join } from 'node:path'; import { getProjectRoot } from 'storybook/internal/common'; -import { findUpSync } from 'find-up'; +import * as pkg from 'empathic/package'; export const findDistFile = (cwd: string, relativePath: string) => { - const nearestPackageJson = findUpSync('package.json', { cwd, stopAt: getProjectRoot() }); + const nearestPackageJson = pkg.up({ cwd, last: getProjectRoot() }); if (!nearestPackageJson) { throw new Error(`Could not find package.json in: ${cwd}`); } diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index ae0071244a18..eb7dfc47d41c 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -57,7 +57,7 @@ "@rollup/pluginutils": "^5.0.2", "@storybook/builder-vite": "workspace:*", "@storybook/react": "workspace:*", - "find-up": "^7.0.0", + "empathic": "^2.0.0", "magic-string": "^0.30.0", "react-docgen": "^8.0.0", "resolve": "^1.22.8", diff --git a/code/frameworks/react-vite/src/plugins/react-docgen.ts b/code/frameworks/react-vite/src/plugins/react-docgen.ts index d63e39b5aa4b..75a6ff8eb27f 100644 --- a/code/frameworks/react-vite/src/plugins/react-docgen.ts +++ b/code/frameworks/react-vite/src/plugins/react-docgen.ts @@ -5,7 +5,7 @@ import { getProjectRoot } from 'storybook/internal/common'; import { logger } from 'storybook/internal/node-logger'; import { createFilter } from '@rollup/pluginutils'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import MagicString from 'magic-string'; import type { Documentation } from 'react-docgen'; import { @@ -44,7 +44,7 @@ export async function reactDocgen({ const cwd = process.cwd(); const filter = createFilter(include, exclude); - const tsconfigPath = await findUp('tsconfig.json', { cwd, stopAt: getProjectRoot() }); + const tsconfigPath = find.up('tsconfig.json', { cwd, last: getProjectRoot() }); const tsconfig = TsconfigPaths.loadConfig(tsconfigPath); let matchPath: TsconfigPaths.MatchPath | undefined; diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index 4fb2bc1e3950..a4bc1639b05d 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -53,14 +53,12 @@ "dependencies": { "@storybook/builder-vite": "workspace:*", "@storybook/vue3": "workspace:*", - "find-package-json": "^1.2.0", "magic-string": "^0.30.0", "typescript": "^5.8.3", "vue-component-meta": "^2.0.0", "vue-docgen-api": "^4.75.1" }, "devDependencies": { - "@types/find-package-json": "^1.2.6", "@types/node": "^22.0.0", "typescript": "^5.8.3", "vite": "^7.0.4" diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index e2248c9239e7..391287daf0a3 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -56,9 +56,9 @@ "boxen": "^7.1.1", "comment-json": "^4.2.5", "cross-spawn": "^7.0.6", + "empathic": "^2.0.0", "envinfo": "^7.14.0", "execa": "^9.6.0", - "find-up": "^7.0.0", "globby": "^14.0.1", "leven": "^4.0.0", "p-limit": "^6.2.0", diff --git a/code/lib/cli-storybook/src/util.ts b/code/lib/cli-storybook/src/util.ts index 0c6bf6416ed9..c12e9c8128f8 100644 --- a/code/lib/cli-storybook/src/util.ts +++ b/code/lib/cli-storybook/src/util.ts @@ -10,7 +10,7 @@ import { import type { StorybookConfigRaw } from 'storybook/internal/types'; import boxen, { type Options } from 'boxen'; -import { findUpMultipleSync } from 'find-up'; +import * as walk from 'empathic/walk'; // eslint-disable-next-line depend/ban-dependencies import { globby, globbySync } from 'globby'; import picocolors from 'picocolors'; @@ -755,21 +755,15 @@ export const getProjects = async ( /** Finds files in the directory tree up to the project root */ export const findFilesUp = (matchers: string[], cwd: string) => { const matchingFiles: string[] = []; - findUpMultipleSync( - (directory) => { - matchingFiles.push( - ...globbySync(matchers, { - gitignore: true, - cwd: directory, - }) - ); - return undefined; - }, - { - cwd, - stopAt: getProjectRoot(), - } - ); + for (const directory of walk.up(cwd, { last: getProjectRoot() })) { + matchingFiles.push( + ...globbySync(matchers, { + gitignore: true, + absolute: true, + cwd: directory, + }) + ); + } return matchingFiles; }; diff --git a/code/lib/create-storybook/package.json b/code/lib/create-storybook/package.json index 87145722e858..f2919cdf6517 100644 --- a/code/lib/create-storybook/package.json +++ b/code/lib/create-storybook/package.json @@ -50,8 +50,8 @@ "@types/semver": "^7.3.4", "boxen": "^7.1.1", "commander": "^12.1.0", + "empathic": "^2.0.0", "execa": "^5.0.0", - "find-up": "^7.0.0", "ora": "^5.4.1", "picocolors": "^1.1.0", "process-ancestry": "^0.0.2", diff --git a/code/lib/create-storybook/src/initiate.ts b/code/lib/create-storybook/src/initiate.ts index 5a818d8a16e3..e073bfe36946 100644 --- a/code/lib/create-storybook/src/initiate.ts +++ b/code/lib/create-storybook/src/initiate.ts @@ -31,7 +31,7 @@ import { NxProjectDetectedError } from 'storybook/internal/server-errors'; import { telemetry } from 'storybook/internal/telemetry'; import boxen from 'boxen'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import picocolors from 'picocolors'; import { getProcessAncestry } from 'process-ancestry'; import prompts from 'prompts'; @@ -628,7 +628,7 @@ export async function doInitiate(options: CommandOptions): Promise< } const vitestConfigFilesData = await vitestConfigFiles.condition( - { babel, findUp, fs } as any, + { babel, empathic: find, fs } as any, { directory: process.cwd() } as any ); if (vitestConfigFilesData.type === 'incompatible') { @@ -714,7 +714,7 @@ export async function doInitiate(options: CommandOptions): Promise< return { shouldRunDev: false }; } - const foundGitIgnoreFile = await findUp('.gitignore'); + const foundGitIgnoreFile = find.up('.gitignore'); const rootDirectory = getProjectRoot(); if (foundGitIgnoreFile && foundGitIgnoreFile.includes(rootDirectory)) { const contents = await fs.readFile(foundGitIgnoreFile, 'utf-8'); diff --git a/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.test.ts b/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.test.ts index 5c7a9f98b2a8..3e25c97ff84f 100644 --- a/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.test.ts +++ b/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.test.ts @@ -4,11 +4,11 @@ import { describe, expect, it } from 'vitest'; import * as babel from 'storybook/internal/babel'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import { vitestConfigFiles } from './vitestConfigFiles'; -const liveContext: any = { babel, findUp, fs }; +const liveContext: any = { babel, empathic: find, fs }; const fileMocks = { 'vitest.config.ts': ` @@ -72,7 +72,7 @@ const fileMocks = { const mockContext: any = { ...liveContext, - findUp: async ([name]: string[]) => name, + empathic: { any: ([name]: string[]) => name }, fs: { readFile: async (path: keyof typeof fileMocks) => fileMocks[path], }, @@ -103,14 +103,19 @@ describe.skip('these tests need to be updated', () => { const result = await vitestConfigFiles.condition({} as any, state); expect(result).toEqual({ type: 'incompatible', - reasons: ['Missing babel on context', 'Missing findUp on context', 'Missing fs on context'], + reasons: ['Missing babel on context', 'Missing empathic on context', 'Missing fs on context'], }); }); describe('Check Vitest workspace files', () => { it('should disallow JSON workspace file', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('workspace', 'vitest.workspace.json') }, + { + ...mockContext, + empathic: { + up: coerce('workspace', 'vitest.workspace.json'), + }, + }, state ); expect(result).toEqual({ @@ -121,7 +126,12 @@ describe.skip('these tests need to be updated', () => { it('should disallow invalid workspace file', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('workspace', 'invalidWorkspace.ts') }, + { + ...mockContext, + empathic: { + up: coerce('workspace', 'invalidWorkspace.ts'), + }, + }, state ); expect(result).toEqual({ @@ -132,7 +142,12 @@ describe.skip('these tests need to be updated', () => { it('should allow defineWorkspace syntax', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('workspace', 'defineWorkspace.ts') }, + { + ...mockContext, + empathic: { + up: coerce('workspace', 'defineWorkspace.ts'), + }, + }, state ); expect(result).toEqual({ @@ -142,7 +157,12 @@ describe.skip('these tests need to be updated', () => { it('should disallow invalid defineWorkspace syntax', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('workspace', 'defineWorkspace-invalid.ts') }, + { + ...mockContext, + empathic: { + up: coerce('workspace', 'defineWorkspace-invalid.ts'), + }, + }, state ); expect(result).toEqual({ @@ -155,7 +175,12 @@ describe.skip('these tests need to be updated', () => { describe('Check Vitest config files', () => { it('should disallow CommonJS config file', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('config', 'vitest.config.cjs') }, + { + ...mockContext, + empathic: { + up: coerce('config', 'vitest.config.cjs'), + }, + }, state ); expect(result).toEqual({ @@ -166,7 +191,12 @@ describe.skip('these tests need to be updated', () => { it('should disallow invalid config file', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('config', 'invalidConfig.ts') }, + { + ...mockContext, + empathic: { + up: coerce('config', 'invalidConfig.ts'), + }, + }, state ); expect(result).toEqual({ @@ -177,7 +207,12 @@ describe.skip('these tests need to be updated', () => { it('should allow existing test config option', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('config', 'testConfig.ts') }, + { + ...mockContext, + empathic: { + up: coerce('config', 'testConfig.ts'), + }, + }, state ); expect(result).toEqual({ @@ -187,7 +222,12 @@ describe.skip('these tests need to be updated', () => { it('should disallow invalid test config option', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('config', 'testConfig-invalid.ts') }, + { + ...mockContext, + empathic: { + up: coerce('config', 'testConfig-invalid.ts'), + }, + }, state ); expect(result).toEqual({ @@ -198,7 +238,12 @@ describe.skip('these tests need to be updated', () => { it('should allow existing test.workspace config option', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('config', 'workspaceConfig.ts') }, + { + ...mockContext, + empathic: { + up: coerce('config', 'workspaceConfig.ts'), + }, + }, state ); expect(result).toEqual({ @@ -208,7 +253,12 @@ describe.skip('these tests need to be updated', () => { it('should disallow invalid test.workspace config option', async () => { const result = await vitestConfigFiles.condition( - { ...mockContext, findUp: coerce('config', 'workspaceConfig-invalid.ts') }, + { + ...mockContext, + empathic: { + up: coerce('config', 'workspaceConfig-invalid.ts'), + }, + }, state ); expect(result).toEqual({ diff --git a/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.tsx b/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.tsx index a8d9eab998ba..0b2188840035 100644 --- a/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.tsx +++ b/code/lib/create-storybook/src/ink/steps/checks/vitestConfigFiles.tsx @@ -3,7 +3,7 @@ import * as fs from 'node:fs/promises'; import * as babel from 'storybook/internal/babel'; import { getProjectRoot } from 'storybook/internal/common'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import type { Check } from './Check'; import { CompatibilityType } from './CompatibilityType'; @@ -89,15 +89,15 @@ export const isValidWorkspaceConfigFile: (fileContents: string, babel: any) => b */ export const vitestConfigFiles: Check = { condition: async (context, state) => { - const deps = ['babel', 'findUp', 'fs']; - if (babel && findUp && fs) { + const deps = ['babel', 'empathic', 'fs']; + if (babel && find && fs) { const reasons = []; const projectRoot = getProjectRoot(); - const vitestWorkspaceFile = await findUp( + const vitestWorkspaceFile = find.any( ['ts', 'js', 'json'].flatMap((ex) => [`vitest.workspace.${ex}`, `vitest.projects.${ex}`]), - { cwd: state.directory, stopAt: projectRoot } + { cwd: state.directory, last: projectRoot } ); if (vitestWorkspaceFile?.endsWith('.json')) { reasons.push(`Cannot auto-update JSON workspace file: ${vitestWorkspaceFile}`); @@ -108,9 +108,9 @@ export const vitestConfigFiles: Check = { } } - const vitestConfigFile = await findUp( + const vitestConfigFile = find.any( ['ts', 'js', 'tsx', 'jsx', 'cts', 'cjs', 'mts', 'mjs'].map((ex) => `vitest.config.${ex}`), - { cwd: state.directory, stopAt: projectRoot } + { cwd: state.directory, last: projectRoot } ); if (vitestConfigFile?.endsWith('.cts') || vitestConfigFile?.endsWith('.cjs')) { reasons.push(`Cannot auto-update CommonJS config file: ${vitestConfigFile}`); diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index 233e625c18dc..3170ef2c876d 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -54,7 +54,7 @@ }, "devDependencies": { "@types/node": "^22.0.0", - "find-up": "^7.0.0", + "empathic": "^2.0.0", "typescript": "^5.8.3" }, "peerDependencies": { diff --git a/code/presets/react-webpack/src/loaders/react-docgen-loader.ts b/code/presets/react-webpack/src/loaders/react-docgen-loader.ts index a987244c624b..bff38248b7c2 100644 --- a/code/presets/react-webpack/src/loaders/react-docgen-loader.ts +++ b/code/presets/react-webpack/src/loaders/react-docgen-loader.ts @@ -1,7 +1,7 @@ import { getProjectRoot } from 'storybook/internal/common'; import { logger } from 'storybook/internal/node-logger'; -import { findUp } from 'find-up'; +import * as find from 'empathic/find'; import MagicString from 'magic-string'; import { ERROR_CODES, @@ -81,10 +81,7 @@ export default async function reactDocgenLoader( const { debug = false } = options; if (!tsconfigPathsInitialized) { - const tsconfigPath = await findUp('tsconfig.json', { - cwd: process.cwd(), - stopAt: getProjectRoot(), - }); + const tsconfigPath = find.up('tsconfig.json', { cwd: process.cwd(), last: getProjectRoot() }); const tsconfig = TsconfigPaths.loadConfig(tsconfigPath); if (tsconfig.resultType === 'success') { diff --git a/code/vitest.config.ts b/code/vitest.config.ts index 0eef8a17b4ba..7cf69b767e92 100644 --- a/code/vitest.config.ts +++ b/code/vitest.config.ts @@ -2,6 +2,10 @@ import { coverageConfigDefaults, defineConfig } from 'vitest/config'; export default defineConfig({ test: { + env: { + NODE_ENV: 'test', + }, + coverage: { all: false, provider: 'istanbul', diff --git a/code/yarn.lock b/code/yarn.lock index 6083534e3c3d..bb99a240803b 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6084,9 +6084,9 @@ __metadata: "@vitest/browser": "npm:^3.2.4" "@vitest/runner": "npm:^3.2.4" boxen: "npm:^8.0.1" + empathic: "npm:^2.0.0" es-toolkit: "npm:^1.36.0" execa: "npm:^8.0.1" - find-up: "npm:^7.0.0" istanbul-lib-report: "npm:^3.0.1" micromatch: "npm:^4.0.8" pathe: "npm:^1.1.2" @@ -6137,8 +6137,7 @@ __metadata: "@storybook/core-webpack": "workspace:*" "@storybook/global": "npm:^5.0.0" "@types/node": "npm:^22.0.0" - fd-package-json: "npm:^1.2.0" - find-up: "npm:^7.0.0" + empathic: "npm:^2.0.0" rimraf: "npm:^6.0.1" telejson: "npm:8.0.0" ts-dedent: "npm:^2.0.0" @@ -6203,10 +6202,9 @@ __metadata: resolution: "@storybook/builder-vite@workspace:builders/builder-vite" dependencies: "@storybook/csf-plugin": "workspace:*" - "@types/find-cache-dir": "npm:^3.2.1" "@types/node": "npm:^22.0.0" + empathic: "npm:^2.0.0" es-module-lexer: "npm:^1.5.0" - find-cache-dir: "npm:^3.0.0" glob: "npm:^10.0.0" knitwork: "npm:^1.1.0" magic-string: "npm:^0.30.0" @@ -6267,9 +6265,9 @@ __metadata: comment-json: "npm:^4.2.5" create-storybook: "workspace:*" cross-spawn: "npm:^7.0.6" + empathic: "npm:^2.0.0" envinfo: "npm:^7.14.0" execa: "npm:^9.6.0" - find-up: "npm:^7.0.0" giget: "npm:^1.0.0" globby: "npm:^14.0.1" jscodeshift: "npm:^0.15.1" @@ -6361,7 +6359,7 @@ __metadata: "@storybook/global": "npm:^5.0.0" babel-loader: "npm:9.1.3" ember-source: "npm:~3.28.1" - find-up: "npm:^7.0.0" + empathic: "npm:2.0.0" typescript: "npm:^5.8.3" peerDependencies: "@babel/core": "*" @@ -6556,7 +6554,7 @@ __metadata: "@storybook/react-docgen-typescript-plugin": "npm:1.0.6--canary.9.0c3f3b7.0" "@types/node": "npm:^22.0.0" "@types/semver": "npm:^7.3.4" - find-up: "npm:^7.0.0" + empathic: "npm:^2.0.0" magic-string: "npm:^0.30.5" react-docgen: "npm:^7.1.1" resolve: "npm:^1.22.8" @@ -6650,7 +6648,7 @@ __metadata: "@storybook/builder-vite": "workspace:*" "@storybook/react": "workspace:*" "@types/node": "npm:^22.0.0" - find-up: "npm:^7.0.0" + empathic: "npm:^2.0.0" magic-string: "npm:^0.30.0" react-docgen: "npm:^8.0.0" resolve: "npm:^1.22.8" @@ -6946,9 +6944,7 @@ __metadata: dependencies: "@storybook/builder-vite": "workspace:*" "@storybook/vue3": "workspace:*" - "@types/find-package-json": "npm:^1.2.6" "@types/node": "npm:^22.0.0" - find-package-json: "npm:^1.2.0" magic-string: "npm:^0.30.0" typescript: "npm:^5.8.3" vite: "npm:^7.0.4" @@ -7620,31 +7616,6 @@ __metadata: languageName: node linkType: hard -"@types/find-cache-dir@npm:^3.2.1": - version: 3.2.1 - resolution: "@types/find-cache-dir@npm:3.2.1" - checksum: 10c0/68059aec88ef776a689c1711a881fd91a9ce1b03dd5898ea1d2ac5d77d7b0235f21fdf210f380c13deca8b45e4499841a63aaf31fd2123af687f2c6b472f41ce - languageName: node - linkType: hard - -"@types/find-cache-dir@npm:^5.0.0": - version: 5.0.2 - resolution: "@types/find-cache-dir@npm:5.0.2" - dependencies: - find-cache-dir: "npm:*" - checksum: 10c0/684efb5961dcc5c8813a5ab14645c692ce036bebbc0258443dc4a154c63f9c87c0287ef32ca792110b82c2b96d590dfdf7d1bf59b61717a8109ee619e489f3b5 - languageName: node - linkType: hard - -"@types/find-package-json@npm:^1.2.6": - version: 1.2.6 - resolution: "@types/find-package-json@npm:1.2.6" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/e9ec7d10f9c919b14cf391e710f41ff6684a6e6d87afc6322e7f7e3afe30b5f046b806767cb1509af6265e3f4ceb11fac9da279757839269a4c849359d7f5f18 - languageName: node - linkType: hard - "@types/fs-extra@npm:^5.0.5": version: 5.1.0 resolution: "@types/fs-extra@npm:5.1.0" @@ -11818,8 +11789,8 @@ __metadata: "@types/semver": "npm:^7.3.4" boxen: "npm:^7.1.1" commander: "npm:^12.1.0" + empathic: "npm:^2.0.0" execa: "npm:^5.0.0" - find-up: "npm:^7.0.0" ora: "npm:^5.4.1" picocolors: "npm:^1.1.0" process-ancestry: "npm:^0.0.2" @@ -13021,6 +12992,13 @@ __metadata: languageName: node linkType: hard +"empathic@npm:2.0.0, empathic@npm:^2.0.0": + version: 2.0.0 + resolution: "empathic@npm:2.0.0" + checksum: 10c0/7d3b14b04a93b35c47bcc950467ec914fd241cd9acc0269b0ea160f13026ec110f520c90fae64720fde72cc1757b57f3f292fb606617b7fccac1f4d008a76506 + languageName: node + linkType: hard + "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -14743,16 +14721,6 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:*, find-cache-dir@npm:^5.0.0": - version: 5.0.0 - resolution: "find-cache-dir@npm:5.0.0" - dependencies: - common-path-prefix: "npm:^3.0.0" - pkg-dir: "npm:^7.0.0" - checksum: 10c0/e6403b35aaf862898aefadbe3ee27246583a69adcef21cd79b9262be407d1ac85b21a7e1c1d41712eae39c6d8a8ac297fd78123b5b7aea13f0f046744aa02453 - languageName: node - linkType: hard - "find-cache-dir@npm:^2.0.0": version: 2.1.0 resolution: "find-cache-dir@npm:2.1.0" @@ -14764,7 +14732,7 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^3.0.0, find-cache-dir@npm:^3.3.1": +"find-cache-dir@npm:^3.3.1": version: 3.3.2 resolution: "find-cache-dir@npm:3.3.2" dependencies: @@ -14792,13 +14760,6 @@ __metadata: languageName: node linkType: hard -"find-package-json@npm:^1.2.0": - version: 1.2.0 - resolution: "find-package-json@npm:1.2.0" - checksum: 10c0/85d6c97afb9f8f0deb0d344a1c4eb8027347cf4d61666c28d3ac3f913e916684441218682b3dd6f8ad570e5d43c96a7db521f70183d70df559d07e1f99cdc635 - languageName: node - linkType: hard - "find-root@npm:^1.1.0": version: 1.1.0 resolution: "find-root@npm:1.1.0" @@ -14854,17 +14815,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^7.0.0": - version: 7.0.0 - resolution: "find-up@npm:7.0.0" - dependencies: - locate-path: "npm:^7.2.0" - path-exists: "npm:^5.0.0" - unicorn-magic: "npm:^0.1.0" - checksum: 10c0/e6ee3e6154560bc0ab3bc3b7d1348b31513f9bdf49a5dd2e952495427d559fa48cdf33953e85a309a323898b43fa1bfbc8b80c880dfc16068384783034030008 - languageName: node - linkType: hard - "find-versions@npm:^4.0.0": version: 4.0.0 resolution: "find-versions@npm:4.0.0" @@ -18264,7 +18214,7 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^7.1.0, locate-path@npm:^7.2.0": +"locate-path@npm:^7.1.0": version: 7.2.0 resolution: "locate-path@npm:7.2.0" dependencies: @@ -23011,13 +22961,6 @@ __metadata: languageName: node linkType: hard -"resolve-from@npm:^5.0.0": - version: 5.0.0 - resolution: "resolve-from@npm:5.0.0" - checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2 - languageName: node - linkType: hard - "resolve-package-path@npm:^1.0.11": version: 1.2.7 resolution: "resolve-package-path@npm:1.2.7" @@ -24460,7 +24403,6 @@ __metadata: "@types/detect-port": "npm:^1.3.0" "@types/diff": "npm:^5.0.9" "@types/ejs": "npm:^3.1.1" - "@types/find-cache-dir": "npm:^5.0.0" "@types/js-yaml": "npm:^4.0.5" "@types/node": "npm:^22.0.0" "@types/npmlog": "npm:^7.0.0" @@ -24498,14 +24440,12 @@ __metadata: diff: "npm:^5.2.0" downshift: "npm:^9.0.4" ejs: "npm:^3.1.10" + empathic: "npm:^2.0.0" es-toolkit: "npm:^1.36.0" esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0" execa: "npm:^8.0.1" exsolve: "npm:^1.0.7" - fd-package-json: "npm:^1.2.0" fetch-retry: "npm:^6.0.0" - find-cache-dir: "npm:^5.0.0" - find-up: "npm:^7.0.0" flush-promises: "npm:^1.0.2" fuse.js: "npm:^3.6.1" get-npm-tarball-url: "npm:^2.0.3" @@ -24542,7 +24482,6 @@ __metadata: react-transition-group: "npm:^4.4.5" recast: "npm:^0.23.5" require-from-string: "npm:^2.0.2" - resolve-from: "npm:^5.0.0" resolve.exports: "npm:^2.0.3" semver: "npm:^7.6.2" sirv: "npm:^2.0.4" @@ -25821,13 +25760,6 @@ __metadata: languageName: node linkType: hard -"unicorn-magic@npm:^0.1.0": - version: 0.1.0 - resolution: "unicorn-magic@npm:0.1.0" - checksum: 10c0/e4ed0de05b0a05e735c7d8a2930881e5efcfc3ec897204d5d33e7e6247f4c31eac92e383a15d9a6bccb7319b4271ee4bea946e211bf14951fec6ff2cbbb66a92 - languageName: node - linkType: hard - "unicorn-magic@npm:^0.3.0": version: 0.3.0 resolution: "unicorn-magic@npm:0.3.0" diff --git a/docs/_snippets/storybook-server-framework-options.md b/docs/_snippets/storybook-server-framework-options.md index e660724c72ee..6918cc12a7e5 100644 --- a/docs/_snippets/storybook-server-framework-options.md +++ b/docs/_snippets/storybook-server-framework-options.md @@ -1,8 +1,9 @@ ```ts filename="my-framework/src/server/options.ts" renderer="common" language="ts" -import { sync } from 'read-pkg-up'; +import { readFileSync } from 'node:fs'; +import * as pkg from 'empathic/package'; export default { - packageJson: sync({ cwd: process.cwd() }).packageJson, + packageJson: JSON.parse(readFileSync(pkg.up({ cwd: process.cwd() }))), framework: 'my-framework', frameworkPath: '@my-framework/storybook', frameworkPresets: [import.meta.resolve('./framework-preset-my-framework.js')], diff --git a/docs/_snippets/storybook-server-options.md b/docs/_snippets/storybook-server-options.md index 8edf6cde1113..29ce1a8206cd 100644 --- a/docs/_snippets/storybook-server-options.md +++ b/docs/_snippets/storybook-server-options.md @@ -1,8 +1,9 @@ ```ts filename="vue/src/server/options.ts" renderer="common" language="ts" -import { sync } from 'read-pkg-up'; +import { readFileSync } from 'node:fs'; +import * as pkg from 'empathic/package'; export default { - packageJson: sync({ cwd: process.cwd() }).packageJson, + packageJson: JSON.parse(readFileSync(pkg.up({ cwd: process.cwd() }))), framework: 'vue', frameworkPresets: [import.meta.resolve('./framework-preset-vue.js')], }; diff --git a/scripts/package.json b/scripts/package.json index 307b8c252be3..0dae28f4b070 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -105,6 +105,7 @@ "diff-match-patch-es": "^0.1.0", "ejs": "^3.1.10", "ejs-lint": "^2.0.1", + "empathic": "^2.0.0", "es-toolkit": "^1.36.0", "esbuild": "^0.25.3", "eslint": "^8.57.0", @@ -126,7 +127,6 @@ "execa": "^6.1.0", "fast-folder-size": "^2.2.0", "fast-glob": "^3.3.2", - "find-up": "^5.0.0", "github-release-from-changelog": "^2.1.1", "glob": "^10.4.5", "http-server": "^14.1.1", @@ -159,7 +159,6 @@ "prompts": "^2.4.2", "react": "^18.3.1", "react-dom": "^18.3.1", - "read-pkg-up": "^7.0.1", "recast": "^0.23.9", "rollup": "^4.21.0", "rollup-plugin-dts": "^6.1.1", diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 46b4c5d9da2e..abb82c0d7b61 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -1558,6 +1558,7 @@ __metadata: diff-match-patch-es: "npm:^0.1.0" ejs: "npm:^3.1.10" ejs-lint: "npm:^2.0.1" + empathic: "npm:^2.0.0" es-toolkit: "npm:^1.36.0" esbuild: "npm:^0.25.3" eslint: "npm:^8.57.0" @@ -1579,7 +1580,6 @@ __metadata: execa: "npm:^6.1.0" fast-folder-size: "npm:^2.2.0" fast-glob: "npm:^3.3.2" - find-up: "npm:^5.0.0" github-release-from-changelog: "npm:^2.1.1" glob: "npm:^10.4.5" http-server: "npm:^14.1.1" @@ -1612,7 +1612,6 @@ __metadata: prompts: "npm:^2.4.2" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" - read-pkg-up: "npm:^7.0.1" recast: "npm:^0.23.9" rollup: "npm:^4.21.0" rollup-plugin-dts: "npm:^6.1.1" @@ -1945,13 +1944,6 @@ __metadata: languageName: node linkType: hard -"@types/normalize-package-data@npm:^2.4.0": - version: 2.4.3 - resolution: "@types/normalize-package-data@npm:2.4.3" - checksum: 10c0/9ad94568b53f65d0c7fffed61c74e4a7b8625b1ebbc549f1de25287c2d20e6bca9d9cdc5826e508c9d95e02a48ac69d0282121c300667071661f37090224416b - languageName: node - linkType: hard - "@types/parse-json@npm:^4.0.0": version: 4.0.1 resolution: "@types/parse-json@npm:4.0.1" @@ -4746,6 +4738,13 @@ __metadata: languageName: node linkType: hard +"empathic@npm:^2.0.0": + version: 2.0.0 + resolution: "empathic@npm:2.0.0" + checksum: 10c0/7d3b14b04a93b35c47bcc950467ec914fd241cd9acc0269b0ea160f13026ec110f520c90fae64720fde72cc1757b57f3f292fb606617b7fccac1f4d008a76506 + languageName: node + linkType: hard + "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -5940,16 +5939,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.1.0": - version: 4.1.0 - resolution: "find-up@npm:4.1.0" - dependencies: - locate-path: "npm:^5.0.0" - path-exists: "npm:^4.0.0" - checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1 - languageName: node - linkType: hard - "find-up@npm:^5.0.0": version: 5.0.0 resolution: "find-up@npm:5.0.0" @@ -6700,13 +6689,6 @@ __metadata: languageName: node linkType: hard -"hosted-git-info@npm:^2.1.4": - version: 2.8.9 - resolution: "hosted-git-info@npm:2.8.9" - checksum: 10c0/317cbc6b1bbbe23c2a40ae23f3dafe9fa349ce42a89a36f930e3f9c0530c179a3882d2ef1e4141a4c3674d6faaea862138ec55b43ad6f75e387fda2483a13c70 - languageName: node - linkType: hard - "html-encoding-sniffer@npm:^3.0.0": version: 3.0.0 resolution: "html-encoding-sniffer@npm:3.0.0" @@ -8066,15 +8048,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^5.0.0": - version: 5.0.0 - resolution: "locate-path@npm:5.0.0" - dependencies: - p-locate: "npm:^4.1.0" - checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59 - languageName: node - linkType: hard - "locate-path@npm:^6.0.0": version: 6.0.0 resolution: "locate-path@npm:6.0.0" @@ -9203,18 +9176,6 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^2.5.0": - version: 2.5.0 - resolution: "normalize-package-data@npm:2.5.0" - dependencies: - hosted-git-info: "npm:^2.1.4" - resolve: "npm:^1.10.0" - semver: "npm:2 || 3 || 4 || 5" - validate-npm-package-license: "npm:^3.0.1" - checksum: 10c0/357cb1646deb42f8eb4c7d42c4edf0eec312f3628c2ef98501963cc4bbe7277021b2b1d977f982b2edce78f5a1014613ce9cf38085c3df2d76730481357ca504 - languageName: node - linkType: hard - "npm-run-path@npm:^2.0.0": version: 2.0.2 resolution: "npm-run-path@npm:2.0.2" @@ -9511,7 +9472,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^2.1.0, p-limit@npm:^2.2.0": +"p-limit@npm:^2.1.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" dependencies: @@ -9529,15 +9490,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^4.1.0": - version: 4.1.0 - resolution: "p-locate@npm:4.1.0" - dependencies: - p-limit: "npm:^2.2.0" - checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9 - languageName: node - linkType: hard - "p-locate@npm:^5.0.0": version: 5.0.0 resolution: "p-locate@npm:5.0.0" @@ -10439,29 +10391,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^7.0.1": - version: 7.0.1 - resolution: "read-pkg-up@npm:7.0.1" - dependencies: - find-up: "npm:^4.1.0" - read-pkg: "npm:^5.2.0" - type-fest: "npm:^0.8.1" - checksum: 10c0/82b3ac9fd7c6ca1bdc1d7253eb1091a98ff3d195ee0a45386582ce3e69f90266163c34121e6a0a02f1630073a6c0585f7880b3865efcae9c452fa667f02ca385 - languageName: node - linkType: hard - -"read-pkg@npm:^5.2.0": - version: 5.2.0 - resolution: "read-pkg@npm:5.2.0" - dependencies: - "@types/normalize-package-data": "npm:^2.4.0" - normalize-package-data: "npm:^2.5.0" - parse-json: "npm:^5.0.0" - type-fest: "npm:^0.6.0" - checksum: 10c0/b51a17d4b51418e777029e3a7694c9bd6c578a5ab99db544764a0b0f2c7c0f58f8a6bc101f86a6fceb8ba6d237d67c89acf6170f6b98695d0420ddc86cf109fb - languageName: node - linkType: hard - "readable-stream@npm:^2.0.0, readable-stream@npm:^2.3.0, readable-stream@npm:^2.3.5, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" @@ -10641,7 +10570,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.10.0, resolve@npm:^1.22.4": +"resolve@npm:^1.22.4": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -10667,7 +10596,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": +"resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -10986,15 +10915,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0": - version: 5.7.2 - resolution: "semver@npm:5.7.2" - bin: - semver: bin/semver - checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 - languageName: node - linkType: hard - "semver@npm:7.6.0": version: 7.6.0 resolution: "semver@npm:7.6.0" @@ -11015,6 +10935,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^5.5.0": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 + languageName: node + linkType: hard + "semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -11452,40 +11381,6 @@ __metadata: languageName: node linkType: hard -"spdx-correct@npm:^3.0.0": - version: 3.2.0 - resolution: "spdx-correct@npm:3.2.0" - dependencies: - spdx-expression-parse: "npm:^3.0.0" - spdx-license-ids: "npm:^3.0.0" - checksum: 10c0/49208f008618b9119208b0dadc9208a3a55053f4fd6a0ae8116861bd22696fc50f4142a35ebfdb389e05ccf2de8ad142573fefc9e26f670522d899f7b2fe7386 - languageName: node - linkType: hard - -"spdx-exceptions@npm:^2.1.0": - version: 2.3.0 - resolution: "spdx-exceptions@npm:2.3.0" - checksum: 10c0/83089e77d2a91cb6805a5c910a2bedb9e50799da091f532c2ba4150efdef6e53f121523d3e2dc2573a340dc0189e648b03157097f65465b3a0c06da1f18d7e8a - languageName: node - linkType: hard - -"spdx-expression-parse@npm:^3.0.0": - version: 3.0.1 - resolution: "spdx-expression-parse@npm:3.0.1" - dependencies: - spdx-exceptions: "npm:^2.1.0" - spdx-license-ids: "npm:^3.0.0" - checksum: 10c0/6f8a41c87759fa184a58713b86c6a8b028250f158159f1d03ed9d1b6ee4d9eefdc74181c8ddc581a341aa971c3e7b79e30b59c23b05d2436d5de1c30bdef7171 - languageName: node - linkType: hard - -"spdx-license-ids@npm:^3.0.0": - version: 3.0.16 - resolution: "spdx-license-ids@npm:3.0.16" - checksum: 10c0/7d88b8f01308948bb3ea69c066448f2776cf3d35a410d19afb836743086ced1566f6824ee8e6d67f8f25aa81fa86d8076a666c60ac4528caecd55e93edb5114e - languageName: node - linkType: hard - "split2@npm:^4.0.0": version: 4.2.0 resolution: "split2@npm:4.2.0" @@ -12570,16 +12465,6 @@ __metadata: languageName: node linkType: hard -"validate-npm-package-license@npm:^3.0.1": - version: 3.0.4 - resolution: "validate-npm-package-license@npm:3.0.4" - dependencies: - spdx-correct: "npm:^3.0.0" - spdx-expression-parse: "npm:^3.0.0" - checksum: 10c0/7b91e455a8de9a0beaa9fe961e536b677da7f48c9a493edf4d4d4a87fd80a7a10267d438723364e432c2fcd00b5650b5378275cded362383ef570276e6312f4f - languageName: node - linkType: hard - "validator@npm:13.11.0": version: 13.11.0 resolution: "validator@npm:13.11.0"