@gigadrive/network-config 4.5.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,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,
@@ -62,6 +64,7 @@ __export(src_exports, {
62
64
  StaticAssetManifestV1Schema: () => StaticAssetManifestV1Schema,
63
65
  V4ConfigParser: () => V4ConfigParser,
64
66
  VercelBuildOutputParser: () => VercelBuildOutputParser,
67
+ defineConfig: () => defineConfig,
65
68
  detectFramework: () => detectFramework,
66
69
  detectPackageManager: () => detectPackageManager,
67
70
  filterFunctionsFromAssets: () => filterFunctionsFromAssets,
@@ -135,6 +138,9 @@ var StaticAssetManifestV1Schema = import_effect2.Schema.mutable(
135
138
  ).pipe(import_effect2.Schema.filter(({ assets }) => new Set(assets.map(({ path: path2 }) => path2)).size === assets.length));
136
139
  var parseStaticAssetManifest = (content) => decodeJson(StaticAssetManifestV1Schema, content);
137
140
 
141
+ // src/define-config.ts
142
+ var defineConfig = (config) => config;
143
+
138
144
  // src/detection/detect-framework.ts
139
145
  var import_platform8 = require("@effect/platform");
140
146
  var import_effect13 = require("effect");
@@ -1286,6 +1292,12 @@ var ConfigFileParseError = class extends import_effect15.Schema.TaggedError()("C
1286
1292
  cause: import_effect15.Schema.optional(import_effect15.Schema.String)
1287
1293
  }) {
1288
1294
  };
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)
1299
+ }) {
1300
+ };
1289
1301
  var ConfigVersionError = class extends import_effect15.Schema.TaggedError()("ConfigVersionError", {
1290
1302
  message: import_effect15.Schema.String,
1291
1303
  filePath: import_effect15.Schema.String,
@@ -1323,85 +1335,157 @@ var DEFAULT_FUNCTION_DURATION_SECONDS = 30;
1323
1335
  var MAX_FUNCTION_DURATION_SECONDS = 28800;
1324
1336
 
1325
1337
  // src/parse-config.ts
1326
- var import_effect20 = require("effect");
1338
+ var import_effect21 = require("effect");
1327
1339
 
1328
1340
  // src/services/raw-config-reader.ts
1329
1341
  var import_platform9 = require("@effect/platform");
1330
- var import_effect16 = require("effect");
1342
+ var import_effect17 = require("effect");
1331
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
1332
1404
  var ALLOWED_CONFIG_NAMES = [
1405
+ "gigadrive.ts",
1406
+ "gigadrive.mts",
1407
+ "gigadrive.cts",
1408
+ "gigadrive.js",
1409
+ "gigadrive.mjs",
1410
+ "gigadrive.cjs",
1333
1411
  "gigadrive.yaml",
1334
1412
  "gigadrive.yml",
1413
+ "gigadrive.json",
1335
1414
  "nebula.yaml",
1336
1415
  "nebula.yml",
1337
1416
  "nebula.json"
1338
1417
  ];
1339
- var RawConfigReader = class extends import_effect16.Effect.Service()("RawConfigReader", {
1340
- effect: import_effect16.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* () {
1341
1422
  const fs = yield* import_platform9.FileSystem.FileSystem;
1342
1423
  const pathService = yield* import_platform9.Path.Path;
1343
- const findConfig = import_effect16.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1424
+ const moduleLoader = yield* ConfigModuleLoader;
1425
+ const findConfig = import_effect17.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1344
1426
  for (const name of ALLOWED_CONFIG_NAMES) {
1345
1427
  const filePath = pathService.join(projectFolder, name);
1346
- const exists = yield* fs.exists(filePath).pipe(import_effect16.Effect.catchAll(() => import_effect16.Effect.succeed(false)));
1428
+ const exists = yield* fs.exists(filePath).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(false)));
1347
1429
  if (exists) {
1348
1430
  return filePath;
1349
1431
  }
1350
1432
  }
1351
1433
  return null;
1352
1434
  });
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)));
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)));
1355
1437
  if (!exists) {
1356
- return yield* import_effect16.Effect.fail(
1438
+ return yield* import_effect17.Effect.fail(
1357
1439
  new ConfigFileNotFoundError({ message: `Config file not found at ${filePath}`, filePath })
1358
1440
  );
1359
1441
  }
1360
1442
  const fileContents = yield* fs.readFileString(filePath).pipe(
1361
- import_effect16.Effect.mapError(
1443
+ import_effect17.Effect.mapError(
1362
1444
  () => new ConfigFileParseError({ message: `Failed to read config file at ${filePath}`, filePath })
1363
1445
  )
1364
1446
  );
1365
1447
  if (fileContents.length === 0) {
1366
- return yield* import_effect16.Effect.fail(
1448
+ return yield* import_effect17.Effect.fail(
1367
1449
  new ConfigFileEmptyError({ message: `Config file is empty at ${filePath}`, filePath })
1368
1450
  );
1369
1451
  }
1370
1452
  const fileExtension = pathService.extname(filePath).toLowerCase();
1371
1453
  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);
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
+ );
1379
1471
  }
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
1472
  }
