@vercel/rust 1.2.0 → 1.4.0

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.
Files changed (2) hide show
  1. package/dist/index.js +307 -74
  2. package/package.json +10 -9
package/dist/index.js CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  build: () => build,
34
+ diagnostics: () => diagnostics,
34
35
  prepareCache: () => prepareCache,
35
36
  shouldServe: () => shouldServe,
36
37
  startDevServer: () => startDevServer2,
@@ -38,7 +39,7 @@ __export(src_exports, {
38
39
  });
39
40
  module.exports = __toCommonJS(src_exports);
40
41
  var import_node_path4 = __toESM(require("path"));
41
- var import_build_utils6 = require("@vercel/build-utils");
42
+ var import_build_utils7 = require("@vercel/build-utils");
42
43
  var import_execa4 = __toESM(require("execa"));
43
44
 
44
45
  // src/lib/rust-toolchain.ts
@@ -74,12 +75,11 @@ var import_node_fs = require("fs");
74
75
  var import_node_path = __toESM(require("path"));
75
76
  var import_smol_toml = require("smol-toml");
76
77
  var import_execa2 = __toESM(require("execa"));
77
- async function getCargoMetadata(options) {
78
- const { stdout: cargoMetaData } = await (0, import_execa2.default)(
79
- "cargo",
80
- ["metadata", "--format-version", "1"],
81
- options
82
- );
78
+ async function getCargoMetadata(options, filterPlatform) {
79
+ const args = ["metadata", "--format-version", "1"];
80
+ if (filterPlatform)
81
+ args.push("--filter-platform", filterPlatform);
82
+ const { stdout: cargoMetaData } = await (0, import_execa2.default)("cargo", args, options);
83
83
  return JSON.parse(cargoMetaData);
84
84
  }
85
85
  async function findCargoWorkspace(config) {
@@ -158,6 +158,7 @@ async function gatherExtraFiles(globMatcher, workPath) {
158
158
  // src/lib/start-dev-server.ts
159
159
  var import_child_process = require("child_process");
160
160
  var import_events = require("events");
161
+ var import_get_port = __toESM(require("get-port"));
161
162
  var import_build_utils5 = require("@vercel/build-utils");
162
163
 
163
164
  // src/lib/dev-build.ts
@@ -213,7 +214,7 @@ async function buildExecutableForDev(workPath, entrypoint) {
213
214
 
214
215
  // src/lib/dev-server.ts
215
216
  var import_build_utils4 = require("@vercel/build-utils");
216
- function createDevServerEnv(baseEnv, meta = {}) {
217
+ function createDevServerEnv(baseEnv, meta = {}, port) {
217
218
  const devEnv = {
218
219
  // Base environment
219
220
  ...Object.fromEntries(
@@ -225,6 +226,9 @@ function createDevServerEnv(baseEnv, meta = {}) {
225
226
  // Runtime environment from meta
226
227
  ...meta.env || {}
227
228
  };
229
+ if (typeof port === "number" && Number.isInteger(port)) {
230
+ devEnv.VERCEL_DEV_PORT = String(port);
231
+ }
228
232
  Object.keys(devEnv).forEach((key) => {
229
233
  if (devEnv[key] === void 0) {
230
234
  delete devEnv[key];
@@ -235,49 +239,147 @@ function createDevServerEnv(baseEnv, meta = {}) {
235
239
  }
236
240
 
237
241
  // src/lib/start-dev-server.ts
242
+ var SHUTDOWN_TIMEOUT = 35e3;
243
+ var ADDR_IN_USE_RE = /address (already )?in use|AddrInUse|EADDRINUSE/i;
244
+ var MAX_STDERR_CAPTURE = 8192;
245
+ var RUNNING_DEV_SERVERS = /* @__PURE__ */ new Set();
246
+ var cleanupHandlersInstalled = false;
247
+ function installGlobalCleanupHandlers() {
248
+ if (cleanupHandlersInstalled)
249
+ return;
250
+ cleanupHandlersInstalled = true;
251
+ const onSignal = () => {
252
+ for (const child of RUNNING_DEV_SERVERS) {
253
+ try {
254
+ child.kill("SIGTERM");
255
+ } catch (err) {
256
+ (0, import_build_utils5.debug)(`Error sending SIGTERM to Rust dev server on signal: ${err}`);
257
+ }
258
+ }
259
+ };
260
+ process.on("SIGINT", onSignal);
261
+ process.on("SIGTERM", onSignal);
262
+ process.on("SIGHUP", onSignal);
263
+ process.on("exit", () => {
264
+ for (const child of RUNNING_DEV_SERVERS) {
265
+ if (child.pid) {
266
+ try {
267
+ process.kill(child.pid, "SIGKILL");
268
+ } catch {
269
+ }
270
+ }
271
+ }
272
+ RUNNING_DEV_SERVERS.clear();
273
+ });
274
+ }
275
+ function trackDevServer(child) {
276
+ installGlobalCleanupHandlers();
277
+ RUNNING_DEV_SERVERS.add(child);
278
+ const untrack = () => {
279
+ RUNNING_DEV_SERVERS.delete(child);
280
+ };
281
+ child.once("exit", untrack);
282
+ child.once("close", untrack);
283
+ }
284
+ var RustDevServerError = class extends Error {
285
+ constructor(message) {
286
+ super(message);
287
+ this.name = "RustDevServerError";
288
+ }
289
+ };
290
+ function terminate(child) {
291
+ return new Promise((resolve) => {
292
+ if (!child.pid || child.exitCode !== null || child.signalCode !== null) {
293
+ resolve();
294
+ return;
295
+ }
296
+ let timer;
297
+ let settled = false;
298
+ const done = () => {
299
+ if (settled)
300
+ return;
301
+ settled = true;
302
+ if (timer)
303
+ clearTimeout(timer);
304
+ resolve();
305
+ };
306
+ child.once("exit", done);
307
+ child.once("close", done);
308
+ try {
309
+ child.kill("SIGTERM");
310
+ } catch (err) {
311
+ (0, import_build_utils5.debug)(`Error sending SIGTERM to Rust dev server: ${err}`);
312
+ done();
313
+ return;
314
+ }
315
+ timer = setTimeout(() => {
316
+ (0, import_build_utils5.debug)(
317
+ `Rust dev server did not exit within ${SHUTDOWN_TIMEOUT}ms, sending SIGKILL`
318
+ );
319
+ try {
320
+ child.kill("SIGKILL");
321
+ } catch (err) {
322
+ (0, import_build_utils5.debug)(`Error sending SIGKILL to Rust dev server: ${err}`);
323
+ }
324
+ }, SHUTDOWN_TIMEOUT);
325
+ timer.unref?.();
326
+ });
327
+ }
238
328
  var startDevServer = async (opts) => {
239
- const { entrypoint, workPath, meta = {} } = opts;
329
+ const { entrypoint, workPath, meta = {}, onStdout, onStderr } = opts;
240
330
  try {
241
331
  await installRustToolchain();
242
332
  const executablePath = await buildExecutableForDev(workPath, entrypoint);
243
- (0, import_build_utils5.debug)(`Starting Rust dev server: ${executablePath}`);
244
- const devEnv = createDevServerEnv(process.env, meta);
333
+ const requestedPort = typeof meta.port === "number" ? meta.port : meta.env?.VERCEL_DEV_PORT ? Number(meta.env.VERCEL_DEV_PORT) : void 0;
334
+ const port = typeof requestedPort === "number" && Number.isInteger(requestedPort) ? requestedPort : await (0, import_get_port.default)();
335
+ (0, import_build_utils5.debug)(`Starting Rust dev server: ${executablePath} (port=${port})`);
336
+ const devEnv = createDevServerEnv(process.env, meta, port);
245
337
  const child = (0, import_child_process.spawn)(executablePath, [], {
246
338
  cwd: workPath,
247
339
  env: devEnv,
248
340
  stdio: ["pipe", "pipe", "pipe"]
249
341
  });
250
342
  if (!child.pid) {
251
- throw new Error("Failed to start dev server process");
343
+ throw new Error("Failed to start Rust dev server process");
252
344
  }
253
- (0, import_build_utils5.debug)(`Dev server process started with PID: ${child.pid}`);
345
+ trackDevServer(child);
346
+ (0, import_build_utils5.debug)(`Rust dev server process started with PID: ${child.pid}`);
254
347
  let buffer = "";
255
348
  let portEmitted = false;
349
+ let stderrTail = "";
256
350
  child.stdout?.on("data", (data) => {
257
- const output = data.toString();
258
- buffer += output;
259
- if (!portEmitted && buffer.includes("Dev server listening:")) {
260
- const portMatch = buffer.match(/Dev server listening: (\d+)/);
261
- if (portMatch) {
262
- const port = parseInt(portMatch[1], 10);
263
- (0, import_build_utils5.debug)(
264
- `Rust dev server detected port ${port}, emitting message event`
265
- );
266
- child.emit("message", { port }, null);
351
+ const chunk = Buffer.isBuffer(data) ? data : Buffer.from(data);
352
+ buffer += chunk.toString();
353
+ if (!portEmitted) {
354
+ const match = buffer.match(/Dev server listening:\s*(\d+)/);
355
+ if (match) {
267
356
  portEmitted = true;
357
+ const reportedPort = parseInt(match[1], 10);
358
+ (0, import_build_utils5.debug)(`Rust dev server reported ready on port ${reportedPort}`);
359
+ child.emit("message", { port: reportedPort }, null);
360
+ buffer = "";
268
361
  }
269
- buffer = "";
270
362
  }
271
- console.log(output);
363
+ if (onStdout) {
364
+ onStdout(chunk);
365
+ } else {
366
+ process.stdout.write(chunk.toString());
367
+ }
272
368
  });
273
369
  child.stderr?.on("data", (data) => {
274
- console.error(data.toString());
370
+ const chunk = Buffer.isBuffer(data) ? data : Buffer.from(data);
371
+ stderrTail = (stderrTail + chunk.toString()).slice(-MAX_STDERR_CAPTURE);
372
+ if (onStderr) {
373
+ onStderr(chunk);
374
+ } else {
375
+ process.stderr.write(chunk.toString());
376
+ }
275
377
  });
276
378
  child.on("error", (err) => {
277
- (0, import_build_utils5.debug)(`Dev server error: ${err}`);
379
+ (0, import_build_utils5.debug)(`Rust dev server error: ${err}`);
278
380
  });
279
- child.on("exit", (code, signal) => {
280
- (0, import_build_utils5.debug)(`Dev server exited with code ${code}, signal ${signal}`);
381
+ child.on("exit", (code, signal2) => {
382
+ (0, import_build_utils5.debug)(`Rust dev server exited with code ${code}, signal ${signal2}`);
281
383
  });
282
384
  const onMessage = (0, import_events.once)(child, "message");
283
385
  const onExit = (0, import_events.once)(child, "close");
@@ -287,40 +389,150 @@ var startDevServer = async (opts) => {
287
389
  return { state: "message", value: messageData };
288
390
  }),
289
391
  onExit.then((args) => {
290
- const [code, signal] = args;
291
- return { state: "exit", value: [code, signal] };
392
+ const [code, signal2] = args;
393
+ return { state: "exit", value: [code, signal2] };
292
394
  })
293
395
  ]);
294
396
  if (result.state === "message") {
295
- const { port } = result.value;
296
- (0, import_build_utils5.debug)(`Rust dev server ready on port ${port}`);
397
+ const readyPort = typeof result.value?.port === "number" ? result.value.port : port;
398
+ (0, import_build_utils5.debug)(`Rust dev server ready on port ${readyPort} (pid ${child.pid})`);
297
399
  if (!child.pid) {
298
400
  throw new Error("Child process has no PID");
299
401
  }
300
- const shutdown = async () => {
301
- try {
302
- process.kill(child.pid, "SIGTERM");
303
- } catch (err) {
304
- (0, import_build_utils5.debug)(`Error terminating Rust dev server: ${err}`);
305
- }
402
+ return {
403
+ port: readyPort,
404
+ pid: child.pid,
405
+ // Wait for exit so the port is released before `vercel dev` continues.
406
+ shutdown: () => terminate(child)
306
407
  };
307
- return { port, pid: child.pid, shutdown };
308
- } else {
309
- const [exitCode, signal] = result.value;
310
- const reason = signal ? `"${signal}" signal` : `exit code ${exitCode}`;
311
- throw new Error(`Rust dev server failed with ${reason}`);
312
408
  }
409
+ const [exitCode, signal] = result.value;
410
+ const reason = signal ? `"${signal}" signal` : `exit code ${exitCode}`;
411
+ const stderr = stderrTail.trim();
412
+ if (ADDR_IN_USE_RE.test(stderr)) {
413
+ throw new RustDevServerError(
414
+ `Rust dev server failed to bind port ${port} ("address already in use"). A previous dev server instance may not have shut down yet. Please retry, or ensure no other process is using that port.`
415
+ );
416
+ }
417
+ (0, import_build_utils5.debug)(
418
+ `Rust dev server exited before becoming ready (${reason}). Falling back to build-and-invoke mode.` + (stderr ? ` stderr:
419
+ ${stderr}` : "")
420
+ );
421
+ return null;
313
422
  } catch (error) {
314
- (0, import_build_utils5.debug)(`Failed to start dev server: ${error}`);
423
+ (0, import_build_utils5.debug)(`Failed to start Rust dev server: ${error}`);
424
+ if (error instanceof RustDevServerError) {
425
+ throw error;
426
+ }
315
427
  return null;
316
428
  }
317
429
  };
318
430
 
431
+ // src/diagnostics.ts
432
+ var import_build_utils6 = require("@vercel/build-utils");
433
+ function parseSource(source) {
434
+ if (!source)
435
+ return { include: false };
436
+ if (source.startsWith("path+file:"))
437
+ return { include: false };
438
+ if (source.startsWith("registry+https://github.com/rust-lang/crates.io-index")) {
439
+ return {
440
+ include: true,
441
+ source: "registry",
442
+ sourceUrl: "https://crates.io"
443
+ };
444
+ }
445
+ if (source.startsWith("registry+")) {
446
+ const url = source.slice("registry+".length).split(/[?#]/)[0];
447
+ return { include: true, source: "registry", sourceUrl: url };
448
+ }
449
+ if (source.startsWith("git+")) {
450
+ const url = source.slice("git+".length).split(/[?#]/)[0];
451
+ return { include: true, source: "git", sourceUrl: url };
452
+ }
453
+ return { include: true };
454
+ }
455
+ async function generateProjectManifest({
456
+ workPath,
457
+ cargoMetadata,
458
+ framework,
459
+ serviceType,
460
+ runtimeVersion
461
+ }) {
462
+ try {
463
+ const { packages, resolve } = cargoMetadata;
464
+ const pkgById = new Map(packages.map((p) => [p.id, p]));
465
+ const rootId = resolve.root;
466
+ const rootNode = resolve.nodes.find((n) => n.id === rootId);
467
+ if (!rootNode)
468
+ return;
469
+ const rootPkg = pkgById.get(rootId);
470
+ const directMap = /* @__PURE__ */ new Map();
471
+ for (const dep of rootNode.deps) {
472
+ const scopes = dep.dep_kinds.map(
473
+ (dk) => dk.kind === "dev" ? "dev" : dk.kind === "build" ? "build" : "prod"
474
+ );
475
+ const depPkg = pkgById.get(dep.pkg);
476
+ const req = rootPkg?.dependencies.find((d) => d.name === depPkg?.name)?.req;
477
+ directMap.set(dep.pkg, {
478
+ scopes: [...new Set(scopes)].sort(),
479
+ requested: req
480
+ });
481
+ }
482
+ const directEntries = [];
483
+ const transitiveEntries = [];
484
+ for (const node of resolve.nodes) {
485
+ if (node.id === rootId)
486
+ continue;
487
+ const pkg = pkgById.get(node.id);
488
+ if (!pkg)
489
+ continue;
490
+ const sourceInfo = parseSource(pkg.source);
491
+ if (!sourceInfo.include)
492
+ continue;
493
+ const directInfo = directMap.get(node.id);
494
+ const entry = {
495
+ name: pkg.name,
496
+ type: directInfo ? "direct" : "transitive",
497
+ // Transitive scope would require full graph traversal to trace which
498
+ // root-level scope pulled this in. 'prod' is a safe default — accurate
499
+ // scope propagation for transitives is left to future work.
500
+ scopes: directInfo ? directInfo.scopes : ["prod"],
501
+ resolved: pkg.version
502
+ };
503
+ if (directInfo?.requested)
504
+ entry.requested = directInfo.requested;
505
+ if (sourceInfo.source)
506
+ entry.source = sourceInfo.source;
507
+ if (sourceInfo.sourceUrl)
508
+ entry.sourceUrl = sourceInfo.sourceUrl;
509
+ if (directInfo)
510
+ directEntries.push(entry);
511
+ else
512
+ transitiveEntries.push(entry);
513
+ }
514
+ const manifest = {
515
+ version: import_build_utils6.MANIFEST_VERSION,
516
+ runtime: "rust",
517
+ ...framework ? { framework } : {},
518
+ ...serviceType ? { serviceType } : {},
519
+ ...runtimeVersion ? { runtimeVersion } : {},
520
+ dependencies: [
521
+ ...directEntries.sort((a, b) => a.name.localeCompare(b.name)),
522
+ ...transitiveEntries.sort((a, b) => a.name.localeCompare(b.name))
523
+ ]
524
+ };
525
+ await (0, import_build_utils6.writeProjectManifest)(manifest, workPath, "rust");
526
+ } catch {
527
+ }
528
+ }
529
+ var diagnostics = (0, import_build_utils6.createDiagnostics)("rust");
530
+
319
531
  // src/index.ts
320
532
  async function buildHandler(options) {
321
533
  const BUILDER_DEBUG = Boolean(process.env.VERCEL_BUILDER_DEBUG ?? false);
322
534
  const isVercelBuild = Boolean(process.env.VERCEL_BUILD_IMAGE ?? false);
323
- const { files, entrypoint, workPath, config, meta } = options;
535
+ const { files, entrypoint, workPath, config, meta, service } = options;
324
536
  const crossCompilationEnabled = !isVercelBuild && !meta?.isDev;
325
537
  if (crossCompilationEnabled && process.platform === "win32") {
326
538
  throw new Error(
@@ -328,8 +540,8 @@ async function buildHandler(options) {
328
540
  );
329
541
  }
330
542
  await installRustToolchain();
331
- (0, import_build_utils6.debug)("Creating file system");
332
- const downloadedFiles = await (0, import_build_utils6.download)(files, workPath, meta);
543
+ (0, import_build_utils7.debug)("Creating file system");
544
+ const downloadedFiles = await (0, import_build_utils7.download)(files, workPath, meta);
333
545
  const entryPath = downloadedFiles[entrypoint].fsPath;
334
546
  const HOME = process.platform === "win32" ? assertEnv("USERPROFILE") : assertEnv("HOME");
335
547
  const PATH = assertEnv("PATH");
@@ -345,25 +557,23 @@ async function buildHandler(options) {
345
557
  const cargoBuildConfiguration = await findCargoBuildConfiguration(cargoWorkspace);
346
558
  await runUserScripts(workPath);
347
559
  const extraFiles = await gatherExtraFiles(config.includeFiles, workPath);
348
- const lambdaOptions = await (0, import_build_utils6.getLambdaOptionsFromFunction)({
560
+ const lambdaOptions = await (0, import_build_utils7.getLambdaOptionsFromFunction)({
349
561
  sourceFile: entrypoint,
350
562
  config
351
563
  });
352
564
  const architecture = lambdaOptions?.architecture || "x86_64";
353
565
  const buildVariant = meta?.isDev ? "debug" : "release";
354
566
  const buildTarget = cargoBuildConfiguration?.build.target ?? "";
567
+ const targetTriple = architecture === "x86_64" ? "x86_64-unknown-linux-gnu" : "aarch64-unknown-linux-gnu";
355
568
  try {
356
- const args = crossCompilationEnabled ? [
357
- "zigbuild",
358
- "--target",
359
- architecture === "x86_64" ? "x86_64-unknown-linux-gnu" : "aarch64-unknown-linux-gnu",
360
- "--bin",
361
- binaryName
362
- ].concat(BUILDER_DEBUG ? ["--verbose"] : ["--quiet"], ["--release"]) : ["build", "--bin", binaryName].concat(
569
+ const args = crossCompilationEnabled ? ["zigbuild", "--target", targetTriple, "--bin", binaryName].concat(
570
+ BUILDER_DEBUG ? ["--verbose"] : ["--quiet"],
571
+ ["--release"]
572
+ ) : ["build", "--bin", binaryName].concat(
363
573
  BUILDER_DEBUG ? ["--verbose"] : ["--quiet"],
364
574
  meta?.isDev ? [] : ["--release"]
365
575
  );
366
- (0, import_build_utils6.debug)(
576
+ (0, import_build_utils7.debug)(
367
577
  `Running \`cargo build\` for \`${binaryName}\` (\`${architecture}\`)`
368
578
  );
369
579
  await (0, import_execa4.default)("cargo", args, {
@@ -371,21 +581,19 @@ async function buildHandler(options) {
371
581
  env: rustEnv
372
582
  });
373
583
  } catch (err) {
374
- (0, import_build_utils6.debug)(`Running \`cargo build\` for \`${binaryName}\` failed`);
584
+ (0, import_build_utils7.debug)(`Running \`cargo build\` for \`${binaryName}\` failed`);
375
585
  throw err;
376
586
  }
377
- (0, import_build_utils6.debug)(
587
+ (0, import_build_utils7.debug)(
378
588
  `Building \`${binaryName}\` for \`${process.platform}\` (\`${architecture}\`) completed`
379
589
  );
380
- let { target_directory: targetDirectory } = await getCargoMetadata({
381
- cwd: workPath,
382
- env: rustEnv
383
- });
590
+ const cargoMetadata = await getCargoMetadata(
591
+ { cwd: workPath, env: rustEnv },
592
+ targetTriple
593
+ );
594
+ let { target_directory: targetDirectory } = cargoMetadata;
384
595
  if (crossCompilationEnabled) {
385
- targetDirectory = import_node_path4.default.join(
386
- targetDirectory,
387
- architecture === "x86_64" ? "x86_64-unknown-linux-gnu" : "aarch64-unknown-linux-gnu"
388
- );
596
+ targetDirectory = import_node_path4.default.join(targetDirectory, targetTriple);
389
597
  }
390
598
  targetDirectory = import_node_path4.default.join(targetDirectory, buildTarget);
391
599
  const bin = import_node_path4.default.join(
@@ -394,8 +602,8 @@ async function buildHandler(options) {
394
602
  getExecutableName(binaryName)
395
603
  );
396
604
  const handler = getExecutableName("executable");
397
- const executableFile = new import_build_utils6.FileFsRef({ mode: 493, fsPath: bin });
398
- const lambda = new import_build_utils6.Lambda({
605
+ const executableFile = new import_build_utils7.FileFsRef({ mode: 493, fsPath: bin });
606
+ const lambda = new import_build_utils7.Lambda({
399
607
  ...lambdaOptions,
400
608
  files: {
401
609
  ...extraFiles,
@@ -408,7 +616,31 @@ async function buildHandler(options) {
408
616
  runtimeLanguage: "rust"
409
617
  });
410
618
  lambda.zipBuffer = await lambda.createZip();
411
- (0, import_build_utils6.debug)(`generating function for \`${entrypoint}\``);
619
+ let resolvedRustVersion;
620
+ try {
621
+ const { stdout: rustcOut } = await (0, import_execa4.default)("rustc", ["--version"], {
622
+ env: rustEnv,
623
+ cwd: workPath
624
+ });
625
+ resolvedRustVersion = rustcOut.split(" ")[1];
626
+ } catch {
627
+ (0, import_build_utils7.debug)("Failed to determine rustc version");
628
+ }
629
+ const rootPkg = cargoMetadata.packages.find(
630
+ (p) => p.id === cargoMetadata.resolve.root
631
+ );
632
+ const requestedRustVersion = rootPkg?.rust_version || void 0;
633
+ await generateProjectManifest({
634
+ workPath,
635
+ cargoMetadata,
636
+ framework: config?.framework ?? void 0,
637
+ serviceType: service ? (0, import_build_utils7.getReportedServiceType)(service) : void 0,
638
+ runtimeVersion: resolvedRustVersion ? {
639
+ ...requestedRustVersion ? { requested: requestedRustVersion } : {},
640
+ resolved: resolvedRustVersion
641
+ } : void 0
642
+ });
643
+ (0, import_build_utils7.debug)(`generating function for \`${entrypoint}\``);
412
644
  return {
413
645
  output: lambda
414
646
  };
@@ -417,8 +649,8 @@ var runtime = {
417
649
  version: 3,
418
650
  build: buildHandler,
419
651
  prepareCache: async ({ workPath }) => {
420
- (0, import_build_utils6.debug)(`Caching \`${workPath}\``);
421
- const cacheFiles = await (0, import_build_utils6.glob)("target/**", workPath);
652
+ (0, import_build_utils7.debug)(`Caching \`${workPath}\``);
653
+ const cacheFiles = await (0, import_build_utils7.glob)("target/**", workPath);
422
654
  for (const f of Object.keys(cacheFiles)) {
423
655
  const accept = /(?:^|\/)target\/release\/\.fingerprint\//.test(f) || /(?:^|\/)target\/release\/build\//.test(f) || /(?:^|\/)target\/release\/deps\//.test(f) || /(?:^|\/)target\/debug\/\.fingerprint\//.test(f) || /(?:^|\/)target\/debug\/build\//.test(f) || /(?:^|\/)target\/debug\/deps\//.test(f);
424
656
  if (!accept) {
@@ -429,10 +661,10 @@ var runtime = {
429
661
  },
430
662
  startDevServer,
431
663
  shouldServe: async (options) => {
432
- (0, import_build_utils6.debug)(`Requested ${options.requestPath} for ${options.entrypoint}`);
664
+ (0, import_build_utils7.debug)(`Requested ${options.requestPath} for ${options.entrypoint}`);
433
665
  const entrypointWithoutExt = options.entrypoint.replace(/\.rs$/, "");
434
666
  const matches = options.requestPath === options.entrypoint || options.requestPath === entrypointWithoutExt;
435
- (0, import_build_utils6.debug)(
667
+ (0, import_build_utils7.debug)(
436
668
  `shouldServe: ${matches} (entrypointWithoutExt: ${entrypointWithoutExt})`
437
669
  );
438
670
  return Promise.resolve(matches);
@@ -442,6 +674,7 @@ var { version, build, prepareCache, startDevServer: startDevServer2, shouldServe
442
674
  // Annotate the CommonJS export names for ESM import in node:
443
675
  0 && (module.exports = {
444
676
  build,
677
+ diagnostics,
445
678
  prepareCache,
446
679
  shouldServe,
447
680
  startDevServer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/rust",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/rust",
@@ -14,27 +14,28 @@
14
14
  ],
15
15
  "dependencies": {
16
16
  "smol-toml": "1.5.2",
17
- "execa": "5"
17
+ "execa": "5",
18
+ "get-port": "5.1.1"
18
19
  },
19
20
  "devDependencies": {
20
- "@types/jest": "^29.4.0",
21
21
  "@types/ms": "^0.7.31",
22
22
  "@types/node": "20.11.0",
23
23
  "@vercel/style-guide": "^4.0.2",
24
24
  "eslint": "^8.35.0",
25
25
  "husky": "^8.0.3",
26
- "jest": "^29.5.0",
27
26
  "ms": "^2.1.3",
28
27
  "prettier": "^2.8.4",
29
28
  "rimraf": "^4.1.1",
30
- "ts-jest": "^29.0.5",
31
- "@vercel/routing-utils": "6.2.0",
32
- "@vercel/build-utils": "13.21.0"
29
+ "vitest": "2.0.3",
30
+ "@vercel/build-utils": "13.32.2",
31
+ "@vercel/routing-utils": "6.4.0"
33
32
  },
34
33
  "scripts": {
35
34
  "build": "node ../../utils/build-builder.mjs",
36
- "test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
35
+ "test": "vitest run --config ../../vitest.config.mts",
37
36
  "test-e2e": "pnpm test",
38
- "type-check": "tsc --noEmit"
37
+ "type-check": "tsc --noEmit",
38
+ "vitest-run": "vitest -c ../../vitest.config.mts",
39
+ "vitest-e2e": "glob --absolute 'test/**/*.test.js' 'test/**/*.test.ts' 'tests/**/*.test.js' 'tests/**/*.test.ts'"
39
40
  }
40
41
  }