@gigadrive/network-config 3.3.2 → 3.4.1

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 CHANGED
@@ -59,6 +59,7 @@ __export(src_exports, {
59
59
  mergeWithFrameworkDefaults: () => mergeWithFrameworkDefaults,
60
60
  parseConfig: () => parseConfig,
61
61
  parseConfigRaw: () => parseConfigRaw,
62
+ parseGigadriveNextBuildManifest: () => parseGigadriveNextBuildManifest,
62
63
  postProcessConfig: () => postProcessConfig,
63
64
  readDependencies: () => readDependencies
64
65
  });
@@ -320,28 +321,48 @@ var getDefaultPathMap = import_effect3.Effect.fn("getDefaultPathMap")(function*
320
321
  return result;
321
322
  });
322
323
 
323
- // src/detection/frameworks/nextjs.ts
324
+ // src/nextjs-manifest.ts
324
325
  var isRecord2 = (value) => typeof value === "object" && value !== null;
325
- var normalizeRelativePath = (value, allowCurrentDirectory = false) => {
326
+ var isPortableRelativePath = (value, allowCurrentDirectory = false) => {
327
+ if (typeof value !== "string") return false;
326
328
  const normalized = value.replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/+$/, "");
327
- if (!allowCurrentDirectory && (!normalized || normalized === ".") || normalized.startsWith("/") || /^[A-Za-z]:/.test(normalized) || normalized.includes(":") || normalized.split("/").some((segment) => segment === "..")) {
328
- return void 0;
329
- }
330
- return normalized || ".";
329
+ return (allowCurrentDirectory || normalized !== "" && normalized !== ".") && !normalized.startsWith("/") && !/^[A-Za-z]:/.test(normalized) && !normalized.includes(":") && !normalized.split("/").some((segment) => segment === "..");
331
330
  };
