@gigadrive/network-config 5.4.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -46,6 +46,7 @@ __export(src_exports, {
46
46
  ContainerConfigError: () => ContainerConfigError,
47
47
  DEFAULT_CONTAINER_MEMORY_MB: () => DEFAULT_CONTAINER_MEMORY_MB,
48
48
  DEFAULT_FUNCTION_DURATION_SECONDS: () => DEFAULT_FUNCTION_DURATION_SECONDS,
49
+ DEFAULT_RUBY_RUNTIME: () => DEFAULT_RUBY_RUNTIME,
49
50
  DEFAULT_SIDECAR_MEMORY_MB: () => DEFAULT_SIDECAR_MEMORY_MB,
50
51
  FRAMEWORK_DEFINITIONS: () => FRAMEWORK_DEFINITIONS,
51
52
  FrameworkNotDetectedError: () => FrameworkNotDetectedError,
@@ -82,6 +83,7 @@ __export(src_exports, {
82
83
  detectContainerProject: () => detectContainerProject,
83
84
  detectFramework: () => detectFramework,
84
85
  detectPackageManager: () => detectPackageManager,
86
+ detectRubyRuntime: () => detectRubyRuntime,
85
87
  dockerFunctionContainerName: () => dockerFunctionContainerName,
86
88
  filterFunctionsFromAssets: () => filterFunctionsFromAssets,
87
89
  generateConfig: () => generateConfig,
@@ -97,6 +99,9 @@ __export(src_exports, {
97
99
  postProcessConfig: () => postProcessConfig,
98
100
  readComposeContainers: () => readComposeContainers,
99
101
  readDependencies: () => readDependencies,
102
+ rubyRuntimeForRequirement: () => rubyRuntimeForRequirement,
103
+ rubyRuntimeForVersion: () => rubyRuntimeForVersion,
104
+ rubyRuntimeFromProjectFiles: () => rubyRuntimeFromProjectFiles,
100
105
  splitCommandWords: () => splitCommandWords
101
106
  });
102
107
  module.exports = __toCommonJS(src_exports);
@@ -1008,8 +1013,8 @@ var detectContainerProject = import_effect6.Effect.fn("detectContainerProject")(
1008
1013
  });
1009
1014
 
1010
1015
  // src/detection/detect-framework.ts
1011
- var import_platform13 = require("@effect/platform");
1012
- var import_effect19 = require("effect");
1016
+ var import_platform16 = require("@effect/platform");
1017
+ var import_effect24 = require("effect");
1013
1018
 
1014
1019
  // src/detection/detect-package-manager.ts
1015
1020
  var import_platform4 = require("@effect/platform");
@@ -1019,7 +1024,10 @@ var LOCKFILE_MAP = [
1019
1024
  { files: ["pnpm-lock.yaml"], pm: "pnpm" },
1020
1025
  { files: ["yarn.lock"], pm: "yarn" },
1021
1026
  { files: ["package-lock.json"], pm: "npm" },
1022
- { files: ["composer.lock"], pm: "composer" }
1027
+ { files: ["composer.lock"], pm: "composer" },
1028
+ // A Gemfile is checked last and counts even without its lockfile: Bundler
1029
+ // resolves and writes Gemfile.lock on the first install.
1030
+ { files: ["Gemfile.lock", "Gemfile"], pm: "bundler" }
1023
1031
  ];
1024
1032
  var detectPackageManager = import_effect7.Effect.fn("detectPackageManager")(function* (projectFolder) {
1025
1033
  const fs = yield* import_platform4.FileSystem.FileSystem;
@@ -1058,6 +1066,192 @@ var astro = {
1058
1066
  })
1059
1067
  };
1060
1068
 
1069
+ // src/detection/frameworks/ruby-runtime.ts
1070
+ var import_platform5 = require("@effect/platform");
1071
+ var import_effect8 = require("effect");
1072
+
1073
+ // src/detection/frameworks/ruby-requirement.ts
1074
+ var RUBY_VERSION = /^(?:ruby-)?(\d+(?:\.\d+)*)(?:p\d+)?(?:[-.]?(?:preview|rc|dev|alpha|beta|pre)\d*)?$/i;
1075
+ var REQUIREMENT_ATOM = /^(~>|>=|<=|!=|=|>|<)?\s*(\S+)$/;
1076
+ var parseRubyVersion = (text) => {
1077
+ const match = RUBY_VERSION.exec(text);
1078
+ return match ? match[1].split(".").map(Number) : void 0;
1079
+ };
1080
+ var compareRubyVersions = (a, b) => {
1081
+ for (let index = 0; index < Math.max(a.length, b.length); index++) {
1082
+ const difference = (a[index] ?? 0) - (b[index] ?? 0);
1083
+ if (difference !== 0) {
1084
+ return difference;
1085
+ }
1086
+ }
1087
+ return 0;
1088
+ };
1089
+ var pessimisticUpperBound = (segments) => {
1090
+ const kept = segments.length > 1 ? segments.slice(0, -1) : [...segments];
1091
+ kept[kept.length - 1] += 1;
1092
+ return kept;
1093
+ };
1094
+ var parseRubyRequirement = (requirement) => {
1095
+ const parts = requirement.split(",").map((part) => part.trim());
1096
+ const atoms = [];
1097
+ for (const part of parts) {
1098
+ const match = REQUIREMENT_ATOM.exec(part);
1099
+ const segments = match ? parseRubyVersion(match[2]) : void 0;
1100
+ if (!match || !segments) {
1101
+ return void 0;
1102
+ }
1103
+ atoms.push({ operator: match[1] ?? "=", segments });
1104
+ }
1105
+ return atoms;
1106
+ };
1107
+ var atomAllows = ({ operator, segments }, version) => {
1108
+ const comparison = compareRubyVersions(version, segments);
1109
+ switch (operator) {
1110
+ case "=":
1111
+ return comparison === 0;
1112
+ case "!=":
1113
+ return comparison !== 0;
1114
+ case ">":
1115
+ return comparison > 0;
1116
+ case "<":
1117
+ return comparison < 0;
1118
+ case ">=":
1119
+ return comparison >= 0;
1120
+ case "<=":
1121
+ return comparison <= 0;
1122
+ case "~>":
1123
+ return comparison >= 0 && compareRubyVersions(version, pessimisticUpperBound(segments)) < 0;
1124
+ }
1125
+ };
1126
+ var rubyRequirementAllows = (requirement, version) => {
1127
+ const atoms = parseRubyRequirement(requirement);
1128
+ const segments = parseRubyVersion(version);
1129
+ if (!atoms || !segments) {
1130
+ return void 0;
1131
+ }
1132
+ return atoms.every((atom) => atomAllows(atom, segments));
1133
+ };
1134
+
1135
+ // src/detection/frameworks/ruby-runtime.ts
1136
+ var DEFAULT_RUBY_RUNTIME = "ruby-34";
1137
+ var RUBY_RUNTIME_CANDIDATES = [
1138
+ { runtime: "ruby-40", series: [4, 0], newestVersion: "4.0.9999" },
1139
+ { runtime: "ruby-34", series: [3, 4], newestVersion: "3.4.9999" },
1140
+ { runtime: "ruby-33", series: [3, 3], newestVersion: "3.3.9999" }
1141
+ ];
1142
+ var rubyRuntimeForVersion = (version) => {
1143
+ const segments = parseRubyVersion(version);
1144
+ if (!segments) {
1145
+ return void 0;
1146
+ }
1147
+ const series = [segments[0], segments[1] ?? 0];
1148
+ const candidate = RUBY_RUNTIME_CANDIDATES.find((candidate2) => compareRubyVersions(candidate2.series, series) <= 0);
1149
+ return (candidate ?? RUBY_RUNTIME_CANDIDATES[RUBY_RUNTIME_CANDIDATES.length - 1]).runtime;
1150
+ };
1151
+ var rubyRuntimeForRequirement = (requirement) => {
1152
+ const atoms = parseRubyRequirement(requirement);
1153
+ if (!atoms) {
1154
+ return void 0;
1155
+ }
1156
+ if (atoms.length === 1 && atoms[0].operator === "=") {
1157
+ return rubyRuntimeForVersion(atoms[0].segments.join("."));
1158
+ }
1159
+ return RUBY_RUNTIME_CANDIDATES.find(({ newestVersion }) => rubyRequirementAllows(requirement, newestVersion) === true)?.runtime;
1160
+ };
1161
+ var versionFromRubyVersionFile = (content) => content.split(/\r?\n/).map((line) => line.trim()).find((line) => line !== "" && !line.startsWith("#"))?.split(/\s/)[0]?.split("@")[0];
1162
+ var versionFromToolVersionsFile = (content) => /^\s*ruby\s+(\S+)/m.exec(content)?.[1];
1163
+ var versionFromGemfileLock = (content) => /^RUBY VERSION\r?\n\s+ruby\s+(\S+)/m.exec(content)?.[1];
1164
+ var GEMFILE_RUBY_DIRECTIVE = /^\s*ruby[\s(]+(.+)$/m;
1165
+ var GEMFILE_RUBY_FILE = /^(?:file:|:file\s*=>|File\.read\s*\(?)\s*(['"])([^'"]+)\1/;
1166
+ var LEADING_STRINGS = /^\s*(['"])([^'"]*)\1\s*(?:,|\)|#|$)/;
1167
+ var RUBY_VERSION_FILES = [".ruby-version", ".tool-versions", "Gemfile", "Gemfile.lock"];
1168
+ var gemfileRubyDirective = (gemfile) => GEMFILE_RUBY_DIRECTIVE.exec(gemfile)?.[1]?.trim();
1169
+ var gemfileRubyVersionFile = (gemfile) => {
1170
+ const directive = gemfileRubyDirective(gemfile);
1171
+ return directive === void 0 ? void 0 : GEMFILE_RUBY_FILE.exec(directive)?.[2];
1172
+ };
1173
+ var runtimeFromVersionFile = (file, content) => {
1174
+ if (content === void 0) {
1175
+ return void 0;
1176
+ }
1177
+ const parse = file.split("/").at(-1) === ".tool-versions" ? versionFromToolVersionsFile : versionFromRubyVersionFile;
1178
+ const version = parse(content);
1179
+ return version === void 0 ? void 0 : rubyRuntimeForVersion(version);
1180
+ };
1181
+ var runtimeFromGemfile = (gemfile, readFile) => {
1182
+ const directive = gemfile === void 0 ? void 0 : gemfileRubyDirective(gemfile);
1183
+ if (directive === void 0) {
1184
+ return void 0;
1185
+ }
1186
+ const versionFile = GEMFILE_RUBY_FILE.exec(directive)?.[2];
1187
+ if (versionFile !== void 0) {
1188
+ return runtimeFromVersionFile(versionFile, readFile(versionFile));
1189
+ }
1190
+ const requirements = [];
1191
+ let rest = directive;
1192
+ for (let match = LEADING_STRINGS.exec(rest); match; match = LEADING_STRINGS.exec(rest)) {
1193
+ requirements.push(match[2]);
1194
+ rest = rest.slice(match[0].length);
1195
+ }
1196
+ return requirements.length === 0 ? void 0 : rubyRuntimeForRequirement(requirements.join(","));
1197
+ };
1198
+ var runtimeFromGemfileLock = (lockfile) => {
1199
+ const version = lockfile === void 0 ? void 0 : versionFromGemfileLock(lockfile);
1200
+ return version === void 0 ? void 0 : rubyRuntimeForVersion(version);
1201
+ };
1202
+ var rubyRuntimeFromProjectFiles = (readFile) => runtimeFromVersionFile(".ruby-version", readFile(".ruby-version")) ?? runtimeFromVersionFile(".tool-versions", readFile(".tool-versions")) ?? runtimeFromGemfile(readFile("Gemfile"), readFile) ?? runtimeFromGemfileLock(readFile("Gemfile.lock"));
1203
+ var readProjectFile = import_effect8.Effect.fn("readProjectFile")(
1204
+ function* (projectFolder, file) {
1205
+ const fs = yield* import_platform5.FileSystem.FileSystem;
1206
+ const pathService = yield* import_platform5.Path.Path;
1207
+ return yield* fs.readFileString(pathService.join(projectFolder, file));
1208
+ },
1209
+ import_effect8.Effect.catchAll(() => import_effect8.Effect.succeed(void 0))
1210
+ );
1211
+ var detectRubyRuntime = import_effect8.Effect.fn("detectRubyRuntime")(function* (projectFolder) {
1212
+ const files = /* @__PURE__ */ new Map();
1213
+ for (const file of RUBY_VERSION_FILES) {
1214
+ files.set(file, yield* readProjectFile(projectFolder, file));
1215
+ }
1216
+ const gemfile = files.get("Gemfile");
1217
+ const versionFile = gemfile === void 0 ? void 0 : gemfileRubyVersionFile(gemfile);
1218
+ if (versionFile !== void 0 && !files.has(versionFile)) {
1219
+ files.set(versionFile, yield* readProjectFile(projectFolder, versionFile));
1220
+ }
1221
+ return rubyRuntimeFromProjectFiles((file) => files.get(file));
1222
+ });
1223
+ var refineRubyRuntime = import_effect8.Effect.fn("refineRubyRuntime")(function* (defaults, projectFolder) {
1224
+ const runtime = yield* detectRubyRuntime(projectFolder);
1225
+ return runtime ? { ...defaults, runtime } : defaults;
1226
+ });
1227
+ var withRubyRuntime = (framework) => ({
1228
+ ...framework,
1229
+ refineDefaultConfig: (defaults, projectFolder) => import_effect8.Effect.gen(function* () {
1230
+ const refined = framework.refineDefaultConfig ? yield* framework.refineDefaultConfig(defaults, projectFolder) : defaults;
1231
+ return yield* refineRubyRuntime(refined, projectFolder);
1232
+ })
1233
+ });
1234
+
1235
+ // src/detection/frameworks/bridgetown.ts
1236
+ var bridgetown = {
1237
+ slug: "bridgetown",
1238
+ name: "Bridgetown",
1239
+ language: "ruby",
1240
+ detectors: [{ matchPackage: "bridgetown" }],
1241
+ priority: 70,
1242
+ getDefaultConfig: () => ({
1243
+ runtime: DEFAULT_RUBY_RUNTIME,
1244
+ memory: 128,
1245
+ maxDuration: 30,
1246
+ streaming: false,
1247
+ commands: ["bin/bridgetown deploy"],
1248
+ assetsDir: "output",
1249
+ populateAssetCache: true,
1250
+ routes: [],
1251
+ environmentVariables: { BRIDGETOWN_ENV: "production" }
1252
+ })
1253
+ };
1254
+
1061
1255
  // src/detection/generated-secret.ts
1062
1256
  var generatedSecret = (format) => `{{gigadrive.secret:${format}}}`;
1063
1257
 
@@ -1132,8 +1326,8 @@ var codeigniter = {
1132
1326
  };
1133
1327
 
1134
1328
  // src/detection/frameworks/resolve-node-entrypoint.ts
1135
- var import_platform5 = require("@effect/platform");
1136
- var import_effect8 = require("effect");
1329
+ var import_platform6 = require("@effect/platform");
1330
+ var import_effect9 = require("effect");
1137
1331
  var SCRIPT_RUNNERS = /* @__PURE__ */ new Set(["node", "bun", "tsx", "ts-node"]);
1138
1332
  var COMMON_ENTRYPOINT_CANDIDATES = [
1139
1333
  "index.js",
@@ -1181,14 +1375,14 @@ var applyEntrypoint = (defaults, entrypoint) => ({
1181
1375
  (route) => route.destination === defaults.entrypoint ? { ...route, destination: entrypoint } : route
1182
1376
  )
1183
1377
  });
1184
- var resolveNodeServerEntrypoint = (defaults, projectFolder) => import_effect8.Effect.gen(function* () {
1185
- const fs = yield* import_platform5.FileSystem.FileSystem;
1186
- const pathService = yield* import_platform5.Path.Path;
1378
+ var resolveNodeServerEntrypoint = (defaults, projectFolder) => import_effect9.Effect.gen(function* () {
1379
+ const fs = yield* import_platform6.FileSystem.FileSystem;
1380
+ const pathService = yield* import_platform6.Path.Path;
1187
1381
  const isFile = (relativePath) => fs.stat(pathService.join(projectFolder, relativePath)).pipe(
1188
- import_effect8.Effect.map((info) => info.type === "File"),
1189
- import_effect8.Effect.catchAll(() => import_effect8.Effect.succeed(false))
1382
+ import_effect9.Effect.map((info) => info.type === "File"),
1383
+ import_effect9.Effect.catchAll(() => import_effect9.Effect.succeed(false))
1190
1384
  );
1191
- const content = yield* fs.readFileString(pathService.join(projectFolder, "package.json")).pipe(import_effect8.Effect.catchAll(() => import_effect8.Effect.succeed(void 0)));
1385
+ const content = yield* fs.readFileString(pathService.join(projectFolder, "package.json")).pipe(import_effect9.Effect.catchAll(() => import_effect9.Effect.succeed(void 0)));
1192
1386
  const manifest = content ? parsePackageJson(content) : void 0;
1193
1387
  const startScript = typeof manifest?.scripts?.start === "string" ? manifest.scripts.start : void 0;
1194
1388
  const candidates = [
@@ -1268,6 +1462,189 @@ var fastify = {
1268
1462
  refineDefaultConfig: resolveNodeServerEntrypoint
1269
1463
  };
1270
1464
 
1465
+ // src/detection/frameworks/hanami.ts
1466
+ var import_effect13 = require("effect");
1467
+
1468
+ // src/detection/read-dependencies.ts
1469
+ var import_platform7 = require("@effect/platform");
1470
+ var import_effect11 = require("effect");
1471
+
1472
+ // src/detection/types.ts
1473
+ var import_effect10 = require("effect");
1474
+ var ManifestNotFoundError = class extends import_effect10.Schema.TaggedError()("ManifestNotFoundError", {
1475
+ message: import_effect10.Schema.String,
1476
+ filePath: import_effect10.Schema.String
1477
+ }) {
1478
+ };
1479
+ var ManifestReadError = class extends import_effect10.Schema.TaggedError()("ManifestReadError", {
1480
+ message: import_effect10.Schema.String,
1481
+ filePath: import_effect10.Schema.String
1482
+ }) {
1483
+ };
1484
+ var ManifestParseError = class extends import_effect10.Schema.TaggedError()("ManifestParseError", {
1485
+ message: import_effect10.Schema.String,
1486
+ filePath: import_effect10.Schema.String
1487
+ }) {
1488
+ };
1489
+ var FrameworkNotDetectedError = class extends import_effect10.Schema.TaggedError()(
1490
+ "FrameworkNotDetectedError",
1491
+ {
1492
+ message: import_effect10.Schema.String,
1493
+ directory: import_effect10.Schema.String
1494
+ }
1495
+ ) {
1496
+ };
1497
+
1498
+ // src/detection/read-dependencies.ts
1499
+ var MANIFEST_CONFIG = {
1500
+ node: { file: "package.json", depKeys: ["dependencies", "devDependencies"] },
1501
+ php: { file: "composer.json", depKeys: ["require", "require-dev"] }
1502
+ };
1503
+ var GEMFILE_LOCK_SOURCE_SECTIONS = /* @__PURE__ */ new Set(["GEM", "GIT", "PATH"]);
1504
+ var GEMFILE_LOCK_SPEC = /^ {4}([A-Za-z0-9_.-]+) \(/;
1505
+ var GEMFILE_GEM = /^\s*gem[\s(]+['"]([^'"]+)['"]/;
1506
+ var parseGemfileLock = (content) => {
1507
+ const gems = /* @__PURE__ */ new Set();
1508
+ let inSourceSection = false;
1509
+ for (const line of content.split(/\r?\n/)) {
1510
+ if (/^\S/.test(line)) {
1511
+ inSourceSection = GEMFILE_LOCK_SOURCE_SECTIONS.has(line.trim());
1512
+ continue;
1513
+ }
1514
+ const match = inSourceSection ? GEMFILE_LOCK_SPEC.exec(line) : null;
1515
+ if (match) {
1516
+ gems.add(match[1]);
1517
+ }
1518
+ }
1519
+ return gems;
1520
+ };
1521
+ var parseGemfile = (content) => {
1522
+ const gems = /* @__PURE__ */ new Set();
1523
+ for (const line of content.split(/\r?\n/)) {
1524
+ const match = GEMFILE_GEM.exec(line);
1525
+ if (match) {
1526
+ gems.add(match[1]);
1527
+ }
1528
+ }
1529
+ return gems;
1530
+ };
1531
+ var readOptionalText = import_effect11.Effect.fn("readOptionalText")(function* (filePath) {
1532
+ const fs = yield* import_platform7.FileSystem.FileSystem;
1533
+ const exists = yield* fs.exists(filePath).pipe(import_effect11.Effect.catchAll(() => import_effect11.Effect.succeed(false)));
1534
+ if (!exists) {
1535
+ return void 0;
1536
+ }
1537
+ return yield* fs.readFileString(filePath).pipe(import_effect11.Effect.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
1538
+ });
1539
+ var readGemNames = import_effect11.Effect.fn("readGemNames")(function* (projectFolder) {
1540
+ const pathService = yield* import_platform7.Path.Path;
1541
+ const lockfile = yield* readOptionalText(pathService.join(projectFolder, "Gemfile.lock"));
1542
+ if (lockfile !== void 0) {
1543
+ return parseGemfileLock(lockfile);
1544
+ }
1545
+ const gemfile = yield* readOptionalText(pathService.join(projectFolder, "Gemfile"));
1546
+ return gemfile === void 0 ? /* @__PURE__ */ new Set() : parseGemfile(gemfile);
1547
+ });
1548
+ var readManifest = import_effect11.Effect.fn("readManifest")(function* (filePath) {
1549
+ const fs = yield* import_platform7.FileSystem.FileSystem;
1550
+ const exists = yield* fs.exists(filePath).pipe(import_effect11.Effect.catchAll(() => import_effect11.Effect.succeed(false)));
1551
+ if (!exists) {
1552
+ return yield* import_effect11.Effect.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
1553
+ }
1554
+ const content = yield* fs.readFileString(filePath).pipe(import_effect11.Effect.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
1555
+ const parsed = yield* import_effect11.Effect.try({
1556
+ try: () => JSON.parse(content),
1557
+ catch: () => new ManifestParseError({ message: "Failed to parse manifest JSON", filePath })
1558
+ });
1559
+ return parsed;
1560
+ });
1561
+ var readDependencies = import_effect11.Effect.fn("readDependencies")(function* (projectFolder, language) {
1562
+ if (language === "ruby") {
1563
+ return yield* readGemNames(projectFolder);
1564
+ }
1565
+ const pathService = yield* import_platform7.Path.Path;
1566
+ const config = MANIFEST_CONFIG[language];
1567
+ const filePath = pathService.join(projectFolder, config.file);
1568
+ const manifest = yield* readManifest(filePath).pipe(
1569
+ import_effect11.Effect.catchTag("ManifestNotFoundError", () => import_effect11.Effect.succeed(null))
1570
+ );
1571
+ if (!manifest) {
1572
+ return /* @__PURE__ */ new Set();
1573
+ }
1574
+ const deps = /* @__PURE__ */ new Set();
1575
+ for (const key of config.depKeys) {
1576
+ const section = manifest[key];
1577
+ if (section && typeof section === "object" && !Array.isArray(section)) {
1578
+ for (const name of Object.keys(section)) {
1579
+ deps.add(name);
1580
+ }
1581
+ }
1582
+ }
1583
+ return deps;
1584
+ });
1585
+
1586
+ // src/detection/frameworks/ruby-server.ts
1587
+ var import_platform8 = require("@effect/platform");
1588
+ var import_effect12 = require("effect");
1589
+ var rubyServerDefaults = ({
1590
+ entrypoint = "config.ru",
1591
+ memory = 256,
1592
+ commands = [],
1593
+ environmentVariables,
1594
+ excludeFiles,
1595
+ writablePaths = []
1596
+ }) => ({
1597
+ runtime: DEFAULT_RUBY_RUNTIME,
1598
+ memory,
1599
+ maxDuration: 30,
1600
+ streaming: true,
1601
+ commands,
1602
+ entrypoint,
1603
+ assetsDir: "public",
1604
+ populateAssetCache: true,
1605
+ routes: [{ source: "/*", destination: entrypoint }],
1606
+ environmentVariables,
1607
+ ...excludeFiles ? { excludeFiles } : {},
1608
+ ...writablePaths.length > 0 ? { package: { writablePaths } } : {}
1609
+ });
1610
+ var refineRubyPublicDirectory = import_effect12.Effect.fn("refineRubyPublicDirectory")(function* (defaults, projectFolder) {
1611
+ if (!defaults.assetsDir) {
1612
+ return defaults;
1613
+ }
1614
+ const fs = yield* import_platform8.FileSystem.FileSystem;
1615
+ const pathService = yield* import_platform8.Path.Path;
1616
+ const exists = yield* fs.exists(pathService.join(projectFolder, defaults.assetsDir)).pipe(import_effect12.Effect.catchAll(() => import_effect12.Effect.succeed(false)));
1617
+ if (exists) {
1618
+ return defaults;
1619
+ }
1620
+ const withoutAssets = { ...defaults };
1621
+ delete withoutAssets.assetsDir;
1622
+ delete withoutAssets.populateAssetCache;
1623
+ return withoutAssets;
1624
+ });
1625
+
1626
+ // src/detection/frameworks/hanami.ts
1627
+ var refineHanamiAssets = import_effect13.Effect.fn("refineHanamiAssets")(function* (defaults, projectFolder) {
1628
+ const gems = yield* readDependencies(projectFolder, "ruby").pipe(
1629
+ import_effect13.Effect.catchAll(() => import_effect13.Effect.succeed(/* @__PURE__ */ new Set()))
1630
+ );
1631
+ const withPublicDirectory = yield* refineRubyPublicDirectory(defaults, projectFolder);
1632
+ return gems.has("hanami-assets") ? { ...withPublicDirectory, commands: [...withPublicDirectory.commands, "bundle exec hanami assets compile"] } : withPublicDirectory;
1633
+ });
1634
+ var hanami = {
1635
+ slug: "hanami",
1636
+ name: "Hanami",
1637
+ language: "ruby",
1638
+ detectors: [{ matchPackage: "hanami" }, { path: "config.ru" }],
1639
+ priority: 75,
1640
+ getDefaultConfig: () => rubyServerDefaults({
1641
+ excludeFiles: ["tmp/", "log/", "spec/", "node_modules/", ".git/"],
1642
+ writablePaths: ["tmp", "log"],
1643
+ environmentVariables: { HANAMI_ENV: "production", RACK_ENV: "production" }
1644
+ }),
1645
+ refineDefaultConfig: refineHanamiAssets
1646
+ };
1647
+
1271
1648
  // src/detection/frameworks/hono.ts
1272
1649
  var hono = {
1273
1650
  slug: "hono",
@@ -1288,6 +1665,30 @@ var hono = {
1288
1665
  refineDefaultConfig: resolveNodeServerEntrypoint
1289
1666
  };
1290
1667
 
1668
+ // src/detection/frameworks/jekyll.ts
1669
+ var jekyll = {
1670
+ slug: "jekyll",
1671
+ name: "Jekyll",
1672
+ language: "ruby",
1673
+ detectors: [{ matchPackage: "jekyll" }],
1674
+ priority: 70,
1675
+ getDefaultConfig: () => ({
1676
+ runtime: DEFAULT_RUBY_RUNTIME,
1677
+ memory: 128,
1678
+ maxDuration: 30,
1679
+ streaming: false,
1680
+ commands: ["bundle exec jekyll build"],
1681
+ assetsDir: "_site",
1682
+ populateAssetCache: true,
1683
+ routes: [],
1684
+ environmentVariables: { JEKYLL_ENV: "production" }
1685
+ })
1686
+ };
1687
+ var jekyllPresets = [
1688
+ jekyll,
1689
+ { ...jekyll, detectors: [{ matchPackage: "github-pages" }] }
1690
+ ];
1691
+
1291
1692
  // src/detection/frameworks/laminas.ts
1292
1693
  var laminas = {
1293
1694
  slug: "laminas",
@@ -1367,8 +1768,8 @@ var mezzio = {
1367
1768
  };
1368
1769
 
1369
1770
  // src/detection/frameworks/nestjs.ts
1370
- var import_platform6 = require("@effect/platform");
1371
- var import_effect9 = require("effect");
1771
+ var import_platform9 = require("@effect/platform");
1772
+ var import_effect14 = require("effect");
1372
1773
  var isRecord3 = (value) => typeof value === "object" && value !== null;
1373
1774
  var parseNestCliJson = (content) => {
1374
1775
  try {
@@ -1419,9 +1820,9 @@ var nestjs = {
1419
1820
  detectors: [{ matchPackage: "@nestjs/core" }],
1420
1821
  priority: 90,
1421
1822
  getDefaultConfig: () => createNestConfig("dist"),
1422
- refineDefaultConfig: (defaults, projectFolder) => import_effect9.Effect.gen(function* () {
1423
- const fs = yield* import_platform6.FileSystem.FileSystem;
1424
- const content = yield* fs.readFileString(`${projectFolder}/nest-cli.json`).pipe(import_effect9.Effect.catchAll(() => import_effect9.Effect.succeed(void 0)));
1823
+ refineDefaultConfig: (defaults, projectFolder) => import_effect14.Effect.gen(function* () {
1824
+ const fs = yield* import_platform9.FileSystem.FileSystem;
1825
+ const content = yield* fs.readFileString(`${projectFolder}/nest-cli.json`).pipe(import_effect14.Effect.catchAll(() => import_effect14.Effect.succeed(void 0)));
1425
1826
  if (!content) return defaults;
1426
1827
  const nestConfig = parseNestCliJson(content);
1427
1828
  const outputPath = nestConfig ? getProjectOutputPath(nestConfig) : void 0;
@@ -1430,28 +1831,28 @@ var nestjs = {
1430
1831
  };
1431
1832
 
1432
1833
  // src/detection/frameworks/nextjs.ts
1433
- var import_platform8 = require("@effect/platform");
1434
- var import_effect12 = require("effect");
1834
+ var import_platform11 = require("@effect/platform");
1835
+ var import_effect17 = require("effect");
1435
1836
 
1436
1837
  // src/build-output-v3/get-default-path-map.ts
1437
- var import_platform7 = require("@effect/platform");
1438
- var import_effect10 = require("effect");
1439
- var getDefaultPathMap = import_effect10.Effect.fn("getDefaultPathMap")(function* (directory) {
1440
- const fs = yield* import_platform7.FileSystem.FileSystem;
1441
- const pathService = yield* import_platform7.Path.Path;
1838
+ var import_platform10 = require("@effect/platform");
1839
+ var import_effect15 = require("effect");
1840
+ var getDefaultPathMap = import_effect15.Effect.fn("getDefaultPathMap")(function* (directory) {
1841
+ const fs = yield* import_platform10.FileSystem.FileSystem;
1842
+ const pathService = yield* import_platform10.Path.Path;
1442
1843
  const result = {};
1443
- const exists = yield* fs.exists(directory).pipe(import_effect10.Effect.catchAll(() => import_effect10.Effect.succeed(false)));
1844
+ const exists = yield* fs.exists(directory).pipe(import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed(false)));
1444
1845
  if (!exists) {
1445
1846
  return result;
1446
1847
  }
1447
1848
  const MAX_DEPTH = 100;
1448
- const processDirectory = (currentPath, basePath = "", depth = 0) => import_effect10.Effect.gen(function* () {
1849
+ const processDirectory = (currentPath, basePath = "", depth = 0) => import_effect15.Effect.gen(function* () {
1449
1850
  if (depth > MAX_DEPTH) return;
1450
- const entries = yield* fs.readDirectory(currentPath).pipe(import_effect10.Effect.catchAll(() => import_effect10.Effect.succeed([])));
1851
+ const entries = yield* fs.readDirectory(currentPath).pipe(import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed([])));
1451
1852
  for (const name of entries) {
1452
1853
  const fullPath = pathService.join(currentPath, name);
1453
1854
  const relativePath = basePath ? pathService.join(basePath, name) : name;
1454
- const stat = yield* fs.stat(fullPath).pipe(import_effect10.Effect.catchAll(() => import_effect10.Effect.succeed(null)));
1855
+ const stat = yield* fs.stat(fullPath).pipe(import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed(null)));
1455
1856
  if (!stat) continue;
1456
1857
  if (stat.type === "Directory") {
1457
1858
  yield* processDirectory(fullPath, relativePath, depth + 1);
@@ -1468,244 +1869,244 @@ var getDefaultPathMap = import_effect10.Effect.fn("getDefaultPathMap")(function*
1468
1869
  var MAXIMUM_ENTRY_PAGE_PATHS = 50;
1469
1870
 
1470
1871
  // src/nextjs-manifest.ts
1471
- var import_effect11 = require("effect");
1472
- var StringArraySchema = import_effect11.Schema.mutable(import_effect11.Schema.Array(import_effect11.Schema.String));
1473
- var StringRecordSchema = import_effect11.Schema.mutable(import_effect11.Schema.Record({ key: import_effect11.Schema.String, value: import_effect11.Schema.String }));
1474
- var JsonValueSchema = import_effect11.Schema.suspend(
1475
- () => import_effect11.Schema.Union(
1476
- import_effect11.Schema.Null,
1477
- import_effect11.Schema.Boolean,
1478
- import_effect11.Schema.Number,
1479
- import_effect11.Schema.String,
1480
- import_effect11.Schema.mutable(import_effect11.Schema.Array(JsonValueSchema)),
1481
- import_effect11.Schema.mutable(import_effect11.Schema.Record({ key: import_effect11.Schema.String, value: JsonValueSchema }))
1872
+ var import_effect16 = require("effect");
1873
+ var StringArraySchema = import_effect16.Schema.mutable(import_effect16.Schema.Array(import_effect16.Schema.String));
1874
+ var StringRecordSchema = import_effect16.Schema.mutable(import_effect16.Schema.Record({ key: import_effect16.Schema.String, value: import_effect16.Schema.String }));
1875
+ var JsonValueSchema = import_effect16.Schema.suspend(
1876
+ () => import_effect16.Schema.Union(
1877
+ import_effect16.Schema.Null,
1878
+ import_effect16.Schema.Boolean,
1879
+ import_effect16.Schema.Number,
1880
+ import_effect16.Schema.String,
1881
+ import_effect16.Schema.mutable(import_effect16.Schema.Array(JsonValueSchema)),
1882
+ import_effect16.Schema.mutable(import_effect16.Schema.Record({ key: import_effect16.Schema.String, value: JsonValueSchema }))
1482
1883
  )
1483
1884
  );
1484
- var ImageLocalPatternSchema = import_effect11.Schema.mutable(
1485
- import_effect11.Schema.Struct({
1486
- pathname: import_effect11.Schema.optional(import_effect11.Schema.String),
1487
- search: import_effect11.Schema.optional(import_effect11.Schema.String)
1885
+ var ImageLocalPatternSchema = import_effect16.Schema.mutable(
1886
+ import_effect16.Schema.Struct({
1887
+ pathname: import_effect16.Schema.optional(import_effect16.Schema.String),
1888
+ search: import_effect16.Schema.optional(import_effect16.Schema.String)
1488
1889
  })
1489
1890
  );
1490
- var ImageRemotePatternSchema = import_effect11.Schema.mutable(
1491
- import_effect11.Schema.Struct({
1492
- protocol: import_effect11.Schema.optional(import_effect11.Schema.Literal("http", "https")),
1493
- hostname: import_effect11.Schema.String,
1494
- port: import_effect11.Schema.optional(import_effect11.Schema.String),
1495
- pathname: import_effect11.Schema.optional(import_effect11.Schema.String),
1496
- search: import_effect11.Schema.optional(import_effect11.Schema.String)
1891
+ var ImageRemotePatternSchema = import_effect16.Schema.mutable(
1892
+ import_effect16.Schema.Struct({
1893
+ protocol: import_effect16.Schema.optional(import_effect16.Schema.Literal("http", "https")),
1894
+ hostname: import_effect16.Schema.String,
1895
+ port: import_effect16.Schema.optional(import_effect16.Schema.String),
1896
+ pathname: import_effect16.Schema.optional(import_effect16.Schema.String),
1897
+ search: import_effect16.Schema.optional(import_effect16.Schema.String)
1497
1898
  })
1498
1899
  );
1499
- var ImageVariantSchema = import_effect11.Schema.mutable(
1500
- import_effect11.Schema.Struct({
1501
- width: import_effect11.Schema.optional(import_effect11.Schema.Number),
1502
- height: import_effect11.Schema.optional(import_effect11.Schema.Number),
1503
- quality: import_effect11.Schema.optional(import_effect11.Schema.Number),
1504
- format: import_effect11.Schema.optional(import_effect11.Schema.Literal("image/avif", "image/webp", "image/jpeg", "image/png")),
1505
- fit: import_effect11.Schema.optional(import_effect11.Schema.Literal("contain", "cover", "fill", "inside", "outside"))
1900
+ var ImageVariantSchema = import_effect16.Schema.mutable(
1901
+ import_effect16.Schema.Struct({
1902
+ width: import_effect16.Schema.optional(import_effect16.Schema.Number),
1903
+ height: import_effect16.Schema.optional(import_effect16.Schema.Number),
1904
+ quality: import_effect16.Schema.optional(import_effect16.Schema.Number),
1905
+ format: import_effect16.Schema.optional(import_effect16.Schema.Literal("image/avif", "image/webp", "image/jpeg", "image/png")),
1906
+ fit: import_effect16.Schema.optional(import_effect16.Schema.Literal("contain", "cover", "fill", "inside", "outside"))
1506
1907
  })
1507
1908
  );
1508
- var PositiveIntSchema = import_effect11.Schema.Int.pipe(import_effect11.Schema.greaterThan(0));
1509
- var ImagePolicySchema = import_effect11.Schema.mutable(
1510
- import_effect11.Schema.Struct({
1511
- localPatterns: import_effect11.Schema.mutable(import_effect11.Schema.Array(ImageLocalPatternSchema)),
1512
- remotePatterns: import_effect11.Schema.mutable(import_effect11.Schema.Array(ImageRemotePatternSchema)),
1513
- widths: import_effect11.Schema.mutable(import_effect11.Schema.Array(PositiveIntSchema)),
1514
- heights: import_effect11.Schema.mutable(import_effect11.Schema.Array(PositiveIntSchema)),
1515
- qualities: import_effect11.Schema.mutable(import_effect11.Schema.Array(import_effect11.Schema.Number.pipe(import_effect11.Schema.between(1, 100)))),
1516
- formats: import_effect11.Schema.mutable(import_effect11.Schema.Array(import_effect11.Schema.Literal("image/avif", "image/webp", "image/jpeg", "image/png"))),
1517
- minimumCacheTTL: import_effect11.Schema.Number,
1518
- dangerouslyAllowSVG: import_effect11.Schema.Boolean,
1519
- contentSecurityPolicy: import_effect11.Schema.String,
1520
- contentDispositionType: import_effect11.Schema.Literal("inline", "attachment"),
1521
- maximumRedirects: import_effect11.Schema.Number,
1522
- maximumResponseBody: import_effect11.Schema.Number,
1523
- variants: import_effect11.Schema.mutable(import_effect11.Schema.Record({ key: import_effect11.Schema.String, value: ImageVariantSchema }))
1909
+ var PositiveIntSchema = import_effect16.Schema.Int.pipe(import_effect16.Schema.greaterThan(0));
1910
+ var ImagePolicySchema = import_effect16.Schema.mutable(
1911
+ import_effect16.Schema.Struct({
1912
+ localPatterns: import_effect16.Schema.mutable(import_effect16.Schema.Array(ImageLocalPatternSchema)),
1913
+ remotePatterns: import_effect16.Schema.mutable(import_effect16.Schema.Array(ImageRemotePatternSchema)),
1914
+ widths: import_effect16.Schema.mutable(import_effect16.Schema.Array(PositiveIntSchema)),
1915
+ heights: import_effect16.Schema.mutable(import_effect16.Schema.Array(PositiveIntSchema)),
1916
+ qualities: import_effect16.Schema.mutable(import_effect16.Schema.Array(import_effect16.Schema.Number.pipe(import_effect16.Schema.between(1, 100)))),
1917
+ formats: import_effect16.Schema.mutable(import_effect16.Schema.Array(import_effect16.Schema.Literal("image/avif", "image/webp", "image/jpeg", "image/png"))),
1918
+ minimumCacheTTL: import_effect16.Schema.Number,
1919
+ dangerouslyAllowSVG: import_effect16.Schema.Boolean,
1920
+ contentSecurityPolicy: import_effect16.Schema.String,
1921
+ contentDispositionType: import_effect16.Schema.Literal("inline", "attachment"),
1922
+ maximumRedirects: import_effect16.Schema.Number,
1923
+ maximumResponseBody: import_effect16.Schema.Number,
1924
+ variants: import_effect16.Schema.mutable(import_effect16.Schema.Record({ key: import_effect16.Schema.String, value: ImageVariantSchema }))
1524
1925
  })
1525
1926
  );
1526
1927
  var GigadriveNextPrerenderOutputFields = {
1527
- id: import_effect11.Schema.String,
1528
- type: import_effect11.Schema.Literal("PRERENDER"),
1928
+ id: import_effect16.Schema.String,
1929
+ type: import_effect16.Schema.Literal("PRERENDER"),
1529
1930
  pathname: UrlPathnameSchema,
1530
- route: import_effect11.Schema.optional(UrlPathnameSchema),
1531
- parentOutputId: import_effect11.Schema.String,
1532
- groupId: import_effect11.Schema.Number,
1533
- pprChain: import_effect11.Schema.optional(import_effect11.Schema.mutable(import_effect11.Schema.Struct({ headers: HttpSingleValueHeadersSchema }))),
1534
- parentFallbackMode: import_effect11.Schema.optional(JsonValueSchema),
1535
- fallback: import_effect11.Schema.optional(
1536
- import_effect11.Schema.mutable(
1537
- import_effect11.Schema.Struct({
1538
- filePath: import_effect11.Schema.optional(PortableRelativePathSchema),
1539
- initialStatus: import_effect11.Schema.optional(import_effect11.Schema.Int.pipe(import_effect11.Schema.between(100, 599))),
1540
- initialHeaders: import_effect11.Schema.optional(HttpHeadersSchema),
1541
- initialExpiration: import_effect11.Schema.optional(import_effect11.Schema.Number),
1542
- initialRevalidate: import_effect11.Schema.optional(import_effect11.Schema.Union(import_effect11.Schema.Number, import_effect11.Schema.Literal(false))),
1543
- postponedState: import_effect11.Schema.optional(import_effect11.Schema.String)
1931
+ route: import_effect16.Schema.optional(UrlPathnameSchema),
1932
+ parentOutputId: import_effect16.Schema.String,
1933
+ groupId: import_effect16.Schema.Number,
1934
+ pprChain: import_effect16.Schema.optional(import_effect16.Schema.mutable(import_effect16.Schema.Struct({ headers: HttpSingleValueHeadersSchema }))),
1935
+ parentFallbackMode: import_effect16.Schema.optional(JsonValueSchema),
1936
+ fallback: import_effect16.Schema.optional(
1937
+ import_effect16.Schema.mutable(
1938
+ import_effect16.Schema.Struct({
1939
+ filePath: import_effect16.Schema.optional(PortableRelativePathSchema),
1940
+ initialStatus: import_effect16.Schema.optional(import_effect16.Schema.Int.pipe(import_effect16.Schema.between(100, 599))),
1941
+ initialHeaders: import_effect16.Schema.optional(HttpHeadersSchema),
1942
+ initialExpiration: import_effect16.Schema.optional(import_effect16.Schema.Number),
1943
+ initialRevalidate: import_effect16.Schema.optional(import_effect16.Schema.Union(import_effect16.Schema.Number, import_effect16.Schema.Literal(false))),
1944
+ postponedState: import_effect16.Schema.optional(import_effect16.Schema.String)
1544
1945
  })
1545
1946
  )
1546
1947
  ),
1547
- config: import_effect11.Schema.mutable(
1548
- import_effect11.Schema.Struct({
1549
- allowQuery: import_effect11.Schema.optional(StringArraySchema),
1550
- allowHeader: import_effect11.Schema.optional(StringArraySchema),
1551
- bypassFor: import_effect11.Schema.optional(import_effect11.Schema.mutable(import_effect11.Schema.Array(JsonValueSchema))),
1552
- renderingMode: import_effect11.Schema.optional(import_effect11.Schema.String),
1553
- partialFallback: import_effect11.Schema.optional(import_effect11.Schema.Boolean),
1554
- bypassToken: import_effect11.Schema.optional(import_effect11.Schema.String)
1948
+ config: import_effect16.Schema.mutable(
1949
+ import_effect16.Schema.Struct({
1950
+ allowQuery: import_effect16.Schema.optional(StringArraySchema),
1951
+ allowHeader: import_effect16.Schema.optional(StringArraySchema),
1952
+ bypassFor: import_effect16.Schema.optional(import_effect16.Schema.mutable(import_effect16.Schema.Array(JsonValueSchema))),
1953
+ renderingMode: import_effect16.Schema.optional(import_effect16.Schema.String),
1954
+ partialFallback: import_effect16.Schema.optional(import_effect16.Schema.Boolean),
1955
+ bypassToken: import_effect16.Schema.optional(import_effect16.Schema.String)
1555
1956
  })
1556
1957
  )
1557
1958
  };
1558
- var GigadriveNextPrerenderClassificationSchema = import_effect11.Schema.Struct({
1559
- routeType: import_effect11.Schema.Literal("route", "fallback", "shell", "page"),
1560
- response: import_effect11.Schema.Literal("empty", "initial", "complete"),
1561
- compute: import_effect11.Schema.Literal("blocking", "resuming", "static"),
1562
- htmlSize: import_effect11.Schema.optional(import_effect11.Schema.Number)
1959
+ var GigadriveNextPrerenderClassificationSchema = import_effect16.Schema.Struct({
1960
+ routeType: import_effect16.Schema.Literal("route", "fallback", "shell", "page"),
1961
+ response: import_effect16.Schema.Literal("empty", "initial", "complete"),
1962
+ compute: import_effect16.Schema.Literal("blocking", "resuming", "static"),
1963
+ htmlSize: import_effect16.Schema.optional(import_effect16.Schema.Number)
1563
1964
  });
1564
- var GigadriveNextPrerenderWithoutClassificationSchema = import_effect11.Schema.Struct({
1565
- routeType: import_effect11.Schema.optional(import_effect11.Schema.Never),
1566
- response: import_effect11.Schema.optional(import_effect11.Schema.Never),
1567
- compute: import_effect11.Schema.optional(import_effect11.Schema.Never),
1568
- htmlSize: import_effect11.Schema.optional(import_effect11.Schema.Never)
1965
+ var GigadriveNextPrerenderWithoutClassificationSchema = import_effect16.Schema.Struct({
1966
+ routeType: import_effect16.Schema.optional(import_effect16.Schema.Never),
1967
+ response: import_effect16.Schema.optional(import_effect16.Schema.Never),
1968
+ compute: import_effect16.Schema.optional(import_effect16.Schema.Never),
1969
+ htmlSize: import_effect16.Schema.optional(import_effect16.Schema.Never)
1569
1970
  });
1570
- var GigadriveNextPrerenderOutputSchema = import_effect11.Schema.Union(
1571
- import_effect11.Schema.mutable(
1572
- import_effect11.Schema.Struct({ ...GigadriveNextPrerenderOutputFields, ...GigadriveNextPrerenderClassificationSchema.fields })
1971
+ var GigadriveNextPrerenderOutputSchema = import_effect16.Schema.Union(
1972
+ import_effect16.Schema.mutable(
1973
+ import_effect16.Schema.Struct({ ...GigadriveNextPrerenderOutputFields, ...GigadriveNextPrerenderClassificationSchema.fields })
1573
1974
  ),
1574
- import_effect11.Schema.mutable(
1575
- import_effect11.Schema.Struct({
1975
+ import_effect16.Schema.mutable(
1976
+ import_effect16.Schema.Struct({
1576
1977
  ...GigadriveNextPrerenderOutputFields,
1577
1978
  ...GigadriveNextPrerenderWithoutClassificationSchema.fields
1578
1979
  })
1579
1980
  )
1580
1981
  );
1581
- var GigadriveNextStaticAssetPrefixSchema = import_effect11.Schema.mutable(
1582
- import_effect11.Schema.Struct({
1982
+ var GigadriveNextStaticAssetPrefixSchema = import_effect16.Schema.mutable(
1983
+ import_effect16.Schema.Struct({
1583
1984
  sourceDir: PortableRelativePathSchema,
1584
1985
  urlPrefix: PortableRelativePathSchema,
1585
- immutable: import_effect11.Schema.Boolean
1986
+ immutable: import_effect16.Schema.Boolean
1586
1987
  })
1587
1988
  );
1588
- var GigadriveNextRouteConditionSchema = import_effect11.Schema.Union(
1589
- import_effect11.Schema.mutable(
1590
- import_effect11.Schema.Struct({
1591
- type: import_effect11.Schema.Literal("header", "cookie", "query"),
1592
- key: import_effect11.Schema.String,
1593
- value: import_effect11.Schema.optional(import_effect11.Schema.String)
1989
+ var GigadriveNextRouteConditionSchema = import_effect16.Schema.Union(
1990
+ import_effect16.Schema.mutable(
1991
+ import_effect16.Schema.Struct({
1992
+ type: import_effect16.Schema.Literal("header", "cookie", "query"),
1993
+ key: import_effect16.Schema.String,
1994
+ value: import_effect16.Schema.optional(import_effect16.Schema.String)
1594
1995
  })
1595
1996
  ),
1596
- import_effect11.Schema.mutable(
1597
- import_effect11.Schema.Struct({
1598
- type: import_effect11.Schema.Literal("host"),
1599
- value: import_effect11.Schema.String
1997
+ import_effect16.Schema.mutable(
1998
+ import_effect16.Schema.Struct({
1999
+ type: import_effect16.Schema.Literal("host"),
2000
+ value: import_effect16.Schema.String
1600
2001
  })
1601
2002
  )
1602
2003
  );
1603
- var GigadriveNextMiddlewareMatcherSchema = import_effect11.Schema.mutable(
1604
- import_effect11.Schema.Struct({
1605
- source: import_effect11.Schema.String,
1606
- sourceRegex: import_effect11.Schema.String,
1607
- has: import_effect11.Schema.optional(import_effect11.Schema.mutable(import_effect11.Schema.Array(GigadriveNextRouteConditionSchema))),
1608
- missing: import_effect11.Schema.optional(import_effect11.Schema.mutable(import_effect11.Schema.Array(GigadriveNextRouteConditionSchema)))
2004
+ var GigadriveNextMiddlewareMatcherSchema = import_effect16.Schema.mutable(
2005
+ import_effect16.Schema.Struct({
2006
+ source: import_effect16.Schema.String,
2007
+ sourceRegex: import_effect16.Schema.String,
2008
+ has: import_effect16.Schema.optional(import_effect16.Schema.mutable(import_effect16.Schema.Array(GigadriveNextRouteConditionSchema))),
2009
+ missing: import_effect16.Schema.optional(import_effect16.Schema.mutable(import_effect16.Schema.Array(GigadriveNextRouteConditionSchema)))
1609
2010
  })
1610
2011
  );
1611
- var GigadriveNextMiddlewareDescriptorSchema = import_effect11.Schema.Union(
1612
- import_effect11.Schema.mutable(
1613
- import_effect11.Schema.Struct({
1614
- present: import_effect11.Schema.Literal(true),
1615
- matchers: import_effect11.Schema.mutable(import_effect11.Schema.Array(GigadriveNextMiddlewareMatcherSchema))
2012
+ var GigadriveNextMiddlewareDescriptorSchema = import_effect16.Schema.Union(
2013
+ import_effect16.Schema.mutable(
2014
+ import_effect16.Schema.Struct({
2015
+ present: import_effect16.Schema.Literal(true),
2016
+ matchers: import_effect16.Schema.mutable(import_effect16.Schema.Array(GigadriveNextMiddlewareMatcherSchema))
1616
2017
  })
1617
2018
  ),
1618
- import_effect11.Schema.mutable(
1619
- import_effect11.Schema.Struct({
1620
- present: import_effect11.Schema.Literal(false),
1621
- matchers: import_effect11.Schema.mutable(import_effect11.Schema.Tuple())
2019
+ import_effect16.Schema.mutable(
2020
+ import_effect16.Schema.Struct({
2021
+ present: import_effect16.Schema.Literal(false),
2022
+ matchers: import_effect16.Schema.mutable(import_effect16.Schema.Tuple())
1622
2023
  })
1623
2024
  )
1624
2025
  );
1625
- var GigadriveNextServerDescriptorSchema = import_effect11.Schema.mutable(
1626
- import_effect11.Schema.Struct({
1627
- maxDuration: import_effect11.Schema.optional(import_effect11.Schema.Number),
1628
- preferredRegion: import_effect11.Schema.optional(import_effect11.Schema.Union(import_effect11.Schema.String, StringArraySchema)),
1629
- env: import_effect11.Schema.optional(StringRecordSchema)
2026
+ var GigadriveNextServerDescriptorSchema = import_effect16.Schema.mutable(
2027
+ import_effect16.Schema.Struct({
2028
+ maxDuration: import_effect16.Schema.optional(import_effect16.Schema.Number),
2029
+ preferredRegion: import_effect16.Schema.optional(import_effect16.Schema.Union(import_effect16.Schema.String, StringArraySchema)),
2030
+ env: import_effect16.Schema.optional(StringRecordSchema)
1630
2031
  })
1631
2032
  );
1632
- var PrerenderArraySchema = import_effect11.Schema.mutable(import_effect11.Schema.Array(GigadriveNextPrerenderOutputSchema));
1633
- var StaticAssetArraySchema = import_effect11.Schema.mutable(import_effect11.Schema.Array(GigadriveNextStaticAssetPrefixSchema));
1634
- var JsonValueArraySchema = import_effect11.Schema.mutable(import_effect11.Schema.Array(JsonValueSchema));
1635
- var GigadriveNextPrerenderSeedMethodsSchema = import_effect11.Schema.mutable(
1636
- import_effect11.Schema.Tuple(import_effect11.Schema.Literal("GET"), import_effect11.Schema.Literal("HEAD"))
2033
+ var PrerenderArraySchema = import_effect16.Schema.mutable(import_effect16.Schema.Array(GigadriveNextPrerenderOutputSchema));
2034
+ var StaticAssetArraySchema = import_effect16.Schema.mutable(import_effect16.Schema.Array(GigadriveNextStaticAssetPrefixSchema));
2035
+ var JsonValueArraySchema = import_effect16.Schema.mutable(import_effect16.Schema.Array(JsonValueSchema));
2036
+ var GigadriveNextPrerenderSeedMethodsSchema = import_effect16.Schema.mutable(
2037
+ import_effect16.Schema.Tuple(import_effect16.Schema.Literal("GET"), import_effect16.Schema.Literal("HEAD"))
1637
2038
  );
1638
- var GigadriveNextBuildManifestV1Schema = import_effect11.Schema.mutable(
1639
- import_effect11.Schema.Struct({
1640
- version: import_effect11.Schema.Literal(1),
1641
- output: import_effect11.Schema.Literal("standalone", "export"),
2039
+ var GigadriveNextBuildManifestV1Schema = import_effect16.Schema.mutable(
2040
+ import_effect16.Schema.Struct({
2041
+ version: import_effect16.Schema.Literal(1),
2042
+ output: import_effect16.Schema.Literal("standalone", "export"),
1642
2043
  distDir: PortableRelativePathSchema,
1643
2044
  repoRootToProject: RepositoryRelativePathSchema,
1644
- nextVersion: import_effect11.Schema.String,
1645
- buildId: import_effect11.Schema.String
2045
+ nextVersion: import_effect16.Schema.String,
2046
+ buildId: import_effect16.Schema.String
1646
2047
  })
1647
2048
  );
1648
- var GigadriveNextBuildManifestV2ExportSchema = import_effect11.Schema.mutable(
1649
- import_effect11.Schema.Struct({
1650
- version: import_effect11.Schema.Literal(2),
1651
- mode: import_effect11.Schema.Literal("export"),
2049
+ var GigadriveNextBuildManifestV2ExportSchema = import_effect16.Schema.mutable(
2050
+ import_effect16.Schema.Struct({
2051
+ version: import_effect16.Schema.Literal(2),
2052
+ mode: import_effect16.Schema.Literal("export"),
1652
2053
  distDir: PortableRelativePathSchema,
1653
2054
  repoRootToProject: RepositoryRelativePathSchema,
1654
- nextVersion: import_effect11.Schema.String,
1655
- buildId: import_effect11.Schema.String
2055
+ nextVersion: import_effect16.Schema.String,
2056
+ buildId: import_effect16.Schema.String
1656
2057
  })
1657
2058
  );
1658
- var GigadriveNextBuildManifestV2StandaloneSchema = import_effect11.Schema.mutable(
1659
- import_effect11.Schema.Struct({
1660
- version: import_effect11.Schema.Literal(2),
1661
- mode: import_effect11.Schema.Literal("standalone-v2"),
2059
+ var GigadriveNextBuildManifestV2StandaloneSchema = import_effect16.Schema.mutable(
2060
+ import_effect16.Schema.Struct({
2061
+ version: import_effect16.Schema.Literal(2),
2062
+ mode: import_effect16.Schema.Literal("standalone-v2"),
1662
2063
  distDir: PortableRelativePathSchema,
1663
2064
  repoRootToProject: RepositoryRelativePathSchema,
1664
- nextVersion: import_effect11.Schema.String,
1665
- buildId: import_effect11.Schema.String,
2065
+ nextVersion: import_effect16.Schema.String,
2066
+ buildId: import_effect16.Schema.String,
1666
2067
  server: GigadriveNextServerDescriptorSchema,
1667
- config: import_effect11.Schema.mutable(
1668
- import_effect11.Schema.Struct({
1669
- basePath: import_effect11.Schema.String,
1670
- trailingSlash: import_effect11.Schema.Boolean,
1671
- cacheComponents: import_effect11.Schema.Boolean,
1672
- i18n: import_effect11.Schema.optional(JsonValueSchema),
1673
- images: import_effect11.Schema.optional(ImagePolicySchema)
2068
+ config: import_effect16.Schema.mutable(
2069
+ import_effect16.Schema.Struct({
2070
+ basePath: import_effect16.Schema.String,
2071
+ trailingSlash: import_effect16.Schema.Boolean,
2072
+ cacheComponents: import_effect16.Schema.Boolean,
2073
+ i18n: import_effect16.Schema.optional(JsonValueSchema),
2074
+ images: import_effect16.Schema.optional(ImagePolicySchema)
1674
2075
  })
1675
2076
  ),
1676
- routing: import_effect11.Schema.mutable(
1677
- import_effect11.Schema.Struct({
2077
+ routing: import_effect16.Schema.mutable(
2078
+ import_effect16.Schema.Struct({
1678
2079
  beforeMiddleware: JsonValueArraySchema,
1679
2080
  beforeFiles: JsonValueArraySchema,
1680
2081
  afterFiles: JsonValueArraySchema,
1681
2082
  dynamicRoutes: JsonValueArraySchema,
1682
2083
  onMatch: JsonValueArraySchema,
1683
2084
  fallback: JsonValueArraySchema,
1684
- shouldNormalizeNextData: import_effect11.Schema.Boolean,
2085
+ shouldNormalizeNextData: import_effect16.Schema.Boolean,
1685
2086
  rsc: JsonValueSchema
1686
2087
  })
1687
2088
  ),
1688
- outputs: import_effect11.Schema.mutable(
1689
- import_effect11.Schema.Struct({
2089
+ outputs: import_effect16.Schema.mutable(
2090
+ import_effect16.Schema.Struct({
1690
2091
  prerenders: PrerenderArraySchema,
1691
- prerenderManifest: import_effect11.Schema.optional(PortableRelativePathSchema),
1692
- assetManifest: import_effect11.Schema.optional(PortableRelativePathSchema),
1693
- entryPagePaths: import_effect11.Schema.optional(import_effect11.Schema.mutable(import_effect11.Schema.Array(UrlPathnameSchema))),
2092
+ prerenderManifest: import_effect16.Schema.optional(PortableRelativePathSchema),
2093
+ assetManifest: import_effect16.Schema.optional(PortableRelativePathSchema),
2094
+ entryPagePaths: import_effect16.Schema.optional(import_effect16.Schema.mutable(import_effect16.Schema.Array(UrlPathnameSchema))),
1694
2095
  staticAssets: StaticAssetArraySchema,
1695
- middleware: import_effect11.Schema.optional(GigadriveNextMiddlewareDescriptorSchema)
2096
+ middleware: import_effect16.Schema.optional(GigadriveNextMiddlewareDescriptorSchema)
1696
2097
  })
1697
2098
  )
1698
2099
  })
1699
2100
  );
1700
- var GigadriveNextBuildManifestSchema = import_effect11.Schema.Union(
2101
+ var GigadriveNextBuildManifestSchema = import_effect16.Schema.Union(
1701
2102
  GigadriveNextBuildManifestV1Schema,
1702
2103
  GigadriveNextBuildManifestV2ExportSchema,
1703
2104
  GigadriveNextBuildManifestV2StandaloneSchema
1704
2105
  );
1705
- var GigadriveNextPrerenderManifestV1Schema = import_effect11.Schema.mutable(
1706
- import_effect11.Schema.Struct({
1707
- version: import_effect11.Schema.Literal(1),
1708
- seedMethods: import_effect11.Schema.optional(GigadriveNextPrerenderSeedMethodsSchema),
2106
+ var GigadriveNextPrerenderManifestV1Schema = import_effect16.Schema.mutable(
2107
+ import_effect16.Schema.Struct({
2108
+ version: import_effect16.Schema.Literal(1),
2109
+ seedMethods: import_effect16.Schema.optional(GigadriveNextPrerenderSeedMethodsSchema),
1709
2110
  prerenders: PrerenderArraySchema
1710
2111
  })
1711
2112
  );
@@ -1715,22 +2116,22 @@ var parseGigadriveNextPrerenderManifest = (content) => decodeJson(GigadriveNextP
1715
2116
  // src/detection/frameworks/nextjs.ts
1716
2117
  var toPortablePath = (value) => value.replaceAll("\\", "/");
1717
2118
  var STANDALONE_SERVER_MEMORY_MB = 1024;
1718
- var resolveStandaloneServer = import_effect12.Effect.fn("nextjs.resolveStandaloneServer")(function* (projectFolder, distDir, repoRootToProject) {
1719
- const fs = yield* import_platform8.FileSystem.FileSystem;
1720
- const pathService = yield* import_platform8.Path.Path;
2119
+ var resolveStandaloneServer = import_effect17.Effect.fn("nextjs.resolveStandaloneServer")(function* (projectFolder, distDir, repoRootToProject) {
2120
+ const fs = yield* import_platform11.FileSystem.FileSystem;
2121
+ const pathService = yield* import_platform11.Path.Path;
1721
2122
  const standaloneRoot = pathService.join(projectFolder, distDir, "standalone");
1722
2123
  const monorepoServer = pathService.join(standaloneRoot, repoRootToProject, "server.js");
1723
2124
  const rootServer = pathService.join(standaloneRoot, "server.js");
1724
- const monorepoServerExists = yield* fs.exists(monorepoServer).pipe(import_effect12.Effect.catchAll(() => import_effect12.Effect.succeed(false)));
2125
+ const monorepoServerExists = yield* fs.exists(monorepoServer).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(false)));
1725
2126
  const serverPath = monorepoServerExists ? monorepoServer : rootServer;
1726
- const serverExists = yield* fs.exists(serverPath).pipe(import_effect12.Effect.catchAll(() => import_effect12.Effect.succeed(false)));
2127
+ const serverExists = yield* fs.exists(serverPath).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(false)));
1727
2128
  if (!serverExists) return void 0;
1728
2129
  const serverDirectory = pathService.dirname(serverPath);
1729
2130
  const entrypoint = toPortablePath(pathService.relative(standaloneRoot, serverPath));
1730
2131
  return { standaloneRoot, serverDirectory, entrypoint };
1731
2132
  });
1732
- var buildStandalonePublicAssets = import_effect12.Effect.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
1733
- const pathService = yield* import_platform8.Path.Path;
2133
+ var buildStandalonePublicAssets = import_effect17.Effect.fn("nextjs.buildStandalonePublicAssets")(function* (projectFolder, standaloneRoot, serverDirectory) {
2134
+ const pathService = yield* import_platform11.Path.Path;
1734
2135
  const publicFiles = yield* getDefaultPathMap(pathService.join(projectFolder, "public"));
1735
2136
  const assetPaths = [];
1736
2137
  const assetOverrides = {};
@@ -1746,8 +2147,8 @@ var buildStandalonePublicAssets = import_effect12.Effect.fn("nextjs.buildStandal
1746
2147
  }
1747
2148
  return { assetPaths, assetOverrides, filePathMap };
1748
2149
  });
1749
- var createStaticExportConfig = import_effect12.Effect.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
1750
- const pathService = yield* import_platform8.Path.Path;
2150
+ var createStaticExportConfig = import_effect17.Effect.fn("nextjs.createStaticExportConfig")(function* (defaults, projectFolder) {
2151
+ const pathService = yield* import_platform11.Path.Path;
1751
2152
  const outputDirectory = pathService.join(projectFolder, "out");
1752
2153
  const files = yield* getDefaultPathMap(outputDirectory);
1753
2154
  const assetPaths = [];
@@ -1770,8 +2171,8 @@ var createStaticExportConfig = import_effect12.Effect.fn("nextjs.createStaticExp
1770
2171
  package: void 0
1771
2172
  };
1772
2173
  });
1773
- var createStandaloneConfig = import_effect12.Effect.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
1774
- const pathService = yield* import_platform8.Path.Path;
2174
+ var createStandaloneConfig = import_effect17.Effect.fn("nextjs.createStandaloneConfig")(function* (defaults, projectFolder, manifest) {
2175
+ const pathService = yield* import_platform11.Path.Path;
1775
2176
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
1776
2177
  if (!resolved) return defaults;
1777
2178
  const { standaloneRoot, serverDirectory, entrypoint } = resolved;
@@ -1804,7 +2205,7 @@ var createStandaloneConfig = import_effect12.Effect.fn("nextjs.createStandaloneC
1804
2205
  }
1805
2206
  };
1806
2207
  });
1807
- var createStandaloneV2Config = import_effect12.Effect.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
2208
+ var createStandaloneV2Config = import_effect17.Effect.fn("nextjs.createStandaloneV2Config")(function* (defaults, projectFolder, manifest) {
1808
2209
  const resolved = yield* resolveStandaloneServer(projectFolder, manifest.distDir, manifest.repoRootToProject);
1809
2210
  if (!resolved) return defaults;
1810
2211
  const { standaloneRoot, serverDirectory, entrypoint } = resolved;
@@ -1912,9 +2313,9 @@ var nextjs = {
1912
2313
  routes: [{ source: "/*", destination: ".next/standalone/server.js" }],
1913
2314
  environmentVariables: { NODE_ENV: "production" }
1914
2315
  }),
1915
- refineDefaultConfig: (defaults, projectFolder) => import_effect12.Effect.gen(function* () {
1916
- const fs = yield* import_platform8.FileSystem.FileSystem;
1917
- const manifestContent = yield* fs.readFileString(`${projectFolder}/.gigadrive/nextjs.json`).pipe(import_effect12.Effect.catchAll(() => import_effect12.Effect.succeed(void 0)));
2316
+ refineDefaultConfig: (defaults, projectFolder) => import_effect17.Effect.gen(function* () {
2317
+ const fs = yield* import_platform11.FileSystem.FileSystem;
2318
+ const manifestContent = yield* fs.readFileString(`${projectFolder}/.gigadrive/nextjs.json`).pipe(import_effect17.Effect.catchAll(() => import_effect17.Effect.succeed(void 0)));
1918
2319
  const manifest = manifestContent ? parseGigadriveNextBuildManifest(manifestContent) : void 0;
1919
2320
  if (!manifest) return defaults;
1920
2321
  if (manifest.version === 2) {
@@ -1925,8 +2326,8 @@ var nextjs = {
1925
2326
  };
1926
2327
 
1927
2328
  // src/detection/frameworks/nuxt.ts
1928
- var import_platform9 = require("@effect/platform");
1929
- var import_effect13 = require("effect");
2329
+ var import_platform12 = require("@effect/platform");
2330
+ var import_effect18 = require("effect");
1930
2331
  var isVercelBuildOutputV3 = (content) => {
1931
2332
  try {
1932
2333
  const config = JSON.parse(content);
@@ -1953,9 +2354,9 @@ var nuxt = {
1953
2354
  routes: [{ source: "/*", destination: ".output/server/index.mjs" }],
1954
2355
  environmentVariables: { NODE_ENV: "production", NITRO_PRESET: "node-server" }
1955
2356
  }),
1956
- refineDefaultConfig: (defaults, projectFolder) => import_effect13.Effect.gen(function* () {
1957
- const fs = yield* import_platform9.FileSystem.FileSystem;
1958
- const buildOutputConfig = yield* fs.readFileString(`${projectFolder}/.vercel/output/config.json`).pipe(import_effect13.Effect.catchAll(() => import_effect13.Effect.succeed(void 0)));
2357
+ refineDefaultConfig: (defaults, projectFolder) => import_effect18.Effect.gen(function* () {
2358
+ const fs = yield* import_platform12.FileSystem.FileSystem;
2359
+ const buildOutputConfig = yield* fs.readFileString(`${projectFolder}/.vercel/output/config.json`).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed(void 0)));
1959
2360
  if (!buildOutputConfig || !isVercelBuildOutputV3(buildOutputConfig)) {
1960
2361
  return defaults;
1961
2362
  }
@@ -1970,16 +2371,16 @@ var nuxt = {
1970
2371
  };
1971
2372
 
1972
2373
  // src/detection/frameworks/php.ts
1973
- var import_platform10 = require("@effect/platform");
1974
- var import_effect14 = require("effect");
2374
+ var import_platform13 = require("@effect/platform");
2375
+ var import_effect19 = require("effect");
1975
2376
  var COMPOSER_FILES = ["composer.json", "composer.lock"];
1976
2377
  var DOCUMENT_ROOTS = ["public", "web", "webroot", "public_html", "htdocs", "."];
1977
- var refinePhpDocumentRoot = (defaults, projectFolder) => import_effect14.Effect.gen(function* () {
1978
- const fs = yield* import_platform10.FileSystem.FileSystem;
1979
- const pathService = yield* import_platform10.Path.Path;
2378
+ var refinePhpDocumentRoot = (defaults, projectFolder) => import_effect19.Effect.gen(function* () {
2379
+ const fs = yield* import_platform13.FileSystem.FileSystem;
2380
+ const pathService = yield* import_platform13.Path.Path;
1980
2381
  for (const documentRoot of DOCUMENT_ROOTS) {
1981
2382
  const frontController = pathService.join(projectFolder, documentRoot, "index.php");
1982
- if (yield* fs.exists(frontController).pipe(import_effect14.Effect.catchAll(() => import_effect14.Effect.succeed(false)))) {
2383
+ if (yield* fs.exists(frontController).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(false)))) {
1983
2384
  return phpFrontControllerDefaults({ documentRoot, excludeFiles: COMPOSER_FILES });
1984
2385
  }
1985
2386
  }
@@ -2003,12 +2404,12 @@ var phpSites = DOCUMENT_ROOTS.map((documentRoot) => ({
2003
2404
  detectors: [{ path: frontControllerPath(documentRoot) }],
2004
2405
  priority: 6,
2005
2406
  getDefaultConfig: () => ({ ...getDefaultConfig(), installCommand: "" }),
2006
- refineDefaultConfig: (defaults, projectFolder) => refinePhpDocumentRoot(defaults, projectFolder).pipe(import_effect14.Effect.map((refined) => ({ ...refined, installCommand: "" })))
2407
+ refineDefaultConfig: (defaults, projectFolder) => refinePhpDocumentRoot(defaults, projectFolder).pipe(import_effect19.Effect.map((refined) => ({ ...refined, installCommand: "" })))
2007
2408
  }));
2008
2409
 
2009
2410
  // src/detection/frameworks/php-runtime.ts
2010
- var import_platform11 = require("@effect/platform");
2011
- var import_effect15 = require("effect");
2411
+ var import_platform14 = require("@effect/platform");
2412
+ var import_effect20 = require("effect");
2012
2413
 
2013
2414
  // src/detection/frameworks/composer-constraint.ts
2014
2415
  var STABILITY_SUFFIX = /-(?:dev|alpha|beta|a|b|rc|patch|pl|p|stable)\.?\d*$/i;
@@ -2132,31 +2533,86 @@ var PHP_RUNTIME_CANDIDATES = [
2132
2533
  { runtime: "php-83", newestVersion: "8.3.9999" }
2133
2534
  ];
2134
2535
  var phpRuntimeForConstraint = (constraint) => PHP_RUNTIME_CANDIDATES.find(({ newestVersion }) => composerConstraintAllows(constraint, newestVersion) === true)?.runtime;
2135
- var readPhpConstraint = import_effect15.Effect.fn("readPhpConstraint")(
2536
+ var readPhpConstraint = import_effect20.Effect.fn("readPhpConstraint")(
2136
2537
  function* (projectFolder) {
2137
- const fs = yield* import_platform11.FileSystem.FileSystem;
2138
- const pathService = yield* import_platform11.Path.Path;
2538
+ const fs = yield* import_platform14.FileSystem.FileSystem;
2539
+ const pathService = yield* import_platform14.Path.Path;
2139
2540
  const content = yield* fs.readFileString(pathService.join(projectFolder, "composer.json"));
2140
- const manifest = yield* import_effect15.Effect.try(() => JSON.parse(content));
2541
+ const manifest = yield* import_effect20.Effect.try(() => JSON.parse(content));
2141
2542
  const requires = manifest && typeof manifest === "object" && "require" in manifest ? manifest.require : void 0;
2142
2543
  const php = requires && typeof requires === "object" && "php" in requires ? requires.php : void 0;
2143
- return typeof php === "string" ? import_effect15.Option.some(php) : import_effect15.Option.none();
2544
+ return typeof php === "string" ? import_effect20.Option.some(php) : import_effect20.Option.none();
2144
2545
  },
2145
- import_effect15.Effect.catchAll(() => import_effect15.Effect.succeed(import_effect15.Option.none()))
2546
+ import_effect20.Effect.catchAll(() => import_effect20.Effect.succeed(import_effect20.Option.none()))
2146
2547
  );
2147
- var refineComposerPhpRuntime = import_effect15.Effect.fn("refineComposerPhpRuntime")(function* (defaults, projectFolder) {
2548
+ var refineComposerPhpRuntime = import_effect20.Effect.fn("refineComposerPhpRuntime")(function* (defaults, projectFolder) {
2148
2549
  const constraint = yield* readPhpConstraint(projectFolder);
2149
- const runtime = import_effect15.Option.getOrUndefined(import_effect15.Option.flatMapNullable(constraint, phpRuntimeForConstraint));
2550
+ const runtime = import_effect20.Option.getOrUndefined(import_effect20.Option.flatMapNullable(constraint, phpRuntimeForConstraint));
2150
2551
  return runtime ? { ...defaults, runtime } : defaults;
2151
2552
  });
2152
2553
  var withComposerPhpRuntime = (framework) => ({
2153
2554
  ...framework,
2154
- refineDefaultConfig: (defaults, projectFolder) => import_effect15.Effect.gen(function* () {
2555
+ refineDefaultConfig: (defaults, projectFolder) => import_effect20.Effect.gen(function* () {
2155
2556
  const refined = framework.refineDefaultConfig ? yield* framework.refineDefaultConfig(defaults, projectFolder) : defaults;
2156
2557
  return yield* refineComposerPhpRuntime(refined, projectFolder);
2157
2558
  })
2158
2559
  });
2159
2560
 
2561
+ // src/detection/frameworks/rack.ts
2562
+ var rack = {
2563
+ slug: "rack",
2564
+ name: "Rack",
2565
+ language: "ruby",
2566
+ detectors: [{ path: "config.ru" }, { path: "Gemfile" }],
2567
+ priority: 10,
2568
+ getDefaultConfig: () => rubyServerDefaults({ environmentVariables: { RACK_ENV: "production" } }),
2569
+ refineDefaultConfig: refineRubyPublicDirectory
2570
+ };
2571
+
2572
+ // src/detection/frameworks/rails.ts
2573
+ var import_effect21 = require("effect");
2574
+ var ASSET_PIPELINE_GEMS = ["propshaft", "sprockets", "sprockets-rails"];
2575
+ var refineRailsAssets = import_effect21.Effect.fn("refineRailsAssets")(function* (defaults, projectFolder) {
2576
+ const gems = yield* readDependencies(projectFolder, "ruby").pipe(
2577
+ import_effect21.Effect.catchAll(() => import_effect21.Effect.succeed(/* @__PURE__ */ new Set()))
2578
+ );
2579
+ const withPublicDirectory = yield* refineRubyPublicDirectory(defaults, projectFolder);
2580
+ return ASSET_PIPELINE_GEMS.some((gem) => gems.has(gem)) ? {
2581
+ ...withPublicDirectory,
2582
+ commands: [...withPublicDirectory.commands, "SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile"]
2583
+ } : withPublicDirectory;
2584
+ });
2585
+ var rails = {
2586
+ slug: "rails",
2587
+ name: "Ruby on Rails",
2588
+ language: "ruby",
2589
+ // `railties` is in every Rails application's Gemfile.lock, including ones
2590
+ // that require individual Rails gems instead of `rails`.
2591
+ detectors: [{ matchPackage: "railties" }, { path: "config/application.rb" }],
2592
+ priority: 80,
2593
+ getDefaultConfig: () => rubyServerDefaults({
2594
+ memory: 512,
2595
+ excludeFiles: ["tmp/", "log/", "storage/", "test/", "spec/", "node_modules/", ".git/"],
2596
+ // tmp/, log/ and storage/ are excluded, so the directories Rails writes
2597
+ // caches, pids, sockets, logs and Active Storage files to are created empty.
2598
+ writablePaths: ["tmp/cache", "tmp/pids", "tmp/sockets", "tmp/storage", "log", "storage"],
2599
+ environmentVariables: {
2600
+ RAILS_ENV: "production",
2601
+ RACK_ENV: "production",
2602
+ // Signs and encrypts cookies and sessions; Rails refuses to boot in production without it.
2603
+ SECRET_KEY_BASE: generatedSecret("hex"),
2604
+ RAILS_LOG_TO_STDOUT: "1",
2605
+ RAILS_SERVE_STATIC_FILES: "1",
2606
+ RAILS_MAX_THREADS: "5"
2607
+ }
2608
+ }),
2609
+ refineDefaultConfig: refineRailsAssets
2610
+ };
2611
+ var railsPresets = [
2612
+ rails,
2613
+ { ...rails, detectors: [{ matchPackage: "rails" }, { path: "config/application.rb" }] }
2614
+ ];
2615
+
2160
2616
  // src/detection/frameworks/remix.ts
2161
2617
  var remix = {
2162
2618
  slug: "remix",
@@ -2178,6 +2634,45 @@ var remix = {
2178
2634
  })
2179
2635
  };
2180
2636
 
2637
+ // src/detection/frameworks/roda.ts
2638
+ var roda = {
2639
+ slug: "roda",
2640
+ name: "Roda",
2641
+ language: "ruby",
2642
+ detectors: [{ matchPackage: "roda" }, { path: "config.ru" }],
2643
+ priority: 60,
2644
+ getDefaultConfig: () => rubyServerDefaults({ environmentVariables: { RACK_ENV: "production" } }),
2645
+ refineDefaultConfig: refineRubyPublicDirectory
2646
+ };
2647
+
2648
+ // src/detection/frameworks/sinatra.ts
2649
+ var import_platform15 = require("@effect/platform");
2650
+ var import_effect22 = require("effect");
2651
+ var SINATRA_ENTRYPOINTS = ["config.ru", "app.rb", "main.rb", "server.rb", "application.rb"];
2652
+ var refineSinatraEntrypoint = import_effect22.Effect.fn("refineSinatraEntrypoint")(function* (defaults, projectFolder) {
2653
+ const fs = yield* import_platform15.FileSystem.FileSystem;
2654
+ const pathService = yield* import_platform15.Path.Path;
2655
+ const entrypoint = yield* import_effect22.Effect.findFirst(
2656
+ SINATRA_ENTRYPOINTS,
2657
+ (file) => fs.exists(pathService.join(projectFolder, file)).pipe(import_effect22.Effect.catchAll(() => import_effect22.Effect.succeed(false)))
2658
+ );
2659
+ const withPublicDirectory = yield* refineRubyPublicDirectory(defaults, projectFolder);
2660
+ return entrypoint._tag === "Some" ? {
2661
+ ...withPublicDirectory,
2662
+ entrypoint: entrypoint.value,
2663
+ routes: [{ source: "/*", destination: entrypoint.value }]
2664
+ } : withPublicDirectory;
2665
+ });
2666
+ var sinatra = {
2667
+ slug: "sinatra",
2668
+ name: "Sinatra",
2669
+ language: "ruby",
2670
+ detectors: [{ matchPackage: "sinatra" }],
2671
+ priority: 60,
2672
+ getDefaultConfig: () => rubyServerDefaults({ environmentVariables: { APP_ENV: "production", RACK_ENV: "production" } }),
2673
+ refineDefaultConfig: refineSinatraEntrypoint
2674
+ };
2675
+
2181
2676
  // src/detection/frameworks/slim.ts
2182
2677
  var slim = {
2183
2678
  slug: "slim",
@@ -2298,17 +2793,33 @@ var FRAMEWORK_DEFINITIONS = [
2298
2793
  mezzio,
2299
2794
  yii,
2300
2795
  slim,
2796
+ ...railsPresets,
2797
+ hanami,
2798
+ ...jekyllPresets,
2799
+ bridgetown,
2800
+ sinatra,
2801
+ roda,
2301
2802
  hono,
2302
2803
  elysia,
2303
2804
  fastify,
2304
2805
  express,
2806
+ rack,
2305
2807
  ...phpComposerProjects,
2306
2808
  ...phpSites,
2307
2809
  vite
2308
- ].map((framework) => framework.language === "php" ? withComposerPhpRuntime(framework) : framework).sort((a, b) => b.priority - a.priority);
2810
+ ].map((framework) => {
2811
+ switch (framework.language) {
2812
+ case "php":
2813
+ return withComposerPhpRuntime(framework);
2814
+ case "ruby":
2815
+ return withRubyRuntime(framework);
2816
+ case "node":
2817
+ return framework;
2818
+ }
2819
+ }).sort((a, b) => b.priority - a.priority);
2309
2820
 
2310
2821
  // src/detection/generate-config.ts
2311
- var import_effect16 = require("effect");
2822
+ var import_effect23 = require("effect");
2312
2823
  var getInstallCommand = (pm) => {
2313
2824
  switch (pm) {
2314
2825
  case "bun":
@@ -2319,6 +2830,8 @@ var getInstallCommand = (pm) => {
2319
2830
  return "yarn install";
2320
2831
  case "composer":
2321
2832
  return "composer install";
2833
+ case "bundler":
2834
+ return "bundle install";
2322
2835
  case "npm":
2323
2836
  default:
2324
2837
  return "npm install";
@@ -2329,11 +2842,17 @@ var isPrivatePhpProjectFile = (projectPath) => {
2329
2842
  const segments = projectPath.split("/").filter((segment) => segment !== "" && segment !== ".");
2330
2843
  return segments.some((segment) => segment.startsWith(".")) || segments[0] === "vendor" || segments[0] === "node_modules" || segments.length === 1 && COMPOSER_ROOT_FILES.has(segments[0] ?? "");
2331
2844
  };
2332
- var generateConfig = import_effect16.Effect.fn("generateConfig")(function* (framework, packageManager, projectFolder, refinedDefaults) {
2845
+ var BUNDLER_FILES = /* @__PURE__ */ new Set(["Gemfile", "Gemfile.lock", "gems.rb", "gems.locked"]);
2846
+ var isPrivateRubyProjectFile = (projectPath) => {
2847
+ const segments = projectPath.split("/").filter((segment) => segment !== "" && segment !== ".");
2848
+ const fileName = segments.at(-1) ?? "";
2849
+ return segments.some((segment) => segment.startsWith(".")) || segments[0] === "vendor" || /\.(rb|ru)$/i.test(fileName) || BUNDLER_FILES.has(fileName);
2850
+ };
2851
+ var generateConfig = import_effect23.Effect.fn("generateConfig")(function* (framework, packageManager, projectFolder, refinedDefaults) {
2333
2852
  const defaults = refinedDefaults ?? framework.getDefaultConfig(packageManager);
2334
2853
  const installCmd = defaults.installCommand ?? getInstallCommand(packageManager);
2335
2854
  const commands = installCmd ? [installCmd, ...defaults.commands] : [...defaults.commands];
2336
- yield* import_effect16.Effect.logDebug(`Generating config for ${framework.name}`, {
2855
+ yield* import_effect23.Effect.logDebug(`Generating config for ${framework.name}`, {
2337
2856
  runtime: defaults.runtime,
2338
2857
  entrypoint: defaults.entrypoint,
2339
2858
  commands
@@ -2376,6 +2895,7 @@ var generateConfig = import_effect16.Effect.fn("generateConfig")(function* (fram
2376
2895
  for (const file of yield* collectAssetFiles(projectFolder, assetsDir)) {
2377
2896
  if (framework.language === "php" && /\.(php|phtml|phar)$/i.test(file)) continue;
2378
2897
  if (framework.language === "php" && isPrivatePhpProjectFile(`${assetsDir}/${file}`)) continue;
2898
+ if (framework.language === "ruby" && isPrivateRubyProjectFile(`${assetsDir}/${file}`)) continue;
2379
2899
  paths.push(`${assetsDir}/${file}`);
2380
2900
  if (!servesDirectoryIndexes || file in overrides) continue;
2381
2901
  if (file === "index.html") {
@@ -2398,80 +2918,10 @@ var generateConfig = import_effect16.Effect.fn("generateConfig")(function* (fram
2398
2918
  return config;
2399
2919
  });
2400
2920
 
2401
- // src/detection/read-dependencies.ts
2402
- var import_platform12 = require("@effect/platform");
2403
- var import_effect18 = require("effect");
2404
-
2405
- // src/detection/types.ts
2406
- var import_effect17 = require("effect");
2407
- var ManifestNotFoundError = class extends import_effect17.Schema.TaggedError()("ManifestNotFoundError", {
2408
- message: import_effect17.Schema.String,
2409
- filePath: import_effect17.Schema.String
2410
- }) {
2411
- };
2412
- var ManifestReadError = class extends import_effect17.Schema.TaggedError()("ManifestReadError", {
2413
- message: import_effect17.Schema.String,
2414
- filePath: import_effect17.Schema.String
2415
- }) {
2416
- };
2417
- var ManifestParseError = class extends import_effect17.Schema.TaggedError()("ManifestParseError", {
2418
- message: import_effect17.Schema.String,
2419
- filePath: import_effect17.Schema.String
2420
- }) {
2421
- };
2422
- var FrameworkNotDetectedError = class extends import_effect17.Schema.TaggedError()(
2423
- "FrameworkNotDetectedError",
2424
- {
2425
- message: import_effect17.Schema.String,
2426
- directory: import_effect17.Schema.String
2427
- }
2428
- ) {
2429
- };
2430
-
2431
- // src/detection/read-dependencies.ts
2432
- var MANIFEST_CONFIG = {
2433
- node: { file: "package.json", depKeys: ["dependencies", "devDependencies"] },
2434
- php: { file: "composer.json", depKeys: ["require", "require-dev"] }
2435
- };
2436
- var readManifest = import_effect18.Effect.fn("readManifest")(function* (filePath) {
2437
- const fs = yield* import_platform12.FileSystem.FileSystem;
2438
- const exists = yield* fs.exists(filePath).pipe(import_effect18.Effect.catchAll(() => import_effect18.Effect.succeed(false)));
2439
- if (!exists) {
2440
- return yield* import_effect18.Effect.fail(new ManifestNotFoundError({ message: "Manifest not found", filePath }));
2441
- }
2442
- const content = yield* fs.readFileString(filePath).pipe(import_effect18.Effect.mapError(() => new ManifestReadError({ message: "Failed to read manifest", filePath })));
2443
- const parsed = yield* import_effect18.Effect.try({
2444
- try: () => JSON.parse(content),
2445
- catch: () => new ManifestParseError({ message: "Failed to parse manifest JSON", filePath })
2446
- });
2447
- return parsed;
2448
- });
2449
- var readDependencies = import_effect18.Effect.fn("readDependencies")(function* (projectFolder, language) {
2450
- const pathService = yield* import_platform12.Path.Path;
2451
- const config = MANIFEST_CONFIG[language];
2452
- const filePath = pathService.join(projectFolder, config.file);
2453
- const manifest = yield* readManifest(filePath).pipe(
2454
- import_effect18.Effect.catchTag("ManifestNotFoundError", () => import_effect18.Effect.succeed(null))
2455
- );
2456
- if (!manifest) {
2457
- return /* @__PURE__ */ new Set();
2458
- }
2459
- const deps = /* @__PURE__ */ new Set();
2460
- for (const key of config.depKeys) {
2461
- const section = manifest[key];
2462
- if (section && typeof section === "object" && !Array.isArray(section)) {
2463
- for (const name of Object.keys(section)) {
2464
- deps.add(name);
2465
- }
2466
- }
2467
- }
2468
- return deps;
2469
- });
2470
-
2471
2921
  // src/detection/detect-framework.ts
2472
- var matchesDetectionItem = import_effect19.Effect.fn("matchesDetectionItem")(function* (item, projectFolder, framework, cachedReadDeps) {
2473
- const fs = yield* import_platform13.FileSystem.FileSystem;
2474
- const pathService = yield* import_platform13.Path.Path;
2922
+ var matchesDetectionItem = import_effect24.Effect.fn("matchesDetectionItem")(function* (item, projectFolder, framework, cachedReadDeps) {
2923
+ const fs = yield* import_platform16.FileSystem.FileSystem;
2924
+ const pathService = yield* import_platform16.Path.Path;
2475
2925
  if (item.matchPackage != null) {
2476
2926
  const deps = yield* cachedReadDeps(`${projectFolder}\0${framework.language}`);
2477
2927
  if (!deps.has(item.matchPackage)) {
@@ -2480,12 +2930,12 @@ var matchesDetectionItem = import_effect19.Effect.fn("matchesDetectionItem")(fun
2480
2930
  }
2481
2931
  if (item.path != null) {
2482
2932
  const filePath = pathService.join(projectFolder, item.path);
2483
- const exists = yield* fs.exists(filePath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed(false)));
2933
+ const exists = yield* fs.exists(filePath).pipe(import_effect24.Effect.catchAll(() => import_effect24.Effect.succeed(false)));
2484
2934
  if (!exists) {
2485
2935
  return false;
2486
2936
  }
2487
2937
  if (item.matchContent != null) {
2488
- const content = yield* fs.readFileString(filePath).pipe(import_effect19.Effect.catchAll(() => import_effect19.Effect.succeed("")));
2938
+ const content = yield* fs.readFileString(filePath).pipe(import_effect24.Effect.catchAll(() => import_effect24.Effect.succeed("")));
2489
2939
  let regexMatch = false;
2490
2940
  try {
2491
2941
  regexMatch = new RegExp(item.matchContent).test(content);
@@ -2498,7 +2948,7 @@ var matchesDetectionItem = import_effect19.Effect.fn("matchesDetectionItem")(fun
2498
2948
  }
2499
2949
  return true;
2500
2950
  });
2501
- var matchesFramework = import_effect19.Effect.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
2951
+ var matchesFramework = import_effect24.Effect.fn("matchesFramework")(function* (framework, projectFolder, cachedReadDeps) {
2502
2952
  for (const detector of framework.detectors) {
2503
2953
  const matches = yield* matchesDetectionItem(detector, projectFolder, framework, cachedReadDeps);
2504
2954
  if (!matches) {
@@ -2507,9 +2957,19 @@ var matchesFramework = import_effect19.Effect.fn("matchesFramework")(function* (
2507
2957
  }
2508
2958
  return true;
2509
2959
  });
2510
- var detectFramework = import_effect19.Effect.fn("detectFramework")(function* (projectFolder) {
2511
- yield* import_effect19.Effect.logDebug(`Detecting framework in ${projectFolder}`);
2512
- const cachedReadDeps = yield* import_effect19.Effect.cachedFunction((key) => {
2960
+ var packageManagerForLanguage = (language, detected) => {
2961
+ switch (language) {
2962
+ case "php":
2963
+ return "composer";
2964
+ case "ruby":
2965
+ return "bundler";
2966
+ case "node":
2967
+ return detected === "bundler" ? "npm" : detected;
2968
+ }
2969
+ };
2970
+ var detectFramework = import_effect24.Effect.fn("detectFramework")(function* (projectFolder) {
2971
+ yield* import_effect24.Effect.logDebug(`Detecting framework in ${projectFolder}`);
2972
+ const cachedReadDeps = yield* import_effect24.Effect.cachedFunction((key) => {
2513
2973
  const sepIndex = key.lastIndexOf("\0");
2514
2974
  const folder = key.slice(0, sepIndex);
2515
2975
  const language = key.slice(sepIndex + 1);
@@ -2518,16 +2978,16 @@ var detectFramework = import_effect19.Effect.fn("detectFramework")(function* (pr
2518
2978
  for (const framework of FRAMEWORK_DEFINITIONS) {
2519
2979
  const matches = yield* matchesFramework(framework, projectFolder, cachedReadDeps);
2520
2980
  if (matches) {
2521
- yield* import_effect19.Effect.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
2981
+ yield* import_effect24.Effect.log(`Detected framework: ${framework.name}`, { slug: framework.slug });
2522
2982
  const detectedPackageManager = yield* detectPackageManager(projectFolder);
2523
- const packageManager = framework.language === "php" ? "composer" : detectedPackageManager;
2983
+ const packageManager = packageManagerForLanguage(framework.language, detectedPackageManager);
2524
2984
  const defaults = framework.getDefaultConfig(packageManager);
2525
2985
  const refinedDefaults = framework.refineDefaultConfig ? yield* framework.refineDefaultConfig(defaults, projectFolder) : defaults;
2526
2986
  const config = yield* generateConfig(framework, packageManager, projectFolder, refinedDefaults);
2527
2987
  return { framework, packageManager, config };
2528
2988
  }
2529
2989
  }
2530
- return yield* import_effect19.Effect.fail(
2990
+ return yield* import_effect24.Effect.fail(
2531
2991
  new FrameworkNotDetectedError({
2532
2992
  message: `No framework detected in project directory`,
2533
2993
  directory: projectFolder
@@ -2536,9 +2996,9 @@ var detectFramework = import_effect19.Effect.fn("detectFramework")(function* (pr
2536
2996
  });
2537
2997
 
2538
2998
  // src/detection/merge-config.ts
2539
- var import_effect20 = require("effect");
2540
- var mergeWithFrameworkDefaults = import_effect20.Effect.fn("mergeWithFrameworkDefaults")(function* (userConfig, frameworkConfig) {
2541
- yield* import_effect20.Effect.logDebug("Merging user config with framework defaults");
2999
+ var import_effect25 = require("effect");
3000
+ var mergeWithFrameworkDefaults = import_effect25.Effect.fn("mergeWithFrameworkDefaults")(function* (userConfig, frameworkConfig) {
3001
+ yield* import_effect25.Effect.logDebug("Merging user config with framework defaults");
2542
3002
  const userHasAssets = (userConfig.assets?.paths?.length ?? 0) > 0 || (userConfig.assets?.prefixes?.length ?? 0) > 0 || (userConfig.assets?.manifests?.length ?? 0) > 0;
2543
3003
  const isContainer = (entrypoint) => entrypoint.runtime === CONTAINER_RUNTIME;
2544
3004
  const userFileFunctions = userConfig.entrypoints.filter((entrypoint) => !isContainer(entrypoint));
@@ -2579,23 +3039,23 @@ var filterFunctionsFromAssets = (config) => {
2579
3039
  };
2580
3040
 
2581
3041
  // src/parse-config.ts
2582
- var import_effect26 = require("effect");
3042
+ var import_effect31 = require("effect");
2583
3043
 
2584
3044
  // src/services/raw-config-reader.ts
2585
- var import_platform14 = require("@effect/platform");
2586
- var import_effect22 = require("effect");
3045
+ var import_platform17 = require("@effect/platform");
3046
+ var import_effect27 = require("effect");
2587
3047
  var import_yaml2 = require("yaml");
2588
3048
 
2589
3049
  // src/services/config-module-loader.ts
2590
- var import_effect21 = require("effect");
3050
+ var import_effect26 = require("effect");
2591
3051
  var import_jiti = require("jiti");
2592
3052
  var MISSING_DEFAULT_EXPORT = /* @__PURE__ */ Symbol("MissingDefaultExport");
2593
3053
  var STRICT_DEFAULT_EXPORT_EXTENSIONS = [".ts", ".mts", ".mjs"];
2594
- var ConfigModuleLoader = class extends import_effect21.Effect.Service()("ConfigModuleLoader", {
2595
- effect: import_effect21.Effect.gen(function* () {
2596
- const loadConfigModule = import_effect21.Effect.fn("ConfigModuleLoader.loadConfigModule")(function* (filePath) {
3054
+ var ConfigModuleLoader = class extends import_effect26.Effect.Service()("ConfigModuleLoader", {
3055
+ effect: import_effect26.Effect.gen(function* () {
3056
+ const loadConfigModule = import_effect26.Effect.fn("ConfigModuleLoader.loadConfigModule")(function* (filePath) {
2597
3057
  const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
2598
- const mod = yield* import_effect21.Effect.tryPromise({
3058
+ const mod = yield* import_effect26.Effect.tryPromise({
2599
3059
  try: async () => {
2600
3060
  const jiti = (0, import_jiti.createJiti)(filePath, { fsCache: false, interopDefault: true, moduleCache: false });
2601
3061
  const namespace = await jiti.import(filePath);
@@ -2614,7 +3074,7 @@ var ConfigModuleLoader = class extends import_effect21.Effect.Service()("ConfigM
2614
3074
  })
2615
3075
  });
2616
3076
  if (mod === MISSING_DEFAULT_EXPORT) {
2617
- return yield* import_effect21.Effect.fail(
3077
+ return yield* import_effect26.Effect.fail(
2618
3078
  new ConfigModuleLoadError({
2619
3079
  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.`,
2620
3080
  filePath
@@ -2622,7 +3082,7 @@ var ConfigModuleLoader = class extends import_effect21.Effect.Service()("ConfigM
2622
3082
  );
2623
3083
  }
2624
3084
  if (typeof mod === "function") {
2625
- return yield* import_effect21.Effect.fail(
3085
+ return yield* import_effect26.Effect.fail(
2626
3086
  new ConfigModuleLoadError({
2627
3087
  message: `Config module at ${filePath} default-exports a function; config factories are not supported. Export a config object instead (optionally wrapped in defineConfig).`,
2628
3088
  filePath
@@ -2630,7 +3090,7 @@ var ConfigModuleLoader = class extends import_effect21.Effect.Service()("ConfigM
2630
3090
  );
2631
3091
  }
2632
3092
  if (typeof mod !== "object" || mod === null || Array.isArray(mod)) {
2633
- return yield* import_effect21.Effect.fail(
3093
+ return yield* import_effect26.Effect.fail(
2634
3094
  new ConfigModuleLoadError({
2635
3095
  message: `Config module at ${filePath} must default-export a config object.`,
2636
3096
  filePath
@@ -2660,36 +3120,36 @@ var ALLOWED_CONFIG_NAMES = [
2660
3120
  "nebula.json"
2661
3121
  ];
2662
3122
  var MODULE_EXTENSIONS = [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs"];
2663
- var RawConfigReader = class extends import_effect22.Effect.Service()("RawConfigReader", {
3123
+ var RawConfigReader = class extends import_effect27.Effect.Service()("RawConfigReader", {
2664
3124
  dependencies: [ConfigModuleLoader.Default],
2665
- effect: import_effect22.Effect.gen(function* () {
2666
- const fs = yield* import_platform14.FileSystem.FileSystem;
2667
- const pathService = yield* import_platform14.Path.Path;
3125
+ effect: import_effect27.Effect.gen(function* () {
3126
+ const fs = yield* import_platform17.FileSystem.FileSystem;
3127
+ const pathService = yield* import_platform17.Path.Path;
2668
3128
  const moduleLoader = yield* ConfigModuleLoader;
2669
- const findConfig = import_effect22.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
3129
+ const findConfig = import_effect27.Effect.fn("RawConfigReader.findConfig")(function* (projectFolder) {
2670
3130
  for (const name of ALLOWED_CONFIG_NAMES) {
2671
3131
  const filePath = pathService.join(projectFolder, name);
2672
- const exists = yield* fs.exists(filePath).pipe(import_effect22.Effect.catchAll(() => import_effect22.Effect.succeed(false)));
3132
+ const exists = yield* fs.exists(filePath).pipe(import_effect27.Effect.catchAll(() => import_effect27.Effect.succeed(false)));
2673
3133
  if (exists) {
2674
3134
  return filePath;
2675
3135
  }
2676
3136
  }
2677
3137
  return null;
2678
3138
  });
2679
- const readRawConfig = import_effect22.Effect.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
2680
- const exists = yield* fs.exists(filePath).pipe(import_effect22.Effect.catchAll(() => import_effect22.Effect.succeed(false)));
3139
+ const readRawConfig = import_effect27.Effect.fn("RawConfigReader.readRawConfig")(function* (filePath, options) {
3140
+ const exists = yield* fs.exists(filePath).pipe(import_effect27.Effect.catchAll(() => import_effect27.Effect.succeed(false)));
2681
3141
  if (!exists) {
2682
- return yield* import_effect22.Effect.fail(
3142
+ return yield* import_effect27.Effect.fail(
2683
3143
  new ConfigFileNotFoundError({ message: `Config file not found at ${filePath}`, filePath })
2684
3144
  );
2685
3145
  }
2686
3146
  const fileContents = yield* fs.readFileString(filePath).pipe(
2687
- import_effect22.Effect.mapError(
3147
+ import_effect27.Effect.mapError(
2688
3148
  () => new ConfigFileParseError({ message: `Failed to read config file at ${filePath}`, filePath })
2689
3149
  )
2690
3150
  );
2691
3151
  if (fileContents.length === 0) {
2692
- return yield* import_effect22.Effect.fail(
3152
+ return yield* import_effect27.Effect.fail(
2693
3153
  new ConfigFileEmptyError({ message: `Config file is empty at ${filePath}`, filePath })
2694
3154
  );
2695
3155
  }
@@ -2705,7 +3165,7 @@ var RawConfigReader = class extends import_effect22.Effect.Service()("RawConfigR
2705
3165
  parsed = (0, import_yaml2.parse)(fileContents);
2706
3166
  }
2707
3167
  } catch (error) {
2708
- return yield* import_effect22.Effect.fail(
3168
+ return yield* import_effect27.Effect.fail(
2709
3169
  new ConfigFileParseError({
2710
3170
  message: `Failed to parse config file at ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`,
2711
3171
  filePath,
@@ -2715,21 +3175,21 @@ var RawConfigReader = class extends import_effect22.Effect.Service()("RawConfigR
2715
3175
  }
2716
3176
  }
2717
3177
  if (parsed == null) {
2718
- return yield* import_effect22.Effect.fail(
3178
+ return yield* import_effect27.Effect.fail(
2719
3179
  new ConfigFileParseError({ message: `Config file could not be parsed at ${filePath}`, filePath })
2720
3180
  );
2721
3181
  }
2722
3182
  if (!options?.disableVersionCheck && typeof parsed.version !== "number") {
2723
- return yield* import_effect22.Effect.fail(
3183
+ return yield* import_effect27.Effect.fail(
2724
3184
  new ConfigVersionError({ message: `Config file is missing version at ${filePath}`, filePath })
2725
3185
  );
2726
3186
  }
2727
3187
  return parsed;
2728
3188
  });
2729
3189
  const readConfigFile = (configFilePath) => readRawConfig(configFilePath, { disableVersionCheck: true }).pipe(
2730
- import_effect22.Effect.map((parsed) => parsed),
2731
- import_effect22.Effect.catchTag("ConfigFileNotFoundError", () => import_effect22.Effect.succeed(null)),
2732
- import_effect22.Effect.withSpan("RawConfigReader.readConfigFile")
3190
+ import_effect27.Effect.map((parsed) => parsed),
3191
+ import_effect27.Effect.catchTag("ConfigFileNotFoundError", () => import_effect27.Effect.succeed(null)),
3192
+ import_effect27.Effect.withSpan("RawConfigReader.readConfigFile")
2733
3193
  );
2734
3194
  return { findConfig, readRawConfig, readConfigFile };
2735
3195
  })
@@ -2739,17 +3199,17 @@ var RawConfigReader = class extends import_effect22.Effect.Service()("RawConfigR
2739
3199
  // src/services/schema-validator.ts
2740
3200
  var import_ajv = __toESM(require("ajv"));
2741
3201
  var import_ajv_formats = __toESM(require("ajv-formats"));
2742
- var import_effect23 = require("effect");
2743
- var SchemaValidator = class extends import_effect23.Effect.Service()("SchemaValidator", {
2744
- effect: import_effect23.Effect.gen(function* () {
3202
+ var import_effect28 = require("effect");
3203
+ var SchemaValidator = class extends import_effect28.Effect.Service()("SchemaValidator", {
3204
+ effect: import_effect28.Effect.gen(function* () {
2745
3205
  const ajv = new import_ajv.default();
2746
3206
  (0, import_ajv_formats.default)(ajv);
2747
- const validate = import_effect23.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
3207
+ const validate = import_effect28.Effect.fn("SchemaValidator.validate")(function* (config, schema, filePath) {
2748
3208
  const compiledValidate = ajv.compile(schema);
2749
3209
  const valid = compiledValidate(config);
2750
3210
  if (!valid) {
2751
3211
  const errors = compiledValidate.errors?.map((e) => `${e.instancePath || "/"} ${e.message ?? ""}`.trim()) ?? [];
2752
- return yield* import_effect23.Effect.fail(
3212
+ return yield* import_effect28.Effect.fail(
2753
3213
  new ConfigSchemaValidationError({
2754
3214
  message: `Config file at ${filePath} is invalid: ${ajv.errorsText(compiledValidate.errors)}`,
2755
3215
  filePath,
@@ -2805,7 +3265,7 @@ var getFilesForPattern = async (pattern, projectFolder, excludeFiles = []) => {
2805
3265
  };
2806
3266
 
2807
3267
  // src/services/v4-config-parser.ts
2808
- var import_effect24 = require("effect");
3268
+ var import_effect29 = require("effect");
2809
3269
  var import_minimatch2 = require("minimatch");
2810
3270
  var import_node_path2 = require("path");
2811
3271
  var import_safe_regex2 = __toESM(require("safe-regex2"));
@@ -2821,7 +3281,7 @@ var toArray = (value) => {
2821
3281
  if (value == null) return void 0;
2822
3282
  return Array.isArray(value) ? value : [value];
2823
3283
  };
2824
- var runtimeStreamsByDefault = (runtime) => runtime == null || runtime.startsWith("node-") || runtime.startsWith("bun-");
3284
+ var runtimeStreamsByDefault = (runtime) => runtime == null || runtime.startsWith("node-") || runtime.startsWith("bun-") || runtime.startsWith("ruby-");
2825
3285
  var normalizeImagePolicy = (images) => {
2826
3286
  if (!images) return void 0;
2827
3287
  return {
@@ -2956,7 +3416,7 @@ var mapRoute = (route, entrypoints) => ({
2956
3416
  negativeRequirements: route.missing,
2957
3417
  status: route.statusCode
2958
3418
  });
2959
- var parseEntrypoints = import_effect24.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
3419
+ var parseEntrypoints = import_effect29.Effect.fn("parseEntrypoints")(function* (config, projectFolder) {
2960
3420
  const entrypoints = [];
2961
3421
  const dockerFunctions = [];
2962
3422
  if (config.functions == null) return { entrypoints, dockerFunctions };
@@ -2967,7 +3427,7 @@ var parseEntrypoints = import_effect24.Effect.fn("parseEntrypoints")(function* (
2967
3427
  functionPath: fnPath
2968
3428
  });
2969
3429
  }
2970
- const matchedFiles = yield* import_effect24.Effect.tryPromise({
3430
+ const matchedFiles = yield* import_effect29.Effect.tryPromise({
2971
3431
  try: () => getFilesForPattern(fnPath, projectFolder, func.excludeFiles),
2972
3432
  catch: (error) => new FunctionConfigError({
2973
3433
  message: `Failed to resolve files for function pattern '${fnPath}': ${error instanceof Error ? error.message : String(error)}`,
@@ -3042,13 +3502,13 @@ var parseEntrypoints = import_effect24.Effect.fn("parseEntrypoints")(function* (
3042
3502
  }
3043
3503
  return { entrypoints, dockerFunctions };
3044
3504
  });
3045
- var collectAssets = import_effect24.Effect.fn("collectAssets")(function* (config, projectFolder) {
3505
+ var collectAssets = import_effect29.Effect.fn("collectAssets")(function* (config, projectFolder) {
3046
3506
  if (config.assets == null) return [];
3047
3507
  const assetNames = yield* collectAssetFiles(projectFolder, config.assets);
3048
3508
  return assetNames.filter((assetName) => getFunctionSettings(`${config.assets}/${assetName}`, config) == null).map((assetName) => `${config.assets}/${assetName}`);
3049
3509
  });
3050
3510
  var reservedRuntimePorts = (entrypoint) => entrypoint.runtime === CONTAINER_RUNTIME ? [] : entrypoint.runtime.startsWith("php-") ? [8080, 9e3] : [8080];
3051
- var parseContainers = import_effect24.Effect.fn("parseContainers")(function* (config, projectFolder, fileEntrypoints, dockerFunctions) {
3511
+ var parseContainers = import_effect29.Effect.fn("parseContainers")(function* (config, projectFolder, fileEntrypoints, dockerFunctions) {
3052
3512
  const warnings = [];
3053
3513
  let containers = {};
3054
3514
  if (config.compose != null) {
@@ -3081,16 +3541,16 @@ var parseContainers = import_effect24.Effect.fn("parseContainers")(function* (co
3081
3541
  }
3082
3542
  return { ...result, warnings };
3083
3543
  });
3084
- var V4ConfigParser = class extends import_effect24.Effect.Service()("V4ConfigParser", {
3544
+ var V4ConfigParser = class extends import_effect29.Effect.Service()("V4ConfigParser", {
3085
3545
  accessors: true,
3086
- effect: import_effect24.Effect.succeed({
3546
+ effect: import_effect29.Effect.succeed({
3087
3547
  /**
3088
3548
  * Parses a ConfigV4 into a NormalizedConfig.
3089
3549
  *
3090
3550
  * @param config - The raw V4 config object
3091
3551
  * @param projectFolder - Absolute path to the project root
3092
3552
  */
3093
- parse: import_effect24.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
3553
+ parse: import_effect29.Effect.fn("V4ConfigParser.parse")(function* (config, projectFolder) {
3094
3554
  const { entrypoints: fileEntrypoints, dockerFunctions } = yield* parseEntrypoints(config, projectFolder);
3095
3555
  const containers = yield* parseContainers(config, projectFolder, fileEntrypoints, dockerFunctions);
3096
3556
  const entrypoints = [...fileEntrypoints, ...containers.entrypoints];
@@ -3132,7 +3592,7 @@ var V4ConfigParser = class extends import_effect24.Effect.Service()("V4ConfigPar
3132
3592
  };
3133
3593
 
3134
3594
  // src/services/vercel-build-output-parser.ts
3135
- var import_platform15 = require("@effect/platform");
3595
+ var import_platform18 = require("@effect/platform");
3136
3596
 
3137
3597
  // ../commons/src/deep-merge.ts
3138
3598
  var deepMerge = (target, ...partials) => {
@@ -3161,7 +3621,7 @@ var deepMerge = (target, ...partials) => {
3161
3621
  };
3162
3622
 
3163
3623
  // src/services/vercel-build-output-parser.ts
3164
- var import_effect25 = require("effect");
3624
+ var import_effect30 = require("effect");
3165
3625
 
3166
3626
  // src/build-output-v3/determine-repo-root.ts
3167
3627
  var import_path = __toESM(require("path"));
@@ -3257,11 +3717,11 @@ var translateVercelRuntime = (runtime) => {
3257
3717
  var CONFIG_PATH = ".vercel/output/config.json";
3258
3718
  var FUNCTIONS_FOLDER = ".vercel/output/functions";
3259
3719
  var FUNCTION_CONFIGS_PATTERN = `${FUNCTIONS_FOLDER}/**/*.func/.vc-config.json`;
3260
- var VercelBuildOutputParser = class extends import_effect25.Effect.Service()("VercelBuildOutputParser", {
3261
- effect: import_effect25.Effect.gen(function* () {
3720
+ var VercelBuildOutputParser = class extends import_effect30.Effect.Service()("VercelBuildOutputParser", {
3721
+ effect: import_effect30.Effect.gen(function* () {
3262
3722
  const rawConfigReader = yield* RawConfigReader;
3263
- const pathService = yield* import_platform15.Path.Path;
3264
- const parse = import_effect25.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
3723
+ const pathService = yield* import_platform18.Path.Path;
3724
+ const parse = import_effect30.Effect.fn("VercelBuildOutputParser.parse")(function* (parseResult, projectFolder) {
3265
3725
  const config = yield* rawConfigReader.readConfigFile(pathService.join(projectFolder, CONFIG_PATH));
3266
3726
  if (!config || typeof config.version !== "number" || config.version < 3) {
3267
3727
  return parseResult;
@@ -3273,8 +3733,8 @@ var VercelBuildOutputParser = class extends import_effect25.Effect.Service()("Ve
3273
3733
  merged.regions = [...new Set(merged.regions)];
3274
3734
  return merged;
3275
3735
  });
3276
- const loadFunctions = import_effect25.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
3277
- const functionConfigs = yield* import_effect25.Effect.tryPromise({
3736
+ const loadFunctions = import_effect30.Effect.fn("VercelBuildOutputParser.loadFunctions")(function* (config, parseResult, projectFolder) {
3737
+ const functionConfigs = yield* import_effect30.Effect.tryPromise({
3278
3738
  try: () => getFilesForPattern(FUNCTION_CONFIGS_PATTERN, projectFolder),
3279
3739
  catch: (error) => new ConfigFileParseError({
3280
3740
  message: `Failed to scan for function configs: ${error instanceof Error ? error.message : String(error)}`,
@@ -3571,7 +4031,7 @@ var schema_default = {
3571
4031
  },
3572
4032
  streaming: {
3573
4033
  type: "boolean",
3574
- description: "Enable function response streaming. When omitted, Node and Bun runtimes stream by default."
4034
+ description: "Enable function response streaming. When omitted, Node, Bun and Ruby runtimes stream by default."
3575
4035
  },
3576
4036
  schedule: {
3577
4037
  $ref: "#/$defs/schedule",
@@ -4137,7 +4597,19 @@ var schema_default = {
4137
4597
  },
4138
4598
  runtimes: {
4139
4599
  type: "string",
4140
- enum: ["php-84", "php-83", "php-81", "node-22", "node-20", "node-18", "node-16", "bun-1"]
4600
+ enum: [
4601
+ "php-84",
4602
+ "php-83",
4603
+ "php-81",
4604
+ "ruby-40",
4605
+ "ruby-34",
4606
+ "ruby-33",
4607
+ "node-22",
4608
+ "node-20",
4609
+ "node-18",
4610
+ "node-16",
4611
+ "bun-1"
4612
+ ]
4141
4613
  },
4142
4614
  matchRequirements: {
4143
4615
  description: "An array of requirements that are needed to match",
@@ -4191,7 +4663,7 @@ var schema_default = {
4191
4663
  };
4192
4664
 
4193
4665
  // src/parse-config.ts
4194
- var parseConfigRaw = import_effect26.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
4666
+ var parseConfigRaw = import_effect31.Effect.fn("parseConfigRaw")(function* (filePath, projectFolder) {
4195
4667
  const rawReader = yield* RawConfigReader;
4196
4668
  const validator = yield* SchemaValidator;
4197
4669
  const v4Parser = yield* V4ConfigParser;
@@ -4202,7 +4674,7 @@ var parseConfigRaw = import_effect26.Effect.fn("parseConfigRaw")(function* (file
4202
4674
  };
4203
4675
  const schema = schemaMap[version];
4204
4676
  if (!schema) {
4205
- return yield* import_effect26.Effect.fail(
4677
+ return yield* import_effect31.Effect.fail(
4206
4678
  new ConfigVersionError({
4207
4679
  message: `Config file at ${filePath} has an unsupported version: ${version}`,
4208
4680
  filePath,
@@ -4213,11 +4685,11 @@ var parseConfigRaw = import_effect26.Effect.fn("parseConfigRaw")(function* (file
4213
4685
  yield* validator.validate(parsed, schema, filePath);
4214
4686
  return yield* v4Parser.parse(parsed, projectFolder);
4215
4687
  });
4216
- var parseConfig = import_effect26.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
4688
+ var parseConfig = import_effect31.Effect.fn("parseConfig")(function* (filePath, projectFolder) {
4217
4689
  const parseResult = yield* parseConfigRaw(filePath, projectFolder);
4218
4690
  return yield* postProcessConfig(parseResult, projectFolder);
4219
4691
  });
4220
- var postProcessConfig = import_effect26.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
4692
+ var postProcessConfig = import_effect31.Effect.fn("postProcessConfig")(function* (config, projectFolder) {
4221
4693
  const vercelParser = yield* VercelBuildOutputParser;
4222
4694
  let result = yield* vercelParser.parse(config, projectFolder);
4223
4695
  const hasAssets = (result.assets?.paths?.length ?? 0) > 0 || (result.assets?.prefixes?.length ?? 0) > 0 || (result.assets?.manifests?.length ?? 0) > 0;
@@ -4265,6 +4737,9 @@ var RUNTIME_DEFINITIONS = [
4265
4737
  "php-84",
4266
4738
  "php-83",
4267
4739
  "php-81",
4740
+ "ruby-40",
4741
+ "ruby-34",
4742
+ "ruby-33",
4268
4743
  "node-22",
4269
4744
  "node-20",
4270
4745
  "node-18",
@@ -4274,14 +4749,14 @@ var RUNTIME_DEFINITIONS = [
4274
4749
  var AVAILABLE_RUNTIMES = [...RUNTIME_DEFINITIONS];
4275
4750
 
4276
4751
  // src/services/index.ts
4277
- var import_effect27 = require("effect");
4278
- var BaseLayers = import_effect27.Layer.mergeAll(
4752
+ var import_effect32 = require("effect");
4753
+ var BaseLayers = import_effect32.Layer.mergeAll(
4279
4754
  ConfigModuleLoader.Default,
4280
4755
  RawConfigReader.Default,
4281
4756
  SchemaValidator.Default,
4282
4757
  V4ConfigParser.Default
4283
4758
  );
4284
- var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect27.Layer.provideMerge(BaseLayers));
4759
+ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect32.Layer.provideMerge(BaseLayers));
4285
4760
  // Annotate the CommonJS export names for ESM import in node:
4286
4761
  0 && (module.exports = {
4287
4762
  ALLOWED_CONFIG_NAMES,
@@ -4300,6 +4775,7 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect27.Lay
4300
4775
  ContainerConfigError,
4301
4776
  DEFAULT_CONTAINER_MEMORY_MB,
4302
4777
  DEFAULT_FUNCTION_DURATION_SECONDS,
4778
+ DEFAULT_RUBY_RUNTIME,
4303
4779
  DEFAULT_SIDECAR_MEMORY_MB,
4304
4780
  FRAMEWORK_DEFINITIONS,
4305
4781
  FrameworkNotDetectedError,
@@ -4336,6 +4812,7 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect27.Lay
4336
4812
  detectContainerProject,
4337
4813
  detectFramework,
4338
4814
  detectPackageManager,
4815
+ detectRubyRuntime,
4339
4816
  dockerFunctionContainerName,
4340
4817
  filterFunctionsFromAssets,
4341
4818
  generateConfig,
@@ -4351,6 +4828,9 @@ var NetworkConfigLive = VercelBuildOutputParser.Default.pipe(import_effect27.Lay
4351
4828
  postProcessConfig,
4352
4829
  readComposeContainers,
4353
4830
  readDependencies,
4831
+ rubyRuntimeForRequirement,
4832
+ rubyRuntimeForVersion,
4833
+ rubyRuntimeFromProjectFiles,
4354
4834
  splitCommandWords
4355
4835
  });
4356
4836
  //# sourceMappingURL=index.js.map