diff --git a/package-lock.json b/package-lock.json index e1195ee4ff..eede7b92d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25430,16 +25430,13 @@ "esbuild": "0.25.6", "execa": "^8.0.0", "fast-glob": "^3.3.3", - "filter-obj": "^6.0.0", "find-up": "^7.0.0", "is-path-inside": "^4.0.0", "junk": "^4.0.0", - "locate-path": "^7.0.0", "merge-options": "^3.0.4", "minimatch": "^9.0.0", "normalize-path": "^3.0.0", "p-map": "^7.0.0", - "path-exists": "^5.0.0", "precinct": "^12.0.0", "require-package-name": "^2.0.1", "resolve": "^2.0.0-next.1", diff --git a/packages/zip-it-and-ship-it/package.json b/packages/zip-it-and-ship-it/package.json index b8faf84018..d8c2221471 100644 --- a/packages/zip-it-and-ship-it/package.json +++ b/packages/zip-it-and-ship-it/package.json @@ -53,16 +53,13 @@ "esbuild": "0.25.6", "execa": "^8.0.0", "fast-glob": "^3.3.3", - "filter-obj": "^6.0.0", "find-up": "^7.0.0", "is-path-inside": "^4.0.0", "junk": "^4.0.0", - "locate-path": "^7.0.0", "merge-options": "^3.0.4", "minimatch": "^9.0.0", "normalize-path": "^3.0.0", "p-map": "^7.0.0", - "path-exists": "^5.0.0", "precinct": "^12.0.0", "require-package-name": "^2.0.1", "resolve": "^2.0.0-next.1", diff --git a/packages/zip-it-and-ship-it/src/runtimes/node/bundlers/zisi/resolve.ts b/packages/zip-it-and-ship-it/src/runtimes/node/bundlers/zisi/resolve.ts index 1d7664c806..0aad94cfc3 100644 --- a/packages/zip-it-and-ship-it/src/runtimes/node/bundlers/zisi/resolve.ts +++ b/packages/zip-it-and-ship-it/src/runtimes/node/bundlers/zisi/resolve.ts @@ -2,7 +2,7 @@ import { createRequire } from 'module' import { version as nodeVersion } from 'process' import { findUp } from 'find-up' -import { pathExists } from 'path-exists' +import { access } from 'fs/promises' // @ts-expect-error doesnt export async import { async as asyncResolve } from 'resolve' import semver from 'semver' @@ -106,9 +106,14 @@ const resolvePackageFallback = async function (moduleName: string, baseDirs: str const isPackageDir = async function (moduleName: string, dir: string) { // Need to use `endsWith()` to take into account `@scope/package`. // Backslashes need to be converted for Windows. - if (!dir.replace(BACKSLASH_REGEXP, '/').endsWith(moduleName) || !(await pathExists(`${dir}/package.json`))) { + if (!dir.replace(BACKSLASH_REGEXP, '/').endsWith(moduleName)) { return } - return dir + try { + await access(`${dir}/package.json`) + return dir + } catch { + return + } } diff --git a/packages/zip-it-and-ship-it/src/runtimes/node/finder.ts b/packages/zip-it-and-ship-it/src/runtimes/node/finder.ts index 34cf62999b..ee6c7e2727 100644 --- a/packages/zip-it-and-ship-it/src/runtimes/node/finder.ts +++ b/packages/zip-it-and-ship-it/src/runtimes/node/finder.ts @@ -1,8 +1,7 @@ import type { Stats } from 'fs' +import { stat } from 'fs/promises' import { join, dirname, basename, extname } from 'path' -import { locatePath } from 'locate-path' - import { SourceFile } from '../../function.js' import { cachedLstat } from '../../utils/fs.js' import { nonNullable } from '../../utils/non_nullable.js' @@ -72,27 +71,24 @@ export const findFunctionInPath: FindFunctionInPathFunction = async function ({ // the same filename as its directory. const getMainFile = async function (srcPath: string, filename: string, stat: Stats): Promise { if (stat.isDirectory()) { - return await locatePath( - [ - // The order of these declarations is important, so that we always bundle the same way - // even if multiple files are found - join(srcPath, `${filename}.js`), - join(srcPath, 'index.js'), - join(srcPath, `${filename}.ts`), - join(srcPath, 'index.ts'), - join(srcPath, `${filename}.mjs`), - join(srcPath, 'index.mjs'), - join(srcPath, `${filename}.cjs`), - join(srcPath, 'index.cjs'), - join(srcPath, `${filename}.tsx`), - join(srcPath, 'index.tsx'), - join(srcPath, `${filename}.mts`), - join(srcPath, 'index.mts'), - join(srcPath, `${filename}.cts`), - join(srcPath, 'index.cts'), - ], - { type: 'file' }, - ) + return await locateFile([ + // The order of these declarations is important, so that we always bundle the same way + // even if multiple files are found + join(srcPath, `${filename}.js`), + join(srcPath, 'index.js'), + join(srcPath, `${filename}.ts`), + join(srcPath, 'index.ts'), + join(srcPath, `${filename}.mjs`), + join(srcPath, 'index.mjs'), + join(srcPath, `${filename}.cjs`), + join(srcPath, 'index.cjs'), + join(srcPath, `${filename}.tsx`), + join(srcPath, 'index.tsx'), + join(srcPath, `${filename}.mts`), + join(srcPath, 'index.mts'), + join(srcPath, `${filename}.cts`), + join(srcPath, 'index.cts'), + ]) } const extension = extname(srcPath) @@ -101,3 +97,16 @@ const getMainFile = async function (srcPath: string, filename: string, stat: Sta return srcPath } } + +const locateFile = async (paths: string[]): Promise => { + for (const path of paths) { + try { + const fileStat = await stat(path) + if (fileStat.isFile()) { + return path + } + } catch { + // File doesn't exist, continue + } + } +} diff --git a/packages/zip-it-and-ship-it/src/utils/remove_undefined.ts b/packages/zip-it-and-ship-it/src/utils/remove_undefined.ts index 4b45a9d956..4cb59a9d99 100644 --- a/packages/zip-it-and-ship-it/src/utils/remove_undefined.ts +++ b/packages/zip-it-and-ship-it/src/utils/remove_undefined.ts @@ -1,7 +1,5 @@ -import { includeKeys } from 'filter-obj' - -const isUndefined = (_key: unknown, value: unknown) => value !== undefined +const isDefined = (value: unknown) => value !== undefined export const removeUndefined = function (obj: T): T { - return includeKeys(obj, isUndefined) as T + return Object.fromEntries(Object.entries(obj).filter(([, value]) => isDefined(value))) as T } diff --git a/packages/zip-it-and-ship-it/tests/helpers/vitest_setup.ts b/packages/zip-it-and-ship-it/tests/helpers/vitest_setup.ts index d5abe34fb9..4b08736a03 100644 --- a/packages/zip-it-and-ship-it/tests/helpers/vitest_setup.ts +++ b/packages/zip-it-and-ship-it/tests/helpers/vitest_setup.ts @@ -1,6 +1,16 @@ -import { pathExists } from 'path-exists' +import { PathLike } from 'fs' +import { access } from 'fs/promises' import { expect } from 'vitest' +const pathExists = async (path: PathLike) => { + try { + await access(path) + return true + } catch { + return false + } +} + expect.extend({ async toPathExist(received) { const { isNot } = this diff --git a/packages/zip-it-and-ship-it/tests/main.test.ts b/packages/zip-it-and-ship-it/tests/main.test.ts index 035b0c2308..1afefba0ab 100644 --- a/packages/zip-it-and-ship-it/tests/main.test.ts +++ b/packages/zip-it-and-ship-it/tests/main.test.ts @@ -1,4 +1,4 @@ -import { mkdir, readFile, rm, symlink, writeFile } from 'fs/promises' +import { mkdir, readFile, rm, symlink, writeFile, access } from 'fs/promises' import { dirname, isAbsolute, join, resolve } from 'path' import { arch, version as nodeVersion, platform } from 'process' @@ -8,7 +8,6 @@ import merge from 'deepmerge' import { execa, execaNode } from 'execa' import glob from 'fast-glob' import isCI from 'is-ci' -import { pathExists } from 'path-exists' import semver from 'semver' import { dir as getTmpDir, tmpName } from 'tmp-promise' import unixify from 'unixify' @@ -565,7 +564,9 @@ describe('zip-it-and-ship-it', () => { const symlinkFile = `${symlinkDir}/file.js` const targetFile = `${symlinkDir}/target.js` - if (!(await pathExists(symlinkFile))) { + try { + await access(symlinkFile) + } catch { await symlink(targetFile, symlinkFile) } diff --git a/packages/zip-it-and-ship-it/tests/v2api.test.ts b/packages/zip-it-and-ship-it/tests/v2api.test.ts index 1c15df6b90..0a5aacd584 100644 --- a/packages/zip-it-and-ship-it/tests/v2api.test.ts +++ b/packages/zip-it-and-ship-it/tests/v2api.test.ts @@ -1,11 +1,10 @@ -import { readFile } from 'fs/promises' +import { readFile, access } from 'fs/promises' import { join, resolve } from 'path' import { platform } from 'process' import { getPath as getBootstrapPath } from '@netlify/serverless-functions-api' import merge from 'deepmerge' import glob from 'fast-glob' -import { pathExists } from 'path-exists' import { dir as getTmpDir } from 'tmp-promise' import { afterEach, describe, expect, test, vi } from 'vitest' @@ -15,6 +14,7 @@ import { DEFAULT_NODE_VERSION } from '../src/runtimes/node/utils/node_version.js import { invokeLambda, readAsBuffer } from './helpers/lambda.js' import { zipFixture, unzipFiles, importFunctionFile, FIXTURES_ESM_DIR, FIXTURES_DIR } from './helpers/main.js' import { testMany } from './helpers/test_many.js' +import { PathLike } from 'fs' vi.mock('../src/utils/shell.js', () => ({ shellUtils: { runCommand: vi.fn() } })) @@ -673,6 +673,15 @@ describe('V2 functions API', () => { resolve(FIXTURES_ESM_DIR, fixtureName, 'blog/post2.md'), ]) + const pathExists = async (path: PathLike) => { + try { + await access(path) + return true + } catch { + return false + } + } + for (const path of includedFiles as string[]) { expect(await pathExists(path)).toBeTruthy() }