@vercel/backends 0.0.23 → 0.0.25

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.
@@ -0,0 +1,272 @@
1
+ import { builtinModules } from "node:module";
2
+ import { build } from "rolldown";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { dirname, extname, join, relative } from "node:path";
5
+ import { existsSync } from "node:fs";
6
+ import { readFile } from "node:fs/promises";
7
+ import { exports } from "resolve.exports";
8
+ import "@vercel/build-utils";
9
+ import "@vercel/nft";
10
+ import "oxc-transform";
11
+
12
+ //#region src/cervel/plugin.ts
13
+ const CJS_SHIM_PREFIX = "\0cjs-shim:";
14
+ const plugin = (args) => {
15
+ const packageJsonCache = /* @__PURE__ */ new Map();
16
+ const shimMeta = /* @__PURE__ */ new Map();
17
+ const { tracedPaths } = args.context;
18
+ const isBareImport = (id) => {
19
+ return !id.startsWith(".") && !id.startsWith("/") && !/^[a-z][a-z0-9+.-]*:/i.test(id);
20
+ };
21
+ /**
22
+ * Read and cache package.json contents
23
+ */
24
+ const getPackageJson = async (pkgPath) => {
25
+ if (packageJsonCache.has(pkgPath)) return packageJsonCache.get(pkgPath);
26
+ try {
27
+ const contents = await readFile(pkgPath, "utf-8");
28
+ const parsed = JSON.parse(contents);
29
+ packageJsonCache.set(pkgPath, parsed);
30
+ return parsed;
31
+ } catch {
32
+ packageJsonCache.set(pkgPath, null);
33
+ return null;
34
+ }
35
+ };
36
+ /**
37
+ * Determine if a resolved module is CommonJS based on package.json exports
38
+ */
39
+ const isCommonJS = async (bareImport, resolvedPath, resolvedInfo) => {
40
+ const ext = extname(resolvedPath);
41
+ if (ext === ".cjs") return true;
42
+ if (ext === ".mjs") return false;
43
+ if (ext === ".js" || ext === ".ts") {
44
+ const pkgJsonPath = resolvedInfo.packageJsonPath;
45
+ if (!pkgJsonPath) return true;
46
+ const pkgJson = await getPackageJson(pkgJsonPath);
47
+ if (!pkgJson) return true;
48
+ const pkgDir = dirname(pkgJsonPath);
49
+ const relativePath = resolvedPath.startsWith(pkgDir) ? resolvedPath.slice(pkgDir.length + 1).replace(/\\/g, "/") : null;
50
+ if (!relativePath) return pkgJson.type !== "module";
51
+ const pkgName = pkgJson.name || "";
52
+ const subpath = bareImport.startsWith(pkgName) ? `.${bareImport.slice(pkgName.length)}` || "." : ".";
53
+ try {
54
+ if (exports(pkgJson, subpath, {
55
+ require: false,
56
+ conditions: ["node", "import"]
57
+ })?.some((p) => p === relativePath || p === `./${relativePath}`)) return false;
58
+ if (exports(pkgJson, subpath, {
59
+ require: true,
60
+ conditions: ["node", "require"]
61
+ })?.some((p) => p === relativePath || p === `./${relativePath}`)) return true;
62
+ } catch (err) {
63
+ console.warn("Export resolution failed::", err);
64
+ }
65
+ if (pkgJson.module) return false;
66
+ return pkgJson.type !== "module";
67
+ }
68
+ return true;
69
+ };
70
+ const isLocalImport = (id) => {
71
+ if (id.startsWith("node:")) return false;
72
+ if (id.includes("node_modules")) return false;
73
+ return true;
74
+ };
75
+ return {
76
+ name: "cervel",
77
+ resolveId: {
78
+ order: "pre",
79
+ async handler(id, importer, rOpts) {
80
+ if (id.startsWith(CJS_SHIM_PREFIX)) return {
81
+ id,
82
+ external: false
83
+ };
84
+ const resolved = await this.resolve(id, importer, rOpts);
85
+ if (builtinModules.includes(id)) return {
86
+ id: `node:${id}`,
87
+ external: true
88
+ };
89
+ if (resolved?.id && isLocalImport(resolved.id)) tracedPaths.add(resolved.id);
90
+ if (importer?.startsWith(CJS_SHIM_PREFIX) && isBareImport(id)) return {
91
+ id,
92
+ external: true
93
+ };
94
+ if (importer && isBareImport(id) && resolved?.id?.includes("node_modules")) {
95
+ if (args.shimBareImports) {
96
+ if (await isCommonJS(id, resolved.id, resolved)) {
97
+ const importerPkgJsonPath = (await this.resolve(importer))?.packageJsonPath;
98
+ if (importerPkgJsonPath) {
99
+ const importerPkgDir = relative(args.repoRootPath, dirname(importerPkgJsonPath));
100
+ const shimId$1 = `${CJS_SHIM_PREFIX}${importerPkgDir.replace(/\//g, "_")}_${id.replace(/\//g, "_")}`;
101
+ shimMeta.set(shimId$1, {
102
+ pkgDir: importerPkgDir,
103
+ pkgName: id
104
+ });
105
+ return {
106
+ id: shimId$1,
107
+ external: false
108
+ };
109
+ }
110
+ const shimId = `${CJS_SHIM_PREFIX}${id.replace(/\//g, "_")}`;
111
+ shimMeta.set(shimId, {
112
+ pkgDir: "",
113
+ pkgName: id
114
+ });
115
+ return {
116
+ id: shimId,
117
+ external: false
118
+ };
119
+ }
120
+ }
121
+ return {
122
+ external: true,
123
+ id
124
+ };
125
+ }
126
+ if (importer && isBareImport(id)) return resolved;
127
+ return {
128
+ external: true,
129
+ ...resolved,
130
+ id: resolved?.id || id
131
+ };
132
+ }
133
+ },
134
+ load: { async handler(id) {
135
+ if (id.startsWith(CJS_SHIM_PREFIX)) {
136
+ const meta = shimMeta.get(id);
137
+ if (!meta) return { code: `module.exports = require('${id.slice(10)}');` };
138
+ const { pkgDir, pkgName } = meta;
139
+ if (pkgDir) return { code: `
140
+ import { createRequire } from 'node:module';
141
+ import { fileURLToPath } from 'node:url';
142
+ import { dirname, join } from 'node:path';
143
+
144
+ const requireFromContext = createRequire(join(dirname(fileURLToPath(import.meta.url)), '${join("..", pkgDir, "package.json")}'));
145
+ module.exports = requireFromContext('${pkgName}');
146
+ `.trim() };
147
+ return { code: `module.exports = require('${pkgName}');` };
148
+ }
149
+ return null;
150
+ } }
151
+ };
152
+ };
153
+
154
+ //#endregion
155
+ //#region src/cervel/rolldown.ts
156
+ const __dirname__filenameShim = `
157
+ import { createRequire as __createRequire } from 'node:module';
158
+ import { fileURLToPath as __fileURLToPath } from 'node:url';
159
+ import { dirname as __dirname_ } from 'node:path';
160
+ var require = typeof require !== 'undefined' ? require : __createRequire(import.meta.url);
161
+ var __filename = typeof __filename !== 'undefined' ? __filename : __fileURLToPath(import.meta.url);
162
+ var __dirname = typeof __dirname !== 'undefined' ? __dirname : __dirname_(__filename);
163
+ `.trim();
164
+
165
+ //#endregion
166
+ //#region src/introspection/loaders/rolldown-hooks.ts
167
+ function findProjectRoot(startDir) {
168
+ let dir = startDir;
169
+ while (dir !== "/" && dir !== ".") {
170
+ if (existsSync(join(dir, "package.json"))) return dir;
171
+ dir = dirname(dir);
172
+ }
173
+ return startDir;
174
+ }
175
+ let honoUrl = null;
176
+ let expressUrl = null;
177
+ const chunkCache = /* @__PURE__ */ new Map();
178
+ const bundled = /* @__PURE__ */ new Set();
179
+ async function resolve(specifier, context, nextResolve) {
180
+ if (context.parentURL && specifier.startsWith("./")) {
181
+ const resolvedUrl = pathToFileURL(join(dirname(fileURLToPath(context.parentURL)), specifier)).href;
182
+ if (chunkCache.has(resolvedUrl)) return {
183
+ url: resolvedUrl,
184
+ shortCircuit: true
185
+ };
186
+ }
187
+ const result = await nextResolve(specifier, context);
188
+ if (specifier === "hono") honoUrl = result.url;
189
+ else if (specifier === "express") expressUrl = result.url;
190
+ return result;
191
+ }
192
+ async function load(url, context, nextLoad) {
193
+ if (honoUrl === url) {
194
+ const pathToHonoExtract = new URL("../hono.mjs", import.meta.url);
195
+ return {
196
+ format: "module",
197
+ source: `
198
+ import { handle } from ${JSON.stringify(pathToHonoExtract.toString())};
199
+ import * as originalHono from ${JSON.stringify(url + "?original")};
200
+
201
+ export * from ${JSON.stringify(url + "?original")};
202
+ export const Hono = handle(originalHono);
203
+ `,
204
+ shortCircuit: true
205
+ };
206
+ }
207
+ if (expressUrl === url) {
208
+ const pathToExpressExtract = new URL("../express.mjs", import.meta.url);
209
+ return {
210
+ format: "module",
211
+ source: `
212
+ import { handle } from ${JSON.stringify(pathToExpressExtract.toString())};
213
+ import originalExpress from ${JSON.stringify(url + "?original")};
214
+
215
+ const extendedExpress = handle(originalExpress);
216
+
217
+ export * from ${JSON.stringify(url + "?original")};
218
+ export default extendedExpress;
219
+ `,
220
+ shortCircuit: true
221
+ };
222
+ }
223
+ if (url.endsWith("?original")) return nextLoad(url, context);
224
+ const cached = chunkCache.get(url);
225
+ if (cached) return {
226
+ format: "module",
227
+ source: cached,
228
+ shortCircuit: true
229
+ };
230
+ if (url.startsWith("file://") && !bundled.has(url) && !url.includes("/node_modules/")) {
231
+ bundled.add(url);
232
+ const filePath = fileURLToPath(url);
233
+ const fileDir = dirname(filePath);
234
+ const projectRoot = findProjectRoot(fileDir);
235
+ const result = await build({
236
+ input: filePath,
237
+ write: false,
238
+ platform: "node",
239
+ cwd: projectRoot,
240
+ plugins: [plugin({
241
+ repoRootPath: projectRoot,
242
+ outDir: fileDir,
243
+ workPath: projectRoot,
244
+ shimBareImports: true,
245
+ context: { tracedPaths: /* @__PURE__ */ new Set() }
246
+ })],
247
+ output: {
248
+ format: "esm",
249
+ banner: __dirname__filenameShim
250
+ }
251
+ });
252
+ for (const chunk of result.output) if (chunk.type === "chunk") {
253
+ const chunkUrl = pathToFileURL(join(fileDir, chunk.fileName)).href;
254
+ chunkCache.set(chunkUrl, chunk.code);
255
+ }
256
+ const entryChunk = result.output.find((chunk) => chunk.type === "chunk" && chunk.isEntry);
257
+ if (entryChunk && entryChunk.type === "chunk") return {
258
+ format: "module",
259
+ source: entryChunk.code,
260
+ shortCircuit: true
261
+ };
262
+ return {
263
+ format: "module",
264
+ source: result.output[0].code,
265
+ shortCircuit: true
266
+ };
267
+ }
268
+ return nextLoad(url, context);
269
+ }
270
+
271
+ //#endregion
272
+ export { load, resolve };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/backends",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.mjs",
6
6
  "homepage": "https://vercel.com/docs",