332
- var parseBuildManifest = (content) => {
331
+ var isStringRecord = (value) => isRecord2(value) && Object.values(value).every((item) => typeof item === "string");
332
+ var isJsonValue = (value) => {
333
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
334
+ if (typeof value === "number") return Number.isFinite(value);
335
+ if (Array.isArray(value)) return value.every(isJsonValue);
336
+ return isRecord2(value) && Object.values(value).every(isJsonValue);
337
+ };
338
+ var isRouteOutput = (value) => isRecord2(value) && typeof value.id === "string" && ["PAGES", "PAGES_API", "APP_PAGE", "APP_ROUTE", "MIDDLEWARE"].includes(String(value.type)) && isPortableRelativePath(value.filePath) && typeof value.pathname === "string" && typeof value.sourcePage === "string" && (value.runtime === "nodejs" || value.runtime === "edge") && isStringRecord(value.assets) && isRecord2(value.config);
339
+ var isPrerenderOutput = (value) => isRecord2(value) && value.type === "PRERENDER" && typeof value.id === "string" && typeof value.pathname === "string" && typeof value.parentOutputId === "string" && typeof value.groupId === "number" && isRecord2(value.config) && (value.fallback === void 0 || isRecord2(value.fallback) && (value.fallback.filePath === void 0 || isPortableRelativePath(value.fallback.filePath)));
340
+ var isStaticOutput = (value) => isRecord2(value) && value.type === "STATIC_FILE" && typeof value.id === "string" && typeof value.pathname === "string" && isPortableRelativePath(value.filePath);
341
+ var isEntrypoint = (value) => isRecord2(value) && typeof value.id === "string" && (value.runtime === "nodejs" || value.runtime === "edge") && isPortableRelativePath(value.filePath) && Array.isArray(value.outputIds) && value.outputIds.every((item) => typeof item === "string") && isStringRecord(value.assets) && isRecord2(value.config);
342
+ var isImagePolicy = (value) => isRecord2(value) && Array.isArray(value.localPatterns) && Array.isArray(value.remotePatterns) && value.remotePatterns.every((pattern) => isRecord2(pattern) && typeof pattern.hostname === "string") && Array.isArray(value.widths) && value.widths.every((item) => typeof item === "number" && Number.isInteger(item) && item > 0) && Array.isArray(value.heights) && value.heights.every((item) => typeof item === "number" && Number.isInteger(item) && item > 0) && Array.isArray(value.qualities) && value.qualities.every((item) => typeof item === "number" && item >= 1 && item <= 100) && Array.isArray(value.formats) && value.formats.every((item) => ["image/avif", "image/webp", "image/jpeg", "image/png"].includes(String(item))) && typeof value.minimumCacheTTL === "number" && typeof value.dangerouslyAllowSVG === "boolean" && typeof value.contentSecurityPolicy === "string" && (value.contentDispositionType === "inline" || value.contentDispositionType === "attachment") && typeof value.maximumRedirects === "number" && typeof value.maximumResponseBody === "number" && isRecord2(value.variants);
343
+ var parseGigadriveNextBuildManifest = (content) => {
333
344
  try {
334
345
  const value = JSON.parse(content);
335
- if (!isRecord2(value) || value.version !== 1 || value.output !== "standalone" && value.output !== "export" || typeof value.distDir !== "string" || typeof value.repoRootToProject !== "string") {
346
+ if (!isRecord2(value)) return void 0;
347
+ if (value.version === 1) {
348
+ if (value.output !== "standalone" && value.output !== "export" || !isPortableRelativePath(value.distDir) || !isPortableRelativePath(value.repoRootToProject, true) || typeof value.nextVersion !== "string" || typeof value.buildId !== "string") {
349
+ return void 0;
350
+ }
351
+ return value;
352
+ }
353
+ if (value.version !== 2 || value.mode !== "adapter-v2" && value.mode !== "export" || !isPortableRelativePath(value.distDir) || !isPortableRelativePath(value.repoRootToProject, true) || typeof value.nextVersion !== "string" || typeof value.buildId !== "string" || !isRecord2(value.config) || typeof value.config.basePath !== "string" || typeof value.config.trailingSlash !== "boolean" || typeof value.config.cacheComponents !== "boolean" || value.config.images !== void 0 && !isImagePolicy(value.config.images) || !isRecord2(value.routing) || !isJsonValue(value.routing) || !isRecord2(value.outputs) || !Array.isArray(value.outputs.pages) || !value.outputs.pages.every(isRouteOutput) || !Array.isArray(value.outputs.pagesApi) || !value.outputs.pagesApi.every(isRouteOutput) || !Array.isArray(value.outputs.appPages) || !value.outputs.appPages.every(isRouteOutput) || !Array.isArray(value.outputs.appRoutes) || !value.outputs.appRoutes.every(isRouteOutput) || !Array.isArray(value.outputs.prerenders) || !value.outputs.prerenders.every(isPrerenderOutput) || !Array.isArray(value.outputs.staticFiles) || !value.outputs.staticFiles.every(isStaticOutput) || value.outputs.middleware !== void 0 && !isRouteOutput(value.outputs.middleware) || !Array.isArray(value.entrypoints) || !value.entrypoints.every(isEntrypoint) || !isStringRecord(value.outputEntrypoints)) {
336
354
  return void 0;
337
355
  }
338
- const distDir = normalizeRelativePath(value.distDir);
339
- const repoRootToProject = normalizeRelativePath(value.repoRootToProject, true);
340
- return distDir && repoRootToProject ? { version: 1, output: value.output, distDir, repoRootToProject } : void 0;
356
+ const entrypointIds = new Set(value.entrypoints.map((item) => item.id));
357
+ if (Object.values(value.outputEntrypoints).some((entrypointId) => !entrypointIds.has(entrypointId)))
358
+ return void 0;
359
+ return value;
341
360
  } catch {
342
361
  return void 0;
343
362
  }
344
363
  };
364
+
365
+ // src/detection/frameworks/nextjs.ts
345
366
  var toPortablePath = (value) => value.replaceAll("\\", "/");
346
367
  var createStaticExportConfig = import_effect4.Effect.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
347
368
  const pathService = yield* import_platform4.Path.Path;
@@ -421,6 +442,116 @@ var createStandaloneConfig = import_effect4.Effect.fn("nextjs.createStandaloneCo
421
442
  }
422
443
  };
423
444
  });
