@gigadrive/network-config 4.6.1 → 5.0.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.mjs CHANGED
@@ -55,16 +55,54 @@ var StaticAssetManifestV1Schema = Schema2.mutable(
55
55
  ).pipe(Schema2.filter(({ assets }) => new Set(assets.map(({ path: path2 }) => path2)).size === assets.length));
56
56
  var parseStaticAssetManifest = (content) => decodeJson(StaticAssetManifestV1Schema, content);
57
57
 
58
+ // src/collect-asset-files.ts
59
+ import { FileSystem, Path } from "@effect/platform";
60
+ import { Effect } from "effect";
61
+ var MAX_ASSET_DEPTH = 100;
62
+ var DISALLOWED_ASSET_EXTENSIONS = [".htaccess", ".htpasswd"];
63
+ var collectFilesRecursively = Effect.fn("collectFilesRecursively")(
64
+ function* (basePath, relativePath = "", depth = 0) {
65
+ if (depth > MAX_ASSET_DEPTH) return [];
66
+ const fs = yield* FileSystem.FileSystem;
67
+ const pathSvc = yield* Path.Path;
68
+ const currentPath = relativePath ? pathSvc.join(basePath, relativePath) : basePath;
69
+ const entries = yield* fs.readDirectory(currentPath).pipe(Effect.catchAll(() => Effect.succeed([])));
70
+ const result = [];
71
+ for (const name of entries) {
72
+ const fullPath = pathSvc.join(currentPath, name);
73
+ const entryRelative = relativePath ? pathSvc.join(relativePath, name) : name;
74
+ const stat = yield* fs.stat(fullPath).pipe(Effect.catchAll(() => Effect.succeed(null)));
75
+ if (!stat) continue;
76
+ if (stat.type === "Directory") {
77
+ const nested = yield* collectFilesRecursively(basePath, entryRelative, depth + 1);
78
+ result.push(...nested);
79
+ } else {
80
+ result.push(entryRelative);
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+ );
86
+ var collectAssetFiles = Effect.fn("collectAssetFiles")(function* (projectFolder, assetsDir) {
87
+ const fs = yield* FileSystem.FileSystem;
88
+ const pathService = yield* Path.Path;
89
+ const assetsPath = pathService.join(projectFolder, assetsDir);
90
+ const stat = yield* fs.stat(assetsPath).pipe(Effect.catchAll(() => Effect.succeed(null)));
91
+ if (!stat || stat.type !== "Directory") return [];
92
+ const files = yield* collectFilesRecursively(assetsPath);
93
+ return files.map((file) => file.replaceAll("\\", "/")).filter((file) => !DISALLOWED_ASSET_EXTENSIONS.some((extension) => file.toLowerCase().endsWith(extension))).sort();
94
+ });
95
+
58
96
  // src/define-config.ts
59
97
  var defineConfig = (config) => config;
60
98
 
61
99
  // src/detection/detect-framework.ts
62
- import { FileSystem as FileSystem8, Path as Path6 } from "@effect/platform";
63
- import { Effect as Effect10 } from "effect";
100
+ import { FileSystem as FileSystem9, Path as Path7 } from "@effect/platform";
101
+ import { Effect as Effect11 } from "effect";
64
102
 
65
103
  // src/detection/detect-package-manager.ts
66
- import { FileSystem, Path } from "@effect/platform";
67
- import { Effect } from "effect";
104
+ import { FileSystem as FileSystem2, Path as Path2 } from "@effect/platform";
105
+ import { Effect as Effect2 } from "effect";
68
106
  var LOCKFILE_MAP = [
69
107
  { files: ["bun.lockb", "bun.lock"], pm: "bun" },
70
108
  { files: ["pnpm-lock.yaml"], pm: "pnpm" },
@@ -72,19 +110,19 @@ var LOCKFILE_MAP = [
72
110
  { files: ["package-lock.json"], pm: "npm" },
73
111
  { files: ["composer.lock"], pm: "composer" }
74
112
  ];
75
- var detectPackageManager = Effect.fn("detectPackageManager")(function* (projectFolder) {
76
- const fs = yield* FileSystem.FileSystem;
77
- const pathService = yield* Path.Path;
113
+ var detectPackageManager = Effect2.fn("detectPackageManager")(function* (projectFolder) {
114
+ const fs = yield* FileSystem2.FileSystem;
115
+ const pathService = yield* Path2.Path;
78
116
  for (const { files, pm } of LOCKFILE_MAP) {
79
117
  for (const file of files) {
80
- const exists = yield* fs.exists(pathService.join(projectFolder, file)).pipe(Effect.catchAll(() => Effect.succeed(false)));
118
+ const exists = yield* fs.exists(pathService.join(projectFolder, file)).pipe(Effect2.catchAll(() => Effect2.succeed(false)));
81
119
  if (exists) {
82
- yield* Effect.logDebug(`Detected package manager: ${pm} (via ${file})`);
120
+ yield* Effect2.logDebug(`Detected package manager: ${pm} (via ${file})`);
83
121
  return pm;
84
122
  }
85
123
  }
86
124
  }
87
- yield* Effect.logDebug("No lockfile found, defaulting to npm");
125
+ yield* Effect2.logDebug("No lockfile found, defaulting to npm");
88
126
  return "npm";
89
127
  });
90
128
 
@@ -110,8 +148,8 @@ var astro = {
110
148
  };
111
149
 
112
150
  // src/detection/frameworks/resolve-node-entrypoint.ts
113
- import { FileSystem as FileSystem2, Path as Path2 } from "@effect/platform";
114
- import { Effect as Effect2 } from "effect";
151
+ import { FileSystem as FileSystem3, Path as Path3 } from "@effect/platform";
152
+ import { Effect as Effect3 } from "effect";
115
153
  var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "tsx", "ts-node"]);
116
154
  var COMMON_ENTRYPOINT_CANDIDATES = [
117
155
  "index.js",
@@ -159,14 +197,14 @@ var applyEntrypoint = (defaults, entrypoint) => ({
159
197
  (route) => route.destination === defaults.entrypoint ? { ...route, destination: entrypoint } : route
160
198
  )
161
199
  });
162
- var resolveNodeServerEntrypoint = (defaults, projectFolder) => Effect2.gen(function* () {
163
- const fs = yield* FileSystem2.FileSystem;
164
- const pathService = yield* Path2.Path;
200
+ var resolveNodeServerEntrypoint = (defaults, projectFolder) => Effect3.gen(function* () {
201
+ const fs = yield* FileSystem3.FileSystem;
202
+ const pathService = yield* Path3.Path;
165
203
  const isFile = (relativePath) => fs.stat(pathService.join(projectFolder, relativePath)).pipe(
166
- Effect2.map((info) => info.type === "File"),
167
- Effect2.catchAll(() => Effect2.succeed(false))
204
+ Effect3.map((info) => info.type === "File"),
205
+ Effect3.catchAll(() => Effect3.succeed(false))
168
206
  );
169
- const content = yield* fs.readFileString(pathService.join(projectFolder, "package.json")).pipe(Effect2.catchAll(() => Effect2.succeed(void 0)));
207
+ const content = yield* fs.readFileString(pathService.join(projectFolder, "package.json")).pipe(Effect3.catchAll(() => Effect3.succeed(void 0)));
170
208
  const manifest = content ? parsePackageJson(content) : void 0;
171
209
  const startScript = typeof manifest?.scripts?.start === "string" ? manifest.scripts.start : void 0;
172
210
  const candidates = [
@@ -298,8 +336,8 @@ var laravel = {
298
336
  };
299
337
 
300
338
  // src/detection/frameworks/nestjs.ts
301
- import { FileSystem as FileSystem3 } from "@effect/platform";
302
- import { Effect as Effect3 } from "effect";
339
+ import { FileSystem as FileSystem4 } from "@effect/platform";
340
+ import { Effect as Effect4 } from "effect";
303
341
  var isRecord2 = (value) => typeof value === "object" && value !== null;
304
342
  var parseNestCliJson = (content) => {
305
343
  try {
@@ -350,9 +388,9 @@ var nestjs = {
350
388
  detectors: [{ matchPackage: "@nestjs/core" }],
351
389
  priority: 90,
352
390
  getDefaultConfig: () => createNestConfig("dist"),
353
- refineDefaultConfig: (defaults, projectFolder) => Effect3.gen(function* () {
354
- const fs = yield* FileSystem3.FileSystem;
355
- const content = yield* fs.readFileString(`${projectFolder}/nest-cli.json`).pipe(Effect3.catchAll(() => Effect3.succeed(void 0)));
391
+ refineDefaultConfig: (defaults, projectFolder) => Effect4.gen(function* () {
392
+ const fs = yield* FileSystem4.FileSystem;
393
+ const content = yield* fs.readFileString(`${projectFolder}/nest-cli.json`).pipe(Effect4.catchAll(() => Effect4.succeed(void 0)));
356
394
  if (!content) return defaults;
357
395
  const nestConfig = parseNestCliJson(content);
358
396
  const outputPath = nestConfig ? getProjectOutputPath(nestConfig) : void 0;
@@ -361,28 +399,28 @@ var nestjs = {
361
399
  };
362
400
 
363
401
  // src/detection/frameworks/nextjs.ts
364
- import { FileSystem as FileSystem5, Path as Path4 } from "@effect/platform";
365
- import { Effect as Effect5 } from "effect";
402
+ import { FileSystem as FileSystem6, Path as Path5 } from "@effect/platform";
403
+ import { Effect as Effect6 } from "effect";
366
404
 
367
405
  // src/build-output-v3/get-default-path-map.ts
368
- import { FileSystem as FileSystem4, Path as Path3 } from "@effect/platform";
369
- import { Effect as Effect4 } from "effect";
370
- var getDefaultPathMap = Effect4.fn("getDefaultPathMap")(function* (directory) {
371
- const fs = yield* FileSystem4.FileSystem;
372
- const pathService = yield* Path3.Path;
406
+ import { FileSystem as FileSystem5, Path as Path4 } from "@effect/platform";
407
+ import { Effect as Effect5 } from "effect";
408
+ var getDefaultPathMap = Effect5.fn("getDefaultPathMap")(function* (directory) {
409
+ const fs = yield* FileSystem5.FileSystem;
410
+ const pathService = yield* Path4.Path;
373
411
  const result = {};
374
- const exists = yield* fs.exists(directory).pipe(Effect4.catchAll(() => Effect4.succeed(false)));
412
+ const exists = yield* fs.exists(directory).pipe(Effect5.catchAll(() => Effect5.succeed(false)));
375
413
  if (!exists) {
376
414
  return result;
377
415
  }
378
416
  const MAX_DEPTH = 100;
379
- const processDirectory = (currentPath, basePath = "", depth = 0) => Effect4.gen(function* () {
417
+ const processDirectory = (currentPath, basePath = "", depth = 0) => Effect5.gen(function* () {
380
418
  if (depth > MAX_DEPTH) return;
381
- const entries = yield* fs.readDirectory(currentPath).pipe(Effect4.catchAll(() => Effect4.succeed([])));
419
+ const entries = yield* fs.readDirectory(currentPath).pipe(Effect5.catchAll(() => Effect5.succeed([])));
382
420
  for (const name of entries) {
383
421
  const fullPath = pathService.join(currentPath, name);
384
422
  const relativePath = basePath ? pathService.join(basePath, name) : name;
385
- const stat = yield* fs.stat(fullPath).pipe(Effect4.catchAll(() => Effect4.succeed(null)));
423
+ const stat = yield* fs.stat(fullPath).pipe(Effect5.catchAll(() => Effect5.succeed(null)));
386
424
  if (!stat) continue;
387
425
  if (stat.type === "Directory") {
388
426
  yield* processDirectory(fullPath, relativePath, depth + 1);
@@ -668,22 +706,22 @@ var AVAILABLE_REGIONS = [...REGION_DEFINITIONS];
668
706
  // src/detection/frameworks/nextjs.ts
669
707
  var toPortablePath = (value) => value.replaceAll("\\", "/");
670
708
  var STANDALONE_SERVER_MEMORY_MB = 1024;
671
- var resolveStandaloneServer = Effect5.fn("nextjs.resolveStandaloneServer")(function* (projectFolder, distDir, repoRootToProject) {
672
- const fs = yield* FileSystem5.FileSystem;
673
- const pathService = yield* Path4.Path;
709
+ var resolveStandaloneServer = Effect6.fn("nextjs.resolveStandaloneServer")(function* (projectFolder, distDir, repoRootToProject) {
710
+ const fs = yield* FileSystem6.FileSystem;
711
+ const pathService = yield* Path5.Path;
674
712
  const standaloneRoot = pathService.join(projectFolder, distDir, "standalone");
675
713
  const monorepoServer = pathService.join(standaloneRoot, repoRootToProject, "server.js");
676
714
  const rootServer = pathService.join(standaloneRoot, "server.js");
677
- const monorepoServerExists = yield* fs.exists(monorepoServer).pipe(Effect5.catchAll(() => Effect5.succeed(false)));
715
+ const monorepoServerExists = yield* fs.exists(monorepoServer).pipe(Effect6.catchAll(() => Effect6.succeed(false)));
678
716
  const serverPath = monorepoServerExists ? monorepoServer : rootServer;
679
- const serverExists = yield* fs.exists(serverPath).pipe(Effect5.catchAll(() => Effect5.succeed(false)));
717
+ const serverExists = yield* fs.exists(serverPath).pipe(Effect6.catchAll(() => Effect6.succeed(false)));
680
718
  if (!serverExists) return void 0;
681
719
  const serverDirectory = pathService.dirname(serverPath);
682
720
  const entrypoint = toPortablePath(pathService.relative(standaloneRoot, serverPath));
683
721
  return { standaloneRoot, serverDirectory, entrypoint };
684
722
  });
685
- var buildStandalonePublicAssets = Effect5.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
686
- const pathService = yield* Path4.Path;
723
+ var buildStandalonePublicAssets = Effect6.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
724
+ const pathService = yield* Path5.Path;
687
725
  const publicFiles = yield* getDefaultPathMap(pathService.join(projectFolder, "public"));
688
726
  const assetPaths = [];
689
727
  const assetOverrides = {};
@@ -699,8 +737,8 @@ var buildStandalonePublicAssets = Effect5.fn("nextjs.buildStandalonePublicAssets
699
737
  }
700
738
  return { assetPaths, assetOverrides, filePathMap };
701
739
  });
702
- var createStaticExportConfig = Effect5.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
703
- const pathService = yield* Path4.Path;
740
+ var createStaticExportConfig = Effect6.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
741
+ const pathService = yield* Path5.Path;
704
742
  const outputDirectory = pathService.join(projectFolder, "out");
705
743
  const files = yield* getDefaultPathMap(outputDirectory);
706
744
  const assetPaths = [];
@@ -723,8 +761,8 @@ var createStaticExportConfig = Effect5.fn("nextjs.createStaticExportConfig")(fun
723
761
  package: void 0
724
762
  };
725
763
  });
726
- var createStandaloneConfig = Effect5.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
727
- const pathService = yield* Path4.Path;
764
+ var createStandaloneConfig = Effect6.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
765
+ const pathService = yield* Path5.Path;
728
766
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
729
767
  if (!resolved) return defaults;
730
768
  const { standaloneRoot, serverDirectory, entrypoint } = resolved;
@@ -757,7 +795,7 @@ var createStandaloneConfig = Effect5.fn("nextjs.createStandaloneConfig")(functio
757
795
  }
758
796
  };
759
797
  });
760
- var createStandaloneV2Config = Effect5.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
798
+ var createStandaloneV2Config = Effect6.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
761
799
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
762
800
  if (!resolved) return defaults;
763
801
  const { standaloneRoot, serverDirectory, entrypoint } = resolved;
@@ -855,14 +893,19 @@ var nextjs = {
855
893
  streaming: true,
856
894
  commands: ["next build"],
857
895
  entrypoint: ".next/standalone/server.js",
858
- assetsDir: ".next/static",
896
+ // No `assetsDir`: this is only the fallback for a standalone build whose
897
+ // Gigadrive manifest is missing, and `.next/static` answers
898
+ // `/_next/static/...` rather than its own stripped prefix. Every path that
899
+ // resolves a real Next.js build (`refineDefaultConfig`) maps those chunks
900
+ // itself, so declaring the directory here would publish them at the wrong
901
+ // URLs.
859
902
  populateAssetCache: true,
860
903
  routes: [{ source: "/*", destination: ".next/standalone/server.js" }],
861
904
  environmentVariables: { NODE_ENV: "production" }
862
905
  }),
863
- refineDefaultConfig: (defaults, projectFolder) => Effect5.gen(function* () {
864
- const fs = yield* FileSystem5.FileSystem;
865
- const manifestContent = yield* fs.readFileString(`${projectFolder}/.gigadrive/nextjs.json`).pipe(Effect5.catchAll(() => Effect5.succeed(void 0)));
906
+ refineDefaultConfig: (defaults, projectFolder) => Effect6.gen(function* () {
907
+ const fs = yield* FileSystem6.FileSystem;
908
+ const manifestContent = yield* fs.readFileString(`${projectFolder}/.gigadrive/nextjs.json`).pipe(Effect6.catchAll(() => Effect6.succeed(void 0)));
866
909
  const manifest = manifestContent ? parseGigadriveNextBuildManifest(manifestContent) : void 0;
867
910
  if (!manifest) return defaults;
868
911
  if (manifest.version === 2) {
@@ -873,8 +916,8 @@ var nextjs = {
873
916
  };
874
917
 
875
918
  // src/detection/frameworks/nuxt.ts
876
- import { FileSystem as FileSystem6 } from "@effect/platform";
877
- import { Effect as Effect6 } from "effect";
919
+ import { FileSystem as FileSystem7 } from "@effect/platform";
920
+ import { Effect as Effect7 } from "effect";
878
921
  var isVercelBuildOutputV3 = (content) => {
879
922
  try {
880
923
  const config = JSON.parse(content);
@@ -901,9 +944,9 @@ var nuxt = {
901
944
  routes: [{ source: "/*", destination: ".output/server/index.mjs" }],
902
945
  environmentVariables: { NODE_ENV: "production", NITRO_PRESET: "node-server" }
903
946
  }),
904
- refineDefaultConfig: (defaults, projectFolder) => Effect6.gen(function* () {
905
- const fs = yield* FileSystem6.FileSystem;
906
- const buildOutputConfig = yield* fs.readFileString(`${projectFolder}/.vercel/output/config.json`).pipe(Effect6.catchAll(() => Effect6.succeed(void 0)));
947
+ refineDefaultConfig: (defaults, projectFolder) => Effect7.gen(function* () {
948
+ const fs = yield* FileSystem7.FileSystem;
949
+ const buildOutputConfig = yield* fs.readFileString(`${projectFolder}/.vercel/output/config.json`).pipe(Effect7.catchAll(() => Effect7.succeed(void 0)));
907
950
  if (!buildOutputConfig || !isVercelBuildOutputV3(buildOutputConfig)) {
908
951
  return defaults;
909
952
  }
@@ -1026,7 +1069,7 @@ var FRAMEWORK_DEFINITIONS = [
1026
1069
  ].sort((a, b) => b.priority - a.priority);
1027
1070
 
1028
1071
  // src/detection/generate-config.ts
1029
- import { Effect as Effect7 } from "effect";
1072
+ import { Effect as Effect8 } from "effect";
1030
1073
  var getInstallCommand = (pm) => {
1031
1074
  switch (pm) {
1032
1075
  case "bun":
@@ -1042,11 +1085,11 @@ var getInstallCommand = (pm) => {
1042
1085
  return "npm install";
1043
1086
  }
1044
1087
  };
1045
- var generateConfig = Effect7.fn("generateConfig")(function* (framework, packageManager, refinedDefaults) {
1088
+ var generateConfig = Effect8.fn("generateConfig")(function* (framework, packageManager, projectFolder, refinedDefaults) {
1046
1089
  const defaults = refinedDefaults ?? framework.getDefaultConfig(packageManager);
1047
1090
  const installCmd = defaults.installCommand ?? getInstallCommand(packageManager);
1048
1091
  const commands = [installCmd, ...defaults.commands];
1049
- yield* Effect7.logDebug(`Generating config for ${framework.name}`, {
1092
+ yield* Effect8.logDebug(`Generating config for ${framework.name}`, {
1050
1093
  runtime: defaults.runtime,
1051
1094
  entrypoint: defaults.entrypoint,
1052
1095
  commands
@@ -1081,10 +1124,26 @@ var generateConfig = Effect7.fn("generateConfig")(function* (framework, packageM
1081
1124
  ...defaults.normalizedConfig
1082
1125
  };
1083
1126
  if (defaults.assetsDir || defaults.assetPaths || defaults.assetPrefixes || defaults.assetManifests) {
1127
+ const paths = defaults.assetPaths ? [...defaults.assetPaths] : [];
1128
+ const overrides = { ...defaults.assetOverrides };
1129
+ const servesDirectoryIndexes = entrypoints.length === 0 && routes.length === 0;
1130
+ const assetsDir = defaults.assetsDir;
1131
+ if (assetsDir && !defaults.assetPaths && !defaults.assetPrefixes && !defaults.assetManifests) {
1132
+ for (const file of yield* collectAssetFiles(projectFolder, assetsDir)) {
1133
+ if (framework.language === "php" && /\.(php|phtml|phar)$/i.test(file)) continue;
1134
+ paths.push(`${assetsDir}/${file}`);
1135
+ if (!servesDirectoryIndexes || file in overrides) continue;
1136
+ if (file === "index.html") {
1137
+ overrides[file] = { path: "" };
1138
+ } else if (file.endsWith("/index.html")) {
1139
+ overrides[file] = { path: file.slice(0, -"/index.html".length) };
1140
+ }
1141
+ }
1142
+ }
1084
1143
  config.assets = {
1085
- paths: defaults.assetPaths ? [...defaults.assetPaths] : [],
1144
+ paths,
1086
1145
  prefixToStrip: defaults.assetsPrefixToStrip ?? (defaults.assetsDir ? defaults.assetsDir + "/" : ""),
1087
- overrides: defaults.assetOverrides ? { ...defaults.assetOverrides } : void 0,
1146
+ overrides: Object.keys(overrides).length > 0 ? overrides : void 0,
1088
1147
  prefixes: defaults.assetPrefixes ? defaults.assetPrefixes.map((prefix) => ({ ...prefix })) : void 0,
1089
1148
  manifests: defaults.assetManifests ? defaults.assetManifests.map((manifest) => ({ ...manifest })) : void 0,
1090
1149
  dynamicRoutes: true,
@@ -1095,8 +1154,8 @@ var generateConfig = Effect7.fn("generateConfig")(function* (framework, packageM
1095
1154
  });
1096
1155
 
1097
1156
  // src/detection/read-dependencies.ts
1098
- import { FileSystem as FileSystem7, Path as Path5 } from "@effect/platform";
1099
- import { Effect as Effect9 } from "effect";
1157
+ import { FileSystem as FileSystem8, Path as Path6 } from "@effect/platform";
1158
+ import { Effect as Effect10 } from "effect";
1100
1159
 
1101
1160
  // src/detection/types.ts
1102
1161
  import { Schema as Schema4 } from "effect";
@@ -1129,25 +1188,25 @@ var MANIFEST_CONFIG = {
1129
1188
  node: { file: "package.json", depKeys: ["dependencies", "devDependencies"] },
1130
1189
  php: { file: "composer.json", depKeys: ["require", "require-dev"] }
1131
1190
  };
1132
- var readManifest = Effect9.fn("readManifest")(function* (filePath) {
1133
- const fs = yield* FileSystem7.FileSystem;
1134
- const exists = yield* fs.exists(filePath).pipe(Effect9.catchAll(() => Effect9.succeed(false)));
1191
+ var readManifest = Effect10.fn("readManifest")(function* (filePath) {
1192
+ const fs = yield* FileSystem8.FileSystem;
1193
+ const exists = yield* fs.exists(filePath).pipe(Effect10.catchAll(() => Effect10.succeed(false)));
1135
1194
  if (!exists) {
1136
- return yield* Effect9.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
1195
+ return yield* Effect10.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
1137
1196
  }
1138
- const content = yield* fs.readFileString(filePath).pipe(Effect9.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
1139
- const parsed = yield* Effect9.try({
1197
+ const content = yield* fs.readFileString(filePath).pipe(Effect10.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
1198
+ const parsed = yield* Effect10.try({
1140
1199
  try: () => JSON.parse(content),
1141
1200
  catch: () => new ManifestParseError({ message: "Failed to parse manifest JSON", filePath })
1142
1201
  });
1143
1202
  return parsed;
1144
1203
  });
1145
- var readDependencies = Effect9.fn("readDependencies")(function* (projectFolder, language) {
1146
- const pathService = yield* Path5.Path;
1204
+ var readDependencies = Effect10.fn("readDependencies")(function* (projectFolder, language) {
1205
+ const pathService = yield* Path6.Path;
1147
1206
  const config = MANIFEST_CONFIG[language];
1148
1207
  const filePath = pathService.join(projectFolder, config.file);
1149
1208
  const manifest = yield* readManifest(filePath).pipe(
1150
- Effect9.catchTag("ManifestNotFoundError", () => Effect9.succeed(null))
1209
+ Effect10.catchTag("ManifestNotFoundError", () => Effect10.succeed(null))
1151
1210
  );
1152
1211
  if (!manifest) {
1153
1212
  return /* @__PURE__ */ new Set();
@@ -1165,9 +1224,9 @@ var readDependencies = Effect9.fn("readDependencies")(function* (projectFolder,
1165
1224
  });
1166
1225
 
1167
1226
  // src/detection/detect-framework.ts
1168
- var matchesDetectionItem = Effect10.fn("matchesDetectionItem")(function* (item, projectFolder, framework, cachedReadDeps) {
1169
- const fs = yield* FileSystem8.FileSystem;
1170
- const pathService = yield* Path6.Path;
1227
+ var matchesDetectionItem = Effect11.fn("matchesDetectionItem")(function* (item, projectFolder, framework, cachedReadDeps) {
1228
+ const fs = yield* FileSystem9.FileSystem;
1229
+ const pathService = yield* Path7.Path;
1171
1230
  if (item.matchPackage != null) {
1172
1231
  const deps = yield* cachedReadDeps(`${projectFolder}\0${framework.language}`);
1173
1232
  if (!deps.has(item.matchPackage)) {
@@ -1176,12 +1235,12 @@ var matchesDetectionItem = Effect10.fn("matchesDetectionItem")(function* (item,
1176
1235
  }
1177
1236
  if (item.path != null) {
1178
1237
  const filePath = pathService.join(projectFolder, item.path);
1179
- const exists = yield* fs.exists(filePath).pipe(Effect10.catchAll(() => Effect10.succeed(false)));
1238
+ const exists = yield* fs.exists(filePath).pipe(Effect11.catchAll(() => Effect11.succeed(false)));
1180
1239
  if (!exists) {
1181
1240
  return false;
1182
1241
  }
1183
1242
  if (item.matchContent != null) {
1184
- const content = yield* fs.readFileString(filePath).pipe(Effect10.catchAll(() => Effect10.succeed("")));
1243
+ const content = yield* fs.readFileString(filePath).pipe(Effect11.catchAll(() => Effect11.succeed("")));
1185
1244
  let regexMatch = false;
1186
1245
  try {
1187
1246
  regexMatch = new RegExp(item.matchContent).test(content);
@@ -1194,7 +1253,7 @@ var matchesDetectionItem = Effect10.fn("matchesDetectionItem")(function* (item,
1194
1253
  }
1195
1254
  return true;
1196
1255
  });
1197
- var matchesFramework = Effect10.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
1256
+ var matchesFramework = Effect11.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
1198
1257
  for (const detector of framework.detectors) {
1199
1258
  const matches = yield* matchesDetectionItem(detector, projectFolder, framework, cachedReadDeps);
1200
1259
  if (!matches) {
@@ -1203,9 +1262,9 @@ var matchesFramework = Effect10.fn("matchesFramework")(function* (framework, pro
1203
1262
  }
1204
1263
  return true;
1205
1264
  });
1206
- var detectFramework = Effect10.fn("detectFramework")(function* (projectFolder) {
1207
- yield* Effect10.logDebug(`Detecting framework in ${projectFolder}`);
1208
- const cachedReadDeps = yield* Effect10.cachedFunction((key) => {
1265
+ var detectFramework = Effect11.fn("detectFramework")(function* (projectFolder) {
1266
+ yield* Effect11.logDebug(`Detecting framework in ${projectFolder}`);
1267
+ const cachedReadDeps = yield* Effect11.cachedFunction((key) => {
1209
1268
  const sepIndex = key.lastIndexOf("\0");
1210
1269
  const folder = key.slice(0, sepIndex);
1211
1270
  const language = key.slice(sepIndex + 1);
@@ -1214,16 +1273,16 @@ var detectFramework = Effect10.fn("detectFramework")(function* (projectFolder) {
1214
1273
  for (const framework of FRAMEWORK_DEFINITIONS) {
1215
1274
  const matches = yield* matchesFramework(framework, projectFolder, cachedReadDeps);
1216
1275
  if (matches) {
1217
- yield* Effect10.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
1276
+ yield* Effect11.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
1218
1277
  const detectedPackageManager = yield* detectPackageManager(projectFolder);
1219
1278
  const packageManager = framework.language === "php" ? "composer" : detectedPackageManager;
1220
1279
  const defaults = framework.getDefaultConfig(packageManager);
1221
1280
  const refinedDefaults = framework.refineDefaultConfig ? yield* framework.refineDefaultConfig(defaults, projectFolder) : defaults;
1222
- const config = yield* generateConfig(framework, packageManager, refinedDefaults);
1281
+ const config = yield* generateConfig(framework, packageManager, projectFolder, refinedDefaults);
1223
1282
  return { framework, packageManager, config };
1224
1283
  }
1225
1284
  }
1226
- return yield* Effect10.fail(
1285
+ return yield* Effect11.fail(
1227
1286
  new FrameworkNotDetectedError({
1228
1287
  message: `No framework detected in project directory`,
1229
1288
  directory: projectFolder
@@ -1232,9 +1291,9 @@ var detectFramework = Effect10.fn("detectFramework")(function* (projectFolder) {
1232
1291
  });
1233
1292
 
1234
1293
  // src/detection/merge-config.ts
1235
- import { Effect as Effect11 } from "effect";
1236
- var mergeWithFrameworkDefaults = Effect11.fn("mergeWithFrameworkDefaults")(function* (userConfig, frameworkConfig) {
1237
- yield* Effect11.logDebug("Merging user config with framework defaults");
1294
+ import { Effect as Effect12 } from "effect";
1295
+ var mergeWithFrameworkDefaults = Effect12.fn("mergeWithFrameworkDefaults")(function* (userConfig, frameworkConfig) {
1296
+ yield* Effect12.logDebug("Merging user config with framework defaults");
1238
1297
  const userHasAssets = (userConfig.assets?.paths?.length ?? 0) > 0 || (userConfig.assets?.prefixes?.length ?? 0) > 0 || (userConfig.assets?.manifests?.length ?? 0) > 0;
1239
1298
  const merged = {
1240
1299
  regions: userConfig.regions,
@@ -1316,23 +1375,23 @@ var DEFAULT_FUNCTION_DURATION_SECONDS = 30;
1316
1375
  var MAX_FUNCTION_DURATION_SECONDS = 28800;
1317
1376
 
1318
1377
  // src/parse-config.ts
1319
- import { Effect as Effect17 } from "effect";
1378
+ import { Effect as Effect18 } from "effect";
1320
1379
 
1321
1380
  // src/services/raw-config-reader.ts
1322
- import { FileSystem as FileSystem9, Path as Path7 } from "@effect/platform";
1323
- import { Effect as Effect13 } from "effect";
1381
+ import { FileSystem as FileSystem10, Path as Path8 } from "@effect/platform";
1382
+ import { Effect as Effect14 } from "effect";
1324
1383
  import { parse as parseYaml } from "yaml";
1325
1384
 
1326
1385
  // src/services/config-module-loader.ts
1327
- import { Effect as Effect12 } from "effect";
1386
+ import { Effect as Effect13 } from "effect";
1328
1387
  import { createJiti } from "jiti";
1329
1388
  var MISSING_DEFAULT_EXPORT = /* @__PURE__ */ Symbol("MissingDefaultExport");
1330
1389
  var STRICT_DEFAULT_EXPORT_EXTENSIONS = [".ts", ".mts", ".mjs"];
1331
- var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader", {
1332
- effect: Effect12.gen(function* () {
1333
- const loadConfigModule = Effect12.fn("ConfigModuleLoader.loadConfigModule")(function* (filePath) {
1390
+ var ConfigModuleLoader = class extends Effect13.Service()("ConfigModuleLoader", {
1391
+ effect: Effect13.gen(function* () {
1392
+ const loadConfigModule = Effect13.fn("ConfigModuleLoader.loadConfigModule")(function* (filePath) {
1334
1393
  const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
1335
- const mod = yield* Effect12.tryPromise({
1394
+ const mod = yield* Effect13.tryPromise({
1336
1395
  try: async () => {
1337
1396
  const jiti = createJiti(filePath, { fsCache: false, interopDefault: true, moduleCache: false });
1338
1397
  const namespace = await jiti.import(filePath);
@@ -1351,7 +1410,7 @@ var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader",
1351
1410
  })
1352
1411
  });
1353
1412
  if (mod === MISSING_DEFAULT_EXPORT) {
1354
- return yield* Effect12.fail(
1413
+ return yield* Effect13.fail(
1355
1414
  new ConfigModuleLoadError({
1356
1415
  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.`,
1357
1416
  filePath
@@ -1359,7 +1418,7 @@ var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader",
1359
1418
  );
1360
1419
  }
1361
1420
  if (typeof mod === "function") {
1362
- return yield* Effect12.fail(
1421
+ return yield* Effect13.fail(
1363
1422
  new ConfigModuleLoadError({
1364
1423
  message: `Config module at ${filePath} default-exports a function; config factories are not supported. Export a config object instead (optionally wrapped in defineConfig).`,
1365
1424
  filePath
@@ -1367,7 +1426,7 @@ var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader",
1367
1426
  );
1368
1427
  }
1369
1428
  if (typeof mod !== "object" || mod === null || Array.isArray(mod)) {
1370
- return yield* Effect12.fail(
1429
+ return yield* Effect13.fail(
1371
1430
  new ConfigModuleLoadError({
1372
1431
  message: `Config module at ${filePath} must default-export a config object.`,
1373
1432
  filePath
@@ -1397,36 +1456,36 @@ var ALLOWED_CONFIG_NAMES = [
1397
1456
  "nebula.json"
1398
1457
  ];
1399
1458
  var MODULE_EXTENSIONS = [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs"];
1400
- var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1459
+ var RawConfigReader = class extends Effect14.Service()("RawConfigReader", {
1401
1460
  dependencies: [ConfigModuleLoader.Default],
1402
- effect: Effect13.gen(function* () {
1403
- const fs = yield* FileSystem9.FileSystem;
1404
- const pathService = yield* Path7.Path;
1461
+ effect: Effect14.gen(function* () {
1462
+ const fs = yield* FileSystem10.FileSystem;
1463
+ const pathService = yield* Path8.Path;
1405
1464
  const moduleLoader = yield* ConfigModuleLoader;
1406
- const findConfig = Effect13.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1465
+ const findConfig = Effect14.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1407
1466
  for (const name of ALLOWED_CONFIG_NAMES) {
1408
1467
  const filePath = pathService.join(projectFolder, name);
1409
- const exists = yield* fs.exists(filePath).pipe(Effect13.catchAll(() => Effect13.succeed(false)));
1468
+ const exists = yield* fs.exists(filePath).pipe(Effect14.catchAll(() => Effect14.succeed(false)));
1410
1469
  if (exists) {
1411
1470
  return filePath;
1412
1471
  }
1413
1472
  }
1414
1473
  return null;
1415
1474
  });
1416
- const readRawConfig = Effect13.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
1417
- const exists = yield* fs.exists(filePath).pipe(Effect13.catchAll(() => Effect13.succeed(false)));
1475
+ const readRawConfig = Effect14.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
1476
+ const exists = yield* fs.exists(filePath).pipe(Effect14.catchAll(() => Effect14.succeed(false)));
1418
1477
  if (!exists) {
1419
- return yield* Effect13.fail(
1478
+ return yield* Effect14.fail(
1420
1479
  new ConfigFileNotFoundError({ message: `Config file not found at ${filePath}`, filePath })
1421
1480
  );
1422
1481
  }
1423
1482
  const fileContents = yield* fs.readFileString(filePath).pipe(
1424
- Effect13.mapError(
1483
+ Effect14.mapError(
1425
1484
  () => new ConfigFileParseError({ message: `Failed to read config file at ${filePath}`, filePath })
1426
1485
  )
1427
1486
  );
1428
1487
  if (fileContents.length === 0) {
1429
- return yield* Effect13.fail(
1488
+ return yield* Effect14.fail(
1430
1489
  new ConfigFileEmptyError({ message: `Config file is empty at ${filePath}`, filePath })
1431
1490
  );
1432
1491
  }
@@ -1442,7 +1501,7 @@ var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1442
1501
  parsed = parseYaml(fileContents);
1443
1502
  }
1444
1503
  } catch (error) {
1445
- return yield* Effect13.fail(
1504
+ return yield* Effect14.fail(
1446
1505
  new ConfigFileParseError({
1447
1506
  message: `Failed to parse config file at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1448
1507
  filePath,
@@ -1452,21 +1511,21 @@ var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1452
1511
  }
1453
1512
  }
1454
1513
  if (parsed == null) {
1455
- return yield* Effect13.fail(
1514
+ return yield* Effect14.fail(
1456
1515
  new ConfigFileParseError({ message: `Config file could not be parsed at ${filePath}`, filePath })
1457
1516
  );
1458
1517
  }
1459
1518
  if (!options?.disableVersionCheck && typeof parsed.version !== "number") {
1460
- return yield* Effect13.fail(
1519
+ return yield* Effect14.fail(
1461
1520
  new ConfigVersionError({ message: `Config file is missing version at ${filePath}`, filePath })
1462
1521
  );
1463
1522
  }
1464
1523
  return parsed;
1465
1524
  });
1466
1525
  const readConfigFile = (configFilePath) => readRawConfig(configFilePath, { disableVersionCheck: true }).pipe(
1467
- Effect13.map((parsed) => parsed),
1468
- Effect13.catchTag("ConfigFileNotFoundError", () => Effect13.succeed(null)),
1469
- Effect13.withSpan("RawConfigReader.readConfigFile")
1526
+ Effect14.map((parsed) => parsed),
1527
+ Effect14.catchTag("ConfigFileNotFoundError", () => Effect14.succeed(null)),
1528
+ Effect14.withSpan("RawConfigReader.readConfigFile")
1470
1529
  );
1471
1530
  return { findConfig, readRawConfig, readConfigFile };
1472
1531
  })
@@ -1476,17 +1535,17 @@ var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1476
1535
  // src/services/schema-validator.ts
1477
1536
  import Ajv from "ajv";
1478
1537
  import addFormats from "ajv-formats";
1479
- import { Effect as Effect14 } from "effect";
1480
- var SchemaValidator = class extends Effect14.Service()("SchemaValidator", {
1481
- effect: Effect14.gen(function* () {
1538
+ import { Effect as Effect15 } from "effect";
1539
+ var SchemaValidator = class extends Effect15.Service()("SchemaValidator", {
1540
+ effect: Effect15.gen(function* () {
1482
1541
  const ajv = new Ajv();
1483
1542
  addFormats(ajv);
1484
- const validate = Effect14.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1543
+ const validate = Effect15.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1485
1544
  const compiledValidate = ajv.compile(schema);
1486
1545
  const valid = compiledValidate(config);
1487
1546
  if (!valid) {
1488
1547
  const errors = compiledValidate.errors?.map((e) => `${e.instancePath || "/"} ${e.message ?? ""}`.trim()) ?? [];
1489
- return yield* Effect14.fail(
1548
+ return yield* Effect15.fail(
1490
1549
  new ConfigSchemaValidationError({
1491
1550
  message: `Config file at ${filePath} is invalid: ${ajv.errorsText(compiledValidate.errors)}`,
1492
1551
  filePath,
@@ -1500,9 +1559,6 @@ var SchemaValidator = class extends Effect14.Service()("SchemaValidator", {
1500
1559
  }) {
1501
1560
  };
1502
1561
 
1503
- // src/services/v4-config-parser.ts
1504
- import { FileSystem as FileSystem10, Path as Path8 } from "@effect/platform";
1505
-
1506
1562
  // ../build-utils/src/get-files-for-pattern.ts
1507
1563
  import { minimatch } from "minimatch";
1508
1564
  import { readdir } from "fs/promises";
@@ -1545,11 +1601,9 @@ var getFilesForPattern = async (pattern, projectFolder, excludeFiles = []) => {
1545
1601
  };
1546
1602
 
1547
1603
  // src/services/v4-config-parser.ts
1548
- import { Effect as Effect15 } from "effect";
1604
+ import { Effect as Effect16 } from "effect";
1549
1605
  import { minimatch as minimatch2 } from "minimatch";
1550
1606
  import safeRegex from "safe-regex2";
1551
- var MAX_ASSET_DEPTH = 100;
1552
- var DISALLOWED_ASSET_EXTENSIONS = [".htaccess", ".htpasswd"];
1553
1607
  var DEFAULT_FUNCTION_SETTINGS = {
1554
1608
  memory: 128,
1555
1609
  max_duration: DEFAULT_FUNCTION_DURATION_SECONDS,
@@ -1651,7 +1705,7 @@ var mapRoute = (route, entrypoints) => ({
1651
1705
  negativeRequirements: route.missing,
1652
1706
  status: route.statusCode
1653
1707
  });
1654
- var parseEntrypoints = Effect15.fn("parseEntrypoints")(function* (config, projectFolder) {
1708
+ var parseEntrypoints = Effect16.fn("parseEntrypoints")(function* (config, projectFolder) {
1655
1709
  const entrypoints = [];
1656
1710
  if (config.functions == null) return entrypoints;
1657
1711
  for (const [fnPath, func] of Object.entries(config.functions)) {
@@ -1661,7 +1715,7 @@ var parseEntrypoints = Effect15.fn("parseEntrypoints")(function* (config, projec
1661
1715
  functionPath: fnPath
1662
1716
  });
1663
1717
  }
1664
- const matchedFiles = yield* Effect15.tryPromise({
1718
+ const matchedFiles = yield* Effect16.tryPromise({
1665
1719
  try: () => getFilesForPattern(fnPath, projectFolder, func.excludeFiles),
1666
1720
  catch: (error) => new FunctionConfigError({
1667
1721
  message: `Failed to resolve files for function pattern '${fnPath}': ${error instanceof Error ? error.message : String(error)}`,
@@ -1697,57 +1751,21 @@ var parseEntrypoints = Effect15.fn("parseEntrypoints")(function* (config, projec
1697
1751
  }
1698
1752
  return entrypoints;
1699
1753
  });
1700
- var collectAssets = Effect15.fn("collectAssets")(function* (config, projectFolder) {
1754
+ var collectAssets = Effect16.fn("collectAssets")(function* (config, projectFolder) {
1701
1755
  if (config.assets == null) return [];
1702
- const fs = yield* FileSystem10.FileSystem;
1703
- const pathService = yield* Path8.Path;
1704
- const assetsPath = pathService.join(projectFolder, config.assets);
1705
- const assetsExist = yield* fs.exists(assetsPath).pipe(Effect15.catchAll(() => Effect15.succeed(false)));
1706
- if (!assetsExist) return [];
1707
- const stat = yield* fs.stat(assetsPath).pipe(Effect15.catchAll(() => Effect15.succeed(null)));
1708
- if (!stat || stat.type !== "Directory") return [];
1709
- const allFiles = yield* collectFilesRecursively(assetsPath);
1710
- const assets = [];
1711
- for (const assetName of allFiles) {
1712
- if (DISALLOWED_ASSET_EXTENSIONS.some((ext) => assetName.toLowerCase().endsWith(ext.toLowerCase()))) continue;
1713
- if (getFunctionSettings(`${config.assets}/${assetName}`, config) != null) continue;
1714
- assets.push(`${config.assets}/${assetName}`);
1715
- }
1716
- return assets;
1756
+ const assetNames = yield* collectAssetFiles(projectFolder, config.assets);
1757
+ return assetNames.filter((assetName) => getFunctionSettings(`${config.assets}/${assetName}`, config) == null).map((assetName) => `${config.assets}/${assetName}`);
1717
1758
  });
1718
- var collectFilesRecursively = Effect15.fn("collectFilesRecursively")(
1719
- function* (basePath, relativePath = "", depth = 0) {
1720
- if (depth > MAX_ASSET_DEPTH) return [];
1721
- const fs = yield* FileSystem10.FileSystem;
1722
- const pathSvc = yield* Path8.Path;
1723
- const currentPath = relativePath ? pathSvc.join(basePath, relativePath) : basePath;
1724
- const entries = yield* fs.readDirectory(currentPath).pipe(Effect15.catchAll(() => Effect15.succeed([])));
1725
- const result = [];
1726
- for (const name of entries) {
1727
- const fullPath = pathSvc.join(currentPath, name);
1728
- const entryRelative = relativePath ? pathSvc.join(relativePath, name) : name;
1729
- const stat = yield* fs.stat(fullPath).pipe(Effect15.catchAll(() => Effect15.succeed(null)));
1730
- if (!stat) continue;
1731
- if (stat.type === "Directory") {
1732
- const nested = yield* collectFilesRecursively(basePath, entryRelative, depth + 1);
1733
- result.push(...nested);
1734
- } else {
1735
- result.push(entryRelative);
1736
- }
1737
- }
1738
- return result;
1739
- }
1740
- );
1741
- var V4ConfigParser = class extends Effect15.Service()("V4ConfigParser", {
1759
+ var V4ConfigParser = class extends Effect16.Service()("V4ConfigParser", {
1742
1760
  accessors: true,
1743
- effect: Effect15.succeed({
1761
+ effect: Effect16.succeed({
1744
1762
  /**
1745
1763
  * Parses a ConfigV4 into a NormalizedConfig.
1746
1764
  *
1747
1765
  * @param config - The raw V4 config object
1748
1766
  * @param projectFolder - Absolute path to the project root
1749
1767
  */
1750
- parse: Effect15.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1768
+ parse: Effect16.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1751
1769
  const entrypoints = yield* parseEntrypoints(config, projectFolder);
1752
1770
  const assets = yield* collectAssets(config, projectFolder);
1753
1771
  return {
@@ -1802,7 +1820,7 @@ var deepMerge = (target, ...partials) => {
1802
1820
  };
1803
1821
 
1804
1822
  // src/services/vercel-build-output-parser.ts
1805
- import { Effect as Effect16 } from "effect";
1823
+ import { Effect as Effect17 } from "effect";
1806
1824
 
1807
1825
  // src/build-output-v3/determine-repo-root.ts
1808
1826
  import path from "path";
@@ -1898,11 +1916,11 @@ var translateVercelRuntime = (runtime) => {
1898
1916
  var CONFIG_PATH = ".vercel/output/config.json";
1899
1917
  var FUNCTIONS_FOLDER = ".vercel/output/functions";
1900
1918
  var FUNCTION_CONFIGS_PATTERN = `${FUNCTIONS_FOLDER}/**/*.func/.vc-config.json`;
1901
- var VercelBuildOutputParser = class extends Effect16.Service()("VercelBuildOutputParser", {
1902
- effect: Effect16.gen(function* () {
1919
+ var VercelBuildOutputParser = class extends Effect17.Service()("VercelBuildOutputParser", {
1920
+ effect: Effect17.gen(function* () {
1903
1921
  const rawConfigReader = yield* RawConfigReader;
1904
1922
  const pathService = yield* Path9.Path;
1905
- const parse = Effect16.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1923
+ const parse = Effect17.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1906
1924
  const config = yield* rawConfigReader.readConfigFile(pathService.join(projectFolder, CONFIG_PATH));
1907
1925
  if (!config || typeof config.version !== "number" || config.version < 3) {
1908
1926
  return parseResult;
@@ -1914,8 +1932,8 @@ var VercelBuildOutputParser = class extends Effect16.Service()("VercelBuildOutpu
1914
1932
  merged.regions = [...new Set(merged.regions)];
1915
1933
  return merged;
1916
1934
  });
1917
- const loadFunctions = Effect16.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1918
- const functionConfigs = yield* Effect16.tryPromise({
1935
+ const loadFunctions = Effect17.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1936
+ const functionConfigs = yield* Effect17.tryPromise({
1919
1937
  try: () => getFilesForPattern(FUNCTION_CONFIGS_PATTERN, projectFolder),
1920
1938
  catch: (error) => new ConfigFileParseError({
1921
1939
  message: `Failed to scan for function configs: ${error instanceof Error ? error.message : String(error)}`,
@@ -2514,7 +2532,7 @@ var schema_default = {
2514
2532
  };
2515
2533
 
2516
2534
  // src/parse-config.ts
2517
- var parseConfigRaw = Effect17.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2535
+ var parseConfigRaw = Effect18.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2518
2536
  const rawReader = yield* RawConfigReader;
2519
2537
  const validator = yield* SchemaValidator;
2520
2538
  const v4Parser = yield* V4ConfigParser;
@@ -2525,7 +2543,7 @@ var parseConfigRaw = Effect17.fn("parseConfigRaw")(function* (filePath, projectF
2525
2543
  };
2526
2544
  const schema = schemaMap[version];
2527
2545
  if (!schema) {
2528
- return yield* Effect17.fail(
2546
+ return yield* Effect18.fail(
2529
2547
  new ConfigVersionError({
2530
2548
  message: `Config file at ${filePath} has an unsupported version: ${version}`,
2531
2549
  filePath,
@@ -2536,11 +2554,11 @@ var parseConfigRaw = Effect17.fn("parseConfigRaw")(function* (filePath, projectF
2536
2554
  yield* validator.validate(parsed, schema, filePath);
2537
2555
  return yield* v4Parser.parse(parsed, projectFolder);
2538
2556
  });
2539
- var parseConfig = Effect17.fn("parseConfig")(function* (filePath, projectFolder) {
2557
+ var parseConfig = Effect18.fn("parseConfig")(function* (filePath, projectFolder) {
2540
2558
  const parseResult = yield* parseConfigRaw(filePath, projectFolder);
2541
2559
  return yield* postProcessConfig(parseResult, projectFolder);
2542
2560
  });
2543
- var postProcessConfig = Effect17.fn("postProcessConfig")(function* (config, projectFolder) {
2561
+ var postProcessConfig = Effect18.fn("postProcessConfig")(function* (config, projectFolder) {
2544
2562
  const vercelParser = yield* VercelBuildOutputParser;
2545
2563
  let result = yield* vercelParser.parse(config, projectFolder);
2546
2564
  const hasAssets = (result.assets?.paths?.length ?? 0) > 0 || (result.assets?.prefixes?.length ?? 0) > 0 || (result.assets?.manifests?.length ?? 0) > 0;
@@ -2616,6 +2634,7 @@ export {
2616
2634
  StaticAssetManifestV1Schema,
2617
2635
  V4ConfigParser,
2618
2636
  VercelBuildOutputParser,
2637
+ collectAssetFiles,
2619
2638
  defineConfig,
2620
2639
  detectFramework,
2621
2640
  detectPackageManager,