@vercel/express 0.1.0 → 0.1.2
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.js +7 -645
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -32,14 +32,12 @@ var src_exports = {};
|
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
build: () => build,
|
|
34
34
|
entrypointCallback: () => entrypointCallback,
|
|
35
|
-
experimentalBuild: () => build2,
|
|
36
|
-
experimentalVersion: () => version,
|
|
37
35
|
findEntrypoint: () => findEntrypoint,
|
|
38
36
|
name: () => name,
|
|
39
37
|
require_: () => require_,
|
|
40
38
|
shouldServe: () => shouldServe,
|
|
41
39
|
startDevServer: () => startDevServer,
|
|
42
|
-
version: () =>
|
|
40
|
+
version: () => version
|
|
43
41
|
});
|
|
44
42
|
module.exports = __toCommonJS(src_exports);
|
|
45
43
|
|
|
@@ -83,20 +81,20 @@ var build = async (args) => {
|
|
|
83
81
|
return entrypointCallback(args);
|
|
84
82
|
}
|
|
85
83
|
});
|
|
86
|
-
let
|
|
84
|
+
let version2 = void 0;
|
|
87
85
|
try {
|
|
88
86
|
const resolved = require_.resolve(`${frameworkName}/package.json`, {
|
|
89
87
|
paths: [args.workPath]
|
|
90
88
|
});
|
|
91
89
|
const expressVersion = require_(resolved).version;
|
|
92
90
|
if (expressVersion) {
|
|
93
|
-
|
|
91
|
+
version2 = expressVersion;
|
|
94
92
|
}
|
|
95
93
|
} catch (e) {
|
|
96
94
|
}
|
|
97
95
|
res.output.framework = {
|
|
98
96
|
slug: frameworkName,
|
|
99
|
-
version:
|
|
97
|
+
version: version2
|
|
100
98
|
};
|
|
101
99
|
return res;
|
|
102
100
|
};
|
|
@@ -205,643 +203,9 @@ var findMainPackageEntrypoint = (files) => {
|
|
|
205
203
|
return null;
|
|
206
204
|
};
|
|
207
205
|
|
|
208
|
-
// src/experimental/build.ts
|
|
209
|
-
var import_build_utils6 = require("@vercel/build-utils");
|
|
210
|
-
|
|
211
|
-
// src/experimental/utils.ts
|
|
212
|
-
var import_path2 = require("path");
|
|
213
|
-
var import_build_utils2 = require("@vercel/build-utils");
|
|
214
|
-
async function downloadInstallAndBundle(args) {
|
|
215
|
-
const { entrypoint, files, workPath, meta, config } = args;
|
|
216
|
-
await (0, import_build_utils2.download)(files, workPath, meta);
|
|
217
|
-
const entrypointFsDirname = (0, import_path2.join)(workPath, (0, import_path2.dirname)(entrypoint));
|
|
218
|
-
const nodeVersion = await (0, import_build_utils2.getNodeVersion)(
|
|
219
|
-
entrypointFsDirname,
|
|
220
|
-
void 0,
|
|
221
|
-
config,
|
|
222
|
-
meta
|
|
223
|
-
);
|
|
224
|
-
const spawnOpts = (0, import_build_utils2.getSpawnOptions)(meta || {}, nodeVersion);
|
|
225
|
-
const {
|
|
226
|
-
cliType,
|
|
227
|
-
lockfileVersion,
|
|
228
|
-
packageJsonPackageManager,
|
|
229
|
-
turboSupportsCorepackHome
|
|
230
|
-
} = await (0, import_build_utils2.scanParentDirs)(entrypointFsDirname, true);
|
|
231
|
-
spawnOpts.env = (0, import_build_utils2.getEnvForPackageManager)({
|
|
232
|
-
cliType,
|
|
233
|
-
lockfileVersion,
|
|
234
|
-
packageJsonPackageManager,
|
|
235
|
-
env: spawnOpts.env || {},
|
|
236
|
-
turboSupportsCorepackHome,
|
|
237
|
-
projectCreatedAt: config.projectSettings?.createdAt
|
|
238
|
-
});
|
|
239
|
-
const installCommand = config.projectSettings?.installCommand;
|
|
240
|
-
if (typeof installCommand === "string") {
|
|
241
|
-
if (installCommand.trim()) {
|
|
242
|
-
console.log(`Running "install" command: \`${installCommand}\`...`);
|
|
243
|
-
await (0, import_build_utils2.execCommand)(installCommand, {
|
|
244
|
-
...spawnOpts,
|
|
245
|
-
cwd: entrypointFsDirname
|
|
246
|
-
});
|
|
247
|
-
} else {
|
|
248
|
-
console.log(`Skipping "install" command...`);
|
|
249
|
-
}
|
|
250
|
-
} else {
|
|
251
|
-
await (0, import_build_utils2.runNpmInstall)(
|
|
252
|
-
entrypointFsDirname,
|
|
253
|
-
[],
|
|
254
|
-
spawnOpts,
|
|
255
|
-
meta,
|
|
256
|
-
config.projectSettings?.createdAt
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
return { entrypointFsDirname, nodeVersion, spawnOpts };
|
|
260
|
-
}
|
|
261
|
-
async function maybeExecBuildCommand(args, options) {
|
|
262
|
-
const projectBuildCommand = args.config.projectSettings?.buildCommand;
|
|
263
|
-
if (projectBuildCommand) {
|
|
264
|
-
await (0, import_build_utils2.execCommand)(projectBuildCommand, {
|
|
265
|
-
...options.spawnOpts,
|
|
266
|
-
cwd: args.workPath
|
|
267
|
-
});
|
|
268
|
-
} else {
|
|
269
|
-
const possibleScripts = ["build"];
|
|
270
|
-
await (0, import_build_utils2.runPackageJsonScript)(
|
|
271
|
-
options.entrypointFsDirname,
|
|
272
|
-
possibleScripts,
|
|
273
|
-
options.spawnOpts,
|
|
274
|
-
args.config.projectSettings?.createdAt
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// src/experimental/rolldown.ts
|
|
280
|
-
var import_build_utils3 = require("@vercel/build-utils");
|
|
281
|
-
var import_nft = require("@vercel/nft");
|
|
282
|
-
var import_fs2 = require("fs");
|
|
283
|
-
var import_path3 = require("path");
|
|
284
|
-
var import_rolldown = require("rolldown");
|
|
285
|
-
var rolldown = async (args) => {
|
|
286
|
-
const baseDir = args.repoRootPath || args.workPath;
|
|
287
|
-
const entrypointPath = (0, import_path3.join)(args.workPath, args.entrypoint);
|
|
288
|
-
const files = {};
|
|
289
|
-
const shouldAddSourcemapSupport = false;
|
|
290
|
-
const extension = (0, import_path3.extname)(args.entrypoint);
|
|
291
|
-
const extensionMap = {
|
|
292
|
-
".ts": { format: "auto", extension: "js" },
|
|
293
|
-
".mts": { format: "esm", extension: "mjs" },
|
|
294
|
-
".cts": { format: "cjs", extension: "cjs" },
|
|
295
|
-
".cjs": { format: "cjs", extension: "cjs" },
|
|
296
|
-
".js": { format: "auto", extension: "js" },
|
|
297
|
-
".mjs": { format: "esm", extension: "mjs" }
|
|
298
|
-
};
|
|
299
|
-
const extensionInfo = extensionMap[extension] || extensionMap[".js"];
|
|
300
|
-
let format = extensionInfo.format;
|
|
301
|
-
const packageJsonPath = (0, import_path3.join)(args.workPath, "package.json");
|
|
302
|
-
const external = [];
|
|
303
|
-
if ((0, import_fs2.existsSync)(packageJsonPath)) {
|
|
304
|
-
const { mode } = (0, import_fs2.lstatSync)(packageJsonPath);
|
|
305
|
-
const source = (0, import_fs2.readFileSync)(packageJsonPath);
|
|
306
|
-
const relPath = (0, import_path3.relative)(baseDir, packageJsonPath);
|
|
307
|
-
let pkg;
|
|
308
|
-
try {
|
|
309
|
-
pkg = JSON.parse(source.toString());
|
|
310
|
-
} catch (_e) {
|
|
311
|
-
pkg = {};
|
|
312
|
-
}
|
|
313
|
-
if (format === "auto") {
|
|
314
|
-
if (pkg.type === "module") {
|
|
315
|
-
format = "esm";
|
|
316
|
-
} else {
|
|
317
|
-
format = "cjs";
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
for (const dependency of Object.keys(pkg.dependencies || {})) {
|
|
321
|
-
external.push(dependency);
|
|
322
|
-
}
|
|
323
|
-
for (const dependency of Object.keys(pkg.devDependencies || {})) {
|
|
324
|
-
external.push(dependency);
|
|
325
|
-
}
|
|
326
|
-
for (const dependency of Object.keys(pkg.peerDependencies || {})) {
|
|
327
|
-
external.push(dependency);
|
|
328
|
-
}
|
|
329
|
-
for (const dependency of Object.keys(pkg.optionalDependencies || {})) {
|
|
330
|
-
external.push(dependency);
|
|
331
|
-
}
|
|
332
|
-
files[relPath] = new import_build_utils3.FileBlob({ data: source, mode });
|
|
333
|
-
}
|
|
334
|
-
const absoluteImportPlugin = {
|
|
335
|
-
name: "absolute-import-resolver",
|
|
336
|
-
resolveId(source) {
|
|
337
|
-
if (external.includes(source)) {
|
|
338
|
-
return { id: source, external: true };
|
|
339
|
-
}
|
|
340
|
-
return null;
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
let tsconfigPath = (0, import_path3.join)(baseDir, "tsconfig.json");
|
|
344
|
-
if (!(0, import_fs2.existsSync)(tsconfigPath)) {
|
|
345
|
-
tsconfigPath = await (0, import_build_utils3.walkParentDirs)({
|
|
346
|
-
base: baseDir,
|
|
347
|
-
start: args.workPath,
|
|
348
|
-
filename: "tsconfig.json"
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
const relativeOutputDir = (0, import_path3.join)(
|
|
352
|
-
".vercel",
|
|
353
|
-
"output",
|
|
354
|
-
"functions",
|
|
355
|
-
"index.func"
|
|
356
|
-
);
|
|
357
|
-
const outputDir = (0, import_path3.join)(baseDir, relativeOutputDir);
|
|
358
|
-
let handler = null;
|
|
359
|
-
await (0, import_rolldown.build)({
|
|
360
|
-
input: entrypointPath,
|
|
361
|
-
cwd: baseDir,
|
|
362
|
-
platform: "node",
|
|
363
|
-
external: /node_modules/,
|
|
364
|
-
plugins: [absoluteImportPlugin],
|
|
365
|
-
tsconfig: tsconfigPath || void 0,
|
|
366
|
-
output: {
|
|
367
|
-
dir: outputDir,
|
|
368
|
-
// FIXME: This is a bit messy, not sure what facadeModuleId even is and the only reason for renaming here
|
|
369
|
-
// is to preserve the proper extension for mjs/cjs scenario.
|
|
370
|
-
// There doesn't seem to be another way to do only specify the entrypoint extension.
|
|
371
|
-
entryFileNames: (info) => {
|
|
372
|
-
if (info.name === "rolldown_runtime") {
|
|
373
|
-
return "rolldown_runtime.js";
|
|
374
|
-
}
|
|
375
|
-
const facadeModuleId = info.facadeModuleId;
|
|
376
|
-
if (!facadeModuleId) {
|
|
377
|
-
throw new Error(`Unable to resolve module for ${info.name}`);
|
|
378
|
-
}
|
|
379
|
-
const relPath = (0, import_path3.relative)(baseDir, facadeModuleId);
|
|
380
|
-
const extension2 = (0, import_path3.extname)(relPath);
|
|
381
|
-
const extensionMap2 = {
|
|
382
|
-
".ts": ".js",
|
|
383
|
-
".mts": ".mjs",
|
|
384
|
-
".mjs": ".mjs",
|
|
385
|
-
".cts": ".cjs",
|
|
386
|
-
".cjs": ".cjs",
|
|
387
|
-
".js": ".js"
|
|
388
|
-
};
|
|
389
|
-
const ext = extensionMap2[extension2] || ".js";
|
|
390
|
-
const nameWithJS = relPath.slice(0, -extension2.length) + ext;
|
|
391
|
-
if (info.isEntry) {
|
|
392
|
-
handler = nameWithJS;
|
|
393
|
-
}
|
|
394
|
-
return nameWithJS;
|
|
395
|
-
},
|
|
396
|
-
format,
|
|
397
|
-
preserveModules: true,
|
|
398
|
-
sourcemap: false
|
|
399
|
-
}
|
|
400
|
-
});
|
|
401
|
-
if (typeof handler !== "string") {
|
|
402
|
-
throw new Error(`Unable to resolve module for ${args.entrypoint}`);
|
|
403
|
-
}
|
|
404
|
-
const nftResult = await (0, import_nft.nodeFileTrace)([(0, import_path3.join)(outputDir, handler)], {
|
|
405
|
-
// This didn't work as I expected it to, didn't find node_modules
|
|
406
|
-
// base: outputDir,
|
|
407
|
-
// processCwd: outputDir,
|
|
408
|
-
ignore: args.config.excludeFiles
|
|
409
|
-
});
|
|
410
|
-
for (const file of nftResult.fileList) {
|
|
411
|
-
if (file.startsWith(relativeOutputDir)) {
|
|
412
|
-
const stats = (0, import_fs2.lstatSync)(file);
|
|
413
|
-
const relPath = (0, import_path3.relative)(outputDir, file);
|
|
414
|
-
files[relPath] = new import_build_utils3.FileFsRef({
|
|
415
|
-
fsPath: file,
|
|
416
|
-
mode: stats.mode
|
|
417
|
-
});
|
|
418
|
-
} else {
|
|
419
|
-
const stats = (0, import_fs2.lstatSync)(file);
|
|
420
|
-
files[file] = new import_build_utils3.FileFsRef({ fsPath: file, mode: stats.mode });
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return {
|
|
424
|
-
files,
|
|
425
|
-
shouldAddSourcemapSupport,
|
|
426
|
-
handler,
|
|
427
|
-
outputDir
|
|
428
|
-
};
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
// src/experimental/find-entrypoint.ts
|
|
432
|
-
var import_build_utils4 = require("@vercel/build-utils");
|
|
433
|
-
var import_node2 = require("@vercel/node");
|
|
434
|
-
var import_module2 = require("module");
|
|
435
|
-
var import_path4 = require("path");
|
|
436
|
-
var import_fs3 = __toESM(require("fs"));
|
|
437
|
-
var REGEX2 = /(?:from|require|import)\s*(?:\(\s*)?["']express["']\s*(?:\))?/g;
|
|
438
|
-
var validFilenames2 = [
|
|
439
|
-
"app",
|
|
440
|
-
"index",
|
|
441
|
-
"server",
|
|
442
|
-
"src/app",
|
|
443
|
-
"src/index",
|
|
444
|
-
"src/server"
|
|
445
|
-
];
|
|
446
|
-
var require_2 = (0, import_module2.createRequire)(__filename);
|
|
447
|
-
var validExtensions2 = ["js", "cjs", "mjs", "ts", "cts", "mts"];
|
|
448
|
-
var entrypointsForMessage2 = validFilenames2.map((filename) => `- ${filename}.{${validExtensions2.join(",")}}`).join("\n");
|
|
449
|
-
var entrypointCallback2 = async (args) => {
|
|
450
|
-
const mainPackageEntrypoint = findMainPackageEntrypoint2(args.files);
|
|
451
|
-
const entrypointGlob = `{${validFilenames2.map((entrypoint) => `${entrypoint}`).join(",")}}.{${validExtensions2.join(",")}}`;
|
|
452
|
-
const dir = args.config.projectSettings?.outputDirectory?.replace(
|
|
453
|
-
/^\/+|\/+$/g,
|
|
454
|
-
""
|
|
455
|
-
);
|
|
456
|
-
if (dir) {
|
|
457
|
-
const { entrypoint: entrypointFromOutputDir, entrypointsNotMatchingRegex: entrypointsNotMatchingRegex2 } = findEntrypoint2(await (0, import_build_utils4.glob)(entrypointGlob, (0, import_path4.join)(args.workPath, dir)));
|
|
458
|
-
if (entrypointFromOutputDir) {
|
|
459
|
-
return (0, import_path4.join)(dir, entrypointFromOutputDir);
|
|
460
|
-
}
|
|
461
|
-
if (entrypointsNotMatchingRegex2.length > 0) {
|
|
462
|
-
throw new Error(
|
|
463
|
-
`No entrypoint found which imports express. Found possible ${pluralize2("entrypoint", entrypointsNotMatchingRegex2.length)}: ${entrypointsNotMatchingRegex2.join(", ")}`
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
|
-
throw new Error(
|
|
467
|
-
`No entrypoint found in output directory: "${dir}". Searched for:
|
|
468
|
-
${entrypointsForMessage2}`
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
const files = await (0, import_build_utils4.glob)(entrypointGlob, args.workPath);
|
|
472
|
-
const { entrypoint: entrypointFromRoot, entrypointsNotMatchingRegex } = findEntrypoint2(files);
|
|
473
|
-
if (entrypointFromRoot) {
|
|
474
|
-
return entrypointFromRoot;
|
|
475
|
-
}
|
|
476
|
-
if (mainPackageEntrypoint) {
|
|
477
|
-
const entrypointFromPackageJson = await (0, import_build_utils4.glob)(
|
|
478
|
-
mainPackageEntrypoint,
|
|
479
|
-
args.workPath
|
|
480
|
-
);
|
|
481
|
-
if (entrypointFromPackageJson[mainPackageEntrypoint]) {
|
|
482
|
-
if (checkMatchesRegex2(entrypointFromPackageJson[mainPackageEntrypoint])) {
|
|
483
|
-
return mainPackageEntrypoint;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
if (entrypointsNotMatchingRegex.length > 0) {
|
|
488
|
-
throw new Error(
|
|
489
|
-
`No entrypoint found which imports express. Found possible ${pluralize2("entrypoint", entrypointsNotMatchingRegex.length)}: ${entrypointsNotMatchingRegex.join(", ")}`
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
throw new Error(
|
|
493
|
-
`No entrypoint found. Searched for:
|
|
494
|
-
${entrypointsForMessage2}`
|
|
495
|
-
);
|
|
496
|
-
};
|
|
497
|
-
function pluralize2(word, count) {
|
|
498
|
-
return count === 1 ? word : `${word}s`;
|
|
499
|
-
}
|
|
500
|
-
var findEntrypoint2 = (files) => {
|
|
501
|
-
const allEntrypoints = validFilenames2.flatMap(
|
|
502
|
-
(filename) => validExtensions2.map((extension) => `${filename}.${extension}`)
|
|
503
|
-
);
|
|
504
|
-
const possibleEntrypointsInFiles = allEntrypoints.filter((entrypoint2) => {
|
|
505
|
-
return files[entrypoint2] !== void 0;
|
|
506
|
-
});
|
|
507
|
-
const entrypointsMatchingRegex = possibleEntrypointsInFiles.filter(
|
|
508
|
-
(entrypoint2) => {
|
|
509
|
-
const file = files[entrypoint2];
|
|
510
|
-
return checkMatchesRegex2(file);
|
|
511
|
-
}
|
|
512
|
-
);
|
|
513
|
-
const entrypointsNotMatchingRegex = possibleEntrypointsInFiles.filter(
|
|
514
|
-
(entrypoint2) => {
|
|
515
|
-
const file = files[entrypoint2];
|
|
516
|
-
return !checkMatchesRegex2(file);
|
|
517
|
-
}
|
|
518
|
-
);
|
|
519
|
-
const entrypoint = entrypointsMatchingRegex[0];
|
|
520
|
-
if (entrypointsMatchingRegex.length > 1) {
|
|
521
|
-
console.warn(
|
|
522
|
-
`Multiple entrypoints found: ${entrypointsMatchingRegex.join(", ")}. Using ${entrypoint}.`
|
|
523
|
-
);
|
|
524
|
-
}
|
|
525
|
-
return {
|
|
526
|
-
entrypoint,
|
|
527
|
-
entrypointsNotMatchingRegex
|
|
528
|
-
};
|
|
529
|
-
};
|
|
530
|
-
var checkMatchesRegex2 = (file) => {
|
|
531
|
-
const content = import_fs3.default.readFileSync(file.fsPath, "utf-8");
|
|
532
|
-
const matchesContent = content.match(REGEX2);
|
|
533
|
-
return matchesContent !== null;
|
|
534
|
-
};
|
|
535
|
-
var findMainPackageEntrypoint2 = (files) => {
|
|
536
|
-
const packageJson = files["package.json"];
|
|
537
|
-
if (packageJson) {
|
|
538
|
-
if (packageJson.type === "FileFsRef") {
|
|
539
|
-
const packageJsonContent = import_fs3.default.readFileSync(packageJson.fsPath, "utf-8");
|
|
540
|
-
let packageJsonJson;
|
|
541
|
-
try {
|
|
542
|
-
packageJsonJson = JSON.parse(packageJsonContent);
|
|
543
|
-
} catch (_e) {
|
|
544
|
-
packageJsonJson = {};
|
|
545
|
-
}
|
|
546
|
-
if ("main" in packageJsonJson && typeof packageJsonJson.main === "string") {
|
|
547
|
-
return packageJsonJson.main;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
return null;
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
// src/experimental/introspection.ts
|
|
555
|
-
var import_build_utils5 = require("@vercel/build-utils");
|
|
556
|
-
var import_path5 = require("path");
|
|
557
|
-
var import_fs_extra = require("fs-extra");
|
|
558
|
-
var import_child_process = require("child_process");
|
|
559
|
-
var import_fs4 = require("fs");
|
|
560
|
-
var import_promises = require("fs/promises");
|
|
561
|
-
var import_module3 = require("module");
|
|
562
|
-
var import_path_to_regexp = require("path-to-regexp");
|
|
563
|
-
var import_zod = require("zod");
|
|
564
|
-
var require_3 = (0, import_module3.createRequire)(__filename);
|
|
565
|
-
var introspectApp = async (args, options) => {
|
|
566
|
-
const source = expressShimSource(options);
|
|
567
|
-
await (0, import_fs_extra.outputFile)(
|
|
568
|
-
(0, import_path5.join)(options.outputDir, "node_modules", "express", "index.js"),
|
|
569
|
-
source
|
|
570
|
-
);
|
|
571
|
-
await invokeFunction(args, options);
|
|
572
|
-
const {
|
|
573
|
-
routes: routesFromIntrospection,
|
|
574
|
-
views,
|
|
575
|
-
staticPaths
|
|
576
|
-
} = await processIntrospection(options);
|
|
577
|
-
await cleanup(options);
|
|
578
|
-
if (views) {
|
|
579
|
-
try {
|
|
580
|
-
const validatedViews = validatePath(views, args.workPath);
|
|
581
|
-
const viewFiles = await (0, import_build_utils5.glob)((0, import_path5.join)(validatedViews, "**/*"), args.workPath);
|
|
582
|
-
for (const [p, f] of Object.entries(viewFiles)) {
|
|
583
|
-
options.files[p] = f;
|
|
584
|
-
}
|
|
585
|
-
} catch (error) {
|
|
586
|
-
console.log(`Skipping invalid views path: ${views}`);
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
if (staticPaths) {
|
|
590
|
-
try {
|
|
591
|
-
const validatedStaticPaths = staticPaths.map(
|
|
592
|
-
(path) => validatePath(path, args.workPath)
|
|
593
|
-
);
|
|
594
|
-
for (const staticPath of validatedStaticPaths) {
|
|
595
|
-
const staticFiles = await (0, import_build_utils5.glob)((0, import_path5.join)(staticPath, "**/*"), args.workPath);
|
|
596
|
-
for (const [p, f] of Object.entries(staticFiles)) {
|
|
597
|
-
options.files[p] = f;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
} catch (error) {
|
|
601
|
-
console.log(`Skipping invalid static paths: ${staticPaths}`);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
const routes = [
|
|
605
|
-
{
|
|
606
|
-
handle: "filesystem"
|
|
607
|
-
},
|
|
608
|
-
...routesFromIntrospection,
|
|
609
|
-
{
|
|
610
|
-
src: "/(.*)",
|
|
611
|
-
dest: "/"
|
|
612
|
-
}
|
|
613
|
-
];
|
|
614
|
-
return { routes };
|
|
615
|
-
};
|
|
616
|
-
var cleanup = async (options) => {
|
|
617
|
-
await (0, import_promises.rm)((0, import_path5.join)(options.outputDir, "node_modules"), {
|
|
618
|
-
recursive: true,
|
|
619
|
-
force: true
|
|
620
|
-
});
|
|
621
|
-
await (0, import_promises.rm)(getIntrospectionPath(options), { force: true });
|
|
622
|
-
};
|
|
623
|
-
var processIntrospection = async (options) => {
|
|
624
|
-
const schema = import_zod.z.object({
|
|
625
|
-
routes: import_zod.z.record(
|
|
626
|
-
import_zod.z.string(),
|
|
627
|
-
import_zod.z.object({
|
|
628
|
-
methods: import_zod.z.array(import_zod.z.string())
|
|
629
|
-
})
|
|
630
|
-
).transform(
|
|
631
|
-
(value) => Object.entries(value).map(([path, route]) => convertExpressRoute(path, route)).filter(Boolean)
|
|
632
|
-
),
|
|
633
|
-
views: import_zod.z.string().optional(),
|
|
634
|
-
staticPaths: import_zod.z.array(import_zod.z.string()).optional(),
|
|
635
|
-
viewEngine: import_zod.z.string().optional()
|
|
636
|
-
});
|
|
637
|
-
try {
|
|
638
|
-
const introspectionPath = (0, import_path5.join)(options.outputDir, "introspection.json");
|
|
639
|
-
const introspection = (0, import_fs4.readFileSync)(introspectionPath, "utf8");
|
|
640
|
-
return schema.parse(JSON.parse(introspection));
|
|
641
|
-
} catch (error) {
|
|
642
|
-
console.log(
|
|
643
|
-
`Unable to extract routes from express, route level observability will not be available`
|
|
644
|
-
);
|
|
645
|
-
return {
|
|
646
|
-
routes: [],
|
|
647
|
-
views: void 0,
|
|
648
|
-
staticPaths: void 0,
|
|
649
|
-
viewEngine: void 0
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
};
|
|
653
|
-
var getIntrospectionPath = (options) => {
|
|
654
|
-
return (0, import_path5.join)(options.outputDir, "introspection.json");
|
|
655
|
-
};
|
|
656
|
-
var invokeFunction = async (args, options) => {
|
|
657
|
-
await new Promise((resolve2) => {
|
|
658
|
-
try {
|
|
659
|
-
const child = (0, import_child_process.spawn)("node", [(0, import_path5.join)(options.outputDir, options.handler)], {
|
|
660
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
661
|
-
cwd: options.outputDir,
|
|
662
|
-
env: {
|
|
663
|
-
...process.env,
|
|
664
|
-
...args.meta?.env || {},
|
|
665
|
-
...args.meta?.buildEnv || {}
|
|
666
|
-
}
|
|
667
|
-
});
|
|
668
|
-
setTimeout(() => {
|
|
669
|
-
child.kill("SIGTERM");
|
|
670
|
-
}, 5e3);
|
|
671
|
-
child.on("error", () => {
|
|
672
|
-
console.log(
|
|
673
|
-
`Unable to extract routes from express, route level observability will not be available`
|
|
674
|
-
);
|
|
675
|
-
resolve2(void 0);
|
|
676
|
-
});
|
|
677
|
-
child.on("close", () => {
|
|
678
|
-
resolve2(void 0);
|
|
679
|
-
});
|
|
680
|
-
} catch (error) {
|
|
681
|
-
console.log(
|
|
682
|
-
`Unable to extract routes from express, route level observability will not be available`
|
|
683
|
-
);
|
|
684
|
-
resolve2(void 0);
|
|
685
|
-
}
|
|
686
|
-
});
|
|
687
|
-
};
|
|
688
|
-
var expressShimSource = (args) => {
|
|
689
|
-
const pathToExpress = require_3.resolve("express", {
|
|
690
|
-
paths: [args.outputDir]
|
|
691
|
-
});
|
|
692
|
-
const introspectionPath = getIntrospectionPath(args);
|
|
693
|
-
return `
|
|
694
|
-
const fs = require('fs');
|
|
695
|
-
const path = require('path');
|
|
696
|
-
const originalExpress = require(${JSON.stringify(pathToExpress)});
|
|
697
|
-
|
|
698
|
-
let app = null
|
|
699
|
-
let staticPaths = [];
|
|
700
|
-
let views = ''
|
|
701
|
-
let viewEngine = ''
|
|
702
|
-
const routes = {};
|
|
703
|
-
const originalStatic = originalExpress.static
|
|
704
|
-
originalExpress.static = (...args) => {
|
|
705
|
-
staticPaths.push(args[0]);
|
|
706
|
-
return originalStatic(...args);
|
|
707
|
-
}
|
|
708
|
-
function expressWrapper() {
|
|
709
|
-
app = originalExpress.apply(this, arguments);
|
|
710
|
-
return app;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
// Copy all properties from the original express to the wrapper
|
|
714
|
-
Object.setPrototypeOf(expressWrapper, originalExpress);
|
|
715
|
-
Object.assign(expressWrapper, originalExpress);
|
|
716
|
-
|
|
717
|
-
// Preserve the original prototype
|
|
718
|
-
expressWrapper.prototype = originalExpress.prototype;
|
|
719
|
-
|
|
720
|
-
module.exports = expressWrapper;
|
|
721
|
-
|
|
722
|
-
let routesExtracted = false;
|
|
723
|
-
|
|
724
|
-
const extractRoutes = () => {
|
|
725
|
-
if (routesExtracted) {
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
routesExtracted = true;
|
|
729
|
-
|
|
730
|
-
const methods = ["all", "get", "post", "put", "delete", "patch", "options", "head"]
|
|
731
|
-
if (!app) {
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
const router = app._router || app.router
|
|
735
|
-
for (const route of router.stack) {
|
|
736
|
-
if(route.route) {
|
|
737
|
-
const m = [];
|
|
738
|
-
for (const method of methods) {
|
|
739
|
-
if(route.route.methods[method]) {
|
|
740
|
-
m.push(method.toUpperCase());
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
routes[route.route.path] = { methods: m };
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
views = app.settings.views
|
|
748
|
-
viewEngine = app.settings['view engine']
|
|
749
|
-
|
|
750
|
-
// Ensure directory exists
|
|
751
|
-
const dir = path.dirname(${JSON.stringify(introspectionPath)});
|
|
752
|
-
if (!fs.existsSync(dir)) {
|
|
753
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
fs.writeFileSync(${JSON.stringify(introspectionPath)}, JSON.stringify({routes, views, staticPaths, viewEngine}, null, 2));
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
process.on('exit', () => {
|
|
760
|
-
extractRoutes()
|
|
761
|
-
});
|
|
762
|
-
|
|
763
|
-
process.on('SIGINT', () => {
|
|
764
|
-
extractRoutes()
|
|
765
|
-
process.exit(0);
|
|
766
|
-
});
|
|
767
|
-
// Write routes to file on SIGTERM
|
|
768
|
-
process.on('SIGTERM', () => {
|
|
769
|
-
extractRoutes()
|
|
770
|
-
process.exit(0);
|
|
771
|
-
});
|
|
772
|
-
`;
|
|
773
|
-
};
|
|
774
|
-
var convertExpressRoute = (route, routeData) => {
|
|
775
|
-
const { regexp } = (0, import_path_to_regexp.pathToRegexp)(route);
|
|
776
|
-
const dest = route;
|
|
777
|
-
if (dest === "/") {
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
const src = regexp.source;
|
|
781
|
-
return {
|
|
782
|
-
src,
|
|
783
|
-
dest,
|
|
784
|
-
methods: routeData.methods
|
|
785
|
-
};
|
|
786
|
-
};
|
|
787
|
-
var validatePath = (inputPath, workPath) => {
|
|
788
|
-
if (inputPath.indexOf("\0") !== -1) {
|
|
789
|
-
throw new Error(`Path contains null bytes: ${inputPath}`);
|
|
790
|
-
}
|
|
791
|
-
const normalizedPath = (0, import_path5.normalize)(inputPath);
|
|
792
|
-
if (normalizedPath.includes("..")) {
|
|
793
|
-
throw new Error(
|
|
794
|
-
`Path contains directory traversal sequences: ${inputPath}`
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
if ((0, import_path5.isAbsolute)(normalizedPath)) {
|
|
798
|
-
throw new Error(`Absolute paths are not allowed: ${inputPath}`);
|
|
799
|
-
}
|
|
800
|
-
const resolvedPath = (0, import_path5.resolve)(workPath, normalizedPath);
|
|
801
|
-
const resolvedWorkPath = (0, import_path5.resolve)(workPath);
|
|
802
|
-
if (!resolvedPath.startsWith(resolvedWorkPath + import_path5.sep) && resolvedPath !== resolvedWorkPath) {
|
|
803
|
-
throw new Error(`Path escapes the intended directory: ${inputPath}`);
|
|
804
|
-
}
|
|
805
|
-
return normalizedPath;
|
|
806
|
-
};
|
|
807
|
-
|
|
808
|
-
// src/experimental/build.ts
|
|
809
|
-
var version = 2;
|
|
810
|
-
var build2 = async (args) => {
|
|
811
|
-
console.log(`Using experimental express build`);
|
|
812
|
-
const downloadResult = await downloadInstallAndBundle(args);
|
|
813
|
-
await maybeExecBuildCommand(args, downloadResult);
|
|
814
|
-
args.entrypoint = await entrypointCallback2(args);
|
|
815
|
-
const rolldownResult = await rolldown(args);
|
|
816
|
-
const { routes } = await introspectApp(args, rolldownResult);
|
|
817
|
-
const lambda = new import_build_utils6.NodejsLambda({
|
|
818
|
-
runtime: downloadResult.nodeVersion.runtime,
|
|
819
|
-
...rolldownResult,
|
|
820
|
-
shouldAddHelpers: false,
|
|
821
|
-
shouldAddSourcemapSupport: true,
|
|
822
|
-
framework: {
|
|
823
|
-
slug: "express"
|
|
824
|
-
},
|
|
825
|
-
awsLambdaHandler: ""
|
|
826
|
-
});
|
|
827
|
-
const output = { index: lambda };
|
|
828
|
-
for (const route of routes) {
|
|
829
|
-
if (route.dest) {
|
|
830
|
-
if (route.dest === "/") {
|
|
831
|
-
continue;
|
|
832
|
-
}
|
|
833
|
-
output[route.dest] = lambda;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
return {
|
|
837
|
-
routes,
|
|
838
|
-
output
|
|
839
|
-
};
|
|
840
|
-
};
|
|
841
|
-
|
|
842
206
|
// src/index.ts
|
|
843
|
-
var
|
|
844
|
-
var
|
|
207
|
+
var import_node2 = require("@vercel/node");
|
|
208
|
+
var version = 3;
|
|
845
209
|
var name = "express";
|
|
846
210
|
var shouldServe = async (opts) => {
|
|
847
211
|
const requestPath = opts.requestPath.replace(/\/$/, "");
|
|
@@ -853,7 +217,7 @@ var shouldServe = async (opts) => {
|
|
|
853
217
|
var startDevServer = async (opts) => {
|
|
854
218
|
const entrypoint = await entrypointCallback(opts);
|
|
855
219
|
process.env.EXPERIMENTAL_NODE_TYPESCRIPT_ERRORS = "1";
|
|
856
|
-
return (0,
|
|
220
|
+
return (0, import_node2.startDevServer)({
|
|
857
221
|
...opts,
|
|
858
222
|
entrypoint,
|
|
859
223
|
publicDir: "public"
|
|
@@ -863,8 +227,6 @@ var startDevServer = async (opts) => {
|
|
|
863
227
|
0 && (module.exports = {
|
|
864
228
|
build,
|
|
865
229
|
entrypointCallback,
|
|
866
|
-
experimentalBuild,
|
|
867
|
-
experimentalVersion,
|
|
868
230
|
findEntrypoint,
|
|
869
231
|
name,
|
|
870
232
|
require_,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/express",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"homepage": "https://vercel.com/docs",
|
|
@@ -24,13 +24,14 @@
|
|
|
24
24
|
"rolldown": "1.0.0-beta.35",
|
|
25
25
|
"ts-morph": "12.0.0",
|
|
26
26
|
"zod": "3.22.4",
|
|
27
|
-
"@vercel/node": "5.5.
|
|
27
|
+
"@vercel/node": "5.5.1",
|
|
28
|
+
"@vercel/cervel": "0.0.2"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@types/fs-extra": "11",
|
|
31
32
|
"@types/jest": "27.5.1",
|
|
32
33
|
"@types/node": "14.18.33",
|
|
33
|
-
"@vercel/build-utils": "12.2.
|
|
34
|
+
"@vercel/build-utils": "12.2.1",
|
|
34
35
|
"execa": "3.2.0",
|
|
35
36
|
"jest-junit": "16.0.0",
|
|
36
37
|
"vite": "^5.1.6",
|