445
+ var createAdapterV2Config = import_effect4.Effect.fn("nextjs.createAdapterV2Config")(function* (defaults, projectFolder, manifest) {
446
+ const pathService = yield* import_platform4.Path.Path;
447
+ let repoRoot = projectFolder;
448
+ if (manifest.repoRootToProject !== ".") {
449
+ repoRoot = manifest.repoRootToProject.split("/").reduce((root) => pathService.dirname(root), repoRoot);
450
+ }
451
+ const artifactUseCount = /* @__PURE__ */ new Map();
452
+ for (const entrypoint of manifest.entrypoints) {
453
+ for (const [targetPath, sourcePath] of Object.entries(entrypoint.assets)) {
454
+ const identity = `${targetPath}\0${sourcePath}`;
455
+ artifactUseCount.set(identity, (artifactUseCount.get(identity) ?? 0) + 1);
456
+ }
457
+ }
458
+ const sharedFilePathMap = {};
459
+ for (const [identity, useCount] of artifactUseCount) {
460
+ if (useCount < 2) continue;
461
+ const [targetPath, sourcePath] = identity.split("\0");
462
+ sharedFilePathMap[pathService.join(repoRoot, sourcePath)] = targetPath;
463
+ }
464
+ const sharedArtifacts = Object.keys(sharedFilePathMap).length > 0 ? [{ id: "next-shared", filePathMap: sharedFilePathMap }] : [];
465
+ const entrypoints = manifest.entrypoints.map((entrypoint) => {
466
+ const filePathMap = {};
467
+ for (const [targetPath, sourcePath] of Object.entries({
468
+ ...entrypoint.assets,
469
+ ...entrypoint.wasmAssets
470
+ })) {
471
+ const identity = `${targetPath}\0${sourcePath}`;
472
+ if ((artifactUseCount.get(identity) ?? 0) >= 2) continue;
473
+ filePathMap[pathService.join(repoRoot, sourcePath)] = targetPath;
474
+ }
475
+ filePathMap[pathService.join(repoRoot, entrypoint.filePath)] = entrypoint.filePath;
476
+ return {
477
+ displayName: entrypoint.id,
478
+ path: entrypoint.filePath,
479
+ runtime: "node-22",
480
+ memory: defaults.memory,
481
+ maxDuration: entrypoint.config.maxDuration ?? defaults.maxDuration,
482
+ streaming: true,
483
+ environmentVariables: {
484
+ GIGADRIVE_NEXT_ENTRYPOINT_ID: entrypoint.id,
485
+ GIGADRIVE_NEXT_RUNTIME: entrypoint.runtime,
486
+ NEXT_BUILD_ID: manifest.buildId,
487
+ ...entrypoint.config.env
488
+ },
489
+ package: {
490
+ trace: false,
491
+ rootOverwrite: repoRoot,
492
+ filePathMap,
493
+ ...sharedArtifacts.length > 0 ? { sharedArtifactIds: sharedArtifacts.map((artifact) => artifact.id) } : {}
494
+ }
495
+ };
496
+ });
497
+ const assetPaths = [];
498
+ const assetOverrides = {};
499
+ for (const output of manifest.outputs.staticFiles) {
500
+ const absolutePath = pathService.join(repoRoot, output.filePath);
501
+ const projectRelativePath = toPortablePath(pathService.relative(projectFolder, absolutePath));
502
+ if (projectRelativePath.startsWith("../")) continue;
503
+ assetPaths.push(projectRelativePath);
504
+ assetOverrides[projectRelativePath] = { path: output.pathname.replace(/^\//, "") };
505
+ }
506
+ const prerenders = manifest.outputs.prerenders.map((output) => {
507
+ if (!output.fallback?.filePath) return output;
508
+ const absolutePath = pathService.join(repoRoot, output.fallback.filePath);
509
+ const projectRelativePath = toPortablePath(pathService.relative(projectFolder, absolutePath));
510
+ if (projectRelativePath.startsWith("../")) return output;
511
+ const internalAssetPath = `_gigadrive/prerender/${encodeURIComponent(output.id)}.html`;
512
+ assetPaths.push(projectRelativePath);
513
+ assetOverrides[projectRelativePath] = { path: internalAssetPath };
514
+ return {
515
+ ...output,
516
+ fallback: { ...output.fallback, filePath: `/${internalAssetPath}` }
517
+ };
518
+ });
519
+ const framework = {
520
+ mode: manifest.mode,
521
+ distDir: manifest.distDir,
522
+ repoRootToProject: manifest.repoRootToProject,
523
+ nextVersion: manifest.nextVersion,
524
+ buildId: manifest.buildId,
525
+ config: manifest.config,
526
+ routing: manifest.routing,
527
+ outputs: manifest.outputs,
528
+ entrypoints: manifest.entrypoints,
529
+ outputEntrypoints: manifest.outputEntrypoints
530
+ };
531
+ return {
532
+ ...defaults,
533
+ entrypoint: void 0,
534
+ routes: [],
535
+ assetPaths,
536
+ assetOverrides,
537
+ assetsDir: manifest.distDir,
538
+ assetsPrefixToStrip: "",
539
+ package: void 0,
540
+ normalizedConfig: {
541
+ entrypoints,
542
+ routes: [],
543
+ framework: {
544
+ ...framework,
545
+ outputs: { ...framework.outputs, prerenders },
546
+ type: "nextjs",
547
+ schemaVersion: 2
548
+ },
549
+ images: manifest.config.images,
550
+ sharedArtifacts,
551
+ userArchive: { rootOverwrite: repoRoot }
552
+ }
553
+ };
554
+ });
424
555
  var nextjs = {
425
556
  slug: "nextjs",
426
557
  name: "Next.js",
@@ -442,8 +573,11 @@ var nextjs = {
442
573
  refineDefaultConfig: (defaults, projectFolder) => import_effect4.Effect.gen(function* () {
443
574
  const fs = yield* import_platform4.FileSystem.FileSystem;
444
575
  const manifestContent = yield* fs.readFileString(`${projectFolder}/.gigadrive/nextjs.json`).pipe(import_effect4.Effect.catchAll(() => import_effect4.Effect.succeed(void 0)));
445
- const manifest = manifestContent ? parseBuildManifest(manifestContent) : void 0;
576
+ const manifest = manifestContent ? parseGigadriveNextBuildManifest(manifestContent) : void 0;
446
577
  if (!manifest) return defaults;
578
+ if (manifest.version === 2) {
579
+ return manifest.mode === "export" ? yield* createStaticExportConfig(defaults, projectFolder) : yield* createAdapterV2Config(defaults, projectFolder, manifest);
580
+ }
447
581
  return manifest.output === "export" ? yield* createStaticExportConfig(defaults, projectFolder) : yield* createStandaloneConfig(defaults, projectFolder, manifest);
448
582
  })
449
583
  };
@@ -651,7 +785,7 @@ var generateConfig = import_effect6.Effect.fn("generateConfig")(function* (frame
651
785
  entrypoint: defaults.entrypoint,
652
786
  commands
653
787
  });
654
- const entrypoints = defaults.entrypoint ? [
788
+ const entrypoints = defaults.normalizedConfig?.entrypoints ?? (defaults.entrypoint ? [
655
789
  {
656
790
  path: defaults.entrypoint,
657
791
  runtime: defaults.runtime,
@@ -661,14 +795,14 @@ var generateConfig = import_effect6.Effect.fn("generateConfig")(function* (frame
661
795
  symlinks: defaults.symlinks,
662
796
  package: defaults.package
663
797
  }
664
- ] : [];
665
- const routes = defaults.entrypoint ? defaults.routes.map((route) => ({
798
+ ] : []);
799
+ const routes = defaults.normalizedConfig?.routes ?? (defaults.entrypoint ? defaults.routes.map((route) => ({
666
800
  path: route.source,
667
801
  destination: route.destination,
668
802
  handler: defaults.streaming ? "SERVERLESS_FUNCTION_STREAMING" : "SERVERLESS_FUNCTION",
669
803
  methods: ["ANY"],
670
804
  headers: {}
671
- })) : [];
805
+ })) : []);
672
806
  const config = {
673
807
  regions: [...AVAILABLE_REGIONS],
674
808
  environmentVariables: { ...defaults.environmentVariables },
@@ -677,7 +811,8 @@ var generateConfig = import_effect6.Effect.fn("generateConfig")(function* (frame
677
811
  routes,
678
812
  excludeFiles: defaults.excludeFiles && defaults.excludeFiles.length > 0 ? [...defaults.excludeFiles] : void 0,
679
813
  warnings: [`Auto-detected framework: ${framework.name}. Create a gigadrive.yaml to customize.`],
680
- errors: []
814
+ errors: [],
815
+ ...defaults.normalizedConfig
681
816
  };
682
817
  if (defaults.assetsDir || defaults.assetPaths) {
683
818
  config.assets = {
@@ -1039,6 +1174,24 @@ var toArray = (value) => {
1039
1174
  return Array.isArray(value) ? value : [value];
1040
1175
  };
1041
1176
  var runtimeStreamsByDefault = (runtime) => runtime == null || runtime.startsWith("node-") || runtime.startsWith("bun-");
1177
+ var normalizeImagePolicy = (images) => {
1178
+ if (!images) return void 0;
1179
+ return {
1180
+ localPatterns: images.localPatterns ?? [{ pathname: "/**" }],
1181
+ remotePatterns: images.remotePatterns ?? [],
1182
+ widths: images.widths ?? [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
1183
+ heights: images.heights ?? [],
1184
+ qualities: images.qualities ?? [75],
1185
+ formats: images.formats ?? ["image/avif", "image/webp"],
1186
+ minimumCacheTTL: images.minimumCacheTTL ?? 14400,
1187
+ dangerouslyAllowSVG: images.dangerouslyAllowSVG ?? false,
1188
+ contentSecurityPolicy: images.contentSecurityPolicy ?? "default-src 'self'; script-src 'none'; sandbox;",
1189
+ contentDispositionType: images.contentDispositionType ?? "attachment",
1190
+ maximumRedirects: images.maximumRedirects ?? 3,
1191
+ maximumResponseBody: images.maximumResponseBody ?? 50 * 1024 * 1024,
1192
+ variants: images.variants ?? {}
1193
+ };
1194
+ };
1042
1195
  var normalizeRouteDestination = (destination) => {
1043
1196
  const [withoutHash] = destination.split("#", 1);
1044
1197
  const [withoutQuery] = withoutHash.split("?", 1);
@@ -1201,6 +1354,7 @@ var V4ConfigParser = class extends import_effect14.Effect.Service()("V4ConfigPar
1201
1354
  },
1202
1355
  environmentVariables: config.env ?? {},
1203
1356
  commands: config.build_commands ?? [],
1357
+ images: normalizeImagePolicy(config.images),
1204
1358
  entrypoints,
1205
1359
  errors: [],
1206
1360
  warnings: [],
@@ -1322,7 +1476,8 @@ var VercelBuildOutputParser = class extends import_effect15.Effect.Service()("Ve
1322
1476
  }
1323
1477
  const functionData = yield* loadFunctions(config, parseResult, projectFolder);
1324
1478
  const assetOverrides = loadAssetOverrides(config, parseResult);
1325
- const merged = (0, import_commons.deepMerge)(parseResult, functionData, assetOverrides);
1479
+ const imagePolicy = loadImagePolicy(config);
1480
+ const merged = (0, import_commons.deepMerge)(parseResult, functionData, assetOverrides, imagePolicy);
1326
1481
  merged.regions = [...new Set(merged.regions)];
1327
1482
  return merged;
1328
1483
  });
@@ -1444,6 +1599,27 @@ var loadAssetOverrides = (config, parseResult) => {
1444
1599
  }
1445
1600
  };
1446
1601
  };
1602
+ var loadImagePolicy = (config) => {
1603
+ if (!config.images) return {};
1604
+ const images = config.images;
1605
+ return {
1606
+ images: {
1607
+ localPatterns: images.localPatterns ?? [{ pathname: "/**" }],
1608
+ remotePatterns: [...images.remotePatterns ?? [], ...images.domains.map((hostname) => ({ hostname }))],
1609
+ widths: images.sizes,
1610
+ heights: [],
1611
+ qualities: images.qualities ?? [75],
1612
+ formats: images.formats ?? ["image/webp"],
1613
+ minimumCacheTTL: images.minimumCacheTTL ?? 60,
1614
+ dangerouslyAllowSVG: images.dangerouslyAllowSVG ?? false,
1615
+ contentSecurityPolicy: images.contentSecurityPolicy ?? "default-src 'self'; script-src 'none'; sandbox;",
1616
+ contentDispositionType: images.contentDispositionType === "inline" ? "inline" : "attachment",
1617
+ maximumRedirects: 3,
1618
+ maximumResponseBody: 50 * 1024 * 1024,
1619
+ variants: {}
1620
+ }
1621
+ };
1622
+ };
1447
1623
 
1448
1624
  // src/v4/schema.json
1449
1625
  var schema_default = {
@@ -1474,6 +1650,91 @@ var schema_default = {
1474
1650
  type: ["boolean", "null"],
1475
1651
  description: "If true, the assets will be cached at the edge during deployment. This may increase the deployment time, depending on the size of the assets. Defaults to false."
1476
1652
  },
1653
+ images: {
1654
+ type: ["object", "null"],
1655
+ description: "Managed image optimization policy for this deployment.",
1656
+ additionalProperties: false,
1657
+ properties: {
1658
+ localPatterns: {
1659
+ type: "array",
1660
+ maxItems: 64,
1661
+ items: {
1662
+ type: "object",
1663
+ additionalProperties: false,
1664
+ properties: {
1665
+ pathname: { type: "string", minLength: 1, maxLength: 2048 },
1666
+ search: { type: "string", maxLength: 2048 }
1667
+ }
1668
+ }
1669
+ },
1670
+ remotePatterns: {
1671
+ type: "array",
1672
+ maxItems: 64,
1673
+ items: {
1674
+ type: "object",
1675
+ required: ["hostname"],
1676
+ additionalProperties: false,
1677
+ properties: {
1678
+ protocol: { type: "string", enum: ["http", "https"] },
1679
+ hostname: { type: "string", minLength: 1, maxLength: 253 },
1680
+ port: { type: "string", pattern: "^[0-9]{0,5}$" },
1681
+ pathname: { type: "string", minLength: 1, maxLength: 2048 },
1682
+ search: { type: "string", maxLength: 2048 }
1683
+ }
1684
+ }
1685
+ },
1686
+ widths: {
1687
+ type: "array",
1688
+ minItems: 1,
1689
+ maxItems: 64,
1690
+ uniqueItems: true,
1691
+ items: { type: "integer", minimum: 1, maximum: 8192 }
1692
+ },
1693
+ heights: {
1694
+ type: "array",
1695
+ maxItems: 64,
1696
+ uniqueItems: true,
1697
+ items: { type: "integer", minimum: 1, maximum: 8192 }
1698
+ },
1699
+ qualities: {
1700
+ type: "array",
1701
+ minItems: 1,
1702
+ maxItems: 100,
1703
+ uniqueItems: true,
1704
+ items: { type: "integer", minimum: 1, maximum: 100 }
1705
+ },
1706
+ formats: {
1707
+ type: "array",
1708
+ minItems: 1,
1709
+ maxItems: 4,
1710
+ uniqueItems: true,
1711
+ items: { type: "string", enum: ["image/avif", "image/webp", "image/jpeg", "image/png"] }
1712
+ },
1713
+ minimumCacheTTL: { type: "integer", minimum: 0, maximum: 31536e3 },
1714
+ dangerouslyAllowSVG: { type: "boolean" },
1715
+ contentSecurityPolicy: { type: "string", maxLength: 4096 },
1716
+ contentDispositionType: { type: "string", enum: ["inline", "attachment"] },
1717
+ maximumRedirects: { type: "integer", minimum: 0, maximum: 10 },
1718
+ maximumResponseBody: { type: "integer", minimum: 1024, maximum: 104857600 },
1719
+ variants: {
1720
+ type: "object",
1721
+ maxProperties: 100,
1722
+ propertyNames: { pattern: "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$" },
1723
+ additionalProperties: {
1724
+ type: "object",
1725
+ minProperties: 1,
1726
+ additionalProperties: false,
1727
+ properties: {
1728
+ width: { type: "integer", minimum: 1, maximum: 8192 },
1729
+ height: { type: "integer", minimum: 1, maximum: 8192 },
1730
+ quality: { type: "integer", minimum: 1, maximum: 100 },
1731
+ format: { type: "string", enum: ["image/avif", "image/webp", "image/jpeg", "image/png"] },
1732
+ fit: { type: "string", enum: ["contain", "cover", "fill", "inside", "outside"] }
1733
+ }
1734
+ }
1735
+ }
1736
+ }
1737
+ },
1477
1738
  regions: {
1478
1739
  type: ["array", "null"],
1479
1740
  description: 'The regions to which the project will be deployed. Use "global" to deploy to all regions. More regions will incur higher costs.',
@@ -1874,6 +2135,7 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect17.Lay
1874
2135
  mergeWithFrameworkDefaults,
1875
2136
  parseConfig,
1876
2137
  parseConfigRaw,
2138
+ parseGigadriveNextBuildManifest,
1877
2139
  postProcessConfig,
1878
2140
  readDependencies
1879
2141
  });