1389
1473
  if (parsed == null) {
1390
- return yield* import_effect16.Effect.fail(
1474
+ return yield* import_effect17.Effect.fail(
1391
1475
  new ConfigFileParseError({ message: `Config file could not be parsed at ${filePath}`, filePath })
1392
1476
  );
1393
1477
  }
1394
1478
  if (!options?.disableVersionCheck && typeof parsed.version !== "number") {
1395
- return yield* import_effect16.Effect.fail(
1479
+ return yield* import_effect17.Effect.fail(
1396
1480
  new ConfigVersionError({ message: `Config file is missing version at ${filePath}`, filePath })
1397
1481
  );
1398
1482
  }
1399
1483
  return parsed;
1400
1484
  });
1401
1485
  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")
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")
1405
1489
  );
1406
1490
  return { findConfig, readRawConfig, readConfigFile };
1407
1491
  })
@@ -1411,17 +1495,17 @@ var RawConfigReader = class extends import_effect16.Effect.Service()("RawConfigR
1411
1495
  // src/services/schema-validator.ts
1412
1496
  var import_ajv = __toESM(require("ajv"));
1413
1497
  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* () {
1498
+ var import_effect18 = require("effect");
1499
+ var SchemaValidator = class extends import_effect18.Effect.Service()("SchemaValidator", {
1500
+ effect: import_effect18.Effect.gen(function* () {
1417
1501
  const ajv = new import_ajv.default();
1418
1502
  (0, import_ajv_formats.default)(ajv);
1419
- const validate = import_effect17.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1503
+ const validate = import_effect18.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1420
1504
  const compiledValidate = ajv.compile(schema);
1421
1505
  const valid = compiledValidate(config);
1422
1506
  if (!valid) {
1423
1507
  const errors = compiledValidate.errors?.map((e) => `${e.instancePath || "/"} ${e.message ?? ""}`.trim()) ?? [];
1424
- return yield* import_effect17.Effect.fail(
1508
+ return yield* import_effect18.Effect.fail(
1425
1509
  new ConfigSchemaValidationError({
1426
1510
  message: `Config file at ${filePath} is invalid: ${ajv.errorsText(compiledValidate.errors)}`,
1427
1511
  filePath,
@@ -1438,7 +1522,7 @@ var SchemaValidator = class extends import_effect17.Effect.Service()("SchemaVali
1438
1522
  // src/services/v4-config-parser.ts
1439
1523
  var import_platform10 = require("@effect/platform");
1440
1524
  var import_build_utils = require("@gigadrive/build-utils");
1441
- var import_effect18 = require("effect");
1525
+ var import_effect19 = require("effect");
1442
1526
  var import_minimatch = require("minimatch");
1443
1527
  var import_safe_regex2 = __toESM(require("safe-regex2"));
1444
1528
  var MAX_ASSET_DEPTH = 100;
@@ -1544,7 +1628,7 @@ var mapRoute = (route, entrypoints) => ({
1544
1628
  negativeRequirements: route.missing,
1545
1629
  status: route.statusCode
1546
1630
  });
1547
- var parseEntrypoints = import_effect18.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
1631
+ var parseEntrypoints = import_effect19.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
1548
1632
  const entrypoints = [];
1549
1633
  if (config.functions == null) return entrypoints;
1550
1634
  for (const [fnPath, func] of Object.entries(config.functions)) {
@@ -1554,7 +1638,7 @@ var parseEntrypoints = import_effect18.Effect.fn("parseEntrypoints")(function* (
1554
1638
  functionPath: fnPath
1555
1639
  });
1556
1640
  }
1557
- const matchedFiles = yield* import_effect18.Effect.tryPromise({
1641
+ const matchedFiles = yield* import_effect19.Effect.tryPromise({
1558
1642
  try: () => (0, import_build_utils.getFilesForPattern)(fnPath, projectFolder, func.excludeFiles),
1559
1643
  catch: (error) => new FunctionConfigError({
1560
1644
  message: `Failed to resolve files for function pattern '${fnPath}': ${error instanceof Error ? error.message : String(error)}`,
@@ -1590,14 +1674,14 @@ var parseEntrypoints = import_effect18.Effect.fn("parseEntrypoints")(function* (
1590
1674
  }
1591
1675
  return entrypoints;
1592
1676
  });
1593
- var collectAssets = import_effect18.Effect.fn("collectAssets")(function* (config, projectFolder) {
1677
+ var collectAssets = import_effect19.Effect.fn("collectAssets")(function* (config, projectFolder) {
1594
1678
  if (config.assets == null) return [];
1595
1679
  const fs = yield* import_platform10.FileSystem.FileSystem;
1596
1680
  const pathService = yield* import_platform10.Path.Path;
1597
1681
  const assetsPath = pathService.join(projectFolder, config.assets);
1598
- const assetsExist = yield* fs.exists(assetsPath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed(false)));
1682
+ const assetsExist = yield* fs.exists(assetsPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(false)));
1599
1683
  if (!assetsExist) return [];
1600
- const stat = yield* fs.stat(assetsPath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed(null)));
1684
+ const stat = yield* fs.stat(assetsPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(null)));
1601
1685
  if (!stat || stat.type !== "Directory") return [];
1602
1686
  const allFiles = yield* collectFilesRecursively(assetsPath);
1603
1687
  const assets = [];
@@ -1608,18 +1692,18 @@ var collectAssets = import_effect18.Effect.fn("collectAssets")(function* (config
1608
1692
  }
1609
1693
  return assets;
1610
1694
  });
1611
- var collectFilesRecursively = import_effect18.Effect.fn("collectFilesRecursively")(
1695
+ var collectFilesRecursively = import_effect19.Effect.fn("collectFilesRecursively")(
1612
1696
  function* (basePath, relativePath = "", depth = 0) {
1613
1697
  if (depth > MAX_ASSET_DEPTH) return [];
1614
1698
  const fs = yield* import_platform10.FileSystem.FileSystem;
1615
1699
  const pathSvc = yield* import_platform10.Path.Path;
1616
1700
  const currentPath = relativePath ? pathSvc.join(basePath, relativePath) : basePath;
1617
- const entries = yield* fs.readDirectory(currentPath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed([])));
1701
+ const entries = yield* fs.readDirectory(currentPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed([])));
1618
1702
  const result = [];
1619
1703
  for (const name of entries) {
1620
1704
  const fullPath = pathSvc.join(currentPath, name);
1621
1705
  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)));
1706
+ const stat = yield* fs.stat(fullPath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(null)));
1623
1707
  if (!stat) continue;
1624
1708
  if (stat.type === "Directory") {
1625
1709
  const nested = yield* collectFilesRecursively(basePath, entryRelative, depth + 1);
@@ -1631,16 +1715,16 @@ var collectFilesRecursively = import_effect18.Effect.fn("collectFilesRecursively
1631
1715
  return result;
1632
1716
  }
1633
1717
  );
1634
- var V4ConfigParser = class extends import_effect18.Effect.Service()("V4ConfigParser", {
1718
+ var V4ConfigParser = class extends import_effect19.Effect.Service()("V4ConfigParser", {
1635
1719
  accessors: true,
1636
- effect: import_effect18.Effect.succeed({
1720
+ effect: import_effect19.Effect.succeed({
1637
1721
  /**
1638
1722
  * Parses a ConfigV4 into a NormalizedConfig.
1639
1723
  *
1640
1724
  * @param config - The raw V4 config object
1641
1725
  * @param projectFolder - Absolute path to the project root
1642
1726
  */
1643
- parse: import_effect18.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1727
+ parse: import_effect19.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1644
1728
  const entrypoints = yield* parseEntrypoints(config, projectFolder);
1645
1729
  const assets = yield* collectAssets(config, projectFolder);
1646
1730
  return {
@@ -1669,7 +1753,7 @@ var V4ConfigParser = class extends import_effect18.Effect.Service()("V4ConfigPar
1669
1753
  var import_platform11 = require("@effect/platform");
1670
1754
  var import_build_utils2 = require("@gigadrive/build-utils");
1671
1755
  var import_commons = require("@gigadrive/commons");
1672
- var import_effect19 = require("effect");
1756
+ var import_effect20 = require("effect");
1673
1757
 
1674
1758
  // src/build-output-v3/determine-repo-root.ts
1675
1759
  var import_path = __toESM(require("path"));
@@ -1765,11 +1849,11 @@ var translateVercelRuntime = (runtime) => {
1765
1849
  var CONFIG_PATH = ".vercel/output/config.json";
1766
1850
  var FUNCTIONS_FOLDER = ".vercel/output/functions";
1767
1851
  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* () {
1852
+ var VercelBuildOutputParser = class extends import_effect20.Effect.Service()("VercelBuildOutputParser", {
1853
+ effect: import_effect20.Effect.gen(function* () {
1770
1854
  const rawConfigReader = yield* RawConfigReader;
1771
1855
  const pathService = yield* import_platform11.Path.Path;
1772
- const parse = import_effect19.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1856
+ const parse = import_effect20.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1773
1857
  const config = yield* rawConfigReader.readConfigFile(pathService.join(projectFolder, CONFIG_PATH));
1774
1858
  if (!config || typeof config.version !== "number" || config.version < 3) {
1775
1859
  return parseResult;
@@ -1781,8 +1865,8 @@ var VercelBuildOutputParser = class extends import_effect19.Effect.Service()("Ve
1781
1865
  merged.regions = [...new Set(merged.regions)];
1782
1866
  return merged;
1783
1867
  });
1784
- const loadFunctions = import_effect19.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1785
- const functionConfigs = yield* import_effect19.Effect.tryPromise({
1868
+ const loadFunctions = import_effect20.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1869
+ const functionConfigs = yield* import_effect20.Effect.tryPromise({
1786
1870
  try: () => (0, import_build_utils2.getFilesForPattern)(FUNCTION_CONFIGS_PATTERN, projectFolder),
1787
1871
  catch: (error) => new ConfigFileParseError({
1788
1872
  message: `Failed to scan for function configs: ${error instanceof Error ? error.message : String(error)}`,
@@ -2381,7 +2465,7 @@ var schema_default = {
2381
2465
  };
2382
2466
 
2383
2467
  // src/parse-config.ts
2384
- var parseConfigRaw = import_effect20.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2468
+ var parseConfigRaw = import_effect21.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2385
2469
  const rawReader = yield* RawConfigReader;
2386
2470
  const validator = yield* SchemaValidator;
2387
2471
  const v4Parser = yield* V4ConfigParser;
@@ -2392,7 +2476,7 @@ var parseConfigRaw = import_effect20.Effect.fn("parseConfigRaw")(function* (file
2392
2476
  };
2393
2477
  const schema = schemaMap[version];
2394
2478
  if (!schema) {
2395
- return yield* import_effect20.Effect.fail(
2479
+ return yield* import_effect21.Effect.fail(
2396
2480
  new ConfigVersionError({
2397
2481
  message: `Config file at ${filePath} has an unsupported version: ${version}`,
2398
2482
  filePath,
@@ -2403,11 +2487,11 @@ var parseConfigRaw = import_effect20.Effect.fn("parseConfigRaw")(function* (file
2403
2487
  yield* validator.validate(parsed, schema, filePath);
2404
2488
  return yield* v4Parser.parse(parsed, projectFolder);
2405
2489
  });
2406
- var parseConfig = import_effect20.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
2490
+ var parseConfig = import_effect21.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
2407
2491
  const parseResult = yield* parseConfigRaw(filePath, projectFolder);
2408
2492
  return yield* postProcessConfig(parseResult, projectFolder);
2409
2493
  });
2410
- var postProcessConfig = import_effect20.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
2494
+ var postProcessConfig = import_effect21.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
2411
2495
  const vercelParser = yield* VercelBuildOutputParser;
2412
2496
  let result = yield* vercelParser.parse(config, projectFolder);
2413
2497
  const hasAssets = (result.assets?.paths?.length ?? 0) > 0 || (result.assets?.prefixes?.length ?? 0) > 0 || (result.assets?.manifests?.length ?? 0) > 0;
@@ -2436,9 +2520,14 @@ var RUNTIME_DEFINITIONS = [
2436
2520
  var AVAILABLE_RUNTIMES = [...RUNTIME_DEFINITIONS];
2437
2521
 
2438
2522
  // 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));
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));
2442
2531
  // Annotate the CommonJS export names for ESM import in node:
2443
2532
  0 && (module.exports = {
2444
2533
  ALLOWED_CONFIG_NAMES,
@@ -2447,6 +2536,8 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect21.Lay
2447
2536
  ConfigFileEmptyError,
2448
2537
  ConfigFileNotFoundError,
2449
2538
  ConfigFileParseError,
2539
+ ConfigModuleLoadError,
2540
+ ConfigModuleLoader,
2450
2541
  ConfigSchemaValidationError,
2451
2542
  ConfigVersionError,
2452
2543
  DEFAULT_FUNCTION_DURATION_SECONDS,
@@ -2473,6 +2564,7 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect21.Lay
2473
2564
  StaticAssetManifestV1Schema,
2474
2565
  V4ConfigParser,
2475
2566
  VercelBuildOutputParser,
2567
+ defineConfig,
2476
2568
  detectFramework,
2477
2569
  detectPackageManager,
2478
2570
  filterFunctionsFromAssets,