@vercel/container 8.2.2 → 8.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 +88 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1244,6 +1244,28 @@ var LIFECYCLE = {
1244
1244
  url: `${BUILDPACK_DIST_BASE_URL}/lifecycle/${LIFECYCLE_VERSION}/lifecycle-v${LIFECYCLE_VERSION}-linux-x86-64.tgz`,
1245
1245
  sha256: distribution.lifecycle.sha256
1246
1246
  };
1247
+ var PRERELEASE_URL_ENV = "VERCEL_BUILDPACK_PRERELEASE_URL";
1248
+ var SHA256_RE = /^[0-9a-f]{64}$/;
1249
+ var ARTIFACT_PREFIX = "vercel-";
1250
+ var ARTIFACT_SUFFIX = ".cnb";
1251
+ var ARTIFACT_NAME_RE = /^[A-Za-z0-9_-]+$/;
1252
+ var ARTIFACT_VERSION_RE = /^\d+\.\d+\.\d+$/;
1253
+ function artifactFileName(name, version2) {
1254
+ return `${ARTIFACT_PREFIX}${name}-${version2}${ARTIFACT_SUFFIX}`;
1255
+ }
1256
+ function parseArtifactFileName(fileName) {
1257
+ if (!fileName.startsWith(ARTIFACT_PREFIX) || !fileName.endsWith(ARTIFACT_SUFFIX)) {
1258
+ return void 0;
1259
+ }
1260
+ const inner = fileName.slice(ARTIFACT_PREFIX.length, -ARTIFACT_SUFFIX.length);
1261
+ const separator = inner.lastIndexOf("-");
1262
+ const name = separator > 0 ? inner.slice(0, separator) : "";
1263
+ const version2 = separator > 0 ? inner.slice(separator + 1) : "";
1264
+ if (!ARTIFACT_NAME_RE.test(name) || !ARTIFACT_VERSION_RE.test(version2)) {
1265
+ return void 0;
1266
+ }
1267
+ return { name, version: version2 };
1268
+ }
1247
1269
  function vercelBuildpack(name) {
1248
1270
  const pinned = distribution.buildpacks[name];
1249
1271
  if (!pinned) {
@@ -1256,10 +1278,69 @@ function vercelBuildpack(name) {
1256
1278
  function vercelBuildpackArtifact(buildpack) {
1257
1279
  const { name, version: version2 } = buildpack;
1258
1280
  return {
1259
- url: `${BUILDPACK_DIST_BASE_URL}/buildpacks/${name}/${version2}/vercel-${name}-${version2}.cnb`,
1281
+ url: buildpack.url ?? `${BUILDPACK_DIST_BASE_URL}/buildpacks/${name}/${version2}/${artifactFileName(name, version2)}`,
1260
1282
  sha256: buildpack.sha256
1261
1283
  };
1262
1284
  }
1285
+ function parseArchiveUrl(value) {
1286
+ let url;
1287
+ try {
1288
+ url = new URL(value);
1289
+ } catch {
1290
+ throw new Error(`${PRERELEASE_URL_ENV} must be an https .cnb archive URL.`);
1291
+ }
1292
+ const fileName = url.pathname.split("/").at(-1) ?? "";
1293
+ const artifact = parseArtifactFileName(fileName);
1294
+ if (url.protocol !== "https:" || !artifact) {
1295
+ throw new Error(
1296
+ `${PRERELEASE_URL_ENV} must be a plain https URL ending in vercel-<name>-<version>.cnb.`
1297
+ );
1298
+ }
1299
+ return {
1300
+ url: url.href,
1301
+ fileName,
1302
+ name: artifact.name,
1303
+ version: artifact.version
1304
+ };
1305
+ }
1306
+ function getPrereleaseUrl(env = process.env) {
1307
+ const value = env[PRERELEASE_URL_ENV]?.trim();
1308
+ return value ? parseArchiveUrl(value).url : void 0;
1309
+ }
1310
+ async function withPrereleaseBuildpack(buildpack, archiveUrl) {
1311
+ const archive = parseArchiveUrl(archiveUrl);
1312
+ const entry = buildpack.buildpacks.find(
1313
+ (candidate) => candidate.name === archive.name && candidate.id === `vercel/${archive.name}`
1314
+ );
1315
+ if (!entry) {
1316
+ throw new Error(
1317
+ `Pre-release archive ${archive.url} does not match a buildpack in the ${buildpack.runtime} runtime.`
1318
+ );
1319
+ }
1320
+ const checksumUrlObj = new URL(archive.url);
1321
+ checksumUrlObj.pathname += ".sha256";
1322
+ const checksumUrl = checksumUrlObj.href;
1323
+ const response = await fetch(checksumUrl);
1324
+ if (!response.ok) {
1325
+ throw new Error(
1326
+ `Failed to fetch pre-release checksum ${checksumUrl}: HTTP ${response.status} ${response.statusText}`
1327
+ );
1328
+ }
1329
+ const fields = (await response.text()).trim().split(/\s+/);
1330
+ const [sha256, fileName] = fields;
1331
+ if (fields.length !== 2 || !SHA256_RE.test(sha256) || fileName !== archive.fileName) {
1332
+ throw new Error(
1333
+ `Invalid pre-release checksum ${checksumUrl}: expected a SHA-256 checksum for ${archive.fileName}.`
1334
+ );
1335
+ }
1336
+ info(`Using pre-release ${entry.id}@${archive.version}: ${archive.url}`);
1337
+ return {
1338
+ ...buildpack,
1339
+ buildpacks: buildpack.buildpacks.map(
1340
+ (candidate) => candidate === entry ? { ...entry, version: archive.version, sha256, url: archive.url } : candidate
1341
+ )
1342
+ };
1343
+ }
1263
1344
 
1264
1345
  // src/buildpacks/lifecycle/lifecycle.ts
1265
1346
  var BUILD_USER_ID = 1001;
@@ -1430,22 +1511,6 @@ function cnbRegistryAuth(credentials) {
1430
1511
  const basic = Buffer.from(`${username}:${token}`).toString("base64");
1431
1512
  return JSON.stringify({ [registry]: `Basic ${basic}` });
1432
1513
  }
1433
- function assertPublishedArchive(name, archive) {
1434
- if (/^0{64}$/.test(archive.sha256)) {
1435
- throw new Error(
1436
- `The ${name} archive has not been published. Publish it and update its checksum in distribution.json.`
1437
- );
1438
- }
1439
- }
1440
- function assertPublishedDistribution(buildpack) {
1441
- assertPublishedArchive("CNB lifecycle", LIFECYCLE);
1442
- for (const entry of buildpack.buildpacks) {
1443
- assertPublishedArchive(
1444
- `${entry.id}@${entry.version} buildpack`,
1445
- vercelBuildpackArtifact(entry)
1446
- );
1447
- }
1448
- }
1449
1514
  function distributionUrls(buildpack) {
1450
1515
  return {
1451
1516
  lifecycle: LIFECYCLE.url,
@@ -1615,7 +1680,6 @@ var buildAndPushWithLifecycle = async (buildpack, params, span) => {
1615
1680
  "image.ref": params.imageRef
1616
1681
  },
1617
1682
  async (lifecycleSpan) => {
1618
- assertPublishedDistribution(buildpack);
1619
1683
  const suffix = `${process.pid}-${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`;
1620
1684
  const buildContainer = `vercel-cnb-${buildpack.runtime}-${suffix}`;
1621
1685
  let cnbDir;
@@ -1809,7 +1873,6 @@ var buildAndPushWithLifecycleDocker = async (buildpack, params, span) => {
1809
1873
  "image.ref": params.imageRef
1810
1874
  },
1811
1875
  async (lifecycleSpan) => {
1812
- assertPublishedDistribution(buildpack);
1813
1876
  let stageDir;
1814
1877
  const containers = [];
1815
1878
  try {
@@ -2138,7 +2201,9 @@ async function buildAndPushBuildpack(params) {
2138
2201
  `The ${params.buildpack.runtime} buildpack was selected, but no supported project marker was found in the service sources. Add ${params.buildpack.projectMarkers.join(" or ")}, or add a Dockerfile.vercel to control the image build.`
2139
2202
  );
2140
2203
  }
2141
- const image = await params.buildpack.resolveImage(sourceDir);
2204
+ const prereleaseUrl = getPrereleaseUrl();
2205
+ const buildpack = prereleaseUrl ? await withPrereleaseBuildpack(params.buildpack, prereleaseUrl) : params.buildpack;
2206
+ const image = await buildpack.resolveImage(sourceDir);
2142
2207
  const nodeToolchain = engine.name === "buildah" ? await resolveNodeToolchain(sourceDir, params.config, params.meta) : await resolveLocalNodeToolchain(
2143
2208
  sourceDir,
2144
2209
  params.config,
@@ -2148,9 +2213,10 @@ async function buildAndPushBuildpack(params) {
2148
2213
  params.parentSpan,
2149
2214
  "container.buildpack.build_and_push",
2150
2215
  {
2151
- "buildpack.runtime": params.buildpack.runtime,
2216
+ "buildpack.runtime": buildpack.runtime,
2152
2217
  "buildpack.runtime_version": image.version,
2153
2218
  "buildpack.node_version": nodeToolchain?.version,
2219
+ "buildpack.prerelease_url": prereleaseUrl,
2154
2220
  "container.engine": engine.name,
2155
2221
  "container.repository": params.repository
2156
2222
  },
@@ -2208,7 +2274,7 @@ async function buildAndPushBuildpack(params) {
2208
2274
  );
2209
2275
  const runLifecycle = engine.name === "buildah" ? buildAndPushWithLifecycle : buildAndPushWithLifecycleDocker;
2210
2276
  const result = await runLifecycle(
2211
- params.buildpack,
2277
+ buildpack,
2212
2278
  {
2213
2279
  workPath: sourceDir,
2214
2280
  image,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/container",
3
- "version": "8.2.2",
3
+ "version": "8.3.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.js",
6
6
  "homepage": "https://vercel.com/docs",