@gigadrive/network-config 4.6.0 → 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);
@@ -454,38 +492,60 @@ var ImagePolicySchema = Schema3.mutable(
454
492
  variants: Schema3.mutable(Schema3.Record({ key: Schema3.String, value: ImageVariantSchema }))
455
493
  })
456
494
  );
457
- var GigadriveNextPrerenderOutputSchema = Schema3.mutable(
458
- Schema3.Struct({
459
- id: Schema3.String,
460
- type: Schema3.Literal("PRERENDER"),
461
- pathname: UrlPathnameSchema,
462
- parentOutputId: Schema3.String,
463
- groupId: Schema3.Number,
464
- pprChain: Schema3.optional(Schema3.mutable(Schema3.Struct({ headers: HttpSingleValueHeadersSchema }))),
465
- parentFallbackMode: Schema3.optional(JsonValueSchema),
466
- fallback: Schema3.optional(
467
- Schema3.mutable(
468
- Schema3.Struct({
469
- filePath: Schema3.optional(PortableRelativePathSchema),
470
- initialStatus: Schema3.optional(Schema3.Int.pipe(Schema3.between(100, 599))),
471
- initialHeaders: Schema3.optional(HttpHeadersSchema),
472
- initialExpiration: Schema3.optional(Schema3.Number),
473
- initialRevalidate: Schema3.optional(Schema3.Union(Schema3.Number, Schema3.Literal(false))),
474
- postponedState: Schema3.optional(Schema3.String)
475
- })
476
- )
477
- ),
478
- config: Schema3.mutable(
495
+ var GigadriveNextPrerenderOutputFields = {
496
+ id: Schema3.String,
497
+ type: Schema3.Literal("PRERENDER"),
498
+ pathname: UrlPathnameSchema,
499
+ route: Schema3.optional(UrlPathnameSchema),
500
+ parentOutputId: Schema3.String,
501
+ groupId: Schema3.Number,
502
+ pprChain: Schema3.optional(Schema3.mutable(Schema3.Struct({ headers: HttpSingleValueHeadersSchema }))),
503
+ parentFallbackMode: Schema3.optional(JsonValueSchema),
504
+ fallback: Schema3.optional(
505
+ Schema3.mutable(
479
506
  Schema3.Struct({
480
- allowQuery: Schema3.optional(StringArraySchema),
481
- allowHeader: Schema3.optional(StringArraySchema),
482
- bypassFor: Schema3.optional(Schema3.mutable(Schema3.Array(JsonValueSchema))),
483
- renderingMode: Schema3.optional(Schema3.String),
484
- partialFallback: Schema3.optional(Schema3.Boolean),
485
- bypassToken: Schema3.optional(Schema3.String)
507
+ filePath: Schema3.optional(PortableRelativePathSchema),
508
+ initialStatus: Schema3.optional(Schema3.Int.pipe(Schema3.between(100, 599))),
509
+ initialHeaders: Schema3.optional(HttpHeadersSchema),
510
+ initialExpiration: Schema3.optional(Schema3.Number),
511
+ initialRevalidate: Schema3.optional(Schema3.Union(Schema3.Number, Schema3.Literal(false))),
512
+ postponedState: Schema3.optional(Schema3.String)
486
513
  })
487
514
  )
488
- })
515
+ ),
516
+ config: Schema3.mutable(
517
+ Schema3.Struct({
518
+ allowQuery: Schema3.optional(StringArraySchema),
519
+ allowHeader: Schema3.optional(StringArraySchema),
520
+ bypassFor: Schema3.optional(Schema3.mutable(Schema3.Array(JsonValueSchema))),
521
+ renderingMode: Schema3.optional(Schema3.String),
522
+ partialFallback: Schema3.optional(Schema3.Boolean),
523
+ bypassToken: Schema3.optional(Schema3.String)
524
+ })
525
+ )
526
+ };
527
+ var GigadriveNextPrerenderClassificationSchema = Schema3.Struct({
528
+ routeType: Schema3.Literal("route", "fallback", "shell", "page"),
529
+ response: Schema3.Literal("empty", "initial", "complete"),
530
+ compute: Schema3.Literal("blocking", "resuming", "static"),
531
+ htmlSize: Schema3.optional(Schema3.Number)
532
+ });
533
+ var GigadriveNextPrerenderWithoutClassificationSchema = Schema3.Struct({
534
+ routeType: Schema3.optional(Schema3.Never),
535
+ response: Schema3.optional(Schema3.Never),
536
+ compute: Schema3.optional(Schema3.Never),
537
+ htmlSize: Schema3.optional(Schema3.Never)
538
+ });
539
+ var GigadriveNextPrerenderOutputSchema = Schema3.Union(
540
+ Schema3.mutable(
541
+ Schema3.Struct({ ...GigadriveNextPrerenderOutputFields, ...GigadriveNextPrerenderClassificationSchema.fields })
542
+ ),
543
+ Schema3.mutable(
544
+ Schema3.Struct({
545
+ ...GigadriveNextPrerenderOutputFields,
546
+ ...GigadriveNextPrerenderWithoutClassificationSchema.fields
547
+ })
548
+ )
489
549
  );
490
550
  var GigadriveNextStaticAssetPrefixSchema = Schema3.mutable(
491
551
  Schema3.Struct({
@@ -494,6 +554,43 @@ var GigadriveNextStaticAssetPrefixSchema = Schema3.mutable(
494
554
  immutable: Schema3.Boolean
495
555
  })
496
556
  );
557
+ var GigadriveNextRouteConditionSchema = Schema3.Union(
558
+ Schema3.mutable(
559
+ Schema3.Struct({
560
+ type: Schema3.Literal("header", "cookie", "query"),
561
+ key: Schema3.String,
562
+ value: Schema3.optional(Schema3.String)
563
+ })
564
+ ),
565
+ Schema3.mutable(
566
+ Schema3.Struct({
567
+ type: Schema3.Literal("host"),
568
+ value: Schema3.String
569
+ })
570
+ )
571
+ );
572
+ var GigadriveNextMiddlewareMatcherSchema = Schema3.mutable(
573
+ Schema3.Struct({
574
+ source: Schema3.String,
575
+ sourceRegex: Schema3.String,
576
+ has: Schema3.optional(Schema3.mutable(Schema3.Array(GigadriveNextRouteConditionSchema))),
577
+ missing: Schema3.optional(Schema3.mutable(Schema3.Array(GigadriveNextRouteConditionSchema)))
578
+ })
579
+ );
580
+ var GigadriveNextMiddlewareDescriptorSchema = Schema3.Union(
581
+ Schema3.mutable(
582
+ Schema3.Struct({
583
+ present: Schema3.Literal(true),
584
+ matchers: Schema3.mutable(Schema3.Array(GigadriveNextMiddlewareMatcherSchema))
585
+ })
586
+ ),
587
+ Schema3.mutable(
588
+ Schema3.Struct({
589
+ present: Schema3.Literal(false),
590
+ matchers: Schema3.mutable(Schema3.Tuple())
591
+ })
592
+ )
593
+ );
497
594
  var GigadriveNextServerDescriptorSchema = Schema3.mutable(
498
595
  Schema3.Struct({
499
596
  maxDuration: Schema3.optional(Schema3.Number),
@@ -504,6 +601,9 @@ var GigadriveNextServerDescriptorSchema = Schema3.mutable(
504
601
  var PrerenderArraySchema = Schema3.mutable(Schema3.Array(GigadriveNextPrerenderOutputSchema));
505
602
  var StaticAssetArraySchema = Schema3.mutable(Schema3.Array(GigadriveNextStaticAssetPrefixSchema));
506
603
  var JsonValueArraySchema = Schema3.mutable(Schema3.Array(JsonValueSchema));
604
+ var GigadriveNextPrerenderSeedMethodsSchema = Schema3.mutable(
605
+ Schema3.Tuple(Schema3.Literal("GET"), Schema3.Literal("HEAD"))
606
+ );
507
607
  var GigadriveNextBuildManifestV1Schema = Schema3.mutable(
508
608
  Schema3.Struct({
509
609
  version: Schema3.Literal(1),
@@ -560,7 +660,8 @@ var GigadriveNextBuildManifestV2StandaloneSchema = Schema3.mutable(
560
660
  prerenderManifest: Schema3.optional(PortableRelativePathSchema),
561
661
  assetManifest: Schema3.optional(PortableRelativePathSchema),
562
662
  entryPagePaths: Schema3.optional(Schema3.mutable(Schema3.Array(UrlPathnameSchema))),
563
- staticAssets: StaticAssetArraySchema
663
+ staticAssets: StaticAssetArraySchema,
664
+ middleware: Schema3.optional(GigadriveNextMiddlewareDescriptorSchema)
564
665
  })
565
666
  )
566
667
  })
@@ -573,6 +674,7 @@ var GigadriveNextBuildManifestSchema = Schema3.Union(
573
674
  var GigadriveNextPrerenderManifestV1Schema = Schema3.mutable(
574
675
  Schema3.Struct({
575
676
  version: Schema3.Literal(1),
677
+ seedMethods: Schema3.optional(GigadriveNextPrerenderSeedMethodsSchema),
576
678
  prerenders: PrerenderArraySchema
577
679
  })
578
680
  );
@@ -604,22 +706,22 @@ var AVAILABLE_REGIONS = [...REGION_DEFINITIONS];
604
706
  // src/detection/frameworks/nextjs.ts
605
707
  var toPortablePath = (value) => value.replaceAll("\\", "/");
606
708
  var STANDALONE_SERVER_MEMORY_MB = 1024;
607
- var resolveStandaloneServer = Effect5.fn("nextjs.resolveStandaloneServer")(function* (projectFolder, distDir, repoRootToProject) {
608
- const fs = yield* FileSystem5.FileSystem;
609
- 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;
610
712
  const standaloneRoot = pathService.join(projectFolder, distDir, "standalone");
611
713
  const monorepoServer = pathService.join(standaloneRoot, repoRootToProject, "server.js");
612
714
  const rootServer = pathService.join(standaloneRoot, "server.js");
613
- 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)));
614
716
  const serverPath = monorepoServerExists ? monorepoServer : rootServer;
615
- 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)));
616
718
  if (!serverExists) return void 0;
617
719
  const serverDirectory = pathService.dirname(serverPath);
618
720
  const entrypoint = toPortablePath(pathService.relative(standaloneRoot, serverPath));
619
721
  return { standaloneRoot, serverDirectory, entrypoint };
620
722
  });
621
- var buildStandalonePublicAssets = Effect5.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
622
- const pathService = yield* Path4.Path;
723
+ var buildStandalonePublicAssets = Effect6.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
724
+ const pathService = yield* Path5.Path;
623
725
  const publicFiles = yield* getDefaultPathMap(pathService.join(projectFolder, "public"));
624
726
  const assetPaths = [];
625
727
  const assetOverrides = {};
@@ -635,8 +737,8 @@ var buildStandalonePublicAssets = Effect5.fn("nextjs.buildStandalonePublicAssets
635
737
  }
636
738
  return { assetPaths, assetOverrides, filePathMap };
637
739
  });
