@vercel/rust 1.1.1 → 1.3.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 +157 -36
  2. package/package.json +8 -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) {
@@ -316,11 +316,111 @@ var startDevServer = async (opts) => {
316
316
  }
317
317
  };
318
318
 
319
+ // src/diagnostics.ts
320
+ var import_build_utils6 = require("@vercel/build-utils");
321
+ function parseSource(source) {
322
+ if (!source)
323
+ return { include: false };
324
+ if (source.startsWith("path+file:"))
325
+ return { include: false };
326
+ if (source.startsWith("registry+https://github.com/rust-lang/crates.io-index")) {
327
+ return {
328
+ include: true,
329
+ source: "registry",
330
+ sourceUrl: "https://crates.io"
331
+ };
332
+ }
333
+ if (source.startsWith("registry+")) {
334
+ const url = source.slice("registry+".length).split(/[?#]/)[0];
335
+ return { include: true, source: "registry", sourceUrl: url };
336
+ }
337
+ if (source.startsWith("git+")) {
338
+ const url = source.slice("git+".length).split(/[?#]/)[0];
339
+ return { include: true, source: "git", sourceUrl: url };
340
+ }
341
+ return { include: true };
342
+ }
343
+ async function generateProjectManifest({
344
+ workPath,
345
+ cargoMetadata,
346
+ framework,
347
+ serviceType,
348
+ runtimeVersion
349
+ }) {
350
+ try {
351
+ const { packages, resolve } = cargoMetadata;
352
+ const pkgById = new Map(packages.map((p) => [p.id, p]));
353
+ const rootId = resolve.root;
354
+ const rootNode = resolve.nodes.find((n) => n.id === rootId);
355
+ if (!rootNode)
356
+ return;
357
+ const rootPkg = pkgById.get(rootId);
358
+ const directMap = /* @__PURE__ */ new Map();
359
+ for (const dep of rootNode.deps) {
360
+ const scopes = dep.dep_kinds.map(
361
+ (dk) => dk.kind === "dev" ? "dev" : dk.kind === "build" ? "build" : "prod"
362
+ );
363
+ const depPkg = pkgById.get(dep.pkg);
364
+ const req = rootPkg?.dependencies.find((d) => d.name === depPkg?.name)?.req;
365
+ directMap.set(dep.pkg, {
366
+ scopes: [...new Set(scopes)].sort(),
367
+ requested: req
368
+ });
369
+ }
370
+ const directEntries = [];
371
+ const transitiveEntries = [];
372
+ for (const node of resolve.nodes) {
373
+ if (node.id === rootId)
374
+ continue;
375
+ const pkg = pkgById.get(node.id);
376
+ if (!pkg)
377
+ continue;
378
+ const sourceInfo = parseSource(pkg.source);
379
+ if (!sourceInfo.include)
380
+ continue;
381
+ const directInfo = directMap.get(node.id);
382
+ const entry = {
383
+ name: pkg.name,
384
+ type: directInfo ? "direct" : "transitive",
385
+ // Transitive scope would require full graph traversal to trace which
386
+ // root-level scope pulled this in. 'prod' is a safe default — accurate
387
+ // scope propagation for transitives is left to future work.
388
+ scopes: directInfo ? directInfo.scopes : ["prod"],
389
+ resolved: pkg.version
390
+ };
391
+ if (directInfo?.requested)
392
+ entry.requested = directInfo.requested;
393
+ if (sourceInfo.source)
394
+ entry.source = sourceInfo.source;
395
+ if (sourceInfo.sourceUrl)
396
+ entry.sourceUrl = sourceInfo.sourceUrl;
397
+ if (directInfo)
398
+ directEntries.push(entry);
399
+ else
400
+ transitiveEntries.push(entry);
401
+ }
402
+ const manifest = {
403
+ version: import_build_utils6.MANIFEST_VERSION,
404
+ runtime: "rust",
405
+ ...framework ? { framework } : {},
406
+ ...serviceType ? { serviceType } : {},
407
+ ...runtimeVersion ? { runtimeVersion } : {},
408
+ dependencies: [
409
+ ...directEntries.sort((a, b) => a.name.localeCompare(b.name)),
410
+ ...transitiveEntries.sort((a, b) => a.name.localeCompare(b.name))
411
+ ]
412
+ };
413
+ await (0, import_build_utils6.writeProjectManifest)(manifest, workPath, "rust");
414
+ } catch {
415
+ }
416
+ }
417
+ var diagnostics = (0, import_build_utils6.createDiagnostics)("rust");
418
+
319
419
  // src/index.ts
320
420
  async function buildHandler(options) {
321
421
  const BUILDER_DEBUG = Boolean(process.env.VERCEL_BUILDER_DEBUG ?? false);
322
422
  const isVercelBuild = Boolean(process.env.VERCEL_BUILD_IMAGE ?? false);
323
- const { files, entrypoint, workPath, config, meta } = options;
423
+ const { files, entrypoint, workPath, config, meta, service } = options;
324
424
  const crossCompilationEnabled = !isVercelBuild && !meta?.isDev;
325
425
  if (crossCompilationEnabled && process.platform === "win32") {
326
426
  throw new Error(
@@ -328,8 +428,8 @@ async function buildHandler(options) {
328
428
  );
329
429
  }
330
430
  await installRustToolchain();
331
- (0, import_build_utils6.debug)("Creating file system");
332
- const downloadedFiles = await (0, import_build_utils6.download)(files, workPath, meta);
431
+ (0, import_build_utils7.debug)("Creating file system");
432
+ const downloadedFiles = await (0, import_build_utils7.download)(files, workPath, meta);
333
433
  const entryPath = downloadedFiles[entrypoint].fsPath;
334
434
  const HOME = process.platform === "win32" ? assertEnv("USERPROFILE") : assertEnv("HOME");
335
435
  const PATH = assertEnv("PATH");
@@ -345,25 +445,23 @@ async function buildHandler(options) {
345
445
  const cargoBuildConfiguration = await findCargoBuildConfiguration(cargoWorkspace);
346
446
  await runUserScripts(workPath);
347
447
  const extraFiles = await gatherExtraFiles(config.includeFiles, workPath);
348
- const lambdaOptions = await (0, import_build_utils6.getLambdaOptionsFromFunction)({
448
+ const lambdaOptions = await (0, import_build_utils7.getLambdaOptionsFromFunction)({
349
449
  sourceFile: entrypoint,
350
450
  config
351
451
  });
352
452
  const architecture = lambdaOptions?.architecture || "x86_64";
353
453
  const buildVariant = meta?.isDev ? "debug" : "release";
354
454
  const buildTarget = cargoBuildConfiguration?.build.target ?? "";
455
+ const targetTriple = architecture === "x86_64" ? "x86_64-unknown-linux-gnu" : "aarch64-unknown-linux-gnu";
355
456
  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(
457
+ const args = crossCompilationEnabled ? ["zigbuild", "--target", targetTriple, "--bin", binaryName].concat(
458
+ BUILDER_DEBUG ? ["--verbose"] : ["--quiet"],
459
+ ["--release"]
460
+ ) : ["build", "--bin", binaryName].concat(
363
461
  BUILDER_DEBUG ? ["--verbose"] : ["--quiet"],
364
462
  meta?.isDev ? [] : ["--release"]
365
463
  );
366
- (0, import_build_utils6.debug)(
464
+ (0, import_build_utils7.debug)(
367
465
  `Running \`cargo build\` for \`${binaryName}\` (\`${architecture}\`)`
368
466
  );
369
467
  await (0, import_execa4.default)("cargo", args, {
@@ -371,21 +469,19 @@ async function buildHandler(options) {
371
469
  env: rustEnv
372
470
  });
373
471
  } catch (err) {
374
- (0, import_build_utils6.debug)(`Running \`cargo build\` for \`${binaryName}\` failed`);
472
+ (0, import_build_utils7.debug)(`Running \`cargo build\` for \`${binaryName}\` failed`);
375
473
  throw err;
376
474
  }
377
- (0, import_build_utils6.debug)(
475
+ (0, import_build_utils7.debug)(
378
476
  `Building \`${binaryName}\` for \`${process.platform}\` (\`${architecture}\`) completed`
379
477
  );
380
- let { target_directory: targetDirectory } = await getCargoMetadata({
381
- cwd: workPath,
382
- env: rustEnv
383
- });
478
+ const cargoMetadata = await getCargoMetadata(
479
+ { cwd: workPath, env: rustEnv },
480
+ targetTriple
481
+ );
482
+ let { target_directory: targetDirectory } = cargoMetadata;
384
483
  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
- );
484
+ targetDirectory = import_node_path4.default.join(targetDirectory, targetTriple);
389
485
  }
390
486
  targetDirectory = import_node_path4.default.join(targetDirectory, buildTarget);
391
487
  const bin = import_node_path4.default.join(
@@ -394,8 +490,8 @@ async function buildHandler(options) {
394
490
  getExecutableName(binaryName)
395
491
  );
396
492
  const handler = getExecutableName("executable");
397
- const executableFile = new import_build_utils6.FileFsRef({ mode: 493, fsPath: bin });
398
- const lambda = new import_build_utils6.Lambda({
493
+ const executableFile = new import_build_utils7.FileFsRef({ mode: 493, fsPath: bin });
494
+ const lambda = new import_build_utils7.Lambda({
399
495
  ...lambdaOptions,
400
496
  files: {
401
497
  ...extraFiles,
@@ -408,7 +504,31 @@ async function buildHandler(options) {
408
504
  runtimeLanguage: "rust"
409
505
  });
410
506
  lambda.zipBuffer = await lambda.createZip();
411
- (0, import_build_utils6.debug)(`generating function for \`${entrypoint}\``);
507
+ let resolvedRustVersion;
508
+ try {
509
+ const { stdout: rustcOut } = await (0, import_execa4.default)("rustc", ["--version"], {
510
+ env: rustEnv,
511
+ cwd: workPath
512
+ });
513
+ resolvedRustVersion = rustcOut.split(" ")[1];
514
+ } catch {
515
+ (0, import_build_utils7.debug)("Failed to determine rustc version");
516
+ }
517
+ const rootPkg = cargoMetadata.packages.find(
518
+ (p) => p.id === cargoMetadata.resolve.root
519
+ );
520
+ const requestedRustVersion = rootPkg?.rust_version || void 0;
521
+ await generateProjectManifest({
522
+ workPath,
523
+ cargoMetadata,
524
+ framework: config?.framework ?? void 0,
525
+ serviceType: service ? (0, import_build_utils7.getReportedServiceType)(service) : void 0,
526
+ runtimeVersion: resolvedRustVersion ? {
527
+ ...requestedRustVersion ? { requested: requestedRustVersion } : {},
528
+ resolved: resolvedRustVersion
529
+ } : void 0
530
+ });
531
+ (0, import_build_utils7.debug)(`generating function for \`${entrypoint}\``);
412
532
  return {
413
533
  output: lambda
414
534
  };
@@ -417,8 +537,8 @@ var runtime = {
417
537
  version: 3,
418
538
  build: buildHandler,
419
539
  prepareCache: async ({ workPath }) => {
420
- (0, import_build_utils6.debug)(`Caching \`${workPath}\``);
421
- const cacheFiles = await (0, import_build_utils6.glob)("target/**", workPath);
540
+ (0, import_build_utils7.debug)(`Caching \`${workPath}\``);
541
+ const cacheFiles = await (0, import_build_utils7.glob)("target/**", workPath);
422
542
  for (const f of Object.keys(cacheFiles)) {
423
543
  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
544
  if (!accept) {
@@ -429,10 +549,10 @@ var runtime = {
429
549
  },
430
550
  startDevServer,
431
551
  shouldServe: async (options) => {
432
- (0, import_build_utils6.debug)(`Requested ${options.requestPath} for ${options.entrypoint}`);
552
+ (0, import_build_utils7.debug)(`Requested ${options.requestPath} for ${options.entrypoint}`);
433
553
  const entrypointWithoutExt = options.entrypoint.replace(/\.rs$/, "");
434
554
  const matches = options.requestPath === options.entrypoint || options.requestPath === entrypointWithoutExt;
435
- (0, import_build_utils6.debug)(
555
+ (0, import_build_utils7.debug)(
436
556
  `shouldServe: ${matches} (entrypointWithoutExt: ${entrypointWithoutExt})`
437
557
  );
438
558
  return Promise.resolve(matches);
@@ -442,6 +562,7 @@ var { version, build, prepareCache, startDevServer: startDevServer2, shouldServe
442
562
  // Annotate the CommonJS export names for ESM import in node:
443
563
  0 && (module.exports = {
444
564
  build,
565
+ diagnostics,
445
566
  prepareCache,
446
567
  shouldServe,
447
568
  startDevServer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/rust",
3
- "version": "1.1.1",
3
+ "version": "1.3.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/rust",
@@ -17,25 +17,24 @@
17
17
  "execa": "5"
18
18
  },
19
19
  "devDependencies": {
20
- "@types/jest": "^29.4.0",
21
20
  "@types/ms": "^0.7.31",
22
21
  "@types/node": "20.11.0",
23
22
  "@vercel/style-guide": "^4.0.2",
24
23
  "eslint": "^8.35.0",
25
24
  "husky": "^8.0.3",
26
- "jest": "^29.5.0",
27
25
  "ms": "^2.1.3",
28
26
  "prettier": "^2.8.4",
29
27
  "rimraf": "^4.1.1",
30
- "ts-jest": "^29.0.5",
31
- "typescript": "^4.9.4",
32
- "@vercel/build-utils": "13.17.0",
33
- "@vercel/routing-utils": "6.1.1"
28
+ "vitest": "2.0.3",
29
+ "@vercel/build-utils": "13.26.2",
30
+ "@vercel/routing-utils": "6.2.0"
34
31
  },
35
32
  "scripts": {
36
33
  "build": "node ../../utils/build-builder.mjs",
37
- "test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
34
+ "test": "vitest run --config ../../vitest.config.mts",
38
35
  "test-e2e": "pnpm test",
39
- "type-check": "tsc --noEmit"
36
+ "type-check": "tsc --noEmit",
37
+ "vitest-run": "vitest -c ../../vitest.config.mts",
38
+ "vitest-e2e": "glob --absolute 'test/**/*.test.js' 'test/**/*.test.ts' 'tests/**/*.test.js' 'tests/**/*.test.ts'"
40
39
  }
41
40
  }