@vercel/backends 0.8.12 → 0.8.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -204,7 +204,7 @@ const resolveEntrypointAndFormat = async (args) => {
204
204
  if (extensionInfo.format === "auto") if (pkg.type === "module") resolvedFormat = "esm";
205
205
  else resolvedFormat = "cjs";
206
206
  }
207
- if (!resolvedFormat) throw new Error(`Unable to resolve format for ${args.entrypoint}`);
207
+ if (!resolvedFormat) resolvedFormat = "esm";
208
208
  return {
209
209
  format: resolvedFormat,
210
210
  extension: resolvedFormat === "esm" ? "mjs" : "cjs"
@@ -978,8 +978,14 @@ const nft = async (args) => {
978
978
  if (!isJsLikeExtension(relPath) || file.type !== "FileBlob") continue;
979
979
  virtualFiles.set(join(args.repoRootPath, relPath), typeof file.data === "string" ? file.data : Buffer.from(new Uint8Array(file.data)));
980
980
  }
981
- const ignorePatterns = [...args.ignoreNodeModules ? ["**/node_modules/**"] : [], ...args.ignore ? Array.isArray(args.ignore) ? args.ignore : [args.ignore] : []];
982
981
  const traceRoots = [...Array.from(args.localBuildFiles).filter((p) => existsSync(p) || virtualFiles.has(p)), ...virtualFiles.keys()];
982
+ const traceBase = getCommonBase(args.repoRootPath, traceRoots);
983
+ const ignorePatterns = getIgnorePatterns({
984
+ ignoreNodeModules: args.ignoreNodeModules,
985
+ ignore: args.ignore,
986
+ traceBase,
987
+ repoRootPath: args.repoRootPath
988
+ });
983
989
  const statOverride = memoize(async (fsPath) => {
984
990
  const virtual = virtualFiles.get(fsPath);
985
991
  if (virtual !== void 0) return createVirtualFileStat(virtual);
@@ -1012,7 +1018,7 @@ const nft = async (args) => {
1012
1018
  }
1013
1019
  });
1014
1020
  const nftResult = await nodeFileTrace$1(traceRoots, {
1015
- base: args.repoRootPath,
1021
+ base: traceBase,
1016
1022
  processCwd: args.workPath,
1017
1023
  ts: true,
1018
1024
  mixedModules: true,
@@ -1026,7 +1032,7 @@ const nft = async (args) => {
1026
1032
  } : {}
1027
1033
  });
1028
1034
  for (const file of nftResult.fileList) {
1029
- const absolutePath = join(args.repoRootPath, file);
1035
+ const absolutePath = join(traceBase, file);
1030
1036
  if (virtualFiles.has(absolutePath)) continue;
1031
1037
  let stats;
1032
1038
  try {
@@ -1035,17 +1041,33 @@ const nft = async (args) => {
1035
1041
  if (isNativeError(error) && "code" in error && error.code === "ENOENT") continue;
1036
1042
  throw error;
1037
1043
  }
1038
- const outputPath = file.split(sep).join("/");
1039
- if (args.localBuildFiles.has(join(args.repoRootPath, outputPath))) continue;
1040
- if (stats.isSymbolicLink() || stats.isFile()) if (args.ignoreNodeModules) {
1041
- if ((stats.isSymbolicLink() ? await stat(absolutePath) : stats).isFile()) args.files[outputPath] = new FileBlob({
1042
- data: await readFile(absolutePath),
1044
+ const normalizedFile = normalizePath(relative(args.repoRootPath, absolutePath));
1045
+ const outputPath = stripParentSegments(normalizedFile);
1046
+ const escapesBase = outputPath !== normalizedFile;
1047
+ if (args.localBuildFiles.has(join(args.repoRootPath, outputPath)) && !isNodeModulesPath(outputPath)) continue;
1048
+ if (stats.isSymbolicLink() || stats.isFile()) {
1049
+ if (stats.isSymbolicLink()) {
1050
+ const symlinkTarget = await readlink(absolutePath);
1051
+ const symlinkTargetPath = normalizePath(relative(args.repoRootPath, resolve(dirname(absolutePath), symlinkTarget)));
1052
+ if (isParentPath(symlinkTargetPath)) {
1053
+ const outputTargetPath = stripParentSegments(symlinkTargetPath);
1054
+ args.files[outputPath] = new FileBlob({
1055
+ data: posix.relative(posix.dirname(outputPath), outputTargetPath),
1056
+ mode: stats.mode
1057
+ });
1058
+ continue;
1059
+ }
1060
+ }
1061
+ if (args.ignoreNodeModules || escapesBase) {
1062
+ if ((stats.isSymbolicLink() ? await stat(absolutePath) : stats).isFile()) args.files[outputPath] = new FileBlob({
1063
+ data: await readFile(absolutePath),
1064
+ mode: stats.mode
1065
+ });
1066
+ } else args.files[outputPath] = new FileFsRef({
1067
+ fsPath: absolutePath,
1043
1068
  mode: stats.mode
1044
1069
  });
1045
- } else args.files[outputPath] = new FileFsRef({
1046
- fsPath: absolutePath,
1047
- mode: stats.mode
1048
- });
1070
+ }
1049
1071
  }
1050
1072
  };
1051
1073
  await nftSpan.trace(runNft);
@@ -1079,6 +1101,40 @@ const isJsLikeExtension = (path) => {
1079
1101
  if (dot === -1) return false;
1080
1102
  return JS_LIKE_EXTENSIONS.has(path.slice(dot).toLowerCase());
1081
1103
  };
1104
+ const getCommonBase = (base, paths) => {
1105
+ let commonBase = base;
1106
+ for (const path of paths) while (!isPathInside(commonBase, path)) {
1107
+ const parent = dirname(commonBase);
1108
+ if (parent === commonBase) break;
1109
+ commonBase = parent;
1110
+ }
1111
+ return commonBase;
1112
+ };
1113
+ const isPathInside = (base, path) => {
1114
+ const relPath = relative(base, path);
1115
+ return relPath === "" || !isParentPath(normalizePath(relPath)) && !isAbsolute(relPath);
1116
+ };
1117
+ const normalizePath = (path) => path.split(sep).join("/");
1118
+ const isParentPath = (path) => path === ".." || path.startsWith("../");
1119
+ const isNodeModulesPath = (path) => path.split("/").includes("node_modules");
1120
+ const stripParentSegments = (path) => {
1121
+ const segments = path.split("/");
1122
+ let index = 0;
1123
+ while (segments[index] === "..") index++;
1124
+ return segments.slice(index).join("/");
1125
+ };
1126
+ const getIgnorePatterns = ({ ignoreNodeModules, ignore, traceBase, repoRootPath }) => {
1127
+ const patterns = [...ignoreNodeModules ? ["**/node_modules/**"] : [], ...ignore ? Array.isArray(ignore) ? ignore : [ignore] : []];
1128
+ const repoRootRelativeToTraceBase = normalizePath(relative(traceBase, repoRootPath));
1129
+ if (!repoRootRelativeToTraceBase || isParentPath(repoRootRelativeToTraceBase)) return patterns;
1130
+ const rebasedPatterns = patterns.map((pattern) => {
1131
+ const isNegated = pattern.startsWith("!");
1132
+ const patternBody = isNegated ? pattern.slice(1) : pattern;
1133
+ const rebased = posix.join(repoRootRelativeToTraceBase, patternBody);
1134
+ return isNegated ? `!${rebased}` : rebased;
1135
+ });
1136
+ return [...patterns, ...rebasedPatterns];
1137
+ };
1082
1138
  const createVirtualFileStat = (data) => {
1083
1139
  const now = /* @__PURE__ */ new Date();
1084
1140
  return {
@@ -1221,7 +1277,8 @@ const rolldown = async (args) => {
1221
1277
  framework.slug = pkgJson.name;
1222
1278
  framework.version = pkgJson.version;
1223
1279
  } catch {}
1224
- if (resolved ? await isCommonJS(id, resolved.id, resolved) : false) {
1280
+ if ((resolved ? await isCommonJS(id, resolved.id, resolved) : false) && resolved) {
1281
+ localBuildFiles.add(resolved.id);
1225
1282
  const importerPkgJsonPath = (await this.resolve(importer))?.packageJsonPath;
1226
1283
  if (importerPkgJsonPath) {
1227
1284
  const importerPkgDir = relative(args.repoRootPath, dirname(importerPkgJsonPath));
@@ -1,6 +1,6 @@
1
1
  import { builtinModules } from "node:module";
2
2
  import { FileBlob, FileFsRef, Span, isBackendFramework } from "@vercel/build-utils";
3
- import { dirname, extname, join, relative, sep } from "node:path";
3
+ import { dirname, extname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
4
4
  import { existsSync } from "node:fs";
5
5
  import { lstat, readFile, readlink, stat } from "node:fs/promises";
6
6
  import { build } from "rolldown";
@@ -81,7 +81,7 @@ const resolveEntrypointAndFormat = async (args) => {
81
81
  if (extensionInfo.format === "auto") if (pkg.type === "module") resolvedFormat = "esm";
82
82
  else resolvedFormat = "cjs";
83
83
  }
84
- if (!resolvedFormat) throw new Error(`Unable to resolve format for ${args.entrypoint}`);
84
+ if (!resolvedFormat) resolvedFormat = "esm";
85
85
  return {
86
86
  format: resolvedFormat,
87
87
  extension: resolvedFormat === "esm" ? "mjs" : "cjs"
@@ -98,8 +98,14 @@ const nft = async (args) => {
98
98
  if (!isJsLikeExtension(relPath) || file.type !== "FileBlob") continue;
99
99
  virtualFiles.set(join(args.repoRootPath, relPath), typeof file.data === "string" ? file.data : Buffer.from(new Uint8Array(file.data)));
100
100
  }
101
- const ignorePatterns = [...args.ignoreNodeModules ? ["**/node_modules/**"] : [], ...args.ignore ? Array.isArray(args.ignore) ? args.ignore : [args.ignore] : []];
102
101
  const traceRoots = [...Array.from(args.localBuildFiles).filter((p) => existsSync(p) || virtualFiles.has(p)), ...virtualFiles.keys()];
102
+ const traceBase = getCommonBase(args.repoRootPath, traceRoots);
103
+ const ignorePatterns = getIgnorePatterns({
104
+ ignoreNodeModules: args.ignoreNodeModules,
105
+ ignore: args.ignore,
106
+ traceBase,
107
+ repoRootPath: args.repoRootPath
108
+ });
103
109
  const statOverride = memoize(async (fsPath) => {
104
110
  const virtual = virtualFiles.get(fsPath);
105
111
  if (virtual !== void 0) return createVirtualFileStat(virtual);
@@ -132,7 +138,7 @@ const nft = async (args) => {
132
138
  }
133
139
  });
134
140
  const nftResult = await nodeFileTrace(traceRoots, {
135
- base: args.repoRootPath,
141
+ base: traceBase,
136
142
  processCwd: args.workPath,
137
143
  ts: true,
138
144
  mixedModules: true,
@@ -146,7 +152,7 @@ const nft = async (args) => {
146
152
  } : {}
147
153
  });
148
154
  for (const file of nftResult.fileList) {
149
- const absolutePath = join(args.repoRootPath, file);
155
+ const absolutePath = join(traceBase, file);
150
156
  if (virtualFiles.has(absolutePath)) continue;
151
157
  let stats;
152
158
  try {
@@ -155,17 +161,33 @@ const nft = async (args) => {
155
161
  if (isNativeError(error) && "code" in error && error.code === "ENOENT") continue;
156
162
  throw error;
157
163
  }
158
- const outputPath = file.split(sep).join("/");
159
- if (args.localBuildFiles.has(join(args.repoRootPath, outputPath))) continue;
160
- if (stats.isSymbolicLink() || stats.isFile()) if (args.ignoreNodeModules) {
161
- if ((stats.isSymbolicLink() ? await stat(absolutePath) : stats).isFile()) args.files[outputPath] = new FileBlob({
162
- data: await readFile(absolutePath),
164
+ const normalizedFile = normalizePath(relative(args.repoRootPath, absolutePath));
165
+ const outputPath = stripParentSegments(normalizedFile);
166
+ const escapesBase = outputPath !== normalizedFile;
167
+ if (args.localBuildFiles.has(join(args.repoRootPath, outputPath)) && !isNodeModulesPath(outputPath)) continue;
168
+ if (stats.isSymbolicLink() || stats.isFile()) {
169
+ if (stats.isSymbolicLink()) {
170
+ const symlinkTarget = await readlink(absolutePath);
171
+ const symlinkTargetPath = normalizePath(relative(args.repoRootPath, resolve(dirname(absolutePath), symlinkTarget)));
172
+ if (isParentPath(symlinkTargetPath)) {
173
+ const outputTargetPath = stripParentSegments(symlinkTargetPath);
174
+ args.files[outputPath] = new FileBlob({
175
+ data: posix.relative(posix.dirname(outputPath), outputTargetPath),
176
+ mode: stats.mode
177
+ });
178
+ continue;
179
+ }
180
+ }
181
+ if (args.ignoreNodeModules || escapesBase) {
182
+ if ((stats.isSymbolicLink() ? await stat(absolutePath) : stats).isFile()) args.files[outputPath] = new FileBlob({
183
+ data: await readFile(absolutePath),
184
+ mode: stats.mode
185
+ });
186
+ } else args.files[outputPath] = new FileFsRef({
187
+ fsPath: absolutePath,
163
188
  mode: stats.mode
164
189
  });
165
- } else args.files[outputPath] = new FileFsRef({
166
- fsPath: absolutePath,
167
- mode: stats.mode
168
- });
190
+ }
169
191
  }
170
192
  };
171
193
  await nftSpan.trace(runNft);
@@ -199,6 +221,40 @@ const isJsLikeExtension = (path) => {
199
221
  if (dot === -1) return false;
200
222
  return JS_LIKE_EXTENSIONS.has(path.slice(dot).toLowerCase());
201
223
  };
224
+ const getCommonBase = (base, paths) => {
225
+ let commonBase = base;
226
+ for (const path of paths) while (!isPathInside(commonBase, path)) {
227
+ const parent = dirname(commonBase);
228
+ if (parent === commonBase) break;
229
+ commonBase = parent;
230
+ }
231
+ return commonBase;
232
+ };
233
+ const isPathInside = (base, path) => {
234
+ const relPath = relative(base, path);
235
+ return relPath === "" || !isParentPath(normalizePath(relPath)) && !isAbsolute(relPath);
236
+ };
237
+ const normalizePath = (path) => path.split(sep).join("/");
238
+ const isParentPath = (path) => path === ".." || path.startsWith("../");
239
+ const isNodeModulesPath = (path) => path.split("/").includes("node_modules");
240
+ const stripParentSegments = (path) => {
241
+ const segments = path.split("/");
242
+ let index = 0;
243
+ while (segments[index] === "..") index++;
244
+ return segments.slice(index).join("/");
245
+ };
246
+ const getIgnorePatterns = ({ ignoreNodeModules, ignore, traceBase, repoRootPath }) => {
247
+ const patterns = [...ignoreNodeModules ? ["**/node_modules/**"] : [], ...ignore ? Array.isArray(ignore) ? ignore : [ignore] : []];
248
+ const repoRootRelativeToTraceBase = normalizePath(relative(traceBase, repoRootPath));
249
+ if (!repoRootRelativeToTraceBase || isParentPath(repoRootRelativeToTraceBase)) return patterns;
250
+ const rebasedPatterns = patterns.map((pattern) => {
251
+ const isNegated = pattern.startsWith("!");
252
+ const patternBody = isNegated ? pattern.slice(1) : pattern;
253
+ const rebased = posix.join(repoRootRelativeToTraceBase, patternBody);
254
+ return isNegated ? `!${rebased}` : rebased;
255
+ });
256
+ return [...patterns, ...rebasedPatterns];
257
+ };
202
258
  const createVirtualFileStat = (data) => {
203
259
  const now = /* @__PURE__ */ new Date();
204
260
  return {
@@ -341,7 +397,8 @@ const rolldown = async (args) => {
341
397
  framework.slug = pkgJson.name;
342
398
  framework.version = pkgJson.version;
343
399
  } catch {}
344
- if (resolved ? await isCommonJS(id, resolved.id, resolved) : false) {
400
+ if ((resolved ? await isCommonJS(id, resolved.id, resolved) : false) && resolved) {
401
+ localBuildFiles.add(resolved.id);
345
402
  const importerPkgJsonPath = (await this.resolve(importer))?.packageJsonPath;
346
403
  if (importerPkgJsonPath) {
347
404
  const importerPkgDir = relative(args.repoRootPath, dirname(importerPkgJsonPath));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/backends",
3
- "version": "0.8.12",
3
+ "version": "0.8.14",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.mjs",
6
6
  "homepage": "https://vercel.com/docs",