@@ -10,7 +10,12 @@
10
10
  },
11
11
  "exports": {
12
12
  ".": "./dist/index.mjs",
13
- "./package.json": "./package.json"
13
+ "./package.json": "./package.json",
14
+ "./introspection/loaders/cjs": "./dist/introspection/loaders/cjs.cjs",
15
+ "./introspection/loaders/esm": "./dist/introspection/loaders/esm.mjs",
16
+ "./introspection/loaders/hooks": "./dist/introspection/loaders/hooks.mjs",
17
+ "./introspection/loaders/rolldown-esm": "./dist/introspection/loaders/rolldown-esm.mjs",
18
+ "./introspection/loaders/rolldown-hooks": "./dist/introspection/loaders/rolldown-hooks.mjs"
14
19
  },
15
20
  "repository": {
16
21
  "type": "git",
@@ -21,31 +26,40 @@
21
26
  "dist"
22
27
  ],
23
28
  "dependencies": {
24
- "@vercel/nft": "1.1.1",
29
+ "@vercel/nft": "1.3.0",
30
+ "execa": "3.2.0",
25
31
  "fs-extra": "11.1.0",
26
- "@vercel/static-config": "3.1.2",
27
- "@vercel/cervel": "0.0.10",
28
- "@vercel/introspection": "0.0.10"
32
+ "oxc-transform": "0.111.0",
33
+ "path-to-regexp": "8.3.0",
34
+ "resolve.exports": "2.0.3",
35
+ "rolldown": "1.0.0-rc.1",
36
+ "srvx": "0.8.9",
37
+ "tsx": "4.21.0",
38
+ "zod": "3.22.4",
39
+ "@vercel/build-utils": "13.2.16"
40
+ },
41
+ "peerDependencies": {
42
+ "typescript": "^4.0.0 || ^5.0.0"
29
43
  },
30
44
  "devDependencies": {
31
45
  "@types/express": "5.0.3",
32
46
  "@types/fs-extra": "11",
33
47
  "@types/jest": "27.5.1",
34
48
  "@types/node": "20.11.0",
35
- "execa": "3.2.0",
36
49
  "hono": "4.10.1",
37
50
  "jest-junit": "16.0.0",
38
51
  "tsdown": "0.16.3",
52
+ "typescript": "4.9.5",
39
53
  "vite": "^5.1.6",
40
- "vitest": "^2.0.1",
41
- "@vercel/build-utils": "13.2.14"
54
+ "vitest": "^2.0.1"
42
55
  },
43
56
  "module": "./dist/index.mjs",
44
57
  "types": "./dist/index.d.mts",
45
58
  "scripts": {
46
59
  "build": "tsdown",
47
60
  "vitest-run": "vitest -c ../../vitest.config.mts",
48
- "vitest-unit": "glob --absolute 'test/unit/**/*.test.ts' 'test/unit/**/*.test.mts'",
61
+ "vitest": "tsdown && vitest",
62
+ "vitest-unit": "glob --absolute 'test/unit.*test.ts'",
49
63
  "type-check": "tsc --noEmit"
50
64
  }
51
65
  }