@gigadrive/network-config 4.5.0 → 4.6.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
@@ -36,6 +36,8 @@ __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,
@@ -46,8 +48,12 @@ __export(src_exports, {
46
48
  GigadriveNextBuildManifestV1Schema: () => GigadriveNextBuildManifestV1Schema,
47
49
  GigadriveNextBuildManifestV2ExportSchema: () => GigadriveNextBuildManifestV2ExportSchema,
48
50
  GigadriveNextBuildManifestV2StandaloneSchema: () => GigadriveNextBuildManifestV2StandaloneSchema,
51
+ GigadriveNextMiddlewareDescriptorSchema: () => GigadriveNextMiddlewareDescriptorSchema,
52
+ GigadriveNextMiddlewareMatcherSchema: () => GigadriveNextMiddlewareMatcherSchema,
49
53
  GigadriveNextPrerenderManifestV1Schema: () => GigadriveNextPrerenderManifestV1Schema,
50
54
  GigadriveNextPrerenderOutputSchema: () => GigadriveNextPrerenderOutputSchema,
55
+ GigadriveNextPrerenderSeedMethodsSchema: () => GigadriveNextPrerenderSeedMethodsSchema,
56
+ GigadriveNextRouteConditionSchema: () => GigadriveNextRouteConditionSchema,
51
57
  GigadriveNextServerDescriptorSchema: () => GigadriveNextServerDescriptorSchema,
52
58
  GigadriveNextStaticAssetPrefixSchema: () => GigadriveNextStaticAssetPrefixSchema,
53
59
  MAX_FUNCTION_DURATION_SECONDS: () => MAX_FUNCTION_DURATION_SECONDS,
@@ -62,6 +68,7 @@ __export(src_exports, {
62
68
  StaticAssetManifestV1Schema: () => StaticAssetManifestV1Schema,
63
69
  V4ConfigParser: () => V4ConfigParser,
64
70
  VercelBuildOutputParser: () => VercelBuildOutputParser,
71
+ defineConfig: () => defineConfig,
65
72
  detectFramework: () => detectFramework,
66
73
  detectPackageManager: () => detectPackageManager,
67
74
  filterFunctionsFromAssets: () => filterFunctionsFromAssets,
@@ -135,6 +142,9 @@ var StaticAssetManifestV1Schema = import_effect2.Schema.mutable(
135
142
  ).pipe(import_effect2.Schema.filter(({ assets }) => new Set(assets.map(({ path: path2 }) => path2)).size === assets.length));
136
143
  var parseStaticAssetManifest = (content) => decodeJson(StaticAssetManifestV1Schema, content);
137
144
 
145
+ // src/define-config.ts
146
+ var defineConfig = (config) => config;
147
+
138
148
  // src/detection/detect-framework.ts
139
149
  var import_platform8 = require("@effect/platform");
140
150
  var import_effect13 = require("effect");
@@ -531,38 +541,60 @@ var ImagePolicySchema = import_effect7.Schema.mutable(
531
541
  variants: import_effect7.Schema.mutable(import_effect7.Schema.Record({ key: import_effect7.Schema.String, value: ImageVariantSchema }))
532
542
  })
533
543
  );
534
- var GigadriveNextPrerenderOutputSchema = import_effect7.Schema.mutable(
535
- import_effect7.Schema.Struct({
536
- id: import_effect7.Schema.String,
537
- type: import_effect7.Schema.Literal("PRERENDER"),
538
- pathname: UrlPathnameSchema,
539
- parentOutputId: import_effect7.Schema.String,
540
- groupId: import_effect7.Schema.Number,
541
- pprChain: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Struct({ headers: HttpSingleValueHeadersSchema }))),
542
- parentFallbackMode: import_effect7.Schema.optional(JsonValueSchema),
543
- fallback: import_effect7.Schema.optional(
544
- import_effect7.Schema.mutable(
545
- import_effect7.Schema.Struct({
546
- filePath: import_effect7.Schema.optional(PortableRelativePathSchema),
547
- initialStatus: import_effect7.Schema.optional(import_effect7.Schema.Int.pipe(import_effect7.Schema.between(100, 599))),
548
- initialHeaders: import_effect7.Schema.optional(HttpHeadersSchema),
549
- initialExpiration: import_effect7.Schema.optional(import_effect7.Schema.Number),
550
- initialRevalidate: import_effect7.Schema.optional(import_effect7.Schema.Union(import_effect7.Schema.Number, import_effect7.Schema.Literal(false))),
551
- postponedState: import_effect7.Schema.optional(import_effect7.Schema.String)
552
- })
553
- )
554
- ),
555
- config: import_effect7.Schema.mutable(
544
+ var GigadriveNextPrerenderOutputFields = {
545
+ id: import_effect7.Schema.String,
546
+ type: import_effect7.Schema.Literal("PRERENDER"),
547
+ pathname: UrlPathnameSchema,
548
+ route: import_effect7.Schema.optional(UrlPathnameSchema),
549
+ parentOutputId: import_effect7.Schema.String,
550
+ groupId: import_effect7.Schema.Number,
551
+ pprChain: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Struct({ headers: HttpSingleValueHeadersSchema }))),
552
+ parentFallbackMode: import_effect7.Schema.optional(JsonValueSchema),
553
+ fallback: import_effect7.Schema.optional(
554
+ import_effect7.Schema.mutable(
556
555
  import_effect7.Schema.Struct({
557
- allowQuery: import_effect7.Schema.optional(StringArraySchema),
558
- allowHeader: import_effect7.Schema.optional(StringArraySchema),
559
- bypassFor: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Array(JsonValueSchema))),
560
- renderingMode: import_effect7.Schema.optional(import_effect7.Schema.String),
561
- partialFallback: import_effect7.Schema.optional(import_effect7.Schema.Boolean),
562
- bypassToken: import_effect7.Schema.optional(import_effect7.Schema.String)
556
+ filePath: import_effect7.Schema.optional(PortableRelativePathSchema),
557
+ initialStatus: import_effect7.Schema.optional(import_effect7.Schema.Int.pipe(import_effect7.Schema.between(100, 599))),
558
+ initialHeaders: import_effect7.Schema.optional(HttpHeadersSchema),
559
+ initialExpiration: import_effect7.Schema.optional(import_effect7.Schema.Number),
560
+ initialRevalidate: import_effect7.Schema.optional(import_effect7.Schema.Union(import_effect7.Schema.Number, import_effect7.Schema.Literal(false))),
561
+ postponedState: import_effect7.Schema.optional(import_effect7.Schema.String)
563
562
  })
564
563
  )
565
- })
564
+ ),
565
+ config: import_effect7.Schema.mutable(
566
+ import_effect7.Schema.Struct({
567
+ allowQuery: import_effect7.Schema.optional(StringArraySchema),
568
+ allowHeader: import_effect7.Schema.optional(StringArraySchema),
569
+ bypassFor: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Array(JsonValueSchema))),
570
+ renderingMode: import_effect7.Schema.optional(import_effect7.Schema.String),
571
+ partialFallback: import_effect7.Schema.optional(import_effect7.Schema.Boolean),
572
+ bypassToken: import_effect7.Schema.optional(import_effect7.Schema.String)
573
+ })
574
+ )
575
+ };
576
+ var GigadriveNextPrerenderClassificationSchema = import_effect7.Schema.Struct({
577
+ routeType: import_effect7.Schema.Literal("route", "fallback", "shell", "page"),
578
+ response: import_effect7.Schema.Literal("empty", "initial", "complete"),
579
+ compute: import_effect7.Schema.Literal("blocking", "resuming", "static"),
580
+ htmlSize: import_effect7.Schema.optional(import_effect7.Schema.Number)
581
+ });
582
+ var GigadriveNextPrerenderWithoutClassificationSchema = import_effect7.Schema.Struct({
583
+ routeType: import_effect7.Schema.optional(import_effect7.Schema.Never),
584
+ response: import_effect7.Schema.optional(import_effect7.Schema.Never),
585
+ compute: import_effect7.Schema.optional(import_effect7.Schema.Never),
586
+ htmlSize: import_effect7.Schema.optional(import_effect7.Schema.Never)
587
+ });
588
+ var GigadriveNextPrerenderOutputSchema = import_effect7.Schema.Union(
589
+ import_effect7.Schema.mutable(
590
+ import_effect7.Schema.Struct({ ...GigadriveNextPrerenderOutputFields, ...GigadriveNextPrerenderClassificationSchema.fields })
591
+ ),
592
+ import_effect7.Schema.mutable(
593
+ import_effect7.Schema.Struct({
594
+ ...GigadriveNextPrerenderOutputFields,
595
+ ...GigadriveNextPrerenderWithoutClassificationSchema.fields
596
+ })
597
+ )
566
598
  );
567
599
  var GigadriveNextStaticAssetPrefixSchema = import_effect7.Schema.mutable(
568
600
  import_effect7.Schema.Struct({
@@ -571,6 +603,43 @@ var GigadriveNextStaticAssetPrefixSchema = import_effect7.Schema.mutable(
571
603
  immutable: import_effect7.Schema.Boolean
572
604
  })
573
605
  );
606
+ var GigadriveNextRouteConditionSchema = import_effect7.Schema.Union(
607
+ import_effect7.Schema.mutable(
608
+ import_effect7.Schema.Struct({
609
+ type: import_effect7.Schema.Literal("header", "cookie", "query"),
610
+ key: import_effect7.Schema.String,
611
+ value: import_effect7.Schema.optional(import_effect7.Schema.String)
612
+ })
613
+ ),
614
+ import_effect7.Schema.mutable(
615
+ import_effect7.Schema.Struct({
616
+ type: import_effect7.Schema.Literal("host"),
617
+ value: import_effect7.Schema.String
618
+ })
619
+ )
620
+ );
621
+ var GigadriveNextMiddlewareMatcherSchema = import_effect7.Schema.mutable(
622
+ import_effect7.Schema.Struct({
623
+ source: import_effect7.Schema.String,
624
+ sourceRegex: import_effect7.Schema.String,
625
+ has: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Array(GigadriveNextRouteConditionSchema))),
626
+ missing: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Array(GigadriveNextRouteConditionSchema)))
627
+ })
628
+ );
629
+ var GigadriveNextMiddlewareDescriptorSchema = import_effect7.Schema.Union(
630
+ import_effect7.Schema.mutable(
631
+ import_effect7.Schema.Struct({
632
+ present: import_effect7.Schema.Literal(true),
633
+ matchers: import_effect7.Schema.mutable(import_effect7.Schema.Array(GigadriveNextMiddlewareMatcherSchema))
634
+ })
635
+ ),
636
+ import_effect7.Schema.mutable(
637
+ import_effect7.Schema.Struct({
638
+ present: import_effect7.Schema.Literal(false),
639
+ matchers: import_effect7.Schema.mutable(import_effect7.Schema.Tuple())
640
+ })
641
+ )
642
+ );
574
643
  var GigadriveNextServerDescriptorSchema = import_effect7.Schema.mutable(
575
644
  import_effect7.Schema.Struct({
576
645
  maxDuration: import_effect7.Schema.optional(import_effect7.Schema.Number),
@@ -581,6 +650,9 @@ var GigadriveNextServerDescriptorSchema = import_effect7.Schema.mutable(
581
650
  var PrerenderArraySchema = import_effect7.Schema.mutable(import_effect7.Schema.Array(GigadriveNextPrerenderOutputSchema));
582
651
  var StaticAssetArraySchema = import_effect7.Schema.mutable(import_effect7.Schema.Array(GigadriveNextStaticAssetPrefixSchema));
583
652
  var JsonValueArraySchema = import_effect7.Schema.mutable(import_effect7.Schema.Array(JsonValueSchema));
653
+ var GigadriveNextPrerenderSeedMethodsSchema = import_effect7.Schema.mutable(
654
+ import_effect7.Schema.Tuple(import_effect7.Schema.Literal("GET"), import_effect7.Schema.Literal("HEAD"))
655
+ );
584
656
  var GigadriveNextBuildManifestV1Schema = import_effect7.Schema.mutable(
585
657
  import_effect7.Schema.Struct({
586
658
  version: import_effect7.Schema.Literal(1),
@@ -637,7 +709,8 @@ var GigadriveNextBuildManifestV2StandaloneSchema = import_effect7.Schema.mutable
637
709
  prerenderManifest: import_effect7.Schema.optional(PortableRelativePathSchema),
638
710
  assetManifest: import_effect7.Schema.optional(PortableRelativePathSchema),
639
711
  entryPagePaths: import_effect7.Schema.optional(import_effect7.Schema.mutable(import_effect7.Schema.Array(UrlPathnameSchema))),
640
- staticAssets: StaticAssetArraySchema
712
+ staticAssets: StaticAssetArraySchema,
713
+ middleware: import_effect7.Schema.optional(GigadriveNextMiddlewareDescriptorSchema)
641
714
  })
642
715
  )
643
716
  })
@@ -650,6 +723,7 @@ var GigadriveNextBuildManifestSchema = import_effect7.Schema.Union(
650
723
  var GigadriveNextPrerenderManifestV1Schema = import_effect7.Schema.mutable(
651
724
  import_effect7.Schema.Struct({
652
725
  version: import_effect7.Schema.Literal(1),
726
+ seedMethods: import_effect7.Schema.optional(GigadriveNextPrerenderSeedMethodsSchema),
653
727
  prerenders: PrerenderArraySchema
654
728
  })
655
729
  );
@@ -1286,6 +1360,12 @@ var ConfigFileParseError = class extends import_effect15.Schema.TaggedError()("C
1286
1360
  cause: import_effect15.Schema.optional(import_effect15.Schema.String)
1287
1361
  }) {
1288
1362
  };
1363
+ var ConfigModuleLoadError = class extends import_effect15.Schema.TaggedError()("ConfigModuleLoadError", {
1364
+ message: import_effect15.Schema.String,
1365
+ filePath: import_effect15.Schema.String,
1366
+ cause: import_effect15.Schema.optional(import_effect15.Schema.String)
1367
+ }) {
1368
+ };
1289
1369
  var ConfigVersionError = class extends import_effect15.Schema.TaggedError()("ConfigVersionError", {
1290
1370
  message: import_effect15.Schema.String,
1291
1371
  filePath: import_effect15.Schema.String,
@@ -1323,85 +1403,157 @@ var DEFAULT_FUNCTION_DURATION_SECONDS = 30;
1323
1403
  var MAX_FUNCTION_DURATION_SECONDS = 28800;
1324
1404
 
1325
1405
  // src/parse-config.ts
1326
- var import_effect20 = require("effect");
1406
+ var import_effect21 = require("effect");
1327
1407
 
1328
1408
  // src/services/raw-config-reader.ts
1329
1409
  var import_platform9 = require("@effect/platform");
1330
- var import_effect16 = require("effect");
1410
+ var import_effect17 = require("effect");
1331
1411
  var import_yaml = require("yaml");
1412
+
1413
+ // src/services/config-module-loader.ts
1414
+ var import_effect16 = require("effect");
1415
+ var import_jiti = require("jiti");
1416
+ var MISSING_DEFAULT_EXPORT = /* @__PURE__ */ Symbol("MissingDefaultExport");
1417
+ var STRICT_DEFAULT_EXPORT_EXTENSIONS = [".ts", ".mts", ".mjs"];
1418
+ var ConfigModuleLoader = class extends import_effect16.Effect.Service()("ConfigModuleLoader", {
1419
+ effect: import_effect16.Effect.gen(function* () {
1420
+ const loadConfigModule = import_effect16.Effect.fn("ConfigModuleLoader.loadConfigModule")(function* (filePath) {
1421
+ const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
1422
+ const mod = yield* import_effect16.Effect.tryPromise({
1423
+ try: async () => {
1424
+ const jiti = (0, import_jiti.createJiti)(filePath, { fsCache: false, interopDefault: true, moduleCache: false });
1425
+ const namespace = await jiti.import(filePath);
1426
+ if (typeof namespace === "object" && namespace !== null && "default" in namespace) {
1427
+ return namespace.default;
1428
+ }
1429
+ if (!STRICT_DEFAULT_EXPORT_EXTENSIONS.includes(extension)) {
1430
+ return namespace.default ?? MISSING_DEFAULT_EXPORT;
1431
+ }
1432
+ return MISSING_DEFAULT_EXPORT;
1433
+ },
1434
+ catch: (error) => new ConfigModuleLoadError({
1435
+ message: `Failed to load config module at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1436
+ filePath,
1437
+ cause: error instanceof Error ? error.message : void 0
1438
+ })
1439
+ });
1440
+ if (mod === MISSING_DEFAULT_EXPORT) {
1441
+ return yield* import_effect16.Effect.fail(
1442
+ new ConfigModuleLoadError({
1443
+ 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.`,
1444
+ filePath
1445
+ })
1446
+ );
1447
+ }
1448
+ if (typeof mod === "function") {
1449
+ return yield* import_effect16.Effect.fail(
1450
+ new ConfigModuleLoadError({
1451
+ message: `Config module at ${filePath} default-exports a function; config factories are not supported. Export a config object instead (optionally wrapped in defineConfig).`,
1452
+ filePath
1453
+ })
1454
+ );
1455
+ }
1456
+ if (typeof mod !== "object" || mod === null || Array.isArray(mod)) {
1457
+ return yield* import_effect16.Effect.fail(
1458
+ new ConfigModuleLoadError({
1459
+ message: `Config module at ${filePath} must default-export a config object.`,
1460
+ filePath
1461
+ })
1462
+ );
1463
+ }
1464
+ return mod;
1465
+ });
1466
+ return { loadConfigModule };
1467
+ })
1468
+ }) {
1469
+ };
1470
+
1471
+ // src/services/raw-config-reader.ts
1332
1472
  var ALLOWED_CONFIG_NAMES = [
1473
+ "gigadrive.ts",
1474
+ "gigadrive.mts",
1475
+ "gigadrive.cts",
1476
+ "gigadrive.js",
1477
+ "gigadrive.mjs",
1478
+ "gigadrive.cjs",
1333
1479
  "gigadrive.yaml",
1334
1480
  "gigadrive.yml",
1481
+ "gigadrive.json",
1335
1482
  "nebula.yaml",
1336
1483
  "nebula.yml",
1337
1484
  "nebula.json"
1338
1485
  ];
1339
- var RawConfigReader = class extends import_effect16.Effect.Service()("RawConfigReader", {
1340
- effect: import_effect16.Effect.gen(function* () {
1486
+ var MODULE_EXTENSIONS = [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs"];
1487
+ var RawConfigReader = class extends import_effect17.Effect.Service()("RawConfigReader", {
1488
+ dependencies: [ConfigModuleLoader.Default],
1489
+ effect: import_effect17.Effect.gen(function* () {
1341
1490
  const fs = yield* import_platform9.FileSystem.FileSystem;
1342
1491
  const pathService = yield* import_platform9.Path.Path;
1343
- const findConfig = import_effect16.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1492
+ const moduleLoader = yield* ConfigModuleLoader;
1493
+ const findConfig = import_effect17.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1344
1494
  for (const name of ALLOWED_CONFIG_NAMES) {
1345
1495
  const filePath = pathService.join(projectFolder, name);
1346
- const exists = yield* fs.exists(filePath).pipe(import_effect16.Effect.catchAll(() => import_effect16.Effect.succeed(false)));
1496
+ const exists = yield* fs.exists(filePath).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(false)));
1347
1497
  if (exists) {
1348
1498
  return filePath;
1349
1499
  }
1350
1500
  }
1351
1501
  return null;
1352
1502
  });
1353
- const readRawConfig = import_effect16.Effect.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
1354
- const exists = yield* fs.exists(filePath).pipe(import_effect16.Effect.catchAll(() => import_effect16.Effect.succeed(false)));
1503
+ const readRawConfig = import_effect17.Effect.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
1504
+ const exists = yield* fs.exists(filePath).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(false)));
1355
1505
  if (!exists) {
1356
- return yield* import_effect16.Effect.fail(
1506
+ return yield* import_effect17.Effect.fail(
1357
1507
  new ConfigFileNotFoundError({ message: `Config file not found at ${filePath}`, filePath })
1358
1508
  );
1359
1509
  }
1360
1510
  const fileContents = yield* fs.readFileString(filePath).pipe(
1361
- import_effect16.Effect.mapError(
1511
+ import_effect17.Effect.mapError(
1362
1512
  () => new ConfigFileParseError({ message: `Failed to read config file at ${filePath}`, filePath })
1363
1513
  )
1364
1514
  );
1365
1515
  if (fileContents.length === 0) {
1366
- return yield* import_effect16.Effect.fail(
1516
+ return yield* import_effect17.Effect.fail(
1367
1517
  new ConfigFileEmptyError({ message: `Config file is empty at ${filePath}`, filePath })
1368
1518
  );
1369
1519
  }
1370
1520
  const fileExtension = pathService.extname(filePath).toLowerCase();
1371
1521
  let parsed;
1372
- try {
1373
- if (fileExtension === ".json") {
1374
- parsed = JSON.parse(fileContents);
1375
- } else if ([".yml", ".yaml"].includes(fileExtension)) {
1376
- parsed = (0, import_yaml.parse)(fileContents);
1377
- } else {
1378
- parsed = (0, import_yaml.parse)(fileContents);
1522
+ if (MODULE_EXTENSIONS.includes(fileExtension)) {
1523
+ parsed = yield* moduleLoader.loadConfigModule(filePath);
1524
+ } else {
1525
+ try {
1526
+ if (fileExtension === ".json") {
1527
+ parsed = JSON.parse(fileContents);
1528
+ } else {
1529
+ parsed = (0, import_yaml.parse)(fileContents);
1530
+ }
1531
+ } catch (error) {
1532
+ return yield* import_effect17.Effect.fail(
1533
+ new ConfigFileParseError({
1534
+ message: `Failed to parse config file at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1535
+ filePath,
1536
+ cause: error instanceof Error ? error.message : void 0
1537
+ })
1538
+ );
1379
1539
  }
1380
- } catch (error) {
1381
- return yield* import_effect16.Effect.fail(
1382
- new ConfigFileParseError({
1383
- message: `Failed to parse config file at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1384
- filePath,
1385
- cause: error instanceof Error ? error.message : void 0
1386
- })
1387
- );
1388
1540
  }
1389
1541
  if (parsed == null) {
1390
- return yield* import_effect16.Effect.fail(
1542
+ return yield* import_effect17.Effect.fail(
1391
1543
  new ConfigFileParseError({ message: `Config file could not be parsed at ${filePath}`, filePath })
1392
1544
  );
1393
1545
  }
1394
1546
  if (!options?.disableVersionCheck && typeof parsed.version !== "number") {
1395
- return yield* import_effect16.Effect.fail(
1547
+ return yield* import_effect17.Effect.fail(
1396
1548
  new ConfigVersionError({ message: `Config file is missing version at ${filePath}`, filePath })
1397
1549
  );
1398
1550
  }
1399
1551
  return parsed;
1400
1552
  });
1401
1553
  const readConfigFile = (configFilePath) => readRawConfig(configFilePath, { disableVersionCheck: true }).pipe(
1402
- import_effect16.Effect.map((parsed) => parsed),
1403
- import_effect16.Effect.catchTag("ConfigFileNotFoundError", () => import_effect16.Effect.succeed(null)),
1404
- import_effect16.Effect.withSpan("RawConfigReader.readConfigFile")
1554
+ import_effect17.Effect.map((parsed) => parsed),
1555
+ import_effect17.Effect.catchTag("ConfigFileNotFoundError", () => import_effect17.Effect.succeed(null)),
1556
+ import_effect17.Effect.withSpan("RawConfigReader.readConfigFile")
1405
1557
  );
1406
1558
  return { findConfig, readRawConfig, readConfigFile };
1407
1559
  })
@@ -1411,17 +1563,17 @@ var RawConfigReader = class extends import_effect16.Effect.Service()("RawConfigR
1411
1563
  // src/services/schema-validator.ts
1412
1564
  var import_ajv = __toESM(require("ajv"));
1413
1565
  var import_ajv_formats = __toESM(require("ajv-formats"));
1414
- var import_effect17 = require("effect");
1415
- var SchemaValidator = class extends import_effect17.Effect.Service()("SchemaValidator", {
1416
- effect: import_effect17.Effect.gen(function* () {
1566
+ var import_effect18 = require("effect");
1567
+ var SchemaValidator = class extends import_effect18.Effect.Service()("SchemaValidator", {
1568
+ effect: import_effect18.Effect.gen(function* () {
1417
1569
  const ajv = new import_ajv.default();
1418
1570
  (0, import_ajv_formats.default)(ajv);
1419
- const validate = import_effect17.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1571
+ const validate = import_effect18.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1420
1572
  const compiledValidate = ajv.compile(schema);
1421
1573
  const valid = compiledValidate(config);
1422
1574
  if (!valid) {
1423
1575
  const errors = compiledValidate.errors?.map((e) => `${e.instancePath || "/"} ${e.message ?? ""}`.trim()) ?? [];
1424
- return yield* import_effect17.Effect.fail(
1576
+ return yield* import_effect18.Effect.fail(
1425
1577
  new ConfigSchemaValidationError({
1426
1578
  message: `Config file at ${filePath} is invalid: ${ajv.errorsText(compiledValidate.errors)}`,
1427
1579
  filePath,
@@ -1437,9 +1589,51 @@ var SchemaValidator = class extends import_effect17.Effect.Service()("SchemaVali
1437
1589
 
1438
1590
  // src/services/v4-config-parser.ts
1439
1591
  var import_platform10 = require("@effect/platform");
1440
- var import_build_utils = require("@gigadrive/build-utils");
1441
- var import_effect18 = require("effect");
1592
+
1593
+ // ../build-utils/src/get-files-for-pattern.ts
1442
1594
  var import_minimatch = require("minimatch");
1595
+ var import_promises = require("fs/promises");
1596
+ var getFilesForPattern = async (pattern, projectFolder, excludeFiles = []) => {
1597
+ const files = [];
1598
+ const filesInFolder = await (0, import_promises.readdir)(projectFolder, { recursive: true });
1599
+ const exactFiles = new Set(filesInFolder.filter((file) => typeof file === "string"));
1600
+ let regex = null;
1601
+ if (!exactFiles.has(pattern)) {
1602
+ try {
1603
+ regex = new RegExp(`^(?:${pattern})$`);
1604
+ } catch {
1605
+ }
1606
+ }
1607
+ const finalExclusions = Array.isArray(excludeFiles) ? excludeFiles : [excludeFiles];
1608
+ for (const file of filesInFolder) {
1609
+ if (typeof file !== "string") {
1610
+ continue;
1611
+ }
1612
+ if (finalExclusions.some((excludeFile) => {
1613
+ if ((0, import_minimatch.minimatch)(file, excludeFile)) {
1614
+ return true;
1615
+ }
1616
+ if (!exactFiles.has(excludeFile)) {
1617
+ try {
1618
+ return new RegExp(`^(?:${excludeFile})$`).test(file);
1619
+ } catch {
1620
+ return false;
1621
+ }
1622
+ }
1623
+ return false;
1624
+ })) {
1625
+ continue;
1626
+ }
1627
+ if ((0, import_minimatch.minimatch)(file, pattern) || regex != null && regex.test(file)) {
1628
+ files.push(file);
1629
+ }
1630
+ }
1631
+ return files;
1632
+ };
1633
+
1634
+ // src/services/v4-config-parser.ts
1635
+ var import_effect19 = require("effect");
1636
+ var import_minimatch2 = require("minimatch");
1443
1637
  var import_safe_regex2 = __toESM(require("safe-regex2"));
1444
1638
  var MAX_ASSET_DEPTH = 100;
1445
1639
  var DISALLOWED_ASSET_EXTENSIONS = [".htaccess", ".htpasswd"];
@@ -1504,7 +1698,7 @@ var destinationMatchesEntrypoint = (destination, entrypointPath) => {
1504
1698
  return new RegExp(`^${pattern}$`).test(entrypointPath);
1505
1699
  };
1506
1700
  var matchesPattern = (path2, pattern) => {
1507
- if ((0, import_minimatch.minimatch)(path2, pattern)) return true;
1701
+ if ((0, import_minimatch2.minimatch)(path2, pattern)) return true;
1508
1702
  try {
1509
1703
  if ((0, import_safe_regex2.default)(pattern)) {
1510
1704
  return new RegExp(pattern).test(path2);
@@ -1544,7 +1738,7 @@ var mapRoute = (route, entrypoints) => ({
1544
1738
  negativeRequirements: route.missing,
1545
1739
  status: route.statusCode
1546
1740
  });
1547
- var parseEntrypoints = import_effect18.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
1741
+ var parseEntrypoints = import_effect19.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
1548
1742
  const entrypoints = [];
1549
1743
  if (config.functions == null) return entrypoints;
1550
1744
  for (const [fnPath, func] of Object.entries(config.functions)) {
@@ -1554,8 +1748,8 @@ var parseEntrypoints = import_effect18.Effect.fn("parseEntrypoints")(function* (
1554
1748
  functionPath: fnPath
1555
1749
  });
1556
1750
  }
1557
- const matchedFiles = yield* import_effect18.Effect.tryPromise({
1558
- try: () => (0, import_build_utils.getFilesForPattern)(fnPath, projectFolder, func.excludeFiles),
1751
+ const matchedFiles = yield* import_effect19.Effect.tryPromise({
1752
+ try: () => getFilesForPattern(fnPath, projectFolder, func.excludeFiles),
1559
1753
  catch: (error) => new FunctionConfigError({
1560
1754
  message: `Failed to resolve files for function pattern '${fnPath}': ${error instanceof Error ? error.message : String(error)}`,
1561
1755
  functionPath: fnPath
@@ -1590,14 +1784,14 @@ var parseEntrypoints = import_effect18.Effect.fn("parseEntrypoints")(function* (
1590
1784
  }
1591
1785
  return entrypoints;
1592
1786
  });
1593
- var collectAssets = import_effect18.Effect.fn("collectAssets")(function* (config, projectFolder) {
1787
+ var collectAssets = import_effect19.Effect.fn("collectAssets")(function* (config, projectFolder) {
1594
1788
  if (config.assets == null) return [];
1595
1789
  const fs = yield* import_platform10.FileSystem.FileSystem;
1596
1790
  const pathService = yield* import_platform10.Path.Path;
1597
1791
  const assetsPath = pathService.join(projectFolder, config.assets);
1598
- const assetsExist = yield* fs.exists(assetsPath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed(false)));
1792
+ const assetsExist = yield* fs.exists(assetsPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(false)));
1599
1793
  if (!assetsExist) return [];
1600
- const stat = yield* fs.stat(assetsPath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed(null)));
1794
+ const stat = yield* fs.stat(assetsPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(null)));
1601
1795
  if (!stat || stat.type !== "Directory") return [];
1602
1796
  const allFiles = yield* collectFilesRecursively(assetsPath);
1603
1797
  const assets = [];
@@ -1608,18 +1802,18 @@ var collectAssets = import_effect18.Effect.fn("collectAssets")(function* (config
1608
1802
  }
1609
1803
  return assets;
1610
1804
  });
1611
- var collectFilesRecursively = import_effect18.Effect.fn("collectFilesRecursively")(
1805
+ var collectFilesRecursively = import_effect19.Effect.fn("collectFilesRecursively")(
1612
1806
  function* (basePath, relativePath = "", depth = 0) {
1613
1807
  if (depth > MAX_ASSET_DEPTH) return [];
1614
1808
  const fs = yield* import_platform10.FileSystem.FileSystem;
1615
1809
  const pathSvc = yield* import_platform10.Path.Path;
1616
1810
  const currentPath = relativePath ? pathSvc.join(basePath, relativePath) : basePath;
1617
- const entries = yield* fs.readDirectory(currentPath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed([])));
1811
+ const entries = yield* fs.readDirectory(currentPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed([])));
1618
1812
  const result = [];
1619
1813
  for (const name of entries) {
1620
1814
  const fullPath = pathSvc.join(currentPath, name);
1621
1815
  const entryRelative = relativePath ? pathSvc.join(relativePath, name) : name;
1622
- const stat = yield* fs.stat(fullPath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed(null)));
1816
+ const stat = yield* fs.stat(fullPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(null)));
1623
1817
  if (!stat) continue;
1624
1818
  if (stat.type === "Directory") {
1625
1819
  const nested = yield* collectFilesRecursively(basePath, entryRelative, depth + 1);
@@ -1631,16 +1825,16 @@ var collectFilesRecursively = import_effect18.Effect.fn("collectFilesRecursively
1631
1825
  return result;
1632
1826
  }
1633
1827
  );
1634
- var V4ConfigParser = class extends import_effect18.Effect.Service()("V4ConfigParser", {
1828
+ var V4ConfigParser = class extends import_effect19.Effect.Service()("V4ConfigParser", {
1635
1829
  accessors: true,
1636
- effect: import_effect18.Effect.succeed({
1830
+ effect: import_effect19.Effect.succeed({
1637
1831
  /**
1638
1832
  * Parses a ConfigV4 into a NormalizedConfig.
1639
1833
  *
1640
1834
  * @param config - The raw V4 config object
1641
1835
  * @param projectFolder - Absolute path to the project root
1642
1836
  */
1643
- parse: import_effect18.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1837
+ parse: import_effect19.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1644
1838
  const entrypoints = yield* parseEntrypoints(config, projectFolder);
1645
1839
  const assets = yield* collectAssets(config, projectFolder);
1646
1840
  return {
@@ -1667,9 +1861,35 @@ var V4ConfigParser = class extends import_effect18.Effect.Service()("V4ConfigPar
1667
1861
 
1668
1862
  // src/services/vercel-build-output-parser.ts
1669
1863
  var import_platform11 = require("@effect/platform");
1670
- var import_build_utils2 = require("@gigadrive/build-utils");
1671
- var import_commons = require("@gigadrive/commons");
1672
- var import_effect19 = require("effect");
1864
+
1865
+ // ../commons/src/deep-merge.ts
1866
+ var deepMerge = (target, ...partials) => {
1867
+ const isObject = (item) => item !== null && typeof item === "object";
1868
+ if (!isObject(target)) {
1869
+ return target;
1870
+ }
1871
+ for (const partial of partials) {
1872
+ if (!isObject(partial)) {
1873
+ continue;
1874
+ }
1875
+ Object.keys(partial).forEach((key) => {
1876
+ if (key === "__proto__" || key === "constructor") return;
1877
+ const targetValue = target[key];
1878
+ const sourceValue = partial[key];
1879
+ if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
1880
+ targetValue.push(...sourceValue);
1881
+ } else if (isObject(targetValue) && isObject(sourceValue)) {
1882
+ deepMerge(targetValue, sourceValue);
1883
+ } else {
1884
+ target[key] = sourceValue;
1885
+ }
1886
+ });
1887
+ }
1888
+ return target;
1889
+ };
1890
+
1891
+ // src/services/vercel-build-output-parser.ts
1892
+ var import_effect20 = require("effect");
1673
1893
 
1674
1894
  // src/build-output-v3/determine-repo-root.ts
1675
1895
  var import_path = __toESM(require("path"));
@@ -1765,11 +1985,11 @@ var translateVercelRuntime = (runtime) => {
1765
1985
  var CONFIG_PATH = ".vercel/output/config.json";
1766
1986
  var FUNCTIONS_FOLDER = ".vercel/output/functions";
1767
1987
  var FUNCTION_CONFIGS_PATTERN = `${FUNCTIONS_FOLDER}/**/*.func/.vc-config.json`;
1768
- var VercelBuildOutputParser = class extends import_effect19.Effect.Service()("VercelBuildOutputParser", {
1769
- effect: import_effect19.Effect.gen(function* () {
1988
+ var VercelBuildOutputParser = class extends import_effect20.Effect.Service()("VercelBuildOutputParser", {
1989
+ effect: import_effect20.Effect.gen(function* () {
1770
1990
  const rawConfigReader = yield* RawConfigReader;
1771
1991
  const pathService = yield* import_platform11.Path.Path;
1772
- const parse = import_effect19.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1992
+ const parse = import_effect20.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1773
1993
  const config = yield* rawConfigReader.readConfigFile(pathService.join(projectFolder, CONFIG_PATH));
1774
1994
  if (!config || typeof config.version !== "number" || config.version < 3) {
1775
1995
  return parseResult;
@@ -1777,13 +1997,13 @@ var VercelBuildOutputParser = class extends import_effect19.Effect.Service()("Ve
1777
1997
  const functionData = yield* loadFunctions(config, parseResult, projectFolder);
1778
1998
  const assetOverrides = loadAssetOverrides(config, parseResult);
1779
1999
  const imagePolicy = loadImagePolicy(config);
1780
- const merged = (0, import_commons.deepMerge)(parseResult, functionData, assetOverrides, imagePolicy);
2000
+ const merged = deepMerge(parseResult, functionData, assetOverrides, imagePolicy);
1781
2001
  merged.regions = [...new Set(merged.regions)];
1782
2002
  return merged;
1783
2003
  });
1784
- const loadFunctions = import_effect19.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1785
- const functionConfigs = yield* import_effect19.Effect.tryPromise({
1786
- try: () => (0, import_build_utils2.getFilesForPattern)(FUNCTION_CONFIGS_PATTERN, projectFolder),
2004
+ const loadFunctions = import_effect20.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
2005
+ const functionConfigs = yield* import_effect20.Effect.tryPromise({
2006
+ try: () => getFilesForPattern(FUNCTION_CONFIGS_PATTERN, projectFolder),
1787
2007
  catch: (error) => new ConfigFileParseError({
1788
2008
  message: `Failed to scan for function configs: ${error instanceof Error ? error.message : String(error)}`,
1789
2009
  filePath: projectFolder
@@ -2381,7 +2601,7 @@ var schema_default = {
2381
2601
  };
2382
2602
 
2383
2603
  // src/parse-config.ts
2384
- var parseConfigRaw = import_effect20.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2604
+ var parseConfigRaw = import_effect21.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2385
2605
  const rawReader = yield* RawConfigReader;
2386
2606
  const validator = yield* SchemaValidator;
2387
2607
  const v4Parser = yield* V4ConfigParser;
@@ -2392,7 +2612,7 @@ var parseConfigRaw = import_effect20.Effect.fn("parseConfigRaw")(function* (file
2392
2612
  };
2393
2613
  const schema = schemaMap[version];
2394
2614
  if (!schema) {
2395
- return yield* import_effect20.Effect.fail(
2615
+ return yield* import_effect21.Effect.fail(
2396
2616
  new ConfigVersionError({
2397
2617
  message: `Config file at ${filePath} has an unsupported version: ${version}`,
2398
2618
  filePath,
@@ -2403,11 +2623,11 @@ var parseConfigRaw = import_effect20.Effect.fn("parseConfigRaw")(function* (file
2403
2623
  yield* validator.validate(parsed, schema, filePath);
2404
2624
  return yield* v4Parser.parse(parsed, projectFolder);
2405
2625
  });
2406
- var parseConfig = import_effect20.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
2626
+ var parseConfig = import_effect21.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
2407
2627
  const parseResult = yield* parseConfigRaw(filePath, projectFolder);
2408
2628
  return yield* postProcessConfig(parseResult, projectFolder);
2409
2629
  });
2410
- var postProcessConfig = import_effect20.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
2630
+ var postProcessConfig = import_effect21.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
2411
2631
  const vercelParser = yield* VercelBuildOutputParser;
2412
2632
  let result = yield* vercelParser.parse(config, projectFolder);
2413
2633
  const hasAssets = (result.assets?.paths?.length ?? 0) > 0 || (result.assets?.prefixes?.length ?? 0) > 0 || (result.assets?.manifests?.length ?? 0) > 0;
@@ -2436,9 +2656,14 @@ var RUNTIME_DEFINITIONS = [
2436
2656
  var AVAILABLE_RUNTIMES = [...RUNTIME_DEFINITIONS];
2437
2657
 
2438
2658
  // src/services/index.ts
2439
- var import_effect21 = require("effect");
2440
- var BaseLayers = import_effect21.Layer.mergeAll(RawConfigReader.Default, SchemaValidator.Default, V4ConfigParser.Default);
2441
- var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect21.Layer.provideMerge(BaseLayers));
2659
+ var import_effect22 = require("effect");
2660
+ var BaseLayers = import_effect22.Layer.mergeAll(
2661
+ ConfigModuleLoader.Default,
2662
+ RawConfigReader.Default,
2663
+ SchemaValidator.Default,
2664
+ V4ConfigParser.Default
2665
+ );
2666
+ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect22.Layer.provideMerge(BaseLayers));
2442
2667
  // Annotate the CommonJS export names for ESM import in node:
2443
2668
  0 && (module.exports = {
2444
2669
  ALLOWED_CONFIG_NAMES,
@@ -2447,6 +2672,8 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect21.Lay
2447
2672
  ConfigFileEmptyError,
2448
2673
  ConfigFileNotFoundError,
2449
2674
  ConfigFileParseError,
2675
+ ConfigModuleLoadError,
2676
+ ConfigModuleLoader,
2450
2677
  ConfigSchemaValidationError,
2451
2678
  ConfigVersionError,
2452
2679
  DEFAULT_FUNCTION_DURATION_SECONDS,
@@ -2457,8 +2684,12 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect21.Lay
2457
2684
  GigadriveNextBuildManifestV1Schema,
2458
2685
  GigadriveNextBuildManifestV2ExportSchema,
2459
2686
  GigadriveNextBuildManifestV2StandaloneSchema,
2687
+ GigadriveNextMiddlewareDescriptorSchema,
2688
+ GigadriveNextMiddlewareMatcherSchema,
2460
2689
  GigadriveNextPrerenderManifestV1Schema,
2461
2690
  GigadriveNextPrerenderOutputSchema,
2691
+ GigadriveNextPrerenderSeedMethodsSchema,
2692
+ GigadriveNextRouteConditionSchema,
2462
2693
  GigadriveNextServerDescriptorSchema,
2463
2694
  GigadriveNextStaticAssetPrefixSchema,
2464
2695
  MAX_FUNCTION_DURATION_SECONDS,
@@ -2473,6 +2704,7 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect21.Lay
2473
2704
  StaticAssetManifestV1Schema,
2474
2705
  V4ConfigParser,
2475
2706
  VercelBuildOutputParser,
2707
+ defineConfig,
2476
2708
  detectFramework,
2477
2709
  detectPackageManager,
2478
2710
  filterFunctionsFromAssets,