638
- var createStaticExportConfig = Effect5.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
639
- const pathService = yield* Path4.Path;
740
+ var createStaticExportConfig = Effect6.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
741
+ const pathService = yield* Path5.Path;
640
742
  const outputDirectory = pathService.join(projectFolder, "out");
641
743
  const files = yield* getDefaultPathMap(outputDirectory);
642
744
  const assetPaths = [];
@@ -659,8 +761,8 @@ var createStaticExportConfig = Effect5.fn("nextjs.createStaticExportConfig")(fun
659
761
  package: void 0
660
762
  };
661
763
  });
662
- var createStandaloneConfig = Effect5.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
663
- const pathService = yield* Path4.Path;
764
+ var createStandaloneConfig = Effect6.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
765
+ const pathService = yield* Path5.Path;
664
766
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
665
767
  if (!resolved) return defaults;
666
768
  const { standaloneRoot, serverDirectory, entrypoint } = resolved;
@@ -693,7 +795,7 @@ var createStandaloneConfig = Effect5.fn("nextjs.createStandaloneConfig")(functio
693
795
  }
694
796
  };
695
797
  });
696
- var createStandaloneV2Config = Effect5.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
798
+ var createStandaloneV2Config = Effect6.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
697
799
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
698
800
  if (!resolved) return defaults;
699
801
  const { standaloneRoot, serverDirectory, entrypoint } = resolved;
@@ -791,14 +893,19 @@ var nextjs = {
791
893
  streaming: true,
792
894
  commands: ["next build"],
793
895
  entrypoint: ".next/standalone/server.js",
794
- 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.
795
902
  populateAssetCache: true,
796
903
  routes: [{ source: "/*", destination: ".next/standalone/server.js" }],
797
904
  environmentVariables: { NODE_ENV: "production" }
798
905
  }),
799
- refineDefaultConfig: (defaults, projectFolder) => Effect5.gen(function* () {
800
- const fs = yield* FileSystem5.FileSystem;
801
- 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)));
802
909
  const manifest = manifestContent ? parseGigadriveNextBuildManifest(manifestContent) : void 0;
803
910
  if (!manifest) return defaults;
804
911
  if (manifest.version === 2) {
@@ -809,8 +916,8 @@ var nextjs = {
809
916
  };
810
917
 
811
918
  // src/detection/frameworks/nuxt.ts
812
- import { FileSystem as FileSystem6 } from "@effect/platform";
813
- import { Effect as Effect6 } from "effect";
919
+ import { FileSystem as FileSystem7 } from "@effect/platform";
920
+ import { Effect as Effect7 } from "effect";
814
921
  var isVercelBuildOutputV3 = (content) => {
815
922
  try {
816
923
  const config = JSON.parse(content);
@@ -837,9 +944,9 @@ var nuxt = {
837
944
  routes: [{ source: "/*", destination: ".output/server/index.mjs" }],
838
945
  environmentVariables: { NODE_ENV: "production", NITRO_PRESET: "node-server" }
839
946
  }),
840
- refineDefaultConfig: (defaults, projectFolder) => Effect6.gen(function* () {
841
- const fs = yield* FileSystem6.FileSystem;
842
- 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)));
843
950
  if (!buildOutputConfig || !isVercelBuildOutputV3(buildOutputConfig)) {
844
951
  return defaults;
845
952
  }
@@ -962,7 +1069,7 @@ var FRAMEWORK_DEFINITIONS = [
962
1069
  ].sort((a, b) => b.priority - a.priority);
963
1070
 
964
1071
  // src/detection/generate-config.ts
965
- import { Effect as Effect7 } from "effect";
1072
+ import { Effect as Effect8 } from "effect";
966
1073
  var getInstallCommand = (pm) => {
967
1074
  switch (pm) {
968
1075
  case "bun":
@@ -978,11 +1085,11 @@ var getInstallCommand = (pm) => {
978
1085
  return "npm install";
979
1086
  }
980
1087
  };
981
- var generateConfig = Effect7.fn("generateConfig")(function* (framework, packageManager, refinedDefaults) {
1088
+ var generateConfig = Effect8.fn("generateConfig")(function* (framework, packageManager, projectFolder, refinedDefaults) {
982
1089
  const defaults = refinedDefaults ?? framework.getDefaultConfig(packageManager);
983
1090
  const installCmd = defaults.installCommand ?? getInstallCommand(packageManager);
984
1091
  const commands = [installCmd, ...defaults.commands];
985
- yield* Effect7.logDebug(`Generating config for ${framework.name}`, {
1092
+ yield* Effect8.logDebug(`Generating config for ${framework.name}`, {
986
1093
  runtime: defaults.runtime,
987
1094
  entrypoint: defaults.entrypoint,
988
1095
  commands
@@ -1017,10 +1124,26 @@ var generateConfig = Effect7.fn("generateConfig")(function* (framework, packageM
1017
1124
  ...defaults.normalizedConfig
1018
1125
  };
1019
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
+ }
1020
1143
  config.assets = {
1021
- paths: defaults.assetPaths ? [...defaults.assetPaths] : [],
1144
+ paths,
1022
1145
  prefixToStrip: defaults.assetsPrefixToStrip ?? (defaults.assetsDir ? defaults.assetsDir + "/" : ""),
1023
- overrides: defaults.assetOverrides ? { ...defaults.assetOverrides } : void 0,
1146
+ overrides: Object.keys(overrides).length > 0 ? overrides : void 0,
1024
1147
  prefixes: defaults.assetPrefixes ? defaults.assetPrefixes.map((prefix) => ({ ...prefix })) : void 0,
1025
1148
  manifests: defaults.assetManifests ? defaults.assetManifests.map((manifest) => ({ ...manifest })) : void 0,
1026
1149
  dynamicRoutes: true,
@@ -1031,8 +1154,8 @@ var generateConfig = Effect7.fn("generateConfig")(function* (framework, packageM
1031
1154
  });
1032
1155
 
1033
1156
  // src/detection/read-dependencies.ts
1034
- import { FileSystem as FileSystem7, Path as Path5 } from "@effect/platform";
1035
- import { Effect as Effect9 } from "effect";
1157
+ import { FileSystem as FileSystem8, Path as Path6 } from "@effect/platform";
1158
+ import { Effect as Effect10 } from "effect";
1036
1159
 
1037
1160
  // src/detection/types.ts
1038
1161
  import { Schema as Schema4 } from "effect";
@@ -1065,25 +1188,25 @@ var MANIFEST_CONFIG = {
1065
1188
  node: { file: "package.json", depKeys: ["dependencies", "devDependencies"] },
1066
1189
  php: { file: "composer.json", depKeys: ["require", "require-dev"] }
1067
1190
  };
1068
- var readManifest = Effect9.fn("readManifest")(function* (filePath) {
1069
- const fs = yield* FileSystem7.FileSystem;
1070
- 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)));
1071
1194
  if (!exists) {
1072
- return yield* Effect9.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
1195
+ return yield* Effect10.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
1073
1196
  }
1074
- const content = yield* fs.readFileString(filePath).pipe(Effect9.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
1075
- 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({
1076
1199
  try: () => JSON.parse(content),
1077
1200
  catch: () => new ManifestParseError({ message: "Failed to parse manifest JSON", filePath })
1078
1201
  });
1079
1202
  return parsed;
1080
1203
  });
1081
- var readDependencies = Effect9.fn("readDependencies")(function* (projectFolder, language) {
1082
- const pathService = yield* Path5.Path;
1204
+ var readDependencies = Effect10.fn("readDependencies")(function* (projectFolder, language) {
1205
+ const pathService = yield* Path6.Path;
1083
1206
  const config = MANIFEST_CONFIG[language];
1084
1207
  const filePath = pathService.join(projectFolder, config.file);
1085
1208
  const manifest = yield* readManifest(filePath).pipe(
1086
- Effect9.catchTag("ManifestNotFoundError", () => Effect9.succeed(null))
1209
+ Effect10.catchTag("ManifestNotFoundError", () => Effect10.succeed(null))
1087
1210
  );
1088
1211
  if (!manifest) {
1089
1212
  return /* @__PURE__ */ new Set();
@@ -1101,9 +1224,9 @@ var readDependencies = Effect9.fn("readDependencies")(function* (projectFolder,
1101
1224
  });
1102
1225
 
1103
1226
  // src/detection/detect-framework.ts
1104
- var matchesDetectionItem = Effect10.fn("matchesDetectionItem")(function* (item, projectFolder, framework, cachedReadDeps) {
1105
- const fs = yield* FileSystem8.FileSystem;
1106
- 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;
1107
1230
  if (item.matchPackage != null) {
1108
1231
  const deps = yield* cachedReadDeps(`${projectFolder}\0${framework.language}`);
1109
1232
  if (!deps.has(item.matchPackage)) {
@@ -1112,12 +1235,12 @@ var matchesDetectionItem = Effect10.fn("matchesDetectionItem")(function* (item,
1112
1235
  }
1113
1236
  if (item.path != null) {
1114
1237
  const filePath = pathService.join(projectFolder, item.path);
1115
- 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)));
1116
1239
  if (!exists) {
1117
1240
  return false;
1118
1241
  }
1119
1242
  if (item.matchContent != null) {
1120
- const content = yield* fs.readFileString(filePath).pipe(Effect10.catchAll(() => Effect10.succeed("")));
1243
+ const content = yield* fs.readFileString(filePath).pipe(Effect11.catchAll(() => Effect11.succeed("")));
1121
1244
  let regexMatch = false;
1122
1245
  try {
1123
1246
  regexMatch = new RegExp(item.matchContent).test(content);
@@ -1130,7 +1253,7 @@ var matchesDetectionItem = Effect10.fn("matchesDetectionItem")(function* (item,
1130
1253
  }
1131
1254
  return true;
1132
1255
  });
1133
- var matchesFramework = Effect10.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
1256
+ var matchesFramework = Effect11.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
1134
1257
  for (const detector of framework.detectors) {
1135
1258
  const matches = yield* matchesDetectionItem(detector, projectFolder, framework, cachedReadDeps);
1136
1259
  if (!matches) {
@@ -1139,9 +1262,9 @@ var matchesFramework = Effect10.fn("matchesFramework")(function* (framework, pro
1139
1262
  }
1140
1263
  return true;
1141
1264
  });
1142
- var detectFramework = Effect10.fn("detectFramework")(function* (projectFolder) {
1143
- yield* Effect10.logDebug(`Detecting framework in ${projectFolder}`);
1144
- 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) => {
1145
1268
  const sepIndex = key.lastIndexOf("\0");
1146
1269
  const folder = key.slice(0, sepIndex);
1147
1270
  const language = key.slice(sepIndex + 1);
@@ -1150,16 +1273,16 @@ var detectFramework = Effect10.fn("detectFramework")(function* (projectFolder) {
1150
1273
  for (const framework of FRAMEWORK_DEFINITIONS) {
1151
1274
  const matches = yield* matchesFramework(framework, projectFolder, cachedReadDeps);
1152
1275
  if (matches) {
1153
- yield* Effect10.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
1276
+ yield* Effect11.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
1154
1277
  const detectedPackageManager = yield* detectPackageManager(projectFolder);
1155
1278
  const packageManager = framework.language === "php" ? "composer" : detectedPackageManager;
1156
1279
  const defaults = framework.getDefaultConfig(packageManager);
1157
1280
  const refinedDefaults = framework.refineDefaultConfig ? yield* framework.refineDefaultConfig(defaults, projectFolder) : defaults;
1158
- const config = yield* generateConfig(framework, packageManager, refinedDefaults);
1281
+ const config = yield* generateConfig(framework, packageManager, projectFolder, refinedDefaults);
1159
1282
  return { framework, packageManager, config };
1160
1283
  }
1161
1284
  }
1162
- return yield* Effect10.fail(
1285
+ return yield* Effect11.fail(
1163
1286
  new FrameworkNotDetectedError({
1164
1287
  message: `No framework detected in project directory`,
1165
1288
  directory: projectFolder
@@ -1168,9 +1291,9 @@ var detectFramework = Effect10.fn("detectFramework")(function* (projectFolder) {
1168
1291
  });
1169
1292
 
1170
1293
  // src/detection/merge-config.ts
1171
- import { Effect as Effect11 } from "effect";
1172
- var mergeWithFrameworkDefaults = Effect11.fn("mergeWithFrameworkDefaults")(function* (userConfig, frameworkConfig) {
1173
- 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");
1174
1297
  const userHasAssets = (userConfig.assets?.paths?.length ?? 0) > 0 || (userConfig.assets?.prefixes?.length ?? 0) > 0 || (userConfig.assets?.manifests?.length ?? 0) > 0;
1175
1298
  const merged = {
1176
1299
  regions: userConfig.regions,
@@ -1252,23 +1375,23 @@ var DEFAULT_FUNCTION_DURATION_SECONDS = 30;
1252
1375
  var MAX_FUNCTION_DURATION_SECONDS = 28800;
1253
1376
 
1254
1377
  // src/parse-config.ts
1255
- import { Effect as Effect17 } from "effect";
1378
+ import { Effect as Effect18 } from "effect";
1256
1379
 
1257
1380
  // src/services/raw-config-reader.ts
1258
- import { FileSystem as FileSystem9, Path as Path7 } from "@effect/platform";
1259
- import { Effect as Effect13 } from "effect";
1381
+ import { FileSystem as FileSystem10, Path as Path8 } from "@effect/platform";
1382
+ import { Effect as Effect14 } from "effect";
1260
1383
  import { parse as parseYaml } from "yaml";
1261
1384
 
1262
1385
  // src/services/config-module-loader.ts
1263
- import { Effect as Effect12 } from "effect";
1386
+ import { Effect as Effect13 } from "effect";
1264
1387
  import { createJiti } from "jiti";
1265
1388
  var MISSING_DEFAULT_EXPORT = /* @__PURE__ */ Symbol("MissingDefaultExport");
1266
1389
  var STRICT_DEFAULT_EXPORT_EXTENSIONS = [".ts", ".mts", ".mjs"];
1267
- var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader", {
1268
- effect: Effect12.gen(function* () {
1269
- 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) {
1270
1393
  const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
1271
- const mod = yield* Effect12.tryPromise({
1394
+ const mod = yield* Effect13.tryPromise({
1272
1395
  try: async () => {
1273
1396
  const jiti = createJiti(filePath, { fsCache: false, interopDefault: true, moduleCache: false });
1274
1397
  const namespace = await jiti.import(filePath);
@@ -1287,7 +1410,7 @@ var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader",
1287
1410
  })
1288
1411
  });
1289
1412
  if (mod === MISSING_DEFAULT_EXPORT) {
1290
- return yield* Effect12.fail(
1413
+ return yield* Effect13.fail(
1291
1414
  new ConfigModuleLoadError({
1292
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.`,
1293
1416
  filePath
@@ -1295,7 +1418,7 @@ var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader",
1295
1418
  );
1296
1419
  }
1297
1420
  if (typeof mod === "function") {
1298
- return yield* Effect12.fail(
1421
+ return yield* Effect13.fail(
1299
1422
  new ConfigModuleLoadError({
1300
1423
  message: `Config module at ${filePath} default-exports a function; config factories are not supported. Export a config object instead (optionally wrapped in defineConfig).`,
1301
1424
  filePath
@@ -1303,7 +1426,7 @@ var ConfigModuleLoader = class extends Effect12.Service()("ConfigModuleLoader",
1303
1426
  );
1304
1427
  }
1305
1428
  if (typeof mod !== "object" || mod === null || Array.isArray(mod)) {
1306
- return yield* Effect12.fail(
1429
+ return yield* Effect13.fail(
1307
1430
  new ConfigModuleLoadError({
1308
1431
  message: `Config module at ${filePath} must default-export a config object.`,
1309
1432
  filePath
@@ -1333,36 +1456,36 @@ var ALLOWED_CONFIG_NAMES = [
1333
1456
  "nebula.json"
1334
1457
  ];
1335
1458
  var MODULE_EXTENSIONS = [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs"];
1336
- var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1459
+ var RawConfigReader = class extends Effect14.Service()("RawConfigReader", {
1337
1460
  dependencies: [ConfigModuleLoader.Default],
1338
- effect: Effect13.gen(function* () {
1339
- const fs = yield* FileSystem9.FileSystem;
1340
- const pathService = yield* Path7.Path;
1461
+ effect: Effect14.gen(function* () {
1462
+ const fs = yield* FileSystem10.FileSystem;
1463
+ const pathService = yield* Path8.Path;
1341
1464
  const moduleLoader = yield* ConfigModuleLoader;
1342
- const findConfig = Effect13.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1465
+ const findConfig = Effect14.fn("RawConfigReader.findConfig")(function* (projectFolder) {
1343
1466
  for (const name of ALLOWED_CONFIG_NAMES) {
1344
1467
  const filePath = pathService.join(projectFolder, name);
1345
- 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)));
1346
1469
  if (exists) {
1347
1470
  return filePath;
1348
1471
  }
1349
1472
  }
1350
1473
  return null;
1351
1474
  });
1352
- const readRawConfig = Effect13.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
1353
- 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)));
1354
1477
  if (!exists) {
1355
- return yield* Effect13.fail(
1478
+ return yield* Effect14.fail(
1356
1479
  new ConfigFileNotFoundError({ message: `Config file not found at ${filePath}`, filePath })
1357
1480
  );
1358
1481
  }
1359
1482
  const fileContents = yield* fs.readFileString(filePath).pipe(
1360
- Effect13.mapError(
1483
+ Effect14.mapError(
1361
1484
  () => new ConfigFileParseError({ message: `Failed to read config file at ${filePath}`, filePath })
1362
1485
  )
1363
1486
  );
1364
1487
  if (fileContents.length === 0) {
1365
- return yield* Effect13.fail(
1488
+ return yield* Effect14.fail(
1366
1489
  new ConfigFileEmptyError({ message: `Config file is empty at ${filePath}`, filePath })
1367
1490
  );
1368
1491
  }
@@ -1378,7 +1501,7 @@ var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1378
1501
  parsed = parseYaml(fileContents);
1379
1502
  }
1380
1503
  } catch (error) {
1381
- return yield* Effect13.fail(
1504
+ return yield* Effect14.fail(
1382
1505
  new ConfigFileParseError({
1383
1506
  message: `Failed to parse config file at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
1384
1507
  filePath,
@@ -1388,21 +1511,21 @@ var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1388
1511
  }
1389
1512
  }
1390
1513
  if (parsed == null) {
1391
- return yield* Effect13.fail(
1514
+ return yield* Effect14.fail(
1392
1515
  new ConfigFileParseError({ message: `Config file could not be parsed at ${filePath}`, filePath })
1393
1516
  );
1394
1517
  }
1395
1518
  if (!options?.disableVersionCheck && typeof parsed.version !== "number") {
1396
- return yield* Effect13.fail(
1519
+ return yield* Effect14.fail(
1397
1520
  new ConfigVersionError({ message: `Config file is missing version at ${filePath}`, filePath })
1398
1521
  );
1399
1522
  }
1400
1523
  return parsed;
1401
1524
  });
1402
1525
  const readConfigFile = (configFilePath) => readRawConfig(configFilePath, { disableVersionCheck: true }).pipe(
1403
- Effect13.map((parsed) => parsed),
1404
- Effect13.catchTag("ConfigFileNotFoundError", () => Effect13.succeed(null)),
1405
- Effect13.withSpan("RawConfigReader.readConfigFile")
1526
+ Effect14.map((parsed) => parsed),
1527
+ Effect14.catchTag("ConfigFileNotFoundError", () => Effect14.succeed(null)),
1528
+ Effect14.withSpan("RawConfigReader.readConfigFile")
1406
1529
  );
1407
1530
  return { findConfig, readRawConfig, readConfigFile };
1408
1531
  })
@@ -1412,17 +1535,17 @@ var RawConfigReader = class extends Effect13.Service()("RawConfigReader", {
1412
1535
  // src/services/schema-validator.ts
1413
1536
  import Ajv from "ajv";
1414
1537
  import addFormats from "ajv-formats";
1415
- import { Effect as Effect14 } from "effect";
1416
- var SchemaValidator = class extends Effect14.Service()("SchemaValidator", {
1417
- effect: Effect14.gen(function* () {
1538
+ import { Effect as Effect15 } from "effect";
1539
+ var SchemaValidator = class extends Effect15.Service()("SchemaValidator", {
1540
+ effect: Effect15.gen(function* () {
1418
1541
  const ajv = new Ajv();
1419
1542
  addFormats(ajv);
1420
- const validate = Effect14.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1543
+ const validate = Effect15.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
1421
1544
  const compiledValidate = ajv.compile(schema);
1422
1545
  const valid = compiledValidate(config);
1423
1546
  if (!valid) {
1424
1547
  const errors = compiledValidate.errors?.map((e) => `${e.instancePath || "/"} ${e.message ?? ""}`.trim()) ?? [];
1425
- return yield* Effect14.fail(
1548
+ return yield* Effect15.fail(
1426
1549
  new ConfigSchemaValidationError({
1427
1550
  message: `Config file at ${filePath} is invalid: ${ajv.errorsText(compiledValidate.errors)}`,
1428
1551
  filePath,
@@ -1436,14 +1559,51 @@ var SchemaValidator = class extends Effect14.Service()("SchemaValidator", {
1436
1559
  }) {
1437
1560
  };
1438
1561
 
1439
- // src/services/v4-config-parser.ts
1440
- import { FileSystem as FileSystem10, Path as Path8 } from "@effect/platform";
1441
- import { getFilesForPattern } from "@gigadrive/build-utils";
1442
- import { Effect as Effect15 } from "effect";
1562
+ // ../build-utils/src/get-files-for-pattern.ts
1443
1563
  import { minimatch } from "minimatch";
1564
+ import { readdir } from "fs/promises";
1565
+ var getFilesForPattern = async (pattern, projectFolder, excludeFiles = []) => {
1566
+ const files = [];
1567
+ const filesInFolder = await readdir(projectFolder, { recursive: true });
1568
+ const exactFiles = new Set(filesInFolder.filter((file) => typeof file === "string"));
1569
+ let regex = null;
1570
+ if (!exactFiles.has(pattern)) {
1571
+ try {
1572
+ regex = new RegExp(`^(?:${pattern})$`);
1573
+ } catch {
1574
+ }
1575
+ }
1576
+ const finalExclusions = Array.isArray(excludeFiles) ? excludeFiles : [excludeFiles];
1577
+ for (const file of filesInFolder) {
1578
+ if (typeof file !== "string") {
1579
+ continue;
1580
+ }
1581
+ if (finalExclusions.some((excludeFile) => {
1582
+ if (minimatch(file, excludeFile)) {
1583
+ return true;
1584
+ }
1585
+ if (!exactFiles.has(excludeFile)) {
1586
+ try {
1587
+ return new RegExp(`^(?:${excludeFile})$`).test(file);
1588
+ } catch {
1589
+ return false;
1590
+ }
1591
+ }
1592
+ return false;
1593
+ })) {
1594
+ continue;
1595
+ }
1596
+ if (minimatch(file, pattern) || regex != null && regex.test(file)) {
1597
+ files.push(file);
1598
+ }
1599
+ }
1600
+ return files;
1601
+ };
1602
+
1603
+ // src/services/v4-config-parser.ts
1604
+ import { Effect as Effect16 } from "effect";
1605
+ import { minimatch as minimatch2 } from "minimatch";
1444
1606
  import safeRegex from "safe-regex2";
1445
- var MAX_ASSET_DEPTH = 100;
1446
- var DISALLOWED_ASSET_EXTENSIONS = [".htaccess", ".htpasswd"];
1447
1607
  var DEFAULT_FUNCTION_SETTINGS = {
1448
1608
  memory: 128,
1449
1609
  max_duration: DEFAULT_FUNCTION_DURATION_SECONDS,
@@ -1505,7 +1665,7 @@ var destinationMatchesEntrypoint = (destination, entrypointPath) => {
1505
1665
  return new RegExp(`^${pattern}$`).test(entrypointPath);
1506
1666
  };
1507
1667
  var matchesPattern = (path2, pattern) => {
1508
- if (minimatch(path2, pattern)) return true;
1668
+ if (minimatch2(path2, pattern)) return true;
1509
1669
  try {
1510
1670
  if (safeRegex(pattern)) {
1511
1671
  return new RegExp(pattern).test(path2);
@@ -1545,7 +1705,7 @@ var mapRoute = (route, entrypoints) => ({
1545
1705
  negativeRequirements: route.missing,
1546
1706
  status: route.statusCode
1547
1707
  });
1548
- var parseEntrypoints = Effect15.fn("parseEntrypoints")(function* (config, projectFolder) {
1708
+ var parseEntrypoints = Effect16.fn("parseEntrypoints")(function* (config, projectFolder) {
1549
1709
  const entrypoints = [];
1550
1710
  if (config.functions == null) return entrypoints;
1551
1711
  for (const [fnPath, func] of Object.entries(config.functions)) {
@@ -1555,7 +1715,7 @@ var parseEntrypoints = Effect15.fn("parseEntrypoints")(function* (config, projec
1555
1715
  functionPath: fnPath
1556
1716
  });
1557
1717
  }
1558
- const matchedFiles = yield* Effect15.tryPromise({
1718
+ const matchedFiles = yield* Effect16.tryPromise({
1559
1719
  try: () => getFilesForPattern(fnPath, projectFolder, func.excludeFiles),
1560
1720
  catch: (error) => new FunctionConfigError({
1561
1721
  message: `Failed to resolve files for function pattern '${fnPath}': ${error instanceof Error ? error.message : String(error)}`,
@@ -1591,57 +1751,21 @@ var parseEntrypoints = Effect15.fn("parseEntrypoints")(function* (config, projec
1591
1751
  }
1592
1752
  return entrypoints;
1593
1753
  });
1594
- var collectAssets = Effect15.fn("collectAssets")(function* (config, projectFolder) {
1754
+ var collectAssets = Effect16.fn("collectAssets")(function* (config, projectFolder) {
1595
1755
  if (config.assets == null) return [];
1596
- const fs = yield* FileSystem10.FileSystem;
1597
- const pathService = yield* Path8.Path;
1598
- const assetsPath = pathService.join(projectFolder, config.assets);
1599
- const assetsExist = yield* fs.exists(assetsPath).pipe(Effect15.catchAll(() => Effect15.succeed(false)));
1600
- if (!assetsExist) return [];
1601
- const stat = yield* fs.stat(assetsPath).pipe(Effect15.catchAll(() => Effect15.succeed(null)));
1602
- if (!stat || stat.type !== "Directory") return [];
1603
- const allFiles = yield* collectFilesRecursively(assetsPath);
1604
- const assets = [];
1605
- for (const assetName of allFiles) {
1606
- if (DISALLOWED_ASSET_EXTENSIONS.some((ext) => assetName.toLowerCase().endsWith(ext.toLowerCase()))) continue;
1607
- if (getFunctionSettings(`${config.assets}/${assetName}`, config) != null) continue;
1608
- assets.push(`${config.assets}/${assetName}`);
1609
- }
1610
- 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}`);
1611
1758
  });
1612
- var collectFilesRecursively = Effect15.fn("collectFilesRecursively")(
1613
- function* (basePath, relativePath = "", depth = 0) {
1614
- if (depth > MAX_ASSET_DEPTH) return [];
1615
- const fs = yield* FileSystem10.FileSystem;
1616
- const pathSvc = yield* Path8.Path;
1617
- const currentPath = relativePath ? pathSvc.join(basePath, relativePath) : basePath;
1618
- const entries = yield* fs.readDirectory(currentPath).pipe(Effect15.catchAll(() => Effect15.succeed([])));
1619
- const result = [];
1620
- for (const name of entries) {
1621
- const fullPath = pathSvc.join(currentPath, name);
1622
- const entryRelative = relativePath ? pathSvc.join(relativePath, name) : name;
1623
- const stat = yield* fs.stat(fullPath).pipe(Effect15.catchAll(() => Effect15.succeed(null)));
1624
- if (!stat) continue;
1625
- if (stat.type === "Directory") {
1626
- const nested = yield* collectFilesRecursively(basePath, entryRelative, depth + 1);
1627
- result.push(...nested);
1628
- } else {
1629
- result.push(entryRelative);
1630
- }
1631
- }
1632
- return result;
1633
- }
1634
- );
1635
- var V4ConfigParser = class extends Effect15.Service()("V4ConfigParser", {
1759
+ var V4ConfigParser = class extends Effect16.Service()("V4ConfigParser", {
1636
1760
  accessors: true,
1637
- effect: Effect15.succeed({
1761
+ effect: Effect16.succeed({
1638
1762
  /**
1639
1763
  * Parses a ConfigV4 into a NormalizedConfig.
1640
1764
  *
1641
1765
  * @param config - The raw V4 config object
1642
1766
  * @param projectFolder - Absolute path to the project root
1643
1767
  */
1644
- parse: Effect15.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1768
+ parse: Effect16.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
1645
1769
  const entrypoints = yield* parseEntrypoints(config, projectFolder);
1646
1770
  const assets = yield* collectAssets(config, projectFolder);
1647
1771
  return {
@@ -1668,9 +1792,35 @@ var V4ConfigParser = class extends Effect15.Service()("V4ConfigParser", {
1668
1792
 
1669
1793
  // src/services/vercel-build-output-parser.ts
1670
1794
  import { Path as Path9 } from "@effect/platform";
1671
- import { getFilesForPattern as getFilesForPattern2 } from "@gigadrive/build-utils";
1672
- import { deepMerge } from "@gigadrive/commons";
1673
- import { Effect as Effect16 } from "effect";
1795
+
1796
+ // ../commons/src/deep-merge.ts
1797
+ var deepMerge = (target, ...partials) => {
1798
+ const isObject = (item) => item !== null && typeof item === "object";
1799
+ if (!isObject(target)) {
1800
+ return target;
1801
+ }
1802
+ for (const partial of partials) {
1803
+ if (!isObject(partial)) {
1804
+ continue;
1805
+ }
1806
+ Object.keys(partial).forEach((key) => {
1807
+ if (key === "__proto__" || key === "constructor") return;
1808
+ const targetValue = target[key];
1809
+ const sourceValue = partial[key];
1810
+ if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
1811
+ targetValue.push(...sourceValue);
1812
+ } else if (isObject(targetValue) && isObject(sourceValue)) {
1813
+ deepMerge(targetValue, sourceValue);
1814
+ } else {
1815
+ target[key] = sourceValue;
1816
+ }
1817
+ });
1818
+ }
1819
+ return target;
1820
+ };
1821
+
1822
+ // src/services/vercel-build-output-parser.ts
1823
+ import { Effect as Effect17 } from "effect";
1674
1824
 
1675
1825
  // src/build-output-v3/determine-repo-root.ts
1676
1826
  import path from "path";
@@ -1766,11 +1916,11 @@ var translateVercelRuntime = (runtime) => {
1766
1916
  var CONFIG_PATH = ".vercel/output/config.json";
1767
1917
  var FUNCTIONS_FOLDER = ".vercel/output/functions";
1768
1918
  var FUNCTION_CONFIGS_PATTERN = `${FUNCTIONS_FOLDER}/**/*.func/.vc-config.json`;
1769
- var VercelBuildOutputParser = class extends Effect16.Service()("VercelBuildOutputParser", {
1770
- effect: Effect16.gen(function* () {
1919
+ var VercelBuildOutputParser = class extends Effect17.Service()("VercelBuildOutputParser", {
1920
+ effect: Effect17.gen(function* () {
1771
1921
  const rawConfigReader = yield* RawConfigReader;
1772
1922
  const pathService = yield* Path9.Path;
1773
- const parse = Effect16.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1923
+ const parse = Effect17.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
1774
1924
  const config = yield* rawConfigReader.readConfigFile(pathService.join(projectFolder, CONFIG_PATH));
1775
1925
  if (!config || typeof config.version !== "number" || config.version < 3) {
1776
1926
  return parseResult;
@@ -1782,9 +1932,9 @@ var VercelBuildOutputParser = class extends Effect16.Service()("VercelBuildOutpu
1782
1932
  merged.regions = [...new Set(merged.regions)];
1783
1933
  return merged;
1784
1934
  });
1785
- const loadFunctions = Effect16.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1786
- const functionConfigs = yield* Effect16.tryPromise({
1787
- try: () => getFilesForPattern2(FUNCTION_CONFIGS_PATTERN, projectFolder),
1935
+ const loadFunctions = Effect17.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
1936
+ const functionConfigs = yield* Effect17.tryPromise({
1937
+ try: () => getFilesForPattern(FUNCTION_CONFIGS_PATTERN, projectFolder),
1788
1938
  catch: (error) => new ConfigFileParseError({
1789
1939
  message: `Failed to scan for function configs: ${error instanceof Error ? error.message : String(error)}`,
1790
1940
  filePath: projectFolder
@@ -2382,7 +2532,7 @@ var schema_default = {
2382
2532
  };
2383
2533
 
2384
2534
  // src/parse-config.ts
2385
- var parseConfigRaw = Effect17.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2535
+ var parseConfigRaw = Effect18.fn("parseConfigRaw")(function* (filePath, projectFolder) {
2386
2536
  const rawReader = yield* RawConfigReader;
2387
2537
  const validator = yield* SchemaValidator;
2388
2538
  const v4Parser = yield* V4ConfigParser;
@@ -2393,7 +2543,7 @@ var parseConfigRaw = Effect17.fn("parseConfigRaw")(function* (filePath, projectF
2393
2543
  };
2394
2544
  const schema = schemaMap[version];
2395
2545
  if (!schema) {
2396
- return yield* Effect17.fail(
2546
+ return yield* Effect18.fail(
2397
2547
  new ConfigVersionError({
2398
2548
  message: `Config file at ${filePath} has an unsupported version: ${version}`,
2399
2549
  filePath,
@@ -2404,11 +2554,11 @@ var parseConfigRaw = Effect17.fn("parseConfigRaw")(function* (filePath, projectF
2404
2554
  yield* validator.validate(parsed, schema, filePath);
2405
2555
  return yield* v4Parser.parse(parsed, projectFolder);
2406
2556
  });
2407
- var parseConfig = Effect17.fn("parseConfig")(function* (filePath, projectFolder) {
2557
+ var parseConfig = Effect18.fn("parseConfig")(function* (filePath, projectFolder) {
2408
2558
  const parseResult = yield* parseConfigRaw(filePath, projectFolder);
2409
2559
  return yield* postProcessConfig(parseResult, projectFolder);
2410
2560
  });
2411
- var postProcessConfig = Effect17.fn("postProcessConfig")(function* (config, projectFolder) {
2561
+ var postProcessConfig = Effect18.fn("postProcessConfig")(function* (config, projectFolder) {
2412
2562
  const vercelParser = yield* VercelBuildOutputParser;
2413
2563
  let result = yield* vercelParser.parse(config, projectFolder);
2414
2564
  const hasAssets = (result.assets?.paths?.length ?? 0) > 0 || (result.assets?.prefixes?.length ?? 0) > 0 || (result.assets?.manifests?.length ?? 0) > 0;
@@ -2464,8 +2614,12 @@ export {
2464
2614
  GigadriveNextBuildManifestV1Schema,
2465
2615
  GigadriveNextBuildManifestV2ExportSchema,
2466
2616
  GigadriveNextBuildManifestV2StandaloneSchema,
2617
+ GigadriveNextMiddlewareDescriptorSchema,
2618
+ GigadriveNextMiddlewareMatcherSchema,
2467
2619
  GigadriveNextPrerenderManifestV1Schema,
2468
2620
  GigadriveNextPrerenderOutputSchema,
2621
+ GigadriveNextPrerenderSeedMethodsSchema,
2622
+ GigadriveNextRouteConditionSchema,
2469
2623
  GigadriveNextServerDescriptorSchema,
2470
2624
  GigadriveNextStaticAssetPrefixSchema,
2471
2625
  MAX_FUNCTION_DURATION_SECONDS,
@@ -2480,6 +2634,7 @@ export {
2480
2634
  StaticAssetManifestV1Schema,
2481
2635
  V4ConfigParser,
2482
2636
  VercelBuildOutputParser,
2637
+ collectAssetFiles,
2483
2638
  defineConfig,
2484
2639
  detectFramework,
2485
2640
  detectPackageManager,