@gigadrive/network-config 4.4.0 → 4.6.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.
package/dist/index.js CHANGED
@@ -36,12 +36,22 @@ __export(src_exports, {
36
36
  ConfigFileEmptyError: () => ConfigFileEmptyError,
37
37
  ConfigFileNotFoundError: () => ConfigFileNotFoundError,
38
38
  ConfigFileParseError: () => ConfigFileParseError,
39
+ ConfigModuleLoadError: () => ConfigModuleLoadError,
40
+ ConfigModuleLoader: () => ConfigModuleLoader,
39
41
  ConfigSchemaValidationError: () => ConfigSchemaValidationError,
40
42
  ConfigVersionError: () => ConfigVersionError,
41
43
  DEFAULT_FUNCTION_DURATION_SECONDS: () => DEFAULT_FUNCTION_DURATION_SECONDS,
42
44
  FRAMEWORK_DEFINITIONS: () => FRAMEWORK_DEFINITIONS,
43
45
  FrameworkNotDetectedError: () => FrameworkNotDetectedError,
44
46
  FunctionConfigError: () => FunctionConfigError,
47
+ GigadriveNextBuildManifestSchema: () => GigadriveNextBuildManifestSchema,
48
+ GigadriveNextBuildManifestV1Schema: () => GigadriveNextBuildManifestV1Schema,
49
+ GigadriveNextBuildManifestV2ExportSchema: () => GigadriveNextBuildManifestV2ExportSchema,
50
+ GigadriveNextBuildManifestV2StandaloneSchema: () => GigadriveNextBuildManifestV2StandaloneSchema,
51
+ GigadriveNextPrerenderManifestV1Schema: () => GigadriveNextPrerenderManifestV1Schema,
52
+ GigadriveNextPrerenderOutputSchema: () => GigadriveNextPrerenderOutputSchema,
53
+ GigadriveNextServerDescriptorSchema: () => GigadriveNextServerDescriptorSchema,
54
+ GigadriveNextStaticAssetPrefixSchema: () => GigadriveNextStaticAssetPrefixSchema,
45
55
  MAX_FUNCTION_DURATION_SECONDS: () => MAX_FUNCTION_DURATION_SECONDS,
46
56
  ManifestNotFoundError: () => ManifestNotFoundError,
47
57
  ManifestParseError: () => ManifestParseError,
@@ -49,8 +59,12 @@ __export(src_exports, {
49
59
  NetworkConfigLive: () => NetworkConfigLive,
50
60
  RawConfigReader: () => RawConfigReader,
51
61
  SchemaValidator: () => SchemaValidator,
62
+ StaticAssetHeadersSchema: () => StaticAssetHeadersSchema,
63
+ StaticAssetManifestEntrySchema: () => StaticAssetManifestEntrySchema,
64
+ StaticAssetManifestV1Schema: () => StaticAssetManifestV1Schema,
52
65
  V4ConfigParser: () => V4ConfigParser,
53
66
  VercelBuildOutputParser: () => VercelBuildOutputParser,
67
+ defineConfig: () => defineConfig,
54
68
  detectFramework: () => detectFramework,
55
69
  detectPackageManager: () => detectPackageManager,
56
70
  filterFunctionsFromAssets: () => filterFunctionsFromAssets,
@@ -60,18 +74,80 @@ __export(src_exports, {
60
74
  parseConfig: () => parseConfig,
61
75
  parseConfigRaw: () => parseConfigRaw,
62
76
  parseGigadriveNextBuildManifest: () => parseGigadriveNextBuildManifest,
77
+ parseGigadriveNextPrerenderManifest: () => parseGigadriveNextPrerenderManifest,
78
+ parseStaticAssetManifest: () => parseStaticAssetManifest,
63
79
  postProcessConfig: () => postProcessConfig,
64
80
  readDependencies: () => readDependencies
65
81
  });
66
82
  module.exports = __toCommonJS(src_exports);
67
83
 
84
+ // src/asset-manifest.ts
85
+ var import_effect2 = require("effect");
86
+
87
+ // src/manifest-schema.ts
88
+ var import_effect = require("effect");
89
+ var HTTP_HEADER_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
90
+ var HTTP_HEADER_VALUE = /^[\t\x20-\x7e\x80-\xff]*$/;
91
+ var URL_PATHNAME_FORBIDDEN_CHARACTER = /[\x00-\x1f\x7f?#\\]/;
92
+ var isUrlDotSegment = (segment) => {
93
+ const decodedDots = segment.replace(/%2e/gi, ".");
94
+ return decodedDots === "." || decodedDots === "..";
95
+ };
96
+ var isPortableRelativePath = (value, allowCurrentDirectory = false) => {
97
+ const normalized = value.replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/+$/, "");
98
+ return (allowCurrentDirectory || normalized !== "" && normalized !== ".") && !normalized.startsWith("/") && !/^[A-Za-z]:/.test(normalized) && !normalized.includes(":") && !normalized.split("/").includes("..");
99
+ };
100
+ var PortableRelativePathSchema = import_effect.Schema.String.pipe(import_effect.Schema.filter((value) => isPortableRelativePath(value)));
101
+ var RepositoryRelativePathSchema = import_effect.Schema.String.pipe(
102
+ import_effect.Schema.filter((value) => isPortableRelativePath(value, true))
103
+ );
104
+ var UrlPathnameSchema = import_effect.Schema.String.pipe(
105
+ import_effect.Schema.filter(
106
+ (value) => value.startsWith("/") && !URL_PATHNAME_FORBIDDEN_CHARACTER.test(value) && !value.split("/").some(isUrlDotSegment)
107
+ )
108
+ );
109
+ var HttpHeaderValueSchema = import_effect.Schema.String.pipe(import_effect.Schema.pattern(HTTP_HEADER_VALUE));
110
+ var HttpHeadersSchema = import_effect.Schema.mutable(
111
+ import_effect.Schema.Record({
112
+ key: import_effect.Schema.String,
113
+ value: import_effect.Schema.Union(HttpHeaderValueSchema, import_effect.Schema.mutable(import_effect.Schema.Array(HttpHeaderValueSchema)))
114
+ })
115
+ ).pipe(import_effect.Schema.filter((headers) => Object.keys(headers).every((name) => HTTP_HEADER_NAME.test(name))));
116
+ var HttpSingleValueHeadersSchema = import_effect.Schema.mutable(
117
+ import_effect.Schema.Record({ key: import_effect.Schema.String, value: HttpHeaderValueSchema })
118
+ ).pipe(import_effect.Schema.filter((headers) => Object.keys(headers).every((name) => HTTP_HEADER_NAME.test(name))));
119
+ var decodeUnknown = (schema, value) => import_effect.Schema.decodeUnknownOption(schema, { onExcessProperty: "preserve" })(value).pipe(import_effect.Option.getOrUndefined);
120
+ var decodeJson = (schema, content) => decodeUnknown(import_effect.Schema.parseJson(schema), content);
121
+
122
+ // src/asset-manifest.ts
123
+ var StaticAssetHeadersSchema = HttpHeadersSchema;
124
+ var StaticAssetManifestEntrySchema = import_effect2.Schema.mutable(
125
+ import_effect2.Schema.Struct({
126
+ source: PortableRelativePathSchema,
127
+ path: UrlPathnameSchema,
128
+ status: import_effect2.Schema.optional(import_effect2.Schema.Int.pipe(import_effect2.Schema.between(100, 599))),
129
+ headers: import_effect2.Schema.optional(StaticAssetHeadersSchema),
130
+ immutable: import_effect2.Schema.optional(import_effect2.Schema.Boolean)
131
+ })
132
+ );
133
+ var StaticAssetManifestV1Schema = import_effect2.Schema.mutable(
134
+ import_effect2.Schema.Struct({
135
+ version: import_effect2.Schema.Literal(1),
136
+ assets: import_effect2.Schema.mutable(import_effect2.Schema.Array(StaticAssetManifestEntrySchema))
137
+ })
138
+ ).pipe(import_effect2.Schema.filter(({ assets }) => new Set(assets.map(({ path: path2 }) => path2)).size === assets.length));
139
+ var parseStaticAssetManifest = (content) => decodeJson(StaticAssetManifestV1Schema, content);
140
+
141
+ // src/define-config.ts
142
+ var defineConfig = (config) => config;
143
+
68
144
  // src/detection/detect-framework.ts
69
145
  var import_platform8 = require("@effect/platform");
70
- var import_effect10 = require("effect");
146
+ var import_effect13 = require("effect");
71
147
 
72
148
  // src/detection/detect-package-manager.ts
73
149
  var import_platform = require("@effect/platform");
74
- var import_effect = require("effect");
150
+ var import_effect3 = require("effect");
75
151
  var LOCKFILE_MAP = [
76
152
  { files: ["bun.lockb", "bun.lock"], pm: "bun" },
77
153
  { files: ["pnpm-lock.yaml"], pm: "pnpm" },
@@ -79,19 +155,19 @@ var LOCKFILE_MAP = [
79
155
  { files: ["package-lock.json"], pm: "npm" },
80
156
  { files: ["composer.lock"], pm: "composer" }
81
157
  ];
82
- var detectPackageManager = import_effect.Effect.fn("detectPackageManager")(function* (projectFolder) {
158
+ var detectPackageManager = import_effect3.Effect.fn("detectPackageManager")(function* (projectFolder) {
83
159
  const fs = yield* import_platform.FileSystem.FileSystem;
84
160
  const pathService = yield* import_platform.Path.Path;
85
161
  for (const { files, pm } of LOCKFILE_MAP) {
86
162
  for (const file of files) {
87
- const exists = yield* fs.exists(pathService.join(projectFolder, file)).pipe(import_effect.Effect.catchAll(() => import_effect.Effect.succeed(false)));
163
+ const exists = yield* fs.exists(pathService.join(projectFolder, file)).pipe(import_effect3.Effect.catchAll(() => import_effect3.Effect.succeed(false)));
88
164
  if (exists) {
89
- yield* import_effect.Effect.logDebug(`Detected package manager: ${pm} (via ${file})`);
165
+ yield* import_effect3.Effect.logDebug(`Detected package manager: ${pm} (via ${file})`);
90
166
  return pm;
91
167
  }
92
168
  }
93
169
  }
94
- yield* import_effect.Effect.logDebug("No lockfile found, defaulting to npm");
170
+ yield* import_effect3.Effect.logDebug("No lockfile found, defaulting to npm");
95
171
  return "npm";
96
172
  });
97
173
 
@@ -118,7 +194,7 @@ var astro = {
118
194
 
119
195
  // src/detection/frameworks/resolve-node-entrypoint.ts
120
196
  var import_platform2 = require("@effect/platform");
121
- var import_effect2 = require("effect");
197
+ var import_effect4 = require("effect");
122
198
  var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "tsx", "ts-node"]);
123
199
  var COMMON_ENTRYPOINT_CANDIDATES = [
124
200
  "index.js",
@@ -166,14 +242,14 @@ var applyEntrypoint = (defaults, entrypoint) => ({
166
242
  (route) => route.destination === defaults.entrypoint ? { ...route, destination: entrypoint } : route
167
243
  )
168
244
  });
169
- var resolveNodeServerEntrypoint = (defaults, projectFolder) => import_effect2.Effect.gen(function* () {
245
+ var resolveNodeServerEntrypoint = (defaults, projectFolder) => import_effect4.Effect.gen(function* () {
170
246
  const fs = yield* import_platform2.FileSystem.FileSystem;
171
247
  const pathService = yield* import_platform2.Path.Path;
172
248
  const isFile = (relativePath) => fs.stat(pathService.join(projectFolder, relativePath)).pipe(
173
- import_effect2.Effect.map((info) => info.type === "File"),
174
- import_effect2.Effect.catchAll(() => import_effect2.Effect.succeed(false))
249
+ import_effect4.Effect.map((info) => info.type === "File"),
250
+ import_effect4.Effect.catchAll(() => import_effect4.Effect.succeed(false))
175
251
  );
176
- const content = yield* fs.readFileString(pathService.join(projectFolder, "package.json")).pipe(import_effect2.Effect.catchAll(() => import_effect2.Effect.succeed(void 0)));
252
+ const content = yield* fs.readFileString(pathService.join(projectFolder, "package.json")).pipe(import_effect4.Effect.catchAll(() => import_effect4.Effect.succeed(void 0)));
177
253
  const manifest = content ? parsePackageJson(content) : void 0;
178
254
  const startScript = typeof manifest?.scripts?.start === "string" ? manifest.scripts.start : void 0;
179
255
  const candidates = [
@@ -306,7 +382,7 @@ var laravel = {
306
382
 
307
383
  // src/detection/frameworks/nestjs.ts
308
384
  var import_platform3 = require("@effect/platform");
309
- var import_effect3 = require("effect");
385
+ var import_effect5 = require("effect");
310
386
  var isRecord2 = (value) => typeof value === "object" && value !== null;
311
387
  var parseNestCliJson = (content) => {
312
388
  try {
@@ -357,9 +433,9 @@ var nestjs = {
357
433
  detectors: [{ matchPackage: "@nestjs/core" }],
358
434
  priority: 90,
359
435
  getDefaultConfig: () => createNestConfig("dist"),
360
- refineDefaultConfig: (defaults, projectFolder) => import_effect3.Effect.gen(function* () {
436
+ refineDefaultConfig: (defaults, projectFolder) => import_effect5.Effect.gen(function* () {
361
437
  const fs = yield* import_platform3.FileSystem.FileSystem;
362
- const content = yield* fs.readFileString(`${projectFolder}/nest-cli.json`).pipe(import_effect3.Effect.catchAll(() => import_effect3.Effect.succeed(void 0)));
438
+ const content = yield* fs.readFileString(`${projectFolder}/nest-cli.json`).pipe(import_effect5.Effect.catchAll(() => import_effect5.Effect.succeed(void 0)));
363
439
  if (!content) return defaults;
364
440
  const nestConfig = parseNestCliJson(content);
365
441
  const outputPath = nestConfig ? getProjectOutputPath(nestConfig) : void 0;
@@ -369,27 +445,27 @@ var nestjs = {
369
445
 
370
446
  // src/detection/frameworks/nextjs.ts
371
447
  var import_platform5 = require("@effect/platform");
372
- var import_effect5 = require("effect");
448
+ var import_effect8 = require("effect");
373
449
 
374
450
  // src/build-output-v3/get-default-path-map.ts
375
451
  var import_platform4 = require("@effect/platform");
376
- var import_effect4 = require("effect");
377
- var getDefaultPathMap = import_effect4.Effect.fn("getDefaultPathMap")(function* (directory) {
452
+ var import_effect6 = require("effect");
453
+ var getDefaultPathMap = import_effect6.Effect.fn("getDefaultPathMap")(function* (directory) {
378
454
  const fs = yield* import_platform4.FileSystem.FileSystem;
379
455
  const pathService = yield* import_platform4.Path.Path;
380
456
  const result = {};
381
- const exists = yield* fs.exists(directory).pipe(import_effect4.Effect.catchAll(() => import_effect4.Effect.succeed(false)));
457
+ const exists = yield* fs.exists(directory).pipe(import_effect6.Effect.catchAll(() => import_effect6.Effect.succeed(false)));
382
458
  if (!exists) {
383
459
  return result;
384
460
  }
385
461
  const MAX_DEPTH = 100;
386
- const processDirectory = (currentPath, basePath = "", depth = 0) => import_effect4.Effect.gen(function* () {
462
+ const processDirectory = (currentPath, basePath = "", depth = 0) => import_effect6.Effect.gen(function* () {
387
463
  if (depth > MAX_DEPTH) return;
388
- const entries = yield* fs.readDirectory(currentPath).pipe(import_effect4.Effect.catchAll(() => import_effect4.Effect.succeed([])));
464
+ const entries = yield* fs.readDirectory(currentPath).pipe(import_effect6.Effect.catchAll(() => import_effect6.Effect.succeed([])));
389
465
  for (const name of entries) {
390
466
  const fullPath = pathService.join(currentPath, name);
391
467
  const relativePath = basePath ? pathService.join(basePath, name) : name;
392
- const stat = yield* fs.stat(fullPath).pipe(import_effect4.Effect.catchAll(() => import_effect4.Effect.succeed(null)));
468
+ const stat = yield* fs.stat(fullPath).pipe(import_effect6.Effect.catchAll(() => import_effect6.Effect.succeed(null)));
393
469
  if (!stat) continue;
394
470
  if (stat.type === "Directory") {
395
471
  yield* processDirectory(fullPath, relativePath, depth + 1);
@@ -402,54 +478,189 @@ var getDefaultPathMap = import_effect4.Effect.fn("getDefaultPathMap")(function*
402
478
  return result;
403
479
  });
404
480
 
481
+ // src/nextjs-constants.ts
482
+ var MAXIMUM_ENTRY_PAGE_PATHS = 50;
483
+
405
484
  // src/nextjs-manifest.ts
406
- var isRecord3 = (value) => typeof value === "object" && value !== null;
407
- var isPortableRelativePath = (value, allowCurrentDirectory = false) => {
408
- if (typeof value !== "string") return false;
409
- const normalized = value.replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/+$/, "");
410
- return (allowCurrentDirectory || normalized !== "" && normalized !== ".") && !normalized.startsWith("/") && !/^[A-Za-z]:/.test(normalized) && !normalized.includes(":") && !normalized.split("/").some((segment) => segment === "..");
411
- };
412
- var isStringRecord = (value) => isRecord3(value) && Object.values(value).every((item) => typeof item === "string");
413
- var isJsonValue = (value) => {
414
- if (value === null || typeof value === "string" || typeof value === "boolean") return true;
415
- if (typeof value === "number") return Number.isFinite(value);
416
- if (Array.isArray(value)) return value.every(isJsonValue);
417
- return isRecord3(value) && Object.values(value).every(isJsonValue);
418
- };
419
- var isPrerenderOutput = (value) => isRecord3(value) && value.type === "PRERENDER" && typeof value.id === "string" && typeof value.pathname === "string" && typeof value.parentOutputId === "string" && typeof value.groupId === "number" && isRecord3(value.config) && (value.fallback === void 0 || isRecord3(value.fallback) && (value.fallback.filePath === void 0 || isPortableRelativePath(value.fallback.filePath)));
420
- var isStaticAssetPrefix = (value) => isRecord3(value) && isPortableRelativePath(value.sourceDir) && isPortableRelativePath(value.urlPrefix) && typeof value.immutable === "boolean";
421
- var isServerDescriptor = (value) => isRecord3(value) && (value.maxDuration === void 0 || typeof value.maxDuration === "number") && (value.preferredRegion === void 0 || typeof value.preferredRegion === "string" || Array.isArray(value.preferredRegion) && value.preferredRegion.every((region) => typeof region === "string")) && (value.env === void 0 || isStringRecord(value.env));
422
- var isImagePolicy = (value) => isRecord3(value) && Array.isArray(value.localPatterns) && Array.isArray(value.remotePatterns) && value.remotePatterns.every((pattern) => isRecord3(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" && isRecord3(value.variants);
423
- var parseGigadriveNextBuildManifest = (content) => {
424
- try {
425
- const value = JSON.parse(content);
426
- if (!isRecord3(value)) return void 0;
427
- if (value.version === 1) {
428
- if (value.output !== "standalone" && value.output !== "export" || !isPortableRelativePath(value.distDir) || !isPortableRelativePath(value.repoRootToProject, true) || typeof value.nextVersion !== "string" || typeof value.buildId !== "string") {
429
- return void 0;
430
- }
431
- return value;
432
- }
433
- if (value.version === 2) {
434
- if (!isPortableRelativePath(value.distDir) || !isPortableRelativePath(value.repoRootToProject, true) || typeof value.nextVersion !== "string" || typeof value.buildId !== "string") {
435
- return void 0;
436
- }
437
- if (value.mode === "export") {
438
- return value;
439
- }
440
- if (value.mode === "standalone-v2") {
441
- if (!isServerDescriptor(value.server) || !isRecord3(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) || !isRecord3(value.routing) || !isJsonValue(value.routing) || !isRecord3(value.outputs) || !Array.isArray(value.outputs.prerenders) || !value.outputs.prerenders.every(isPrerenderOutput) || !Array.isArray(value.outputs.staticAssets) || !value.outputs.staticAssets.every(isStaticAssetPrefix)) {
442
- return void 0;
443
- }
444
- return value;
445
- }
446
- return void 0;
447
- }
448
- return void 0;
449
- } catch {
450
- return void 0;
451
- }
452
- };
485
+ var import_effect7 = require("effect");
486
+ var StringArraySchema = import_effect7.Schema.mutable(import_effect7.Schema.Array(import_effect7.Schema.String));
487
+ var StringRecordSchema = import_effect7.Schema.mutable(import_effect7.Schema.Record({ key: import_effect7.Schema.String, value: import_effect7.Schema.String }));
488
+ var JsonValueSchema = import_effect7.Schema.suspend(
489
+ () => import_effect7.Schema.Union(
490
+ import_effect7.Schema.Null,
491
+ import_effect7.Schema.Boolean,
492
+ import_effect7.Schema.Number,
493
+ import_effect7.Schema.String,
494
+ import_effect7.Schema.mutable(import_effect7.Schema.Array(JsonValueSchema)),
495
+ import_effect7.Schema.mutable(import_effect7.Schema.Record({ key: import_effect7.Schema.String, value: JsonValueSchema }))
496
+ )
497
+ );
498
+ var ImageLocalPatternSchema = import_effect7.Schema.mutable(
499
+ import_effect7.Schema.Struct({
500
+ pathname: import_effect7.Schema.optional(import_effect7.Schema.String),
501
+ search: import_effect7.Schema.optional(import_effect7.Schema.String)
502
+ })
503
+ );
504
+ var ImageRemotePatternSchema = import_effect7.Schema.mutable(
505
+ import_effect7.Schema.Struct({
506
+ protocol: import_effect7.Schema.optional(import_effect7.Schema.Literal("http", "https")),
507
+ hostname: import_effect7.Schema.String,
508
+ port: import_effect7.Schema.optional(import_effect7.Schema.String),
509
+ pathname: import_effect7.Schema.optional(import_effect7.Schema.String),
510
+ search: import_effect7.Schema.optional(import_effect7.Schema.String)
511
+ })
512
+ );
513
+ var ImageVariantSchema = import_effect7.Schema.mutable(
514
+ import_effect7.Schema.Struct({
515
+ width: import_effect7.Schema.optional(import_effect7.Schema.Number),
516
+ height: import_effect7.Schema.optional(import_effect7.Schema.Number),
517
+ quality: import_effect7.Schema.optional(import_effect7.Schema.Number),
518
+ format: import_effect7.Schema.optional(import_effect7.Schema.Literal("image/avif", "image/webp", "image/jpeg", "image/png")),
519
+ fit: import_effect7.Schema.optional(import_effect7.Schema.Literal("contain", "cover", "fill", "inside", "outside"))
520
+ })
521
+ );
522
+ var PositiveIntSchema = import_effect7.Schema.Int.pipe(import_effect7.Schema.greaterThan(0));
523
+ var ImagePolicySchema = import_effect7.Schema.mutable(
524
+ import_effect7.Schema.Struct({
525
+ localPatterns: import_effect7.Schema.mutable(import_effect7.Schema.Array(ImageLocalPatternSchema)),
526
+ remotePatterns: import_effect7.Schema.mutable(import_effect7.Schema.Array(ImageRemotePatternSchema)),
527
+ widths: import_effect7.Schema.mutable(import_effect7.Schema.Array(PositiveIntSchema)),
528
+ heights: import_effect7.Schema.mutable(import_effect7.Schema.Array(PositiveIntSchema)),
529
+ qualities: import_effect7.Schema.mutable(import_effect7.Schema.Array(import_effect7.Schema.Number.pipe(import_effect7.Schema.between(1, 100)))),
530
+ formats: import_effect7.Schema.mutable(import_effect7.Schema.Array(import_effect7.Schema.Literal("image/avif", "image/webp", "image/jpeg", "image/png"))),
531
+ minimumCacheTTL: import_effect7.Schema.Number,
532
+ dangerouslyAllowSVG: import_effect7.Schema.Boolean,
533
+ contentSecurityPolicy: import_effect7.Schema.String,
534
+ contentDispositionType: import_effect7.Schema.Literal("inline", "attachment"),
535
+ maximumRedirects: import_effect7.Schema.Number,
536
+ maximumResponseBody: import_effect7.Schema.Number,
537
+ variants: import_effect7.Schema.mutable(import_effect7.Schema.Record({ key: import_effect7.Schema.String, value: ImageVariantSchema }))
538
+ })
539
+ );
540
+ var GigadriveNextPrerenderOutputSchema = import_effect7.Schema.mutable(
541
+ import_effect7.Schema.Struct({
542
+ id: import_effect7.Schema.String,
543
+ type: import_effect7.Schema.Literal("PRERENDER"),
544
+ pathname: UrlPathnameSchema,
545
+ parentOutputId: import_effect7.Schema.String,
546
+ groupId: import_effect7.Schema.Number,
547
+ pprChain: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Struct({ headers: HttpSingleValueHeadersSchema }))),
548
+ parentFallbackMode: import_effect7.Schema.optional(JsonValueSchema),
549
+ fallback: import_effect7.Schema.optional(
550
+ import_effect7.Schema.mutable(
551
+ import_effect7.Schema.Struct({
552
+ filePath: import_effect7.Schema.optional(PortableRelativePathSchema),
553
+ initialStatus: import_effect7.Schema.optional(import_effect7.Schema.Int.pipe(import_effect7.Schema.between(100, 599))),
554
+ initialHeaders: import_effect7.Schema.optional(HttpHeadersSchema),
555
+ initialExpiration: import_effect7.Schema.optional(import_effect7.Schema.Number),
556
+ initialRevalidate: import_effect7.Schema.optional(import_effect7.Schema.Union(import_effect7.Schema.Number, import_effect7.Schema.Literal(false))),
557
+ postponedState: import_effect7.Schema.optional(import_effect7.Schema.String)
558
+ })
559
+ )
560
+ ),
561
+ config: import_effect7.Schema.mutable(
562
+ import_effect7.Schema.Struct({
563
+ allowQuery: import_effect7.Schema.optional(StringArraySchema),
564
+ allowHeader: import_effect7.Schema.optional(StringArraySchema),
565
+ bypassFor: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Array(JsonValueSchema))),
566
+ renderingMode: import_effect7.Schema.optional(import_effect7.Schema.String),
567
+ partialFallback: import_effect7.Schema.optional(import_effect7.Schema.Boolean),
568
+ bypassToken: import_effect7.Schema.optional(import_effect7.Schema.String)
569
+ })
570
+ )
571
+ })
572
+ );
573
+ var GigadriveNextStaticAssetPrefixSchema = import_effect7.Schema.mutable(
574
+ import_effect7.Schema.Struct({
575
+ sourceDir: PortableRelativePathSchema,
576
+ urlPrefix: PortableRelativePathSchema,
577
+ immutable: import_effect7.Schema.Boolean
578
+ })
579
+ );
580
+ var GigadriveNextServerDescriptorSchema = import_effect7.Schema.mutable(
581
+ import_effect7.Schema.Struct({
582
+ maxDuration: import_effect7.Schema.optional(import_effect7.Schema.Number),
583
+ preferredRegion: import_effect7.Schema.optional(import_effect7.Schema.Union(import_effect7.Schema.String, StringArraySchema)),
584
+ env: import_effect7.Schema.optional(StringRecordSchema)
585
+ })
586
+ );
587
+ var PrerenderArraySchema = import_effect7.Schema.mutable(import_effect7.Schema.Array(GigadriveNextPrerenderOutputSchema));
588
+ var StaticAssetArraySchema = import_effect7.Schema.mutable(import_effect7.Schema.Array(GigadriveNextStaticAssetPrefixSchema));
589
+ var JsonValueArraySchema = import_effect7.Schema.mutable(import_effect7.Schema.Array(JsonValueSchema));
590
+ var GigadriveNextBuildManifestV1Schema = import_effect7.Schema.mutable(
591
+ import_effect7.Schema.Struct({
592
+ version: import_effect7.Schema.Literal(1),
593
+ output: import_effect7.Schema.Literal("standalone", "export"),
594
+ distDir: PortableRelativePathSchema,
595
+ repoRootToProject: RepositoryRelativePathSchema,
596
+ nextVersion: import_effect7.Schema.String,
597
+ buildId: import_effect7.Schema.String
598
+ })
599
+ );
600
+ var GigadriveNextBuildManifestV2ExportSchema = import_effect7.Schema.mutable(
601
+ import_effect7.Schema.Struct({
602
+ version: import_effect7.Schema.Literal(2),
603
+ mode: import_effect7.Schema.Literal("export"),
604
+ distDir: PortableRelativePathSchema,
605
+ repoRootToProject: RepositoryRelativePathSchema,
606
+ nextVersion: import_effect7.Schema.String,
607
+ buildId: import_effect7.Schema.String
608
+ })
609
+ );
610
+ var GigadriveNextBuildManifestV2StandaloneSchema = import_effect7.Schema.mutable(
611
+ import_effect7.Schema.Struct({
612
+ version: import_effect7.Schema.Literal(2),
613
+ mode: import_effect7.Schema.Literal("standalone-v2"),
614
+ distDir: PortableRelativePathSchema,
615
+ repoRootToProject: RepositoryRelativePathSchema,
616
+ nextVersion: import_effect7.Schema.String,
617
+ buildId: import_effect7.Schema.String,
618
+ server: GigadriveNextServerDescriptorSchema,
619
+ config: import_effect7.Schema.mutable(
620
+ import_effect7.Schema.Struct({
621
+ basePath: import_effect7.Schema.String,
622
+ trailingSlash: import_effect7.Schema.Boolean,
623
+ cacheComponents: import_effect7.Schema.Boolean,
624
+ i18n: import_effect7.Schema.optional(JsonValueSchema),
625
+ images: import_effect7.Schema.optional(ImagePolicySchema)
626
+ })
627
+ ),
628
+ routing: import_effect7.Schema.mutable(
629
+ import_effect7.Schema.Struct({
630
+ beforeMiddleware: JsonValueArraySchema,
631
+ beforeFiles: JsonValueArraySchema,
632
+ afterFiles: JsonValueArraySchema,
633
+ dynamicRoutes: JsonValueArraySchema,
634
+ onMatch: JsonValueArraySchema,
635
+ fallback: JsonValueArraySchema,
636
+ shouldNormalizeNextData: import_effect7.Schema.Boolean,
637
+ rsc: JsonValueSchema
638
+ })
639
+ ),
640
+ outputs: import_effect7.Schema.mutable(
641
+ import_effect7.Schema.Struct({
642
+ prerenders: PrerenderArraySchema,
643
+ prerenderManifest: import_effect7.Schema.optional(PortableRelativePathSchema),
644
+ assetManifest: import_effect7.Schema.optional(PortableRelativePathSchema),
645
+ entryPagePaths: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Array(UrlPathnameSchema))),
646
+ staticAssets: StaticAssetArraySchema
647
+ })
648
+ )
649
+ })
650
+ );
651
+ var GigadriveNextBuildManifestSchema = import_effect7.Schema.Union(
652
+ GigadriveNextBuildManifestV1Schema,
653
+ GigadriveNextBuildManifestV2ExportSchema,
654
+ GigadriveNextBuildManifestV2StandaloneSchema
655
+ );
656
+ var GigadriveNextPrerenderManifestV1Schema = import_effect7.Schema.mutable(
657
+ import_effect7.Schema.Struct({
658
+ version: import_effect7.Schema.Literal(1),
659
+ prerenders: PrerenderArraySchema
660
+ })
661
+ );
662
+ var parseGigadriveNextBuildManifest = (content) => decodeJson(GigadriveNextBuildManifestSchema, content);
663
+ var parseGigadriveNextPrerenderManifest = (content) => decodeJson(GigadriveNextPrerenderManifestV1Schema, content);
453
664
 
454
665
  // src/regions.ts
455
666
  var REGION_DEFINITIONS = [
@@ -475,23 +686,22 @@ var AVAILABLE_REGIONS = [...REGION_DEFINITIONS];
475
686
 
476
687
  // src/detection/frameworks/nextjs.ts
477
688
  var toPortablePath = (value) => value.replaceAll("\\", "/");
478
- var MAXIMUM_ENTRY_PAGE_PATHS = 50;
479
689
  var STANDALONE_SERVER_MEMORY_MB = 1024;
480
- var resolveStandaloneServer = import_effect5.Effect.fn("nextjs.resolveStandaloneServer")(function* (projectFolder, distDir, repoRootToProject) {
690
+ var resolveStandaloneServer = import_effect8.Effect.fn("nextjs.resolveStandaloneServer")(function* (projectFolder, distDir, repoRootToProject) {
481
691
  const fs = yield* import_platform5.FileSystem.FileSystem;
482
692
  const pathService = yield* import_platform5.Path.Path;
483
693
  const standaloneRoot = pathService.join(projectFolder, distDir, "standalone");
484
694
  const monorepoServer = pathService.join(standaloneRoot, repoRootToProject, "server.js");
485
695
  const rootServer = pathService.join(standaloneRoot, "server.js");
486
- const monorepoServerExists = yield* fs.exists(monorepoServer).pipe(import_effect5.Effect.catchAll(() => import_effect5.Effect.succeed(false)));
696
+ const monorepoServerExists = yield* fs.exists(monorepoServer).pipe(import_effect8.Effect.catchAll(() => import_effect8.Effect.succeed(false)));
487
697
  const serverPath = monorepoServerExists ? monorepoServer : rootServer;
488
- const serverExists = yield* fs.exists(serverPath).pipe(import_effect5.Effect.catchAll(() => import_effect5.Effect.succeed(false)));
698
+ const serverExists = yield* fs.exists(serverPath).pipe(import_effect8.Effect.catchAll(() => import_effect8.Effect.succeed(false)));
489
699
  if (!serverExists) return void 0;
490
700
  const serverDirectory = pathService.dirname(serverPath);
491
701
  const entrypoint = toPortablePath(pathService.relative(standaloneRoot, serverPath));
492
702
  return { standaloneRoot, serverDirectory, entrypoint };
493
703
  });
494
- var buildStandalonePublicAssets = import_effect5.Effect.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
704
+ var buildStandalonePublicAssets = import_effect8.Effect.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
495
705
  const pathService = yield* import_platform5.Path.Path;
496
706
  const publicFiles = yield* getDefaultPathMap(pathService.join(projectFolder, "public"));
497
707
  const assetPaths = [];
@@ -508,7 +718,7 @@ var buildStandalonePublicAssets = import_effect5.Effect.fn("nextjs.buildStandalo
508
718
  }
509
719
  return { assetPaths, assetOverrides, filePathMap };
510
720
  });
511
- var createStaticExportConfig = import_effect5.Effect.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
721
+ var createStaticExportConfig = import_effect8.Effect.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
512
722
  const pathService = yield* import_platform5.Path.Path;
513
723
  const outputDirectory = pathService.join(projectFolder, "out");
514
724
  const files = yield* getDefaultPathMap(outputDirectory);
@@ -532,7 +742,7 @@ var createStaticExportConfig = import_effect5.Effect.fn("nextjs.createStaticExpo
532
742
  package: void 0
533
743
  };
534
744
  });
535
- var createStandaloneConfig = import_effect5.Effect.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
745
+ var createStandaloneConfig = import_effect8.Effect.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
536
746
  const pathService = yield* import_platform5.Path.Path;
537
747
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
538
748
  if (!resolved) return defaults;
@@ -566,7 +776,7 @@ var createStandaloneConfig = import_effect5.Effect.fn("nextjs.createStandaloneCo
566
776
  }
567
777
  };
568
778
  });
569
- var createStandaloneV2Config = import_effect5.Effect.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
779
+ var createStandaloneV2Config = import_effect8.Effect.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
570
780
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
571
781
  if (!resolved) return defaults;
572
782
  const { standaloneRoot, serverDirectory, entrypoint } = resolved;
@@ -580,9 +790,11 @@ var createStandaloneV2Config = import_effect5.Effect.fn("nextjs.createStandalone
580
790
  immutable: staticAsset.immutable,
581
791
  populateCache: true
582
792
  }));
583
- const entryPagePaths = [
793
+ const assetManifests = manifest.outputs.assetManifest ? [{ source: manifest.outputs.assetManifest }] : void 0;
794
+ const { entryPagePaths: manifestEntryPagePaths, ...manifestOutputs } = manifest.outputs;
795
+ const entryPagePaths = manifestEntryPagePaths?.slice(0, MAXIMUM_ENTRY_PAGE_PATHS) ?? [
584
796
  ...new Set(
585
- manifest.outputs.prerenders.filter((output) => !output.fallback?.postponedState).map((output) => output.pathname).filter((pathname) => pathname.startsWith("/") && !pathname.includes("["))
797
+ manifest.outputs.prerenders.filter((output) => output.fallback?.postponedState === void 0).map((output) => output.pathname).filter((pathname) => pathname.startsWith("/") && !pathname.includes("["))
586
798
  )
587
799
  ].sort((left, right) => left.split("/").length - right.split("/").length || left.localeCompare(right)).slice(0, MAXIMUM_ENTRY_PAGE_PATHS);
588
800
  const singleEntrypoint = {
@@ -611,10 +823,9 @@ var createStandaloneV2Config = import_effect5.Effect.fn("nextjs.createStandalone
611
823
  server: manifest.server,
612
824
  config: manifest.config,
613
825
  routing: manifest.routing,
614
- // The prerender table is deliberately not forwarded: the standalone server
615
- // serves build-time prerenders from its own bundle, so the platform only
616
- // needs the warming sample below.
617
- outputs: { prerenders: [], staticAssets: manifest.outputs.staticAssets },
826
+ // Keep high-cardinality output metadata in portable sidecars rather than
827
+ // expanding it into normalized deployment configuration.
828
+ outputs: { ...manifestOutputs, prerenders: [] },
618
829
  entryPagePaths,
619
830
  type: "nextjs",
620
831
  schemaVersion: 2
@@ -626,6 +837,7 @@ var createStandaloneV2Config = import_effect5.Effect.fn("nextjs.createStandalone
626
837
  assetPaths,
627
838
  assetOverrides,
628
839
  assetPrefixes,
840
+ assetManifests,
629
841
  assetsDir: manifest.distDir,
630
842
  assetsPrefixToStrip: "",
631
843
  populateAssetCache: true,
@@ -667,9 +879,9 @@ var nextjs = {
667
879
  routes: [{ source: "/*", destination: ".next/standalone/server.js" }],
668
880
  environmentVariables: { NODE_ENV: "production" }
669
881
  }),
670
- refineDefaultConfig: (defaults, projectFolder) => import_effect5.Effect.gen(function* () {
882
+ refineDefaultConfig: (defaults, projectFolder) => import_effect8.Effect.gen(function* () {
671
883
  const fs = yield* import_platform5.FileSystem.FileSystem;
672
- const manifestContent = yield* fs.readFileString(`${projectFolder}/.gigadrive/nextjs.json`).pipe(import_effect5.Effect.catchAll(() => import_effect5.Effect.succeed(void 0)));
884
+ const manifestContent = yield* fs.readFileString(`${projectFolder}/.gigadrive/nextjs.json`).pipe(import_effect8.Effect.catchAll(() => import_effect8.Effect.succeed(void 0)));
673
885
  const manifest = manifestContent ? parseGigadriveNextBuildManifest(manifestContent) : void 0;
674
886
  if (!manifest) return defaults;
675
887
  if (manifest.version === 2) {
@@ -681,7 +893,7 @@ var nextjs = {
681
893
 
682
894
  // src/detection/frameworks/nuxt.ts
683
895
  var import_platform6 = require("@effect/platform");
684
- var import_effect6 = require("effect");
896
+ var import_effect9 = require("effect");
685
897
  var isVercelBuildOutputV3 = (content) => {
686
898
  try {
687
899
  const config = JSON.parse(content);
@@ -708,9 +920,9 @@ var nuxt = {
708
920
  routes: [{ source: "/*", destination: ".output/server/index.mjs" }],
709
921
  environmentVariables: { NODE_ENV: "production", NITRO_PRESET: "node-server" }
710
922
  }),
711
- refineDefaultConfig: (defaults, projectFolder) => import_effect6.Effect.gen(function* () {
923
+ refineDefaultConfig: (defaults, projectFolder) => import_effect9.Effect.gen(function* () {
712
924
  const fs = yield* import_platform6.FileSystem.FileSystem;
713
- const buildOutputConfig = yield* fs.readFileString(`${projectFolder}/.vercel/output/config.json`).pipe(import_effect6.Effect.catchAll(() => import_effect6.Effect.succeed(void 0)));
925
+ const buildOutputConfig = yield* fs.readFileString(`${projectFolder}/.vercel/output/config.json`).pipe(import_effect9.Effect.catchAll(() => import_effect9.Effect.succeed(void 0)));
714
926
  if (!buildOutputConfig || !isVercelBuildOutputV3(buildOutputConfig)) {
715
927
  return defaults;
716
928
  }
@@ -833,7 +1045,7 @@ var FRAMEWORK_DEFINITIONS = [
833
1045
  ].sort((a, b) => b.priority - a.priority);
834
1046
 
835
1047
  // src/detection/generate-config.ts
836
- var import_effect7 = require("effect");
1048
+ var import_effect10 = require("effect");
837
1049
  var getInstallCommand = (pm) => {
838
1050
  switch (pm) {
839
1051
  case "bun":
@@ -849,11 +1061,11 @@ var getInstallCommand = (pm) => {
849
1061
  return "npm install";
850
1062
  }
851
1063
  };
852
- var generateConfig = import_effect7.Effect.fn("generateConfig")(function* (framework, packageManager, refinedDefaults) {
1064
+ var generateConfig = import_effect10.Effect.fn("generateConfig")(function* (framework, packageManager, refinedDefaults) {
853
1065
  const defaults = refinedDefaults ?? framework.getDefaultConfig(packageManager);
854
1066
  const installCmd = defaults.installCommand ?? getInstallCommand(packageManager);
855
1067
  const commands = [installCmd, ...defaults.commands];
856
- yield* import_effect7.Effect.logDebug(`Generating config for ${framework.name}`, {
1068
+ yield* import_effect10.Effect.logDebug(`Generating config for ${framework.name}`, {
857
1069
  runtime: defaults.runtime,
858
1070
  entrypoint: defaults.entrypoint,
859
1071
  commands
@@ -887,12 +1099,13 @@ var generateConfig = import_effect7.Effect.fn("generateConfig")(function* (frame
887
1099
  errors: [],
888
1100
  ...defaults.normalizedConfig
889
1101
  };
890
- if (defaults.assetsDir || defaults.assetPaths || defaults.assetPrefixes) {
1102
+ if (defaults.assetsDir || defaults.assetPaths || defaults.assetPrefixes || defaults.assetManifests) {
891
1103
  config.assets = {
892
1104
  paths: defaults.assetPaths ? [...defaults.assetPaths] : [],
893
1105
  prefixToStrip: defaults.assetsPrefixToStrip ?? (defaults.assetsDir ? defaults.assetsDir + "/" : ""),
894
1106
  overrides: defaults.assetOverrides ? { ...defaults.assetOverrides } : void 0,
895
1107
  prefixes: defaults.assetPrefixes ? defaults.assetPrefixes.map((prefix) => ({ ...prefix })) : void 0,
1108
+ manifests: defaults.assetManifests ? defaults.assetManifests.map((manifest) => ({ ...manifest })) : void 0,
896
1109
  dynamicRoutes: true,
897
1110
  populateCache: defaults.populateAssetCache ?? false
898
1111
  };
@@ -902,30 +1115,30 @@ var generateConfig = import_effect7.Effect.fn("generateConfig")(function* (frame
902
1115
 
903
1116
  // src/detection/read-dependencies.ts
904
1117
  var import_platform7 = require("@effect/platform");
905
- var import_effect9 = require("effect");
1118
+ var import_effect12 = require("effect");
906
1119
 
907
1120
  // src/detection/types.ts
908
- var import_effect8 = require("effect");
909
- var ManifestNotFoundError = class extends import_effect8.Schema.TaggedError()("ManifestNotFoundError", {
910
- message: import_effect8.Schema.String,
911
- filePath: import_effect8.Schema.String
1121
+ var import_effect11 = require("effect");
1122
+ var ManifestNotFoundError = class extends import_effect11.Schema.TaggedError()("ManifestNotFoundError", {
1123
+ message: import_effect11.Schema.String,
1124
+ filePath: import_effect11.Schema.String
912
1125
  }) {
913
1126
  };
914
- var ManifestReadError = class extends import_effect8.Schema.TaggedError()("ManifestReadError", {
915
- message: import_effect8.Schema.String,
916
- filePath: import_effect8.Schema.String
1127
+ var ManifestReadError = class extends import_effect11.Schema.TaggedError()("ManifestReadError", {
1128
+ message: import_effect11.Schema.String,
1129
+ filePath: import_effect11.Schema.String
917
1130
  }) {
918
1131
  };
919
- var ManifestParseError = class extends import_effect8.Schema.TaggedError()("ManifestParseError", {
920
- message: import_effect8.Schema.String,
921
- filePath: import_effect8.Schema.String
1132
+ var ManifestParseError = class extends import_effect11.Schema.TaggedError()("ManifestParseError", {
1133
+ message: import_effect11.Schema.String,
1134
+ filePath: import_effect11.Schema.String
922
1135
  }) {
923
1136
  };
924
- var FrameworkNotDetectedError = class extends import_effect8.Schema.TaggedError()(
1137
+ var FrameworkNotDetectedError = class extends import_effect11.Schema.TaggedError()(
925
1138
  "FrameworkNotDetectedError",
926
1139
  {
927
- message: import_effect8.Schema.String,
928
- directory: import_effect8.Schema.String
1140
+ message: import_effect11.Schema.String,
1141
+ directory: import_effect11.Schema.String
929
1142
  }
930
1143
  ) {
931
1144
  };
@@ -935,25 +1148,25 @@ var MANIFEST_CONFIG = {
935
1148
  node: { file: "package.json", depKeys: ["dependencies", "devDependencies"] },
936
1149
  php: { file: "composer.json", depKeys: ["require", "require-dev"] }
937
1150
  };
938
- var readManifest = import_effect9.Effect.fn("readManifest")(function* (filePath) {
1151
+ var readManifest = import_effect12.Effect.fn("readManifest")(function* (filePath) {
939
1152
  const fs = yield* import_platform7.FileSystem.FileSystem;
940
- const exists = yield* fs.exists(filePath).pipe(import_effect9.Effect.catchAll(() => import_effect9.Effect.succeed(false)));
1153
+ const exists = yield* fs.exists(filePath).pipe(import_effect12.Effect.catchAll(() => import_effect12.Effect.succeed(false)));
941
1154
  if (!exists) {
942
- return yield* import_effect9.Effect.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
1155
+ return yield* import_effect12.Effect.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
943
1156
  }
944
- const content = yield* fs.readFileString(filePath).pipe(import_effect9.Effect.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
945
- const parsed = yield* import_effect9.Effect.try({
1157
+ const content = yield* fs.readFileString(filePath).pipe(import_effect12.Effect.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
1158
+ const parsed = yield* import_effect12.Effect.try({
946
1159
  try: () => JSON.parse(content),
947
1160
  catch: () => new ManifestParseError({ message: "Failed to parse manifest JSON", filePath })
948
1161
  });
949
1162
  return parsed;
950
1163
  });
951
- var readDependencies = import_effect9.Effect.fn("readDependencies")(function* (projectFolder, language) {
1164
+ var readDependencies = import_effect12.Effect.fn("readDependencies")(function* (projectFolder, language) {
952
1165
  const pathService = yield* import_platform7.Path.Path;
953
1166
  const config = MANIFEST_CONFIG[language];
954
1167
  const filePath = pathService.join(projectFolder, config.file);
955
1168
  const manifest = yield* readManifest(filePath).pipe(
956
- import_effect9.Effect.catchTag("ManifestNotFoundError", () => import_effect9.Effect.succeed(null))
1169
+ import_effect12.Effect.catchTag("ManifestNotFoundError", () => import_effect12.Effect.succeed(null))
957
1170
  );
958
1171
  if (!manifest) {
959
1172
  return /* @__PURE__ */ new Set();
@@ -971,7 +1184,7 @@ var readDependencies = import_effect9.Effect.fn("readDependencies")(function* (p
971
1184
  });
972
1185
 
973
1186
  // src/detection/detect-framework.ts
974
- var matchesDetectionItem = import_effect10.Effect.fn("matchesDetectionItem")(function* (item, projectFolder, framework, cachedReadDeps) {
1187
+ var matchesDetectionItem = import_effect13.Effect.fn("matchesDetectionItem")(function* (item, projectFolder, framework, cachedReadDeps) {
975
1188
  const fs = yield* import_platform8.FileSystem.FileSystem;
976
1189
  const pathService = yield* import_platform8.Path.Path;
977
1190
  if (item.matchPackage != null) {
@@ -982,12 +1195,12 @@ var matchesDetectionItem = import_effect10.Effect.fn("matchesDetectionItem")(fun
982
1195
  }
983
1196
  if (item.path != null) {
984
1197
  const filePath = pathService.join(projectFolder, item.path);
985
- const exists = yield* fs.exists(filePath).pipe(import_effect10.Effect.catchAll(() => import_effect10.Effect.succeed(false)));
1198
+ const exists = yield* fs.exists(filePath).pipe(import_effect13.Effect.catchAll(() => import_effect13.Effect.succeed(false)));
986
1199
  if (!exists) {
987
1200
  return false;
988
1201
  }
989
1202
  if (item.matchContent != null) {
990
- const content = yield* fs.readFileString(filePath).pipe(import_effect10.Effect.catchAll(() => import_effect10.Effect.succeed("")));
1203
+ const content = yield* fs.readFileString(filePath).pipe(import_effect13.Effect.catchAll(() => import_effect13.Effect.succeed("")));
991
1204
  let regexMatch = false;
992
1205
  try {
993
1206
  regexMatch = new RegExp(item.matchContent).test(content);
@@ -1000,7 +1213,7 @@ var matchesDetectionItem = import_effect10.Effect.fn("matchesDetectionItem")(fun
1000
1213
  }
1001
1214
  return true;
1002
1215
  });
1003
- var matchesFramework = import_effect10.Effect.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
1216
+ var matchesFramework = import_effect13.Effect.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
1004
1217
  for (const detector of framework.detectors) {
1005
1218
  const matches = yield* matchesDetectionItem(detector, projectFolder, framework, cachedReadDeps);
1006
1219
  if (!matches) {
@@ -1009,9 +1222,9 @@ var matchesFramework = import_effect10.Effect.fn("matchesFramework")(function* (
1009
1222
  }
1010
1223
  return true;
1011
1224
  });
1012
- var detectFramework = import_effect10.Effect.fn("detectFramework")(function* (projectFolder) {
1013
- yield* import_effect10.Effect.logDebug(`Detecting framework in ${projectFolder}`);
1014
- const cachedReadDeps = yield* import_effect10.Effect.cachedFunction((key) => {
1225
+ var detectFramework = import_effect13.Effect.fn("detectFramework")(function* (projectFolder) {
1226
+ yield* import_effect13.Effect.logDebug(`Detecting framework in ${projectFolder}`);
1227
+ const cachedReadDeps = yield* import_effect13.Effect.cachedFunction((key) => {
1015
1228
  const sepIndex = key.lastIndexOf("\0");
1016
1229
  const folder = key.slice(0, sepIndex);
1017
1230
  const language = key.slice(sepIndex + 1);
@@ -1020,7 +1233,7 @@ var detectFramework = import_effect10.Effect.fn("detectFramework")(function* (pr
1020
1233
  for (const framework of FRAMEWORK_DEFINITIONS) {
1021
1234
  const matches = yield* matchesFramework(framework, projectFolder, cachedReadDeps);
1022
1235
  if (matches) {
1023
- yield* import_effect10.Effect.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
1236
+ yield* import_effect13.Effect.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
1024
1237
  const detectedPackageManager = yield* detectPackageManager(projectFolder);
1025
1238
  const packageManager = framework.language === "php" ? "composer" : detectedPackageManager;
1026
1239
  const defaults = framework.getDefaultConfig(packageManager);
@@ -1029,7 +1242,7 @@ var detectFramework = import_effect10.Effect.fn("detectFramework")(function* (pr
1029
1242
  return { framework, packageManager, config };
1030
1243
  }
1031
1244
  }
1032
- return yield* import_effect10.Effect.fail(
1245
+ return yield* import_effect13.Effect.fail(
1033
1246
  new FrameworkNotDetectedError({
1034
1247
  message: `No framework detected in project directory`,
1035
1248
  directory: projectFolder
@@ -1038,15 +1251,16 @@ var detectFramework = import_effect10.Effect.fn("detectFramework")(function* (pr
1038
1251
  });
1039
1252
 
1040
1253
  // src/detection/merge-config.ts
1041
- var import_effect11 = require("effect");
1042
- var mergeWithFrameworkDefaults = import_effect11.Effect.fn("mergeWithFrameworkDefaults")(function* (userConfig, frameworkConfig) {
1043
- yield* import_effect11.Effect.logDebug("Merging user config with framework defaults");
1254
+ var import_effect14 = require("effect");
1255
+ var mergeWithFrameworkDefaults = import_effect14.Effect.fn("mergeWithFrameworkDefaults")(function* (userConfig, frameworkConfig) {
1256
+ yield* import_effect14.Effect.logDebug("Merging user config with framework defaults");
1257
+ const userHasAssets = (userConfig.assets?.paths?.length ?? 0) > 0 || (userConfig.assets?.prefixes?.length ?? 0) > 0 || (userConfig.assets?.manifests?.length ?? 0) > 0;
1044
1258
  const merged = {
1045
1259
  regions: userConfig.regions,
1046
1260
  commands: userConfig.commands.length > 0 ? userConfig.commands : frameworkConfig.commands,
1047
1261
  entrypoints: userConfig.entrypoints.length > 0 ? userConfig.entrypoints : frameworkConfig.entrypoints,
1048
1262
  routes: userConfig.routes.length > 0 ? userConfig.routes : frameworkConfig.routes,
1049
- assets: userConfig.assets?.paths && userConfig.assets.paths.length > 0 ? userConfig.assets : frameworkConfig.assets,
1263
+ assets: userHasAssets ? userConfig.assets : frameworkConfig.assets,
1050
1264
  environmentVariables: {
1051
1265
  ...frameworkConfig.environmentVariables,
1052
1266
  ...userConfig.environmentVariables
@@ -1061,41 +1275,47 @@ var mergeWithFrameworkDefaults = import_effect11.Effect.fn("mergeWithFrameworkDe
1061
1275
  });
1062
1276
 
1063
1277
  // src/errors.ts
1064
- var import_effect12 = require("effect");
1065
- var ConfigFileNotFoundError = class extends import_effect12.Schema.TaggedError()("ConfigFileNotFoundError", {
1066
- message: import_effect12.Schema.String,
1067
- filePath: import_effect12.Schema.String
1278
+ var import_effect15 = require("effect");
1279
+ var ConfigFileNotFoundError = class extends import_effect15.Schema.TaggedError()("ConfigFileNotFoundError", {
1280
+ message: import_effect15.Schema.String,
1281
+ filePath: import_effect15.Schema.String
1282
+ }) {
1283
+ };
1284
+ var ConfigFileEmptyError = class extends import_effect15.Schema.TaggedError()("ConfigFileEmptyError", {
1285
+ message: import_effect15.Schema.String,
1286
+ filePath: import_effect15.Schema.String
1068
1287
  }) {
1069
1288
  };
1070
- var ConfigFileEmptyError = class extends import_effect12.Schema.TaggedError()("ConfigFileEmptyError", {
1071
- message: import_effect12.Schema.String,
1072
- filePath: import_effect12.Schema.String
1289
+ var ConfigFileParseError = class extends import_effect15.Schema.TaggedError()("ConfigFileParseError", {
1290
+ message: import_effect15.Schema.String,
1291
+ filePath: import_effect15.Schema.String,
1292
+ cause: import_effect15.Schema.optional(import_effect15.Schema.String)
1073
1293
  }) {
1074
1294
  };
1075
- var ConfigFileParseError = class extends import_effect12.Schema.TaggedError()("ConfigFileParseError", {
1076
- message: import_effect12.Schema.String,
1077
- filePath: import_effect12.Schema.String,
1078
- cause: import_effect12.Schema.optional(import_effect12.Schema.String)
1295
+ var ConfigModuleLoadError = class extends import_effect15.Schema.TaggedError()("ConfigModuleLoadError", {
1296
+ message: import_effect15.Schema.String,
1297
+ filePath: import_effect15.Schema.String,
1298
+ cause: import_effect15.Schema.optional(import_effect15.Schema.String)
1079
1299
  }) {
1080
1300
  };
1081
- var ConfigVersionError = class extends import_effect12.Schema.TaggedError()("ConfigVersionError", {
1082
- message: import_effect12.Schema.String,
1083
- filePath: import_effect12.Schema.String,
1084
- version: import_effect12.Schema.optional(import_effect12.Schema.Number)
1301
+ var ConfigVersionError = class extends import_effect15.Schema.TaggedError()("ConfigVersionError", {
1302
+ message: import_effect15.Schema.String,
1303
+ filePath: import_effect15.Schema.String,
1304
+ version: import_effect15.Schema.optional(import_effect15.Schema.Number)
1085
1305
  }) {
1086
1306
  };
1087
- var ConfigSchemaValidationError = class extends import_effect12.Schema.TaggedError()(
1307
+ var ConfigSchemaValidationError = class extends import_effect15.Schema.TaggedError()(
1088
1308
  "ConfigSchemaValidationError",
1089
1309
  {
1090
- message: import_effect12.Schema.String,
1091
- filePath: import_effect12.Schema.String,
1092
- validationErrors: import_effect12.Schema.Array(import_effect12.Schema.String)
1310
+ message: import_effect15.Schema.String,
1311
+ filePath: import_effect15.Schema.String,
1312
+ validationErrors: import_effect15.Schema.Array(import_effect15.Schema.String)
1093
1313
  }
1094
1314
  ) {
1095
1315
  };
1096
- var FunctionConfigError = class extends import_effect12.Schema.TaggedError()("FunctionConfigError", {
1097
- message: import_effect12.Schema.String,
1098
- functionPath: import_effect12.Schema.String
1316
+ var FunctionConfigError = class extends import_effect15.Schema.TaggedError()("FunctionConfigError", {
1317
+ message: import_effect15.Schema.String,
1318
+ functionPath: import_effect15.Schema.String
1099
1319
  }) {
1100
1320
  };
1101
1321
 
@@ -1115,85 +1335,157 @@ var DEFAULT_FUNCTION_DURATION_SECONDS = 30;
1115
1335
  var MAX_FUNCTION_DURATION_SECONDS = 28800;
1116
1336
 
1117
1337
  // src/parse-config.ts
1118
- var import_effect17 = require("effect");
1338
+ var import_effect21 = require("effect");
1119
1339
 
1120
1340
  // src/services/raw-config-reader.ts
1121
1341
  var import_platform9 = require("@effect/platform");
1122
- var import_effect13 = require("effect");
1342
+ var import_effect17 = require("effect");
1123
1343
  var import_yaml = require("yaml");
1344
+
1345
+ // src/services/config-module-loader.ts
1346
+ var import_effect16 = require("effect");
1347
+ var import_jiti = require("jiti");
1348
+ var MISSING_DEFAULT_EXPORT = /* @__PURE__ */ Symbol("MissingDefaultExport");
1349
+ var STRICT_DEFAULT_EXPORT_EXTENSIONS = [".ts", ".mts", ".mjs"];
1350
+ var ConfigModuleLoader = class extends import_effect16.Effect.Service()("ConfigModuleLoader", {
1351
+ effect: import_effect16.Effect.gen(function* () {
1352
+ const loadConfigModule = import_effect16.Effect.fn("ConfigModuleLoader.loadConfigModule")(function* (filePath) {
1353
+ const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
1354
+ const mod = yield* import_effect16.Effect.tryPromise({
1355
+ try: async () => {
1356
+ const jiti = (0, import_jiti.createJiti)(filePath, { fsCache: false, interopDefault: true, moduleCache: false });
1357
+ const namespace = await jiti.import(filePath);
1358
+ if (typeof namespace === "object" && namespace !== null && "default" in namespace) {
1359
+ return namespace.default;
1360
+ }
1361
+ if (!STRICT_DEFAULT_EXPORT_EXTENSIONS.includes(extension)) {
1362
+ return namespace.default ?? MISSING_DEFAULT_EXPORT;
1363
+ }
1364
+ return MISSING_DEFAULT_EXPORT;
1365
+ },
1366
+ catch: (error) => new ConfigModuleLoadError({
1367
+ message: `Failed to load config module at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1368
+ filePath,
1369
+ cause: error instanceof Error ? error.message : void 0
1370
+ })
1371
+ });
1372
+ if (mod === MISSING_DEFAULT_EXPORT) {
1373
+ return yield* import_effect16.Effect.fail(
1374
+ new ConfigModuleLoadError({
1375
+ message: `Config module at ${filePath} does not have a default export. Export the config object as the default export (or via module.exports for CommonJS files), optionally wrapped in defineConfig.`,
1376
+ filePath
1377
+ })
1378
+ );
1379
+ }
1380
+ if (typeof mod === "function") {
1381
+ return yield* import_effect16.Effect.fail(
1382
+ new ConfigModuleLoadError({
1383
+ message: `Config module at ${filePath} default-exports a function; config factories are not supported. Export a config object instead (optionally wrapped in defineConfig).`,
1384
+ filePath
1385
+ })
1386
+ );
1387
+ }
1388
+ if (typeof mod !== "object" || mod === null || Array.isArray(mod)) {
1389
+ return yield* import_effect16.Effect.fail(
1390
+ new ConfigModuleLoadError({
1391
+ message: `Config module at ${filePath} must default-export a config object.`,
1392
+ filePath
1393
+ })
1394
+ );
1395
+ }
1396
+ return mod;
1397
+ });
1398
+ return { loadConfigModule };
1399
+ })
1400
+ }) {
1401
+ };
1402
+
1403
+ // src/services/raw-config-reader.ts
1124
1404
  var ALLOWED_CONFIG_NAMES = [
1405
+ "gigadrive.ts",
1406
+ "gigadrive.mts",
1407
+ "gigadrive.cts",
1408
+ "gigadrive.js",
1409
+ "gigadrive.mjs",
1410
+ "gigadrive.cjs",
1125
1411
  "gigadrive.yaml",
1126
1412
  "gigadrive.yml",
1413
+ "gigadrive.json",
1127
1414
  "nebula.yaml",
1128
1415
  "nebula.yml",
1129
1416
  "nebula.json"
1130
1417
  ];
1131
- var RawConfigReader = class extends import_effect13.Effect.Service()("RawConfigReader", {
1132
- effect: import_effect13.Effect.gen(function* () {
1418
+ var MODULE_EXTENSIONS = [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs"];
1419
+ var RawConfigReader = class extends import_effect17.Effect.Service()("RawConfigReader", {
1420
+ dependencies: [ConfigModuleLoader.Default],
1421
+ effect: import_effect17.Effect.gen(function* () {
1133
1422
  const fs = yield* import_platform9.FileSystem.FileSystem;
1134
1423
  const pathService = yield* import_platform9.Path.Path;
1135
- const findConfig = import_effect13.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1424
+ const moduleLoader = yield* ConfigModuleLoader;
1425
+ const findConfig = import_effect17.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1136
1426
  for (const name of ALLOWED_CONFIG_NAMES) {
1137
1427
  const filePath = pathService.join(projectFolder, name);
1138
- const exists = yield* fs.exists(filePath).pipe(import_effect13.Effect.catchAll(() => import_effect13.Effect.succeed(false)));
1428
+ const exists = yield* fs.exists(filePath).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(false)));
1139
1429
  if (exists) {
1140
1430
  return filePath;
1141
1431
  }
1142
1432
  }
1143
1433
  return null;
1144
1434
  });
1145
- const readRawConfig = import_effect13.Effect.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
1146
- const exists = yield* fs.exists(filePath).pipe(import_effect13.Effect.catchAll(() => import_effect13.Effect.succeed(false)));
1435
+ const readRawConfig = import_effect17.Effect.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
1436
+ const exists = yield* fs.exists(filePath).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(false)));
1147
1437
  if (!exists) {
1148
- return yield* import_effect13.Effect.fail(
1438
+ return yield* import_effect17.Effect.fail(
1149
1439
  new ConfigFileNotFoundError({ message: `Config file not found at ${filePath}`, filePath })
1150
1440
  );
1151
1441
  }
1152
1442
  const fileContents = yield* fs.readFileString(filePath).pipe(
1153
- import_effect13.Effect.mapError(
1443
+ import_effect17.Effect.mapError(
1154
1444
  () => new ConfigFileParseError({ message: `Failed to read config file at ${filePath}`, filePath })
1155
1445
  )
1156
1446
  );
1157
1447
  if (fileContents.length === 0) {
1158
- return yield* import_effect13.Effect.fail(
1448
+ return yield* import_effect17.Effect.fail(
1159
1449
  new ConfigFileEmptyError({ message: `Config file is empty at ${filePath}`, filePath })
1160
1450
  );
1161
1451
  }
1162
1452
  const fileExtension = pathService.extname(filePath).toLowerCase();
1163
1453
  let parsed;
1164
- try {
1165
- if (fileExtension === ".json") {
1166
- parsed = JSON.parse(fileContents);
1167
- } else if ([".yml", ".yaml"].includes(fileExtension)) {
1168
- parsed = (0, import_yaml.parse)(fileContents);
1169
- } else {
1170
- parsed = (0, import_yaml.parse)(fileContents);
1454
+ if (MODULE_EXTENSIONS.includes(fileExtension)) {
1455
+ parsed = yield* moduleLoader.loadConfigModule(filePath);
1456
+ } else {
1457
+ try {
1458
+ if (fileExtension === ".json") {
1459
+ parsed = JSON.parse(fileContents);
1460
+ } else {
1461
+ parsed = (0, import_yaml.parse)(fileContents);
1462
+ }
1463
+ } catch (error) {
1464
+ return yield* import_effect17.Effect.fail(
1465
+ new ConfigFileParseError({
1466
+ message: `Failed to parse config file at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1467
+ filePath,
1468
+ cause: error instanceof Error ? error.message : void 0
1469
+ })
1470
+ );
1171
1471
  }
1172
- } catch (error) {
1173
- return yield* import_effect13.Effect.fail(
1174
- new ConfigFileParseError({
1175
- message: `Failed to parse config file at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1176
- filePath,
1177
- cause: error instanceof Error ? error.message : void 0
1178
- })
1179
- );
1180
1472
  }
1181
1473
  if (parsed == null) {
1182
- return yield* import_effect13.Effect.fail(
1474
+ return yield* import_effect17.Effect.fail(
1183
1475
  new ConfigFileParseError({ message: `Config file could not be parsed at ${filePath}`, filePath })
1184
1476
  );
1185
1477
  }
1186
1478
  if (!options?.disableVersionCheck && typeof parsed.version !== "number") {
1187
- return yield* import_effect13.Effect.fail(
1479
+ return yield* import_effect17.Effect.fail(
1188
1480
  new ConfigVersionError({ message: `Config file is missing version at ${filePath}`, filePath })
1189
1481
  );
1190
1482
  }
1191
1483
  return parsed;
1192
1484
  });
1193
1485
  const readConfigFile = (configFilePath) => readRawConfig(configFilePath, { disableVersionCheck: true }).pipe(
1194
- import_effect13.Effect.map((parsed) => parsed),
1195
- import_effect13.Effect.catchTag("ConfigFileNotFoundError", () => import_effect13.Effect.succeed(null)),
1196
- import_effect13.Effect.withSpan("RawConfigReader.readConfigFile")
1486
+ import_effect17.Effect.map((parsed) => parsed),
1487
+ import_effect17.Effect.catchTag("ConfigFileNotFoundError", () => import_effect17.Effect.succeed(null)),
1488
+ import_effect17.Effect.withSpan("RawConfigReader.readConfigFile")
1197
1489
  );
1198
1490
  return { findConfig, readRawConfig, readConfigFile };
1199
1491
  })
@@ -1203,17 +1495,17 @@ var RawConfigReader = class extends import_effect13.Effect.Service()("RawConfigR
1203
1495
  // src/services/schema-validator.ts
1204
1496
  var import_ajv = __toESM(require("ajv"));
1205
1497
  var import_ajv_formats = __toESM(require("ajv-formats"));
1206
- var import_effect14 = require("effect");
1207
- var SchemaValidator = class extends import_effect14.Effect.Service()("SchemaValidator", {
1208
- effect: import_effect14.Effect.gen(function* () {
1498
+ var import_effect18 = require("effect");
1499
+ var SchemaValidator = class extends import_effect18.Effect.Service()("SchemaValidator", {
1500
+ effect: import_effect18.Effect.gen(function* () {
1209
1501
  const ajv = new import_ajv.default();
1210
1502
  (0, import_ajv_formats.default)(ajv);
1211
- const validate = import_effect14.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1503
+ const validate = import_effect18.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1212
1504
  const compiledValidate = ajv.compile(schema);
1213
1505
  const valid = compiledValidate(config);
1214
1506
  if (!valid) {
1215
1507
  const errors = compiledValidate.errors?.map((e) => `${e.instancePath || "/"} ${e.message ?? ""}`.trim()) ?? [];
1216
- return yield* import_effect14.Effect.fail(
1508
+ return yield* import_effect18.Effect.fail(
1217
1509
  new ConfigSchemaValidationError({
1218
1510
  message: `Config file at ${filePath} is invalid: ${ajv.errorsText(compiledValidate.errors)}`,
1219
1511
  filePath,
@@ -1230,7 +1522,7 @@ var SchemaValidator = class extends import_effect14.Effect.Service()("SchemaVali
1230
1522
  // src/services/v4-config-parser.ts
1231
1523
  var import_platform10 = require("@effect/platform");
1232
1524
  var import_build_utils = require("@gigadrive/build-utils");
1233
- var import_effect15 = require("effect");
1525
+ var import_effect19 = require("effect");
1234
1526
  var import_minimatch = require("minimatch");
1235
1527
  var import_safe_regex2 = __toESM(require("safe-regex2"));
1236
1528
  var MAX_ASSET_DEPTH = 100;
@@ -1336,7 +1628,7 @@ var mapRoute = (route, entrypoints) => ({
1336
1628
  negativeRequirements: route.missing,
1337
1629
  status: route.statusCode
1338
1630
  });
1339
- var parseEntrypoints = import_effect15.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
1631
+ var parseEntrypoints = import_effect19.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
1340
1632
  const entrypoints = [];
1341
1633
  if (config.functions == null) return entrypoints;
1342
1634
  for (const [fnPath, func] of Object.entries(config.functions)) {
@@ -1346,7 +1638,7 @@ var parseEntrypoints = import_effect15.Effect.fn("parseEntrypoints")(function* (
1346
1638
  functionPath: fnPath
1347
1639
  });
1348
1640
  }
1349
- const matchedFiles = yield* import_effect15.Effect.tryPromise({
1641
+ const matchedFiles = yield* import_effect19.Effect.tryPromise({
1350
1642
  try: () => (0, import_build_utils.getFilesForPattern)(fnPath, projectFolder, func.excludeFiles),
1351
1643
  catch: (error) => new FunctionConfigError({
1352
1644
  message: `Failed to resolve files for function pattern '${fnPath}': ${error instanceof Error ? error.message : String(error)}`,
@@ -1382,14 +1674,14 @@ var parseEntrypoints = import_effect15.Effect.fn("parseEntrypoints")(function* (
1382
1674
  }
1383
1675
  return entrypoints;
1384
1676
  });
1385
- var collectAssets = import_effect15.Effect.fn("collectAssets")(function* (config, projectFolder) {
1677
+ var collectAssets = import_effect19.Effect.fn("collectAssets")(function* (config, projectFolder) {
1386
1678
  if (config.assets == null) return [];
1387
1679
  const fs = yield* import_platform10.FileSystem.FileSystem;
1388
1680
  const pathService = yield* import_platform10.Path.Path;
1389
1681
  const assetsPath = pathService.join(projectFolder, config.assets);
1390
- const assetsExist = yield* fs.exists(assetsPath).pipe(import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed(false)));
1682
+ const assetsExist = yield* fs.exists(assetsPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(false)));
1391
1683
  if (!assetsExist) return [];
1392
- const stat = yield* fs.stat(assetsPath).pipe(import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed(null)));
1684
+ const stat = yield* fs.stat(assetsPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(null)));
1393
1685
  if (!stat || stat.type !== "Directory") return [];
1394
1686
  const allFiles = yield* collectFilesRecursively(assetsPath);
1395
1687
  const assets = [];
@@ -1400,18 +1692,18 @@ var collectAssets = import_effect15.Effect.fn("collectAssets")(function* (config
1400
1692
  }
1401
1693
  return assets;
1402
1694
  });
1403
- var collectFilesRecursively = import_effect15.Effect.fn("collectFilesRecursively")(
1695
+ var collectFilesRecursively = import_effect19.Effect.fn("collectFilesRecursively")(
1404
1696
  function* (basePath, relativePath = "", depth = 0) {
1405
1697
  if (depth > MAX_ASSET_DEPTH) return [];
1406
1698
  const fs = yield* import_platform10.FileSystem.FileSystem;
1407
1699
  const pathSvc = yield* import_platform10.Path.Path;
1408
1700
  const currentPath = relativePath ? pathSvc.join(basePath, relativePath) : basePath;
1409
- const entries = yield* fs.readDirectory(currentPath).pipe(import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed([])));
1701
+ const entries = yield* fs.readDirectory(currentPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed([])));
1410
1702
  const result = [];
1411
1703
  for (const name of entries) {
1412
1704
  const fullPath = pathSvc.join(currentPath, name);
1413
1705
  const entryRelative = relativePath ? pathSvc.join(relativePath, name) : name;
1414
- const stat = yield* fs.stat(fullPath).pipe(import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed(null)));
1706
+ const stat = yield* fs.stat(fullPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(null)));
1415
1707
  if (!stat) continue;
1416
1708
  if (stat.type === "Directory") {
1417
1709
  const nested = yield* collectFilesRecursively(basePath, entryRelative, depth + 1);
@@ -1423,16 +1715,16 @@ var collectFilesRecursively = import_effect15.Effect.fn("collectFilesRecursively
1423
1715
  return result;
1424
1716
  }
1425
1717
  );
1426
- var V4ConfigParser = class extends import_effect15.Effect.Service()("V4ConfigParser", {
1718
+ var V4ConfigParser = class extends import_effect19.Effect.Service()("V4ConfigParser", {
1427
1719
  accessors: true,
1428
- effect: import_effect15.Effect.succeed({
1720
+ effect: import_effect19.Effect.succeed({
1429
1721
  /**
1430
1722
  * Parses a ConfigV4 into a NormalizedConfig.
1431
1723
  *
1432
1724
  * @param config - The raw V4 config object
1433
1725
  * @param projectFolder - Absolute path to the project root
1434
1726
  */
1435
- parse: import_effect15.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1727
+ parse: import_effect19.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1436
1728
  const entrypoints = yield* parseEntrypoints(config, projectFolder);
1437
1729
  const assets = yield* collectAssets(config, projectFolder);
1438
1730
  return {
@@ -1461,7 +1753,7 @@ var V4ConfigParser = class extends import_effect15.Effect.Service()("V4ConfigPar
1461
1753
  var import_platform11 = require("@effect/platform");
1462
1754
  var import_build_utils2 = require("@gigadrive/build-utils");
1463
1755
  var import_commons = require("@gigadrive/commons");
1464
- var import_effect16 = require("effect");
1756
+ var import_effect20 = require("effect");
1465
1757
 
1466
1758
  // src/build-output-v3/determine-repo-root.ts
1467
1759
  var import_path = __toESM(require("path"));
@@ -1557,11 +1849,11 @@ var translateVercelRuntime = (runtime) => {
1557
1849
  var CONFIG_PATH = ".vercel/output/config.json";
1558
1850
  var FUNCTIONS_FOLDER = ".vercel/output/functions";
1559
1851
  var FUNCTION_CONFIGS_PATTERN = `${FUNCTIONS_FOLDER}/**/*.func/.vc-config.json`;
1560
- var VercelBuildOutputParser = class extends import_effect16.Effect.Service()("VercelBuildOutputParser", {
1561
- effect: import_effect16.Effect.gen(function* () {
1852
+ var VercelBuildOutputParser = class extends import_effect20.Effect.Service()("VercelBuildOutputParser", {
1853
+ effect: import_effect20.Effect.gen(function* () {
1562
1854
  const rawConfigReader = yield* RawConfigReader;
1563
1855
  const pathService = yield* import_platform11.Path.Path;
1564
- const parse = import_effect16.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1856
+ const parse = import_effect20.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1565
1857
  const config = yield* rawConfigReader.readConfigFile(pathService.join(projectFolder, CONFIG_PATH));
1566
1858
  if (!config || typeof config.version !== "number" || config.version < 3) {
1567
1859
  return parseResult;
@@ -1573,8 +1865,8 @@ var VercelBuildOutputParser = class extends import_effect16.Effect.Service()("Ve
1573
1865
  merged.regions = [...new Set(merged.regions)];
1574
1866
  return merged;
1575
1867
  });
1576
- const loadFunctions = import_effect16.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1577
- const functionConfigs = yield* import_effect16.Effect.tryPromise({
1868
+ const loadFunctions = import_effect20.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1869
+ const functionConfigs = yield* import_effect20.Effect.tryPromise({
1578
1870
  try: () => (0, import_build_utils2.getFilesForPattern)(FUNCTION_CONFIGS_PATTERN, projectFolder),
1579
1871
  catch: (error) => new ConfigFileParseError({
1580
1872
  message: `Failed to scan for function configs: ${error instanceof Error ? error.message : String(error)}`,
@@ -2173,7 +2465,7 @@ var schema_default = {
2173
2465
  };
2174
2466
 
2175
2467
  // src/parse-config.ts
2176
- var parseConfigRaw = import_effect17.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2468
+ var parseConfigRaw = import_effect21.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2177
2469
  const rawReader = yield* RawConfigReader;
2178
2470
  const validator = yield* SchemaValidator;
2179
2471
  const v4Parser = yield* V4ConfigParser;
@@ -2184,7 +2476,7 @@ var parseConfigRaw = import_effect17.Effect.fn("parseConfigRaw")(function* (file
2184
2476
  };
2185
2477
  const schema = schemaMap[version];
2186
2478
  if (!schema) {
2187
- return yield* import_effect17.Effect.fail(
2479
+ return yield* import_effect21.Effect.fail(
2188
2480
  new ConfigVersionError({
2189
2481
  message: `Config file at ${filePath} has an unsupported version: ${version}`,
2190
2482
  filePath,
@@ -2195,18 +2487,19 @@ var parseConfigRaw = import_effect17.Effect.fn("parseConfigRaw")(function* (file
2195
2487
  yield* validator.validate(parsed, schema, filePath);
2196
2488
  return yield* v4Parser.parse(parsed, projectFolder);
2197
2489
  });
2198
- var parseConfig = import_effect17.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
2490
+ var parseConfig = import_effect21.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
2199
2491
  const parseResult = yield* parseConfigRaw(filePath, projectFolder);
2200
2492
  return yield* postProcessConfig(parseResult, projectFolder);
2201
2493
  });
2202
- var postProcessConfig = import_effect17.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
2494
+ var postProcessConfig = import_effect21.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
2203
2495
  const vercelParser = yield* VercelBuildOutputParser;
2204
2496
  let result = yield* vercelParser.parse(config, projectFolder);
2205
- if (result.entrypoints.length === 0 && (result.assets?.paths?.length || 0) === 0 && result.routes.length === 0) {
2497
+ const hasAssets = (result.assets?.paths?.length ?? 0) > 0 || (result.assets?.prefixes?.length ?? 0) > 0 || (result.assets?.manifests?.length ?? 0) > 0;
2498
+ if (result.entrypoints.length === 0 && !hasAssets && result.routes.length === 0) {
2206
2499
  result.errors.push(
2207
2500
  "The current project config does not resolve to any functions, assets or routes and can not be deployed."
2208
2501
  );
2209
- } else if (result.entrypoints.length === 0 && (result.assets?.paths?.length || 0) === 0) {
2502
+ } else if (result.entrypoints.length === 0 && !hasAssets) {
2210
2503
  result.warnings.push("The current project does not have any functions or assets to deploy.");
2211
2504
  }
2212
2505
  result = filterFunctionsFromAssets(result);
@@ -2227,9 +2520,14 @@ var RUNTIME_DEFINITIONS = [
2227
2520
  var AVAILABLE_RUNTIMES = [...RUNTIME_DEFINITIONS];
2228
2521
 
2229
2522
  // src/services/index.ts
2230
- var import_effect18 = require("effect");
2231
- var BaseLayers = import_effect18.Layer.mergeAll(RawConfigReader.Default, SchemaValidator.Default, V4ConfigParser.Default);
2232
- var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect18.Layer.provideMerge(BaseLayers));
2523
+ var import_effect22 = require("effect");
2524
+ var BaseLayers = import_effect22.Layer.mergeAll(
2525
+ ConfigModuleLoader.Default,
2526
+ RawConfigReader.Default,
2527
+ SchemaValidator.Default,
2528
+ V4ConfigParser.Default
2529
+ );
2530
+ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect22.Layer.provideMerge(BaseLayers));
2233
2531
  // Annotate the CommonJS export names for ESM import in node:
2234
2532
  0 && (module.exports = {
2235
2533
  ALLOWED_CONFIG_NAMES,
@@ -2238,12 +2536,22 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect18.Lay
2238
2536
  ConfigFileEmptyError,
2239
2537
  ConfigFileNotFoundError,
2240
2538
  ConfigFileParseError,
2539
+ ConfigModuleLoadError,
2540
+ ConfigModuleLoader,
2241
2541
  ConfigSchemaValidationError,
2242
2542
  ConfigVersionError,
2243
2543
  DEFAULT_FUNCTION_DURATION_SECONDS,
2244
2544
  FRAMEWORK_DEFINITIONS,
2245
2545
  FrameworkNotDetectedError,
2246
2546
  FunctionConfigError,
2547
+ GigadriveNextBuildManifestSchema,
2548
+ GigadriveNextBuildManifestV1Schema,
2549
+ GigadriveNextBuildManifestV2ExportSchema,
2550
+ GigadriveNextBuildManifestV2StandaloneSchema,
2551
+ GigadriveNextPrerenderManifestV1Schema,
2552
+ GigadriveNextPrerenderOutputSchema,
2553
+ GigadriveNextServerDescriptorSchema,
2554
+ GigadriveNextStaticAssetPrefixSchema,
2247
2555
  MAX_FUNCTION_DURATION_SECONDS,
2248
2556
  ManifestNotFoundError,
2249
2557
  ManifestParseError,
@@ -2251,8 +2559,12 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect18.Lay
2251
2559
  NetworkConfigLive,
2252
2560
  RawConfigReader,
2253
2561
  SchemaValidator,
2562
+ StaticAssetHeadersSchema,
2563
+ StaticAssetManifestEntrySchema,
2564
+ StaticAssetManifestV1Schema,
2254
2565
  V4ConfigParser,
2255
2566
  VercelBuildOutputParser,
2567
+ defineConfig,
2256
2568
  detectFramework,
2257
2569
  detectPackageManager,
2258
2570
  filterFunctionsFromAssets,
@@ -2262,6 +2574,8 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect18.Lay
2262
2574
  parseConfig,
2263
2575
  parseConfigRaw,
2264
2576
  parseGigadriveNextBuildManifest,
2577
+ parseGigadriveNextPrerenderManifest,
2578
+ parseStaticAssetManifest,
2265
2579
  postProcessConfig,
2266
2580
  readDependencies
2267
2581
  });