@absolutejs/absolute 0.19.0-beta.1050 → 0.19.0-beta.1052

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/cli/index.js CHANGED
@@ -172240,23 +172240,237 @@ var init_mem = __esm(() => {
172240
172240
  });
172241
172241
 
172242
172242
  // src/cli/config/schema/fromType.ts
172243
- var import_typescript3, cache;
172243
+ import {
172244
+ existsSync as existsSync14,
172245
+ mkdirSync as mkdirSync7,
172246
+ readFileSync as readFileSync16,
172247
+ statSync as statSync2,
172248
+ writeFileSync as writeFileSync6
172249
+ } from "fs";
172250
+ import { resolve as resolve11 } from "path";
172251
+ var import_typescript3, VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFrameworkRepo = (cwd) => {
172252
+ try {
172253
+ const pkg = JSON.parse(readFileSync16(resolve11(cwd, "package.json"), "utf-8"));
172254
+ return pkg?.name === "@absolutejs/absolute";
172255
+ } catch {
172256
+ return false;
172257
+ }
172258
+ }, compilerOptionsFor = (cwd) => {
172259
+ const tsconfigPath = import_typescript3.default.findConfigFile(cwd, import_typescript3.default.sys.fileExists, "tsconfig.json");
172260
+ const base = tsconfigPath && import_typescript3.default.getParsedCommandLineOfConfigFile(tsconfigPath, {}, {
172261
+ ...import_typescript3.default.sys,
172262
+ onUnRecoverableConfigFileDiagnostic: () => {}
172263
+ })?.options;
172264
+ return {
172265
+ ...base ?? import_typescript3.default.getDefaultCompilerOptions(),
172266
+ noEmit: true,
172267
+ skipDefaultLibCheck: true,
172268
+ skipLibCheck: true,
172269
+ types: []
172270
+ };
172271
+ }, SCHEMA_VERSION = 1, packageVersion = (cwd, specifier) => {
172272
+ const candidates = specifier === "@absolutejs/absolute" ? [
172273
+ resolve11(cwd, "node_modules", "@absolutejs", "absolute", "package.json"),
172274
+ resolve11(cwd, "package.json")
172275
+ ] : [resolve11(cwd, "node_modules", ...specifier.split("/"), "package.json")];
172276
+ for (const candidate of candidates) {
172277
+ try {
172278
+ const { version: version2 } = JSON.parse(readFileSync16(candidate, "utf-8"));
172279
+ if (typeof version2 === "string")
172280
+ return version2;
172281
+ } catch {}
172282
+ }
172283
+ return "unknown";
172284
+ }, cacheSignature = (cwd, typeName, local, specifier) => {
172285
+ let signature = `${SCHEMA_VERSION}:${specifier}:${packageVersion(cwd, specifier)}`;
172286
+ if (local) {
172287
+ const file = typeName === "PackageJson" ? "packageJson.ts" : "build.ts";
172288
+ try {
172289
+ signature += `:${statSync2(resolve11(cwd, "types", file)).mtimeMs}`;
172290
+ } catch {}
172291
+ }
172292
+ return signature;
172293
+ }, cacheSlug = (specifier) => specifier.replace("@", "").split("/").join("-"), cacheFile = (cwd, typeName, specifier) => {
172294
+ const name = specifier === "@absolutejs/absolute" ? typeName : `${typeName}.${cacheSlug(specifier)}`;
172295
+ return resolve11(cwd, ".absolutejs", "config-schema", `${name}.json`);
172296
+ }, readDiskCache = (cwd, typeName, signature, specifier) => {
172297
+ try {
172298
+ const cached = JSON.parse(readFileSync16(cacheFile(cwd, typeName, specifier), "utf-8"));
172299
+ if (cached?.signature === signature && Array.isArray(cached.fields)) {
172300
+ return cached.fields;
172301
+ }
172302
+ } catch {}
172303
+ return null;
172304
+ }, writeDiskCache = (cwd, typeName, signature, fields, specifier) => {
172305
+ try {
172306
+ mkdirSync7(resolve11(cwd, ".absolutejs", "config-schema"), {
172307
+ recursive: true
172308
+ });
172309
+ writeFileSync6(cacheFile(cwd, typeName, specifier), JSON.stringify({ fields, signature }));
172310
+ } catch {}
172311
+ }, docOf = (symbol, checker) => import_typescript3.default.displayPartsToString(symbol.getDocumentationComment(checker)).trim(), typeOfSymbol = (symbol, checker) => {
172312
+ const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
172313
+ return declaration ? checker.getTypeOfSymbolAtLocation(symbol, declaration) : checker.getDeclaredTypeOfSymbol(symbol);
172314
+ }, hasFlag = (type, flag) => (type.flags & flag) !== 0, unionParts = (type) => type.isUnion() ? type.types : [type], literalChoice = (type) => {
172315
+ if (type.isStringLiteral())
172316
+ return type.value;
172317
+ if (type.isNumberLiteral())
172318
+ return type.value;
172319
+ return null;
172320
+ }, toSchema = (type, checker, depth, seen) => {
172321
+ const opaque = () => ({
172322
+ kind: "opaque",
172323
+ typeText: checker.typeToString(type)
172324
+ });
172325
+ if (depth > MAX_DEPTH)
172326
+ return opaque();
172327
+ const parts = unionParts(type).filter((part) => !hasFlag(part, import_typescript3.default.TypeFlags.Undefined) && !hasFlag(part, import_typescript3.default.TypeFlags.Null));
172328
+ if (parts.length === 0)
172329
+ return opaque();
172330
+ if (parts.every((part) => hasFlag(part, import_typescript3.default.TypeFlags.BooleanLike))) {
172331
+ return { kind: "boolean" };
172332
+ }
172333
+ const choices = parts.map(literalChoice);
172334
+ if (parts.length > 1 && choices.every((choice) => choice !== null)) {
172335
+ return { choices: choices.filter((c) => c !== null), kind: "enum" };
172336
+ }
172337
+ if (parts.length > 1) {
172338
+ return {
172339
+ kind: "union",
172340
+ variants: parts.map((part) => single(part, checker, depth, seen))
172341
+ };
172342
+ }
172343
+ const [only] = parts;
172344
+ return only ? single(only, checker, depth, seen) : opaque();
172345
+ }, single = (type, checker, depth, seen) => {
172346
+ const opaque = () => ({
172347
+ kind: "opaque",
172348
+ typeText: checker.typeToString(type)
172349
+ });
172350
+ if (hasFlag(type, import_typescript3.default.TypeFlags.BooleanLike))
172351
+ return { kind: "boolean" };
172352
+ if (hasFlag(type, import_typescript3.default.TypeFlags.NumberLike))
172353
+ return { kind: "number" };
172354
+ if (hasFlag(type, import_typescript3.default.TypeFlags.StringLike))
172355
+ return { kind: "string" };
172356
+ if (!hasFlag(type, import_typescript3.default.TypeFlags.Object))
172357
+ return opaque();
172358
+ if (type.getCallSignatures().length > 0)
172359
+ return opaque();
172360
+ const element = type.getNumberIndexType();
172361
+ const stringIndex = type.getStringIndexType();
172362
+ const props = checker.getPropertiesOfType(type);
172363
+ if (element && props.length === 0) {
172364
+ return {
172365
+ item: toSchema(element, checker, depth + 1, seen),
172366
+ kind: "array"
172367
+ };
172368
+ }
172369
+ if (seen.has(type))
172370
+ return opaque();
172371
+ seen.add(type);
172372
+ try {
172373
+ if (props.length > 0) {
172374
+ const fields = props.map((symbol) => ({
172375
+ description: docOf(symbol, checker),
172376
+ name: symbol.getName(),
172377
+ optional: (symbol.flags & import_typescript3.default.SymbolFlags.Optional) !== 0,
172378
+ schema: toSchema(typeOfSymbol(symbol, checker), checker, depth + 1, seen)
172379
+ }));
172380
+ return { fields, kind: "object" };
172381
+ }
172382
+ if (stringIndex) {
172383
+ return {
172384
+ kind: "record",
172385
+ value: toSchema(stringIndex, checker, depth + 1, seen)
172386
+ };
172387
+ }
172388
+ } finally {
172389
+ seen.delete(type);
172390
+ }
172391
+ return opaque();
172392
+ }, introspectFrom = (cwd, specifier, typeName, options, exclude) => {
172393
+ const virtualPath = resolve11(cwd, VIRTUAL_NAME);
172394
+ const source = `import type { ${typeName} } from '${specifier}';
172395
+ declare const value: ${typeName};
172396
+ export { value };
172397
+ `;
172398
+ const host = import_typescript3.default.createCompilerHost(options, true);
172399
+ const getSourceFile = host.getSourceFile.bind(host);
172400
+ host.getSourceFile = (fileName, languageVersion, onError, shouldCreate) => fileName === virtualPath ? import_typescript3.default.createSourceFile(fileName, source, languageVersion, true) : getSourceFile(fileName, languageVersion, onError, shouldCreate);
172401
+ const fileExists = host.fileExists.bind(host);
172402
+ host.fileExists = (fileName) => fileName === virtualPath ? true : fileExists(fileName);
172403
+ const readFile = host.readFile.bind(host);
172404
+ host.readFile = (fileName) => fileName === virtualPath ? source : readFile(fileName);
172405
+ const program = import_typescript3.default.createProgram([virtualPath], options, host);
172406
+ const checker = program.getTypeChecker();
172407
+ const sourceFile = program.getSourceFile(virtualPath);
172408
+ if (!sourceFile)
172409
+ return [];
172410
+ const nodes = [];
172411
+ sourceFile.forEachChild((node) => {
172412
+ if (!import_typescript3.default.isVariableStatement(node))
172413
+ return;
172414
+ const declaration = node.declarationList.declarations[0];
172415
+ if (!declaration)
172416
+ return;
172417
+ const type = checker.getTypeAtLocation(declaration);
172418
+ for (const symbol of checker.getPropertiesOfType(type)) {
172419
+ const name = symbol.getName();
172420
+ if (exclude.has(name) || name.startsWith("__"))
172421
+ continue;
172422
+ nodes.push({
172423
+ description: docOf(symbol, checker),
172424
+ name,
172425
+ optional: (symbol.flags & import_typescript3.default.SymbolFlags.Optional) !== 0,
172426
+ schema: toSchema(typeOfSymbol(symbol, checker), checker, 1, new Set)
172427
+ });
172428
+ }
172429
+ });
172430
+ return nodes.sort((left, right) => left.name.localeCompare(right.name));
172431
+ }, cache, introspectType = (cwd, typeName, exclude = new Set, specifier = "@absolutejs/absolute") => {
172432
+ const cacheKey = `${specifier}:${typeName}`;
172433
+ const cached = cache.get(cacheKey);
172434
+ if (cached)
172435
+ return cached;
172436
+ const local = specifier === "@absolutejs/absolute" && isFrameworkRepo(cwd) && existsSync14(resolve11(cwd, "types/index.ts"));
172437
+ const signature = cacheSignature(cwd, typeName, local, specifier);
172438
+ const fromDisk = readDiskCache(cwd, typeName, signature, specifier);
172439
+ if (fromDisk) {
172440
+ cache.set(cacheKey, fromDisk);
172441
+ return fromDisk;
172442
+ }
172443
+ const options = compilerOptionsFor(cwd);
172444
+ const specifiers = local ? [specifier, "./types"] : [specifier];
172445
+ for (const candidate of specifiers) {
172446
+ try {
172447
+ const nodes = introspectFrom(cwd, candidate, typeName, options, exclude);
172448
+ if (nodes.length > 0) {
172449
+ cache.set(cacheKey, nodes);
172450
+ writeDiskCache(cwd, typeName, signature, nodes, specifier);
172451
+ return nodes;
172452
+ }
172453
+ } catch {}
172454
+ }
172455
+ cache.set(cacheKey, []);
172456
+ return cache.get(cacheKey) ?? [];
172457
+ };
172244
172458
  var init_fromType = __esm(() => {
172245
172459
  import_typescript3 = __toESM(require_typescript(), 1);
172246
172460
  cache = new Map;
172247
172461
  });
172248
172462
 
172249
172463
  // src/cli/config/absolute/resolveAbsoluteConfig.ts
172250
- import { existsSync as existsSync14, readFileSync as readFileSync16 } from "fs";
172251
- import { resolve as resolve11 } from "path";
172464
+ import { existsSync as existsSync15, readFileSync as readFileSync17 } from "fs";
172465
+ import { resolve as resolve12 } from "path";
172252
172466
  var import_typescript4, CONFIG_CANDIDATES2, RUNTIME_FIELDS, findConfigPath2 = (cwd, override) => {
172253
172467
  if (override) {
172254
- const resolved = resolve11(cwd, override);
172255
- return existsSync14(resolved) ? resolved : null;
172468
+ const resolved = resolve12(cwd, override);
172469
+ return existsSync15(resolved) ? resolved : null;
172256
172470
  }
172257
172471
  for (const name of CONFIG_CANDIDATES2) {
172258
- const candidate = resolve11(cwd, name);
172259
- if (existsSync14(candidate))
172472
+ const candidate = resolve12(cwd, name);
172473
+ if (existsSync15(candidate))
172260
172474
  return candidate;
172261
172475
  }
172262
172476
  return null;
@@ -172278,7 +172492,7 @@ var import_typescript4, CONFIG_CANDIDATES2, RUNTIME_FIELDS, findConfigPath2 = (c
172278
172492
  visit(sourceFile);
172279
172493
  return found;
172280
172494
  }, parseConfigObject = (configPath2) => {
172281
- const text = readFileSync16(configPath2, "utf-8");
172495
+ const text = readFileSync17(configPath2, "utf-8");
172282
172496
  return { object: findConfigObject(parseSource(configPath2, text)), text };
172283
172497
  }, evalLiteral = (node) => {
172284
172498
  if (import_typescript4.default.isStringLiteralLike(node)) {
@@ -172490,8 +172704,8 @@ var init_frameworks = __esm(() => {
172490
172704
  });
172491
172705
 
172492
172706
  // src/cli/generate/context.ts
172493
- import { dirname as dirname4, isAbsolute, join as join14, relative as relative3, resolve as resolve12 } from "path";
172494
- var asString = (value) => typeof value === "string" ? value : undefined, isRecord3 = (value) => typeof value === "object" && value !== null, resolveDir = (cwd, value) => isAbsolute(value) ? value : resolve12(cwd, value), resolveStylesDir = (cwd, config) => {
172707
+ import { dirname as dirname4, isAbsolute, join as join14, relative as relative3, resolve as resolve13 } from "path";
172708
+ var asString = (value) => typeof value === "string" ? value : undefined, isRecord3 = (value) => typeof value === "object" && value !== null, resolveDir = (cwd, value) => isAbsolute(value) ? value : resolve13(cwd, value), resolveStylesDir = (cwd, config) => {
172495
172709
  const styles = config.stylesConfig;
172496
172710
  if (typeof styles === "string")
172497
172711
  return resolveDir(cwd, styles);
@@ -172500,10 +172714,10 @@ var asString = (value) => typeof value === "string" ? value : undefined, isRecor
172500
172714
  if (indexes)
172501
172715
  return resolveDir(cwd, indexes);
172502
172716
  }
172503
- return resolve12(cwd, "src/frontend/styles/indexes");
172717
+ return resolve13(cwd, "src/frontend/styles/indexes");
172504
172718
  }, configuredFrameworks = (project) => FRAMEWORK_KEYS2.filter((key) => project.frameworkDirs[key] !== undefined), frontendRootFor = (project, framework) => {
172505
172719
  const dir = project.frameworkDirs[framework];
172506
- return dir ? dirname4(dir) : resolve12(project.cwd, "src/frontend");
172720
+ return dir ? dirname4(dir) : resolve13(project.cwd, "src/frontend");
172507
172721
  }, resolveProject = async (cwd, configOverride) => {
172508
172722
  const loaded = await loadConfig(configOverride);
172509
172723
  const config = isRecord3(loaded) ? loaded : {};
@@ -172581,7 +172795,7 @@ var emptyOutcome = () => ({
172581
172795
  });
172582
172796
 
172583
172797
  // src/cli/generate/routeWiring.ts
172584
- import { existsSync as existsSync15, readFileSync as readFileSync17, readdirSync as readdirSync4, writeFileSync as writeFileSync6 } from "fs";
172798
+ import { existsSync as existsSync16, readFileSync as readFileSync18, readdirSync as readdirSync4, writeFileSync as writeFileSync7 } from "fs";
172585
172799
  import { dirname as dirname5, join as join15 } from "path";
172586
172800
  var import_typescript5, DEFAULT_SEPARATOR = `
172587
172801
  `, BOUNDARY_USE, applyEdits = (text, edits) => {
@@ -172730,13 +172944,13 @@ ${newLines.join(`
172730
172944
  return lines.join(`
172731
172945
  `);
172732
172946
  }, hasChain = (path) => {
172733
- if (!existsSync15(path))
172947
+ if (!existsSync16(path))
172734
172948
  return false;
172735
- const sourceFile = parse2(path, readFileSync17(path, "utf-8"));
172949
+ const sourceFile = parse2(path, readFileSync18(path, "utf-8"));
172736
172950
  const found = findElysiaNew(sourceFile);
172737
172951
  return found !== null;
172738
172952
  }, firstChainFile = (pluginsDir) => {
172739
- if (!existsSync15(pluginsDir))
172953
+ if (!existsSync16(pluginsDir))
172740
172954
  return null;
172741
172955
  for (const name of readdirSync4(pluginsDir)) {
172742
172956
  if (!name.endsWith(".ts"))
@@ -172781,7 +172995,7 @@ ${newLines.join(`
172781
172995
  };
172782
172996
  if (!hasChain(serverEntry))
172783
172997
  return fallback;
172784
- const text = readFileSync17(serverEntry, "utf-8");
172998
+ const text = readFileSync18(serverEntry, "utf-8");
172785
172999
  const sourceFile = parse2(serverEntry, text);
172786
173000
  const newExpr = findElysiaNew(sourceFile);
172787
173001
  if (!newExpr)
@@ -172794,7 +173008,7 @@ ${newLines.join(`
172794
173008
  start: offset,
172795
173009
  text: `${separator}.use(${pluginName})`
172796
173010
  });
172797
- writeFileSync6(serverEntry, applyEdits(text, edits), "utf-8");
173011
+ writeFileSync7(serverEntry, applyEdits(text, edits), "utf-8");
172798
173012
  return { kind: "edited", routingFile: serverEntry };
172799
173013
  }, wireRoute = (input) => {
172800
173014
  const routingFile = findRoutingFile(input.serverEntry);
@@ -172810,7 +173024,7 @@ ${newLines.join(`
172810
173024
  ${routeExpr}`
172811
173025
  };
172812
173026
  }
172813
- const text = readFileSync17(routingFile, "utf-8");
173027
+ const text = readFileSync18(routingFile, "utf-8");
172814
173028
  const sourceFile = parse2(routingFile, text);
172815
173029
  const newExpr = findElysiaNew(sourceFile);
172816
173030
  if (!newExpr) {
@@ -172830,7 +173044,7 @@ ${routeExpr}`
172830
173044
  start: offset,
172831
173045
  text: `${separator}${routeExpr}`
172832
173046
  });
172833
- writeFileSync6(routingFile, applyEdits(text, edits), "utf-8");
173047
+ writeFileSync7(routingFile, applyEdits(text, edits), "utf-8");
172834
173048
  return { kind: "edited", routingFile };
172835
173049
  };
172836
173050
  var init_routeWiring = __esm(() => {
@@ -172840,7 +173054,7 @@ var init_routeWiring = __esm(() => {
172840
173054
  });
172841
173055
 
172842
173056
  // src/cli/generate/generateApi.ts
172843
- import { existsSync as existsSync16, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "fs";
173057
+ import { existsSync as existsSync17, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
172844
173058
  import { dirname as dirname6, join as join16 } from "path";
172845
173059
  var apiPluginTemplate = (pluginName, base) => `import { Elysia } from 'elysia';
172846
173060
 
@@ -172855,12 +173069,12 @@ export const ${pluginName} = new Elysia()
172855
173069
  const outcome = { ...emptyOutcome(), route: base };
172856
173070
  const pluginsDir = join16(dirname6(project.serverEntry), "plugins");
172857
173071
  const fileAbs = join16(pluginsDir, `${pluginName}.ts`);
172858
- if (existsSync16(fileAbs)) {
173072
+ if (existsSync17(fileAbs)) {
172859
173073
  outcome.notes.push(`${pluginName} already exists at ${fileAbs} \u2014 skipped.`);
172860
173074
  return outcome;
172861
173075
  }
172862
- mkdirSync7(pluginsDir, { recursive: true });
172863
- writeFileSync7(fileAbs, apiPluginTemplate(pluginName, base), "utf-8");
173076
+ mkdirSync8(pluginsDir, { recursive: true });
173077
+ writeFileSync8(fileAbs, apiPluginTemplate(pluginName, base), "utf-8");
172864
173078
  outcome.created.push(fileAbs);
172865
173079
  const specifier = toModuleSpecifier(dirname6(project.serverEntry), fileAbs.replace(/\.ts$/, ""));
172866
173080
  const wired = wirePluginUse(project.serverEntry, pluginName, specifier);
@@ -172928,7 +173142,7 @@ var init_componentTemplates = __esm(() => {
172928
173142
  });
172929
173143
 
172930
173144
  // src/cli/generate/generateComponent.ts
172931
- import { existsSync as existsSync17, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
173145
+ import { existsSync as existsSync18, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
172932
173146
  import { dirname as dirname7, join as join17 } from "path";
172933
173147
  var generateComponent = (project, framework, rawName) => {
172934
173148
  const def = frameworks2[framework];
@@ -172941,12 +173155,12 @@ var generateComponent = (project, framework, rawName) => {
172941
173155
  return outcome;
172942
173156
  }
172943
173157
  const fileAbs = join17(frameworkDir, "components", def.componentFile({ kebab, pascal }));
172944
- if (existsSync17(fileAbs)) {
173158
+ if (existsSync18(fileAbs)) {
172945
173159
  outcome.notes.push(`${pascal} already exists at ${fileAbs} \u2014 skipped.`);
172946
173160
  return outcome;
172947
173161
  }
172948
- mkdirSync8(dirname7(fileAbs), { recursive: true });
172949
- writeFileSync8(fileAbs, componentTemplates[framework]({
173162
+ mkdirSync9(dirname7(fileAbs), { recursive: true });
173163
+ writeFileSync9(fileAbs, componentTemplates[framework]({
172950
173164
  kebab,
172951
173165
  pascal,
172952
173166
  title: toTitleCase(rawName)
@@ -172960,7 +173174,7 @@ var init_generateComponent = __esm(() => {
172960
173174
  });
172961
173175
 
172962
173176
  // src/cli/generate/cssStrategy.ts
172963
- import { existsSync as existsSync18 } from "fs";
173177
+ import { existsSync as existsSync19 } from "fs";
172964
173178
  import { join as join18 } from "path";
172965
173179
  var import_typescript6, CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
172966
173180
  margin: 0 auto;
@@ -173008,7 +173222,7 @@ var import_typescript6, CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `
173008
173222
  return {
173009
173223
  assetKey: sharedKey,
173010
173224
  contents: DEFAULT_CSS,
173011
- create: !existsSync18(cssFileAbs2),
173225
+ create: !existsSync19(cssFileAbs2),
173012
173226
  cssFileAbs: cssFileAbs2,
173013
173227
  shared: true
173014
173228
  };
@@ -173017,7 +173231,7 @@ var import_typescript6, CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `
173017
173231
  return {
173018
173232
  assetKey: `${pascal}${CSS_SUFFIX}`,
173019
173233
  contents: DEFAULT_CSS,
173020
- create: !existsSync18(cssFileAbs),
173234
+ create: !existsSync19(cssFileAbs),
173021
173235
  cssFileAbs,
173022
173236
  shared: false
173023
173237
  };
@@ -173027,7 +173241,7 @@ var init_cssStrategy = __esm(() => {
173027
173241
  });
173028
173242
 
173029
173243
  // src/cli/generate/navData.ts
173030
- import { existsSync as existsSync19, mkdirSync as mkdirSync9, readFileSync as readFileSync18, writeFileSync as writeFileSync9 } from "fs";
173244
+ import { existsSync as existsSync20, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync10 } from "fs";
173031
173245
  import { dirname as dirname8 } from "path";
173032
173246
  var import_typescript7, NAV_DATA_TEMPLATE = `type NavItem = {
173033
173247
  href: string;
@@ -173066,9 +173280,9 @@ export const navData: NavItem[] = [];
173066
173280
  }
173067
173281
  return items;
173068
173282
  }, readNavItems = (navDataPath) => {
173069
- if (!existsSync19(navDataPath))
173283
+ if (!existsSync20(navDataPath))
173070
173284
  return [];
173071
- const text = readFileSync18(navDataPath, "utf-8");
173285
+ const text = readFileSync19(navDataPath, "utf-8");
173072
173286
  const sourceFile = import_typescript7.default.createSourceFile(navDataPath, text, import_typescript7.default.ScriptTarget.Latest, true);
173073
173287
  const array = findNavArray(sourceFile);
173074
173288
  return array ? parseNavItems(array) : [];
@@ -173103,22 +173317,22 @@ ${indentOf(text, array.getStart(sourceFile))}`;
173103
173317
  ${indent}${entry}`;
173104
173318
  return text.slice(0, insertAt) + insertion + text.slice(insertAt);
173105
173319
  }, upsertNavItem = (navDataPath, item) => {
173106
- const created = !existsSync19(navDataPath);
173320
+ const created = !existsSync20(navDataPath);
173107
173321
  if (created) {
173108
- mkdirSync9(dirname8(navDataPath), { recursive: true });
173109
- writeFileSync9(navDataPath, NAV_DATA_TEMPLATE, "utf-8");
173322
+ mkdirSync10(dirname8(navDataPath), { recursive: true });
173323
+ writeFileSync10(navDataPath, NAV_DATA_TEMPLATE, "utf-8");
173110
173324
  }
173111
173325
  const existing = readNavItems(navDataPath);
173112
173326
  if (existing.some((candidate) => candidate.href === item.href)) {
173113
173327
  return { changed: created, created, items: existing };
173114
173328
  }
173115
- const text = readFileSync18(navDataPath, "utf-8");
173329
+ const text = readFileSync19(navDataPath, "utf-8");
173116
173330
  const sourceFile = import_typescript7.default.createSourceFile(navDataPath, text, import_typescript7.default.ScriptTarget.Latest, true);
173117
173331
  const array = findNavArray(sourceFile);
173118
173332
  if (!array)
173119
173333
  return { changed: created, created, items: existing };
173120
173334
  const entry = `{ href: '${item.href}', label: '${item.label}' }`;
173121
- writeFileSync9(navDataPath, insertElement(text, array, sourceFile, entry), "utf-8");
173335
+ writeFileSync10(navDataPath, insertElement(text, array, sourceFile, entry), "utf-8");
173122
173336
  return { changed: true, created, items: [...existing, item] };
173123
173337
  };
173124
173338
  var init_navData = __esm(() => {
@@ -173271,25 +173485,25 @@ var init_pageTemplates = __esm(() => {
173271
173485
 
173272
173486
  // src/cli/generate/generatePage.ts
173273
173487
  import {
173274
- existsSync as existsSync20,
173275
- mkdirSync as mkdirSync10,
173276
- readFileSync as readFileSync19,
173488
+ existsSync as existsSync21,
173489
+ mkdirSync as mkdirSync11,
173490
+ readFileSync as readFileSync20,
173277
173491
  readdirSync as readdirSync5,
173278
- writeFileSync as writeFileSync10
173492
+ writeFileSync as writeFileSync11
173279
173493
  } from "fs";
173280
173494
  import { dirname as dirname9, join as join19, relative as relative4 } from "path";
173281
173495
  var writeNew = (path, contents) => {
173282
- mkdirSync10(dirname9(path), { recursive: true });
173283
- writeFileSync10(path, contents, "utf-8");
173496
+ mkdirSync11(dirname9(path), { recursive: true });
173497
+ writeFileSync11(path, contents, "utf-8");
173284
173498
  }, toHref = (fromDir, toFile) => {
173285
173499
  const rel = relative4(fromDir, toFile).split("\\").join("/");
173286
173500
  return rel.startsWith(".") ? rel : `./${rel}`;
173287
- }, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join19(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync20(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join19(pagesDir, name))), resyncPage = (file, items) => {
173288
- const html = readFileSync19(file, "utf-8");
173501
+ }, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join19(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync21(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join19(pagesDir, name))), resyncPage = (file, items) => {
173502
+ const html = readFileSync20(file, "utf-8");
173289
173503
  const synced = syncStaticNav(html, items);
173290
173504
  if (synced === null || synced === html)
173291
173505
  return false;
173292
- writeFileSync10(file, synced, "utf-8");
173506
+ writeFileSync11(file, synced, "utf-8");
173293
173507
  return true;
173294
173508
  }, resyncStaticPages = (project, items, skipFile) => {
173295
173509
  const updated = [];
@@ -173313,12 +173527,12 @@ var writeNew = (path, contents) => {
173313
173527
  return outcome;
173314
173528
  }
173315
173529
  const pageFileAbs = join19(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
173316
- if (existsSync20(pageFileAbs)) {
173530
+ if (existsSync21(pageFileAbs)) {
173317
173531
  outcome.notes.push(`${pascal} already exists at ${pageFileAbs} \u2014 skipped.`);
173318
173532
  return outcome;
173319
173533
  }
173320
173534
  const routingFile = findRoutingFile(project.serverEntry);
173321
- const routingText = routingFile ? readFileSync19(routingFile, "utf-8") : "";
173535
+ const routingText = routingFile ? readFileSync20(routingFile, "utf-8") : "";
173322
173536
  const css = planCss(routingText, project.stylesDir, pascal, kebab);
173323
173537
  const navDataPath = join19(sharedDirFor(project, framework), "navData.ts");
173324
173538
  const nav = upsertNavItem(navDataPath, { href: route, label: title });
@@ -173509,7 +173723,7 @@ ${indent.repeat(level)}}`;
173509
173723
  var init_serialize = () => {};
173510
173724
 
173511
173725
  // src/cli/config/absolute/editAbsoluteConfig.ts
173512
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync11 } from "fs";
173726
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync12 } from "fs";
173513
173727
  var import_typescript8, lineStartOffset = (text, position) => {
173514
173728
  let index = position;
173515
173729
  while (index > 0 && text[index - 1] !== `
@@ -173518,7 +173732,7 @@ var import_typescript8, lineStartOffset = (text, position) => {
173518
173732
  return index;
173519
173733
  }, indentBefore2 = (text, position) => text.slice(lineStartOffset(text, position), position), findProperty = (object, name) => object.properties.find((property) => import_typescript8.default.isPropertyAssignment(property) && (import_typescript8.default.isIdentifier(property.name) || import_typescript8.default.isStringLiteral(property.name)) && property.name.text === name), applyAbsoluteConfigEdit = (configPath2, request) => {
173520
173734
  try {
173521
- const text = readFileSync20(configPath2, "utf-8");
173735
+ const text = readFileSync21(configPath2, "utf-8");
173522
173736
  const sourceFile = import_typescript8.default.createSourceFile(configPath2, text, import_typescript8.default.ScriptTarget.Latest, true);
173523
173737
  const object = findConfigObject(sourceFile);
173524
173738
  if (!object) {
@@ -173538,14 +173752,14 @@ var import_typescript8, lineStartOffset = (text, position) => {
173538
173752
  if (text[end] === `
173539
173753
  `)
173540
173754
  end += 1;
173541
- writeFileSync11(configPath2, text.slice(0, start2) + text.slice(end), "utf-8");
173755
+ writeFileSync12(configPath2, text.slice(0, start2) + text.slice(end), "utf-8");
173542
173756
  return { message: `Removed ${request.name}`, ok: true };
173543
173757
  }
173544
173758
  const valueText = serializeValue(request.value);
173545
173759
  if (existing) {
173546
173760
  const start2 = existing.initializer.getStart(sourceFile);
173547
173761
  const end = existing.initializer.getEnd();
173548
- writeFileSync11(configPath2, text.slice(0, start2) + valueText + text.slice(end), "utf-8");
173762
+ writeFileSync12(configPath2, text.slice(0, start2) + valueText + text.slice(end), "utf-8");
173549
173763
  return { message: `Updated ${request.name}`, ok: true };
173550
173764
  }
173551
173765
  const { properties } = object;
@@ -173565,14 +173779,14 @@ var import_typescript8, lineStartOffset = (text, position) => {
173565
173779
  at += 1;
173566
173780
  const insertion = `${hasComma ? "" : ","}
173567
173781
  ${indent}${entry}`;
173568
- writeFileSync11(configPath2, text.slice(0, at) + insertion + text.slice(at), "utf-8");
173782
+ writeFileSync12(configPath2, text.slice(0, at) + insertion + text.slice(at), "utf-8");
173569
173783
  } else {
173570
173784
  const at = object.getStart(sourceFile) + 1;
173571
173785
  const indent = `${indentBefore2(text, object.getStart(sourceFile))} `;
173572
173786
  const insertion = `
173573
173787
  ${indent}${entry}
173574
173788
  ${indentBefore2(text, object.getStart(sourceFile))}`;
173575
- writeFileSync11(configPath2, text.slice(0, at) + insertion + text.slice(at), "utf-8");
173789
+ writeFileSync12(configPath2, text.slice(0, at) + insertion + text.slice(at), "utf-8");
173576
173790
  }
173577
173791
  return { message: `Updated ${request.name}`, ok: true };
173578
173792
  } catch (error) {
@@ -173702,14 +173916,14 @@ var init_catalog = __esm(() => {
173702
173916
  });
173703
173917
 
173704
173918
  // src/cli/integrations/addPlugin.ts
173705
- import { existsSync as existsSync21, readFileSync as readFileSync21 } from "fs";
173919
+ import { existsSync as existsSync22, readFileSync as readFileSync22 } from "fs";
173706
173920
  import { join as join20 } from "path";
173707
173921
  var isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readPackageJson = (cwd) => {
173708
173922
  const path = join20(cwd, "package.json");
173709
- if (!existsSync21(path))
173923
+ if (!existsSync22(path))
173710
173924
  return null;
173711
173925
  try {
173712
- const parsed = JSON.parse(readFileSync21(path, "utf-8"));
173926
+ const parsed = JSON.parse(readFileSync22(path, "utf-8"));
173713
173927
  return isRecord5(parsed) ? parsed : null;
173714
173928
  } catch {
173715
173929
  return null;
@@ -173805,14 +174019,707 @@ var init_addPlugin = __esm(() => {
173805
174019
  init_catalog();
173806
174020
  });
173807
174021
 
174022
+ // src/cli/config/auth/authScaffolds.ts
174023
+ var TODO = (message) => `async () => { throw new Error("TODO: ${message}"); }`, AUTH_SCAFFOLDS, isScaffoldableFeature = (id) => (id in AUTH_SCAFFOLDS);
174024
+ var init_authScaffolds = __esm(() => {
174025
+ AUTH_SCAFFOLDS = {
174026
+ audit: {
174027
+ configKey: "audit",
174028
+ exportName: "auditConfig",
174029
+ fields: [
174030
+ { name: "auditStore", value: "createInMemoryAuditSink()" },
174031
+ { name: "getUserId", value: "(user) => user.sub" }
174032
+ ],
174033
+ generic: true,
174034
+ imports: ["createInMemoryAuditSink"],
174035
+ note: "Swap the in-memory sink for a durable store (append-only table); add `onAuditEvent` to forward to a SIEM.",
174036
+ packages: [],
174037
+ typeName: "AuditConfig"
174038
+ },
174039
+ authorization: {
174040
+ configKey: "authorization",
174041
+ exportName: "authorizationConfig",
174042
+ fields: [
174043
+ {
174044
+ name: "hasPermission",
174045
+ value: '({ user, permission, organizationId }) => { throw new Error("TODO: decide if user has permission"); }'
174046
+ }
174047
+ ],
174048
+ generic: true,
174049
+ imports: [],
174050
+ note: "Pair with `createMembershipPermissionResolver` (from @absolutejs/auth) when you also use organizations + roles.",
174051
+ packages: [],
174052
+ typeName: "AuthorizationConfig"
174053
+ },
174054
+ compliance: {
174055
+ configKey: "compliance",
174056
+ exportName: "complianceConfig",
174057
+ fields: [
174058
+ { name: "deleteUserData", value: TODO("erase or anonymize the user in your stores") },
174059
+ { name: "exportUserData", value: "async ({ user }) => ({})" },
174060
+ { name: "getUserId", value: "(user) => user.sub" }
174061
+ ],
174062
+ generic: true,
174063
+ imports: [],
174064
+ note: "exportUserData must return everything you hold on the user; getUserId lets the route revoke sibling sessions.",
174065
+ packages: [],
174066
+ typeName: "ComplianceConfig"
174067
+ },
174068
+ credentials: {
174069
+ configKey: "credentials",
174070
+ exportName: "credentialsConfig",
174071
+ fields: [
174072
+ { name: "credentialStore", value: "createInMemoryCredentialStore()" },
174073
+ { name: "getUserByEmail", value: TODO("look up a user by email") },
174074
+ { name: "onCreateCredentialUser", value: TODO("create and return the user for identity.email") },
174075
+ { name: "onSendEmail", value: TODO("send the verification / reset email containing message.token") },
174076
+ { name: "requireEmailVerification", value: "false" }
174077
+ ],
174078
+ generic: true,
174079
+ imports: ["createInMemoryCredentialStore"],
174080
+ note: "Swap the in-memory credential store for a real one (it holds password hashes + tokens).",
174081
+ packages: [],
174082
+ typeName: "CredentialsConfig"
174083
+ },
174084
+ lockout: {
174085
+ configKey: "lockout",
174086
+ exportName: "lockoutConfig",
174087
+ fields: [
174088
+ { name: "lockoutStore", value: "createInMemoryLockoutStore()" },
174089
+ { name: "maxAttempts", value: "5" },
174090
+ { name: "windowMs", value: "15 * 60 * 1000" }
174091
+ ],
174092
+ generic: false,
174093
+ imports: ["createInMemoryLockoutStore"],
174094
+ note: "Throttles the credential login route; pair with the `credentials` block.",
174095
+ packages: [],
174096
+ typeName: "LockoutConfig"
174097
+ },
174098
+ mfa: {
174099
+ configKey: "mfa",
174100
+ exportName: "mfaConfig",
174101
+ fields: [
174102
+ { name: "mfaStore", value: "createInMemoryMfaStore()" },
174103
+ { name: "getUserId", value: "(user) => user.sub" },
174104
+ { name: "getChallengeUser", value: TODO("resolve the parked challenge identity to a user") },
174105
+ { name: "issuer", value: "'YourApp'" }
174106
+ ],
174107
+ generic: true,
174108
+ imports: ["createInMemoryMfaStore"],
174109
+ note: "Set `encryptionKey` (base64url) to encrypt the TOTP secret at rest in any real deployment.",
174110
+ packages: [],
174111
+ typeName: "MfaConfig"
174112
+ },
174113
+ organizations: {
174114
+ configKey: "organizations",
174115
+ exportName: "organizationsConfig",
174116
+ fields: [
174117
+ { name: "getUserId", value: "(user) => user.sub" },
174118
+ { name: "organizationStore", value: "createInMemoryOrganizationStore()" }
174119
+ ],
174120
+ generic: true,
174121
+ imports: ["createInMemoryOrganizationStore"],
174122
+ note: "Add `onSendInvitation` to deliver invite emails; otherwise the plaintext token is returned from the invite route.",
174123
+ packages: [],
174124
+ typeName: "OrganizationsConfig"
174125
+ },
174126
+ passwordless: {
174127
+ configKey: "passwordless",
174128
+ exportName: "passwordlessConfig",
174129
+ fields: [
174130
+ { name: "passwordlessTokenStore", value: "createInMemoryPasswordlessTokenStore()" },
174131
+ { name: "getUserByEmail", value: TODO("look up a user by email") },
174132
+ { name: "onSendMagicLink", value: TODO("email the magic link containing message.token") }
174133
+ ],
174134
+ generic: true,
174135
+ imports: ["createInMemoryPasswordlessTokenStore"],
174136
+ note: "The magic-link flow mounts when `onSendMagicLink` is set; add `onSendOtp` to also mount the email/SMS OTP flow.",
174137
+ packages: [],
174138
+ typeName: "PasswordlessConfig"
174139
+ },
174140
+ portal: {
174141
+ configKey: "portal",
174142
+ exportName: "portalConfig",
174143
+ fields: [
174144
+ { name: "setupSessionStore", value: "createInMemorySetupSessionStore()" }
174145
+ ],
174146
+ generic: false,
174147
+ imports: ["createInMemorySetupSessionStore"],
174148
+ note: "Pass the same `ssoConnectionStore` / `scimTokenStore` your sso / scim blocks use so portal edits take effect live.",
174149
+ packages: [],
174150
+ typeName: "PortalConfig"
174151
+ },
174152
+ roles: {
174153
+ configKey: "roles",
174154
+ exportName: "rolesConfig",
174155
+ fields: [
174156
+ { name: "getUserId", value: "(user) => user.sub" },
174157
+ { name: "organizationStore", value: "createInMemoryOrganizationStore()" },
174158
+ { name: "roleStore", value: "createInMemoryRoleStore()" }
174159
+ ],
174160
+ generic: true,
174161
+ imports: ["createInMemoryOrganizationStore", "createInMemoryRoleStore"],
174162
+ note: "Builds on the `organizations` block \u2014 reuse the same organizationStore instance there.",
174163
+ packages: [],
174164
+ typeName: "RolesConfig"
174165
+ },
174166
+ scim: {
174167
+ configKey: "scim",
174168
+ exportName: "scimConfig",
174169
+ fields: [
174170
+ { name: "scimTokenStore", value: "createInMemoryScimTokenStore()" },
174171
+ { name: "getScimUser", value: TODO("return the SCIM user for { id, organizationId }") },
174172
+ { name: "listScimUsers", value: "async () => []" },
174173
+ { name: "onScimUserCreate", value: TODO("create and return the SCIM user") },
174174
+ { name: "onScimUserDeactivate", value: TODO("deprovision the user (hard-delete or deactivate)") },
174175
+ { name: "onScimUserReplace", value: TODO("replace and return the SCIM user (undefined if unknown)") }
174176
+ ],
174177
+ generic: false,
174178
+ imports: ["createInMemoryScimTokenStore"],
174179
+ note: "Group hooks are optional (the /Groups routes 501 without them). Mint per-org tokens with `createScimToken`.",
174180
+ packages: [],
174181
+ typeName: "ScimConfig"
174182
+ },
174183
+ sessions: {
174184
+ configKey: "sessions",
174185
+ exportName: "sessionsConfig",
174186
+ fields: [{ name: "getUserId", value: "(user) => user.sub" }],
174187
+ generic: true,
174188
+ imports: [],
174189
+ note: "Requires an `authSessionStore` (top-level) that can enumerate a user\u2019s sessions.",
174190
+ packages: [],
174191
+ typeName: "SessionsConfig"
174192
+ },
174193
+ sso: {
174194
+ configKey: "sso",
174195
+ exportName: "ssoConfig",
174196
+ fields: [
174197
+ { name: "ssoConnectionStore", value: "createInMemorySsoConnectionStore()" },
174198
+ { name: "getSsoUser", value: TODO("map the verified SSO identity to your user (create on first sign-in)") }
174199
+ ],
174200
+ generic: true,
174201
+ imports: ["createInMemorySsoConnectionStore"],
174202
+ note: "OIDC works out of the box; add a `samlAdapter` (wrapping e.g. @node-saml/node-saml) to also mount SAML.",
174203
+ packages: [],
174204
+ typeName: "SSOConfig"
174205
+ },
174206
+ webauthn: {
174207
+ configKey: "webauthn",
174208
+ exportName: "webauthnConfig",
174209
+ fields: [
174210
+ { name: "credentialStore", value: "createInMemoryWebAuthnCredentialStore()" },
174211
+ { name: "getUserId", value: "(user) => user.sub" },
174212
+ { name: "getWebAuthnUser", value: TODO("resolve a stored credential userId back to a user") },
174213
+ { name: "origin", value: "'http://localhost:3000'" },
174214
+ { name: "rpId", value: "'localhost'" },
174215
+ { name: "rpName", value: "'YourApp'" },
174216
+ {
174217
+ name: "webauthnAdapter",
174218
+ value: "{} as unknown as WebAuthnAdapter"
174219
+ }
174220
+ ],
174221
+ generic: true,
174222
+ imports: ["createInMemoryWebAuthnCredentialStore", "type WebAuthnAdapter"],
174223
+ note: "Provide a real `webauthnAdapter` wrapping a vetted library (e.g. @simplewebauthn/server); set origin/rpId/rpName for your domain.",
174224
+ packages: [],
174225
+ typeName: "WebAuthnConfig"
174226
+ },
174227
+ webhooks: {
174228
+ configKey: "webhooks",
174229
+ exportName: "webhooksConfig",
174230
+ fields: [{ name: "endpoints", value: "[]" }],
174231
+ generic: false,
174232
+ imports: [],
174233
+ note: "Add endpoints as { url, secret } \u2014 each event is HMAC-signed (Standard Webhooks) with that secret.",
174234
+ packages: [],
174235
+ typeName: "WebhooksConfig"
174236
+ }
174237
+ };
174238
+ });
174239
+
174240
+ // src/cli/config/auth/authCatalog.ts
174241
+ var AUTH_FEATURES;
174242
+ var init_authCatalog = __esm(() => {
174243
+ AUTH_FEATURES = [
174244
+ {
174245
+ blurb: "Email/password \u2014 register, verify-email, login, reset-password \u2014 minting the same session as OAuth.",
174246
+ configKey: "credentials",
174247
+ id: "credentials",
174248
+ kind: "routes",
174249
+ label: "Credentials"
174250
+ },
174251
+ {
174252
+ blurb: "Magic links + email/SMS one-time codes; each verify route mints the same session as every other flow.",
174253
+ configKey: "passwordless",
174254
+ id: "passwordless",
174255
+ kind: "routes",
174256
+ label: "Passwordless"
174257
+ },
174258
+ {
174259
+ blurb: "TOTP + backup codes; auto-wires the login MFA gate over credentials and mounts enroll/challenge routes.",
174260
+ configKey: "mfa",
174261
+ id: "mfa",
174262
+ kind: "routes",
174263
+ label: "MFA"
174264
+ },
174265
+ {
174266
+ blurb: "Passkeys (WebAuthn): registration ceremony for the caller + passwordless authentication ceremony.",
174267
+ configKey: "webauthn",
174268
+ id: "webauthn",
174269
+ kind: "routes",
174270
+ label: "WebAuthn / passkeys"
174271
+ },
174272
+ {
174273
+ blurb: "Per-organization enterprise SSO (OIDC + SAML); id_tokens verified in-house against the issuer JWKS.",
174274
+ configKey: "sso",
174275
+ id: "sso",
174276
+ kind: "routes",
174277
+ label: "Enterprise SSO"
174278
+ },
174279
+ {
174280
+ blurb: "SCIM 2.0 directory provisioning (Okta / Azure AD) with per-org bearer-token auth.",
174281
+ configKey: "scim",
174282
+ id: "scim",
174283
+ kind: "routes",
174284
+ label: "SCIM provisioning"
174285
+ },
174286
+ {
174287
+ blurb: "First-class multi-tenancy: orgs, memberships, invitations, and org-scoped roles.",
174288
+ configKey: "organizations",
174289
+ id: "organizations",
174290
+ kind: "routes",
174291
+ label: "Organizations"
174292
+ },
174293
+ {
174294
+ blurb: "Org-scoped roles & permissions \u2014 list an org\u2019s roles and set a member\u2019s roles.",
174295
+ configKey: "roles",
174296
+ id: "roles",
174297
+ kind: "routes",
174298
+ label: "Roles & permissions"
174299
+ },
174300
+ {
174301
+ blurb: "Headless admin-portal setup-link endpoints so a customer\u2019s IT admin self-serves their SSO/SCIM.",
174302
+ configKey: "portal",
174303
+ id: "portal",
174304
+ kind: "routes",
174305
+ label: "Admin portal"
174306
+ },
174307
+ {
174308
+ blurb: "Self-service session management: list the caller\u2019s active sessions and remote-revoke by id.",
174309
+ configKey: "sessions",
174310
+ id: "sessions",
174311
+ kind: "routes",
174312
+ label: "Session management"
174313
+ },
174314
+ {
174315
+ blurb: "GDPR/CCPA self-service: data export (right to access) + erasure (right to be forgotten).",
174316
+ configKey: "compliance",
174317
+ id: "compliance",
174318
+ kind: "routes",
174319
+ label: "Compliance"
174320
+ },
174321
+ {
174322
+ blurb: "Built-in HTMX fragment routes (login, identities, connectors, account, signout, delete-account).",
174323
+ configKey: "htmx",
174324
+ id: "htmx",
174325
+ kind: "routes",
174326
+ label: "HTMX fragments"
174327
+ },
174328
+ {
174329
+ blurb: "Append-only structured audit events (register, login, mfa_*, logout\u2026) to your store + hook. SOC 2 prerequisite.",
174330
+ configKey: "audit",
174331
+ id: "audit",
174332
+ kind: "behavior",
174333
+ label: "Audit log"
174334
+ },
174335
+ {
174336
+ blurb: "HMAC-signed outbound webhooks (Standard Webhooks) for every emitted auth event.",
174337
+ configKey: "webhooks",
174338
+ id: "webhooks",
174339
+ kind: "behavior",
174340
+ label: "Webhooks"
174341
+ },
174342
+ {
174343
+ blurb: "RBAC/ABAC: adds a protectPermission(check, handler) derive that delegates to your hasPermission hook.",
174344
+ configKey: "authorization",
174345
+ id: "authorization",
174346
+ kind: "behavior",
174347
+ label: "Authorization"
174348
+ },
174349
+ {
174350
+ blurb: "Per-identity attempt throttling + progressive account lockout on the credential login route.",
174351
+ configKey: "lockout",
174352
+ id: "lockout",
174353
+ kind: "behavior",
174354
+ label: "Lockout"
174355
+ }
174356
+ ];
174357
+ });
174358
+
174359
+ // src/cli/config/auth/resolveAuthSettings.ts
174360
+ import { existsSync as existsSync23, readFileSync as readFileSync23 } from "fs";
174361
+ import { resolve as resolve14 } from "path";
174362
+ var import_typescript9, AUTH_PACKAGE = "@absolutejs/auth", CONFIG_CANDIDATES3, findAuthSettingsPath = (cwd, override) => {
174363
+ if (override) {
174364
+ const resolved = resolve14(cwd, override);
174365
+ return existsSync23(resolved) ? resolved : null;
174366
+ }
174367
+ for (const name of CONFIG_CANDIDATES3) {
174368
+ const candidate = resolve14(cwd, name);
174369
+ if (existsSync23(candidate))
174370
+ return candidate;
174371
+ }
174372
+ return null;
174373
+ }, parseSource2 = (configPath2, text) => import_typescript9.default.createSourceFile(configPath2, text, import_typescript9.default.ScriptTarget.Latest, true), findAuthSettingsObject = (sourceFile) => {
174374
+ let found = null;
174375
+ const visit = (node) => {
174376
+ if (found)
174377
+ return;
174378
+ const [firstArgument] = import_typescript9.default.isCallExpression(node) ? node.arguments : [];
174379
+ if (import_typescript9.default.isCallExpression(node) && import_typescript9.default.isIdentifier(node.expression) && node.expression.text === "defineAuthSettings" && firstArgument && import_typescript9.default.isObjectLiteralExpression(firstArgument)) {
174380
+ found = firstArgument;
174381
+ return;
174382
+ }
174383
+ if (import_typescript9.default.isExportAssignment(node) && import_typescript9.default.isObjectLiteralExpression(node.expression)) {
174384
+ found = node.expression;
174385
+ return;
174386
+ }
174387
+ import_typescript9.default.forEachChild(node, visit);
174388
+ };
174389
+ visit(sourceFile);
174390
+ return found;
174391
+ }, parseAuthSettingsObject = (configPath2) => {
174392
+ const text = readFileSync23(configPath2, "utf-8");
174393
+ return {
174394
+ object: findAuthSettingsObject(parseSource2(configPath2, text)),
174395
+ text
174396
+ };
174397
+ }, evalLiteral2 = (node) => {
174398
+ if (import_typescript9.default.isStringLiteralLike(node))
174399
+ return { opaque: false, value: node.text };
174400
+ if (node.kind === import_typescript9.default.SyntaxKind.TrueKeyword) {
174401
+ return { opaque: false, value: true };
174402
+ }
174403
+ if (node.kind === import_typescript9.default.SyntaxKind.FalseKeyword) {
174404
+ return { opaque: false, value: false };
174405
+ }
174406
+ if (node.kind === import_typescript9.default.SyntaxKind.NullKeyword) {
174407
+ return { opaque: false, value: null };
174408
+ }
174409
+ if (import_typescript9.default.isNumericLiteral(node)) {
174410
+ return { opaque: false, value: Number(node.text) };
174411
+ }
174412
+ if (import_typescript9.default.isPrefixUnaryExpression(node) && node.operator === import_typescript9.default.SyntaxKind.MinusToken && import_typescript9.default.isNumericLiteral(node.operand)) {
174413
+ return { opaque: false, value: -Number(node.operand.text) };
174414
+ }
174415
+ if (import_typescript9.default.isArrayLiteralExpression(node)) {
174416
+ const items = [];
174417
+ for (const element of node.elements) {
174418
+ const result = evalLiteral2(element);
174419
+ if (result.opaque)
174420
+ return { opaque: true, value: undefined };
174421
+ items.push(result.value);
174422
+ }
174423
+ return { opaque: false, value: items };
174424
+ }
174425
+ return { opaque: true, value: undefined };
174426
+ }, readCurrent2 = (configPath2) => {
174427
+ const current = {};
174428
+ const opaqueKeys = [];
174429
+ const { object } = parseAuthSettingsObject(configPath2);
174430
+ if (!object)
174431
+ return { current, opaqueKeys };
174432
+ for (const property of object.properties) {
174433
+ if (!import_typescript9.default.isPropertyAssignment(property) || !(import_typescript9.default.isIdentifier(property.name) || import_typescript9.default.isStringLiteral(property.name))) {
174434
+ continue;
174435
+ }
174436
+ const name = property.name.text;
174437
+ const result = evalLiteral2(property.initializer);
174438
+ if (result.opaque)
174439
+ opaqueKeys.push(name);
174440
+ else
174441
+ current[name] = result.value;
174442
+ }
174443
+ return { current, opaqueKeys };
174444
+ }, resolveAuthSettingsState = (cwd, override) => {
174445
+ const configPath2 = findAuthSettingsPath(cwd, override);
174446
+ const fields = introspectType(cwd, "AuthSettings", new Set, AUTH_PACKAGE);
174447
+ const { current, opaqueKeys } = configPath2 ? readCurrent2(configPath2) : { current: {}, opaqueKeys: [] };
174448
+ return {
174449
+ available: fields.length > 0,
174450
+ configPath: configPath2,
174451
+ current,
174452
+ fields,
174453
+ opaqueKeys
174454
+ };
174455
+ };
174456
+ var init_resolveAuthSettings = __esm(() => {
174457
+ init_fromType();
174458
+ import_typescript9 = __toESM(require_typescript(), 1);
174459
+ CONFIG_CANDIDATES3 = [
174460
+ "auth.config.ts",
174461
+ "auth.config.js",
174462
+ "auth.config.mjs"
174463
+ ];
174464
+ });
174465
+
174466
+ // src/cli/config/auth/resolveAuthState.ts
174467
+ import { existsSync as existsSync24, readdirSync as readdirSync6, readFileSync as readFileSync24 } from "fs";
174468
+ import { join as join21, relative as relative6, resolve as resolve15 } from "path";
174469
+ var import_typescript10, AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
174470
+ if (!existsSync24(path))
174471
+ return null;
174472
+ try {
174473
+ const parsed = JSON.parse(readFileSync24(path, "utf-8"));
174474
+ return isRecord6(parsed) ? parsed : null;
174475
+ } catch {
174476
+ return null;
174477
+ }
174478
+ }, stringField = (record, key) => {
174479
+ const value = record?.[key];
174480
+ return typeof value === "string" ? value : null;
174481
+ }, declaredVersionFor = (cwd) => {
174482
+ const pkg = readJson(join21(cwd, "package.json"));
174483
+ if (!pkg)
174484
+ return null;
174485
+ for (const field of ["dependencies", "devDependencies"]) {
174486
+ const group = pkg[field];
174487
+ if (!isRecord6(group))
174488
+ continue;
174489
+ const version2 = group[AUTH_PACKAGE2];
174490
+ if (typeof version2 === "string")
174491
+ return version2;
174492
+ }
174493
+ return null;
174494
+ }, installedVersionFor = (cwd) => stringField(readJson(join21(cwd, "node_modules", AUTH_PACKAGE2, "package.json")), "version"), SOURCE_FILE, safeReaddir = (dir) => {
174495
+ try {
174496
+ return readdirSync6(dir, { withFileTypes: true });
174497
+ } catch {
174498
+ return [];
174499
+ }
174500
+ }, sortEntry = (dir, entry, found, dirs) => {
174501
+ const full = join21(dir, entry.name);
174502
+ if (entry.isDirectory()) {
174503
+ if (SKIP_DIRS.has(entry.name) || entry.name.startsWith("."))
174504
+ return;
174505
+ dirs.push(full);
174506
+ return;
174507
+ }
174508
+ if (SOURCE_FILE.test(entry.name))
174509
+ found.push(full);
174510
+ }, collectFrom = (dir, found, stack) => {
174511
+ for (const entry of safeReaddir(dir))
174512
+ sortEntry(dir, entry, found, stack);
174513
+ }, candidateFiles = (root) => {
174514
+ const found = [];
174515
+ const stack = [root];
174516
+ while (stack.length > 0 && found.length < MAX_FILES) {
174517
+ const dir = stack.pop();
174518
+ if (dir === undefined)
174519
+ break;
174520
+ collectFrom(dir, found, stack);
174521
+ }
174522
+ return found;
174523
+ }, isAuthPackageImport = (statement) => import_typescript10.default.isImportDeclaration(statement) && import_typescript10.default.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === AUTH_PACKAGE2, addAuthNames = (statement, names) => {
174524
+ const bindings = statement.importClause?.namedBindings;
174525
+ if (!bindings || !import_typescript10.default.isNamedImports(bindings))
174526
+ return;
174527
+ for (const element of bindings.elements) {
174528
+ const imported = element.propertyName?.text ?? element.name.text;
174529
+ if (!SETUP_EXPORTS.has(imported))
174530
+ continue;
174531
+ names.add(element.name.text);
174532
+ }
174533
+ }, authBindings = (sourceFile) => {
174534
+ const names = new Set;
174535
+ for (const statement of sourceFile.statements) {
174536
+ if (isAuthPackageImport(statement))
174537
+ addAuthNames(statement, names);
174538
+ }
174539
+ return names;
174540
+ }, isAuthCall = (node, bindings) => import_typescript10.default.isIdentifier(node.expression) && bindings.has(node.expression.text), providerCountOf = (property) => {
174541
+ if (!import_typescript10.default.isPropertyAssignment(property) || !import_typescript10.default.isObjectLiteralExpression(property.initializer)) {
174542
+ return null;
174543
+ }
174544
+ return property.initializer.properties.length;
174545
+ }, readConfigKeys = (object) => {
174546
+ const keys = new Set;
174547
+ let providerCount = null;
174548
+ const usesSpread = object.properties.some((property) => import_typescript10.default.isSpreadAssignment(property));
174549
+ for (const property of object.properties) {
174550
+ const { name } = property;
174551
+ if (name === undefined || !import_typescript10.default.isIdentifier(name))
174552
+ continue;
174553
+ keys.add(name.text);
174554
+ if (name.text !== "providersConfiguration")
174555
+ continue;
174556
+ providerCount = providerCountOf(property);
174557
+ }
174558
+ return { keys, providerCount, usesSpread };
174559
+ }, matchFromCall = (node) => {
174560
+ const [arg] = node.arguments;
174561
+ if (arg && import_typescript10.default.isObjectLiteralExpression(arg))
174562
+ return readConfigKeys(arg);
174563
+ return { keys: new Set, providerCount: null, usesSpread: true };
174564
+ }, readFileOrNull = (path) => {
174565
+ try {
174566
+ return readFileSync24(path, "utf-8");
174567
+ } catch {
174568
+ return null;
174569
+ }
174570
+ }, findSetupInFile = (path) => {
174571
+ const text = readFileOrNull(path);
174572
+ if (text === null || !text.includes(AUTH_PACKAGE2))
174573
+ return null;
174574
+ const sourceFile = import_typescript10.default.createSourceFile(path, text, import_typescript10.default.ScriptTarget.Latest, true);
174575
+ const bindings = authBindings(sourceFile);
174576
+ if (bindings.size === 0)
174577
+ return null;
174578
+ let match = null;
174579
+ const visit = (node) => {
174580
+ if (match)
174581
+ return;
174582
+ if (import_typescript10.default.isCallExpression(node) && isAuthCall(node, bindings)) {
174583
+ match = matchFromCall(node);
174584
+ return;
174585
+ }
174586
+ import_typescript10.default.forEachChild(node, visit);
174587
+ };
174588
+ visit(sourceFile);
174589
+ return match;
174590
+ }, featureStatuses = (keys) => AUTH_FEATURES.map((feature) => ({
174591
+ blurb: feature.blurb,
174592
+ configKey: feature.configKey,
174593
+ configured: keys.has(feature.configKey),
174594
+ id: feature.id,
174595
+ kind: feature.kind,
174596
+ label: feature.label,
174597
+ scaffoldable: isScaffoldableFeature(feature.id)
174598
+ })), resolveAuthState = (cwd) => {
174599
+ const installedVersion = installedVersionFor(cwd);
174600
+ const root = existsSync24(join21(cwd, "src")) ? join21(cwd, "src") : cwd;
174601
+ let match = null;
174602
+ let setupPath = null;
174603
+ for (const file of candidateFiles(root)) {
174604
+ const found = findSetupInFile(file);
174605
+ if (found === null)
174606
+ continue;
174607
+ match = found;
174608
+ setupPath = relative6(cwd, resolve15(file));
174609
+ break;
174610
+ }
174611
+ const keys = match?.keys ?? new Set;
174612
+ const state = {
174613
+ declaredVersion: declaredVersionFor(cwd),
174614
+ features: featureStatuses(keys),
174615
+ installed: installedVersion !== null,
174616
+ installedVersion,
174617
+ introspected: match !== null,
174618
+ npmUrl: NPM_URL,
174619
+ providerCount: match?.providerCount ?? null,
174620
+ repoUrl: REPO_URL,
174621
+ settings: resolveAuthSettingsState(cwd),
174622
+ setupPath,
174623
+ usesSpread: match?.usesSpread ?? false
174624
+ };
174625
+ return state;
174626
+ };
174627
+ var init_resolveAuthState = __esm(() => {
174628
+ init_authCatalog();
174629
+ init_authScaffolds();
174630
+ init_resolveAuthSettings();
174631
+ import_typescript10 = __toESM(require_typescript(), 1);
174632
+ SKIP_DIRS = new Set([
174633
+ "node_modules",
174634
+ ".git",
174635
+ "build",
174636
+ "dist",
174637
+ ".absolutejs",
174638
+ "coverage",
174639
+ ".next"
174640
+ ]);
174641
+ SETUP_EXPORTS = new Set(["auth", "absoluteAuth"]);
174642
+ SOURCE_FILE = /\.(ts|tsx|mts|cts|js|mjs)$/;
174643
+ });
174644
+
174645
+ // src/cli/config/auth/scaffoldAuthFeature.ts
174646
+ import { existsSync as existsSync25, writeFileSync as writeFileSync13 } from "fs";
174647
+ import { dirname as dirname10, join as join22, relative as relative7, resolve as resolve16 } from "path";
174648
+ var renderScaffold = (scaffold) => {
174649
+ const importNames = [...scaffold.imports, `type ${scaffold.typeName}`];
174650
+ const importLine = `import { ${importNames.join(", ")} } from '@absolutejs/auth';`;
174651
+ const userType = scaffold.generic ? `
174652
+ // TODO: replace with your app's user type (the one you pass to auth<User>()).
174653
+ type User = {
174654
+ sub: string;
174655
+ };
174656
+ ` : "";
174657
+ const note = scaffold.note ? `
174658
+ // ${scaffold.note}
174659
+ ` : `
174660
+ `;
174661
+ const generic = scaffold.generic ? "<User>" : "";
174662
+ const body = scaffold.fields.map((field) => ` ${field.name}: ${field.value}`).join(`,
174663
+ `);
174664
+ return `${importLine}
174665
+ ${userType}${note}export const ${scaffold.exportName}: ${scaffold.typeName}${generic} = {
174666
+ ${body}
174667
+ };
174668
+ `;
174669
+ }, targetDir = (cwd) => {
174670
+ const { setupPath } = resolveAuthState(cwd);
174671
+ if (setupPath)
174672
+ return dirname10(resolve16(cwd, setupPath));
174673
+ const src = join22(cwd, "src");
174674
+ return existsSync25(src) ? src : cwd;
174675
+ }, spreadFor = (scaffold) => `import { ${scaffold.exportName} } from './${scaffold.exportName}';
174676
+ // add to your auth() call:
174677
+ ${scaffold.configKey}: ${scaffold.exportName}`, failure2 = (message) => ({
174678
+ created: null,
174679
+ installed: false,
174680
+ message,
174681
+ ok: false,
174682
+ spreadSnippet: null
174683
+ }), scaffoldAuthFeature = (cwd, id, options = {}) => {
174684
+ const scaffold = AUTH_SCAFFOLDS[id];
174685
+ if (!scaffold)
174686
+ return failure2(`Unknown auth feature "${id}".`);
174687
+ const filePath = join22(targetDir(cwd), `${scaffold.exportName}.ts`);
174688
+ const relPath = relative7(cwd, filePath);
174689
+ if (existsSync25(filePath)) {
174690
+ return {
174691
+ created: null,
174692
+ installed: false,
174693
+ message: `${relPath} already exists \u2014 left untouched.`,
174694
+ ok: true,
174695
+ spreadSnippet: spreadFor(scaffold)
174696
+ };
174697
+ }
174698
+ const install = options.install ?? true;
174699
+ const installOk = install && scaffold.packages.length > 0 ? installPackages(cwd, scaffold.packages) : true;
174700
+ writeFileSync13(filePath, renderScaffold(scaffold));
174701
+ return {
174702
+ created: relPath,
174703
+ installed: installOk,
174704
+ message: `Scaffolded ${relPath}.`,
174705
+ ok: true,
174706
+ spreadSnippet: spreadFor(scaffold)
174707
+ };
174708
+ };
174709
+ var init_scaffoldAuthFeature = __esm(() => {
174710
+ init_dependencies();
174711
+ init_authScaffolds();
174712
+ init_resolveAuthState();
174713
+ });
174714
+
173808
174715
  // src/cli/htmx/install.ts
173809
- import { existsSync as existsSync22, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12 } from "fs";
173810
- import { join as join21 } from "path";
174716
+ import { existsSync as existsSync26, mkdirSync as mkdirSync12, readFileSync as readFileSync25, writeFileSync as writeFileSync14 } from "fs";
174717
+ import { join as join23 } from "path";
173811
174718
  var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
173812
- join21(import.meta.dir, "htmx.min.js"),
173813
- join21(import.meta.dir, "htmx", "htmx.min.js"),
173814
- join21(import.meta.dir, "..", "htmx", "htmx.min.js")
173815
- ].find((path) => existsSync22(path)) ?? null, detectHtmxVersion = (content) => {
174719
+ join23(import.meta.dir, "htmx.min.js"),
174720
+ join23(import.meta.dir, "htmx", "htmx.min.js"),
174721
+ join23(import.meta.dir, "..", "htmx", "htmx.min.js")
174722
+ ].find((path) => existsSync26(path)) ?? null, detectHtmxVersion = (content) => {
173816
174723
  const match = content.match(/version:"([0-9.]+)"/);
173817
174724
  return match ? match[1] : null;
173818
174725
  }, fetchHtmx = async (version2) => {
@@ -173823,17 +174730,17 @@ var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
173823
174730
  }
173824
174731
  return response.text();
173825
174732
  }, installedHtmxVersion = (htmxDir) => {
173826
- const file = join21(htmxDir, "htmx.min.js");
173827
- if (!existsSync22(file))
174733
+ const file = join23(htmxDir, "htmx.min.js");
174734
+ if (!existsSync26(file))
173828
174735
  return null;
173829
- return detectHtmxVersion(readFileSync22(file, "utf-8"));
174736
+ return detectHtmxVersion(readFileSync25(file, "utf-8"));
173830
174737
  }, readVendoredHtmx = () => {
173831
174738
  const file = vendoredHtmxFile();
173832
- return file ? readFileSync22(file, "utf-8") : null;
174739
+ return file ? readFileSync25(file, "utf-8") : null;
173833
174740
  }, writeHtmx = (htmxDir, content) => {
173834
- mkdirSync11(htmxDir, { recursive: true });
173835
- const file = join21(htmxDir, "htmx.min.js");
173836
- writeFileSync12(file, content, "utf-8");
174741
+ mkdirSync12(htmxDir, { recursive: true });
174742
+ const file = join23(htmxDir, "htmx.min.js");
174743
+ writeFileSync14(file, content, "utf-8");
173837
174744
  return file;
173838
174745
  };
173839
174746
  var init_install = () => {};
@@ -173843,7 +174750,7 @@ var exports_add = {};
173843
174750
  __export(exports_add, {
173844
174751
  runAdd: () => runAdd
173845
174752
  });
173846
- import { dirname as dirname10, join as join22, relative as relative6 } from "path";
174753
+ import { dirname as dirname11, join as join24, relative as relative8 } from "path";
173847
174754
  var write2 = (text) => process.stdout.write(`${text}
173848
174755
  `), fail2 = (message) => {
173849
174756
  process.stdout.write(`${colors.red}${message}${colors.reset}
@@ -173854,11 +174761,11 @@ var write2 = (text) => process.stdout.write(`${text}
173854
174761
  return;
173855
174762
  write2(` ${colors.dim}${label}${colors.reset}`);
173856
174763
  for (const path of paths)
173857
- write2(` ${relative6(cwd, path)}`);
174764
+ write2(` ${relative8(cwd, path)}`);
173858
174765
  }, frontendRoot = (project, cwd) => {
173859
174766
  const [firstKey] = configuredFrameworks(project);
173860
174767
  const firstDir = firstKey ? project.frameworkDirs[firstKey] : undefined;
173861
- return firstDir ? dirname10(firstDir) : join22(cwd, "src", "frontend");
174768
+ return firstDir ? dirname11(firstDir) : join24(cwd, "src", "frontend");
173862
174769
  }, addIntegrationCli = (id, install) => {
173863
174770
  const result = addIntegration(process.cwd(), id, { install });
173864
174771
  if (!result.ok) {
@@ -173875,9 +174782,29 @@ var write2 = (text) => process.stdout.write(`${text}
173875
174782
  }
173876
174783
  write2(`
173877
174784
  ${colors.dim}Next${colors.reset} ${result.wired ? "run `absolute dev`" : "wire it in, then run `absolute dev`"}`);
174785
+ }, addAuthFeatureCli = (id, install) => {
174786
+ const result = scaffoldAuthFeature(process.cwd(), id, { install });
174787
+ if (!result.ok) {
174788
+ fail2(result.message);
174789
+ return;
174790
+ }
174791
+ write2(`${colors.green}\u2713${colors.reset} ${result.message}`);
174792
+ if (result.spreadSnippet) {
174793
+ write2(`
174794
+ ${colors.dim}Wire it in${colors.reset}:`);
174795
+ for (const line of result.spreadSnippet.split(`
174796
+ `))
174797
+ write2(` ${line}`);
174798
+ }
174799
+ write2(`
174800
+ ${colors.dim}Next${colors.reset} fill the TODO stubs, run \`absolute prettier --write\`, then \`absolute dev\``);
173878
174801
  }, runAdd = async (args) => {
173879
174802
  const [framework] = args.filter((arg) => !arg.startsWith("--"));
173880
174803
  const noInstall = args.includes("--no-install");
174804
+ if (framework?.startsWith("auth:")) {
174805
+ addAuthFeatureCli(framework.slice("auth:".length), !noInstall);
174806
+ return;
174807
+ }
173881
174808
  if (framework && isIntegrationId(framework)) {
173882
174809
  addIntegrationCli(framework, !noInstall);
173883
174810
  return;
@@ -173902,8 +174829,8 @@ var write2 = (text) => process.stdout.write(`${text}
173902
174829
  write2(`${colors.yellow}!${colors.reset} ${frameworks2[framework].label} is already configured \u2014 nothing to do.`);
173903
174830
  return;
173904
174831
  }
173905
- const dirAbs = join22(frontendRoot(project, cwd), framework);
173906
- const dirRel = `./${relative6(cwd, dirAbs).split("\\").join("/")}`;
174832
+ const dirAbs = join24(frontendRoot(project, cwd), framework);
174833
+ const dirRel = `./${relative8(cwd, dirAbs).split("\\").join("/")}`;
173907
174834
  let depNote = "Skipped dependency install (--no-install).";
173908
174835
  if (!noInstall) {
173909
174836
  write2(`${colors.dim}Installing ${frameworks2[framework].label} dependencies\u2026${colors.reset}`);
@@ -173962,6 +174889,7 @@ var init_add = __esm(() => {
173962
174889
  init_dependencies();
173963
174890
  init_addPlugin();
173964
174891
  init_catalog();
174892
+ init_scaffoldAuthFeature();
173965
174893
  init_install();
173966
174894
  init_tuiPrimitives();
173967
174895
  });
@@ -173971,8 +174899,8 @@ var exports_analyze = {};
173971
174899
  __export(exports_analyze, {
173972
174900
  runAnalyze: () => runAnalyze
173973
174901
  });
173974
- import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync2, writeFileSync as writeFileSync13 } from "fs";
173975
- import { join as join23, resolve as resolve13 } from "path";
174902
+ import { existsSync as existsSync27, readFileSync as readFileSync26, statSync as statSync3, writeFileSync as writeFileSync15 } from "fs";
174903
+ import { join as join25, resolve as resolve17 } from "path";
173976
174904
  var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_WIDTH = 16, SIZE_WIDTH = 12, CHANGE_WIDTH = 10, CATEGORY_ORDER, categoryOf = (key) => {
173977
174905
  if (key.startsWith("Island"))
173978
174906
  return "Islands";
@@ -173987,26 +174915,26 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
173987
174915
  return "Pages";
173988
174916
  }, fileSize2 = (path) => {
173989
174917
  try {
173990
- return statSync2(path).size;
174918
+ return statSync3(path).size;
173991
174919
  } catch {
173992
174920
  return 0;
173993
174921
  }
173994
174922
  }, readSizes = (manifestDir) => {
173995
- const manifestPath = join23(manifestDir, "manifest.json");
173996
- if (!existsSync23(manifestPath))
174923
+ const manifestPath = join25(manifestDir, "manifest.json");
174924
+ if (!existsSync27(manifestPath))
173997
174925
  return null;
173998
- const manifest = JSON.parse(readFileSync23(manifestPath, "utf-8"));
174926
+ const manifest = JSON.parse(readFileSync26(manifestPath, "utf-8"));
173999
174927
  const sizes = {};
174000
174928
  for (const [key, value] of Object.entries(manifest)) {
174001
- sizes[key] = fileSize2(join23(manifestDir, value.replace(/^\//, "")));
174929
+ sizes[key] = fileSize2(join25(manifestDir, value.replace(/^\//, "")));
174002
174930
  }
174003
174931
  return sizes;
174004
174932
  }, readBaseline = (cwd) => {
174005
- const path = join23(cwd, BASELINE_FILE);
174006
- if (!existsSync23(path))
174933
+ const path = join25(cwd, BASELINE_FILE);
174934
+ if (!existsSync27(path))
174007
174935
  return null;
174008
174936
  try {
174009
- const parsed = JSON.parse(readFileSync23(path, "utf-8"));
174937
+ const parsed = JSON.parse(readFileSync26(path, "utf-8"));
174010
174938
  return parsed;
174011
174939
  } catch {
174012
174940
  return null;
@@ -174084,14 +175012,14 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
174084
175012
  const config = await loadConfig(configIndex >= 0 ? args[configIndex + 1] : undefined);
174085
175013
  const outdirIndex = args.indexOf("--outdir");
174086
175014
  const outdir = outdirIndex >= 0 ? args[outdirIndex + 1] : config.buildDirectory;
174087
- const sizes = readSizes(resolve13(cwd, outdir ?? "build"));
175015
+ const sizes = readSizes(resolve17(cwd, outdir ?? "build"));
174088
175016
  if (sizes === null) {
174089
175017
  process.stdout.write(`${colors.dim}No build found. Run \`absolute build\` first.${colors.reset}
174090
175018
  `);
174091
175019
  return;
174092
175020
  }
174093
175021
  if (args.includes("--save")) {
174094
- writeFileSync13(join23(cwd, BASELINE_FILE), `${JSON.stringify(sizes, null, 2)}
175022
+ writeFileSync15(join25(cwd, BASELINE_FILE), `${JSON.stringify(sizes, null, 2)}
174095
175023
  `);
174096
175024
  process.stdout.write(`${colors.green}\u2713${colors.reset} Saved size baseline (${Object.keys(sizes).length} entries) to ${BASELINE_FILE}
174097
175025
  `);
@@ -174337,8 +175265,8 @@ var exports_remove = {};
174337
175265
  __export(exports_remove, {
174338
175266
  runRemove: () => runRemove
174339
175267
  });
174340
- import { existsSync as existsSync24, readFileSync as readFileSync24 } from "fs";
174341
- import { relative as relative7 } from "path";
175268
+ import { existsSync as existsSync28, readFileSync as readFileSync27 } from "fs";
175269
+ import { relative as relative9 } from "path";
174342
175270
  var write3 = (text) => process.stdout.write(`${text}
174343
175271
  `), fail3 = (message) => {
174344
175272
  process.stdout.write(`${colors.red}${message}${colors.reset}
@@ -174348,10 +175276,10 @@ var write3 = (text) => process.stdout.write(`${text}
174348
175276
  const candidates = [findRoutingFile(serverEntry), serverEntry];
174349
175277
  const seen = new Set;
174350
175278
  return candidates.filter((file) => {
174351
- if (file === null || seen.has(file) || !existsSync24(file))
175279
+ if (file === null || seen.has(file) || !existsSync28(file))
174352
175280
  return false;
174353
175281
  seen.add(file);
174354
- return readFileSync24(file, "utf-8").includes(handler);
175282
+ return readFileSync27(file, "utf-8").includes(handler);
174355
175283
  });
174356
175284
  }, runRemove = async (args) => {
174357
175285
  const [framework] = args.filter((arg) => !arg.startsWith("--"));
@@ -174387,10 +175315,10 @@ var write3 = (text) => process.stdout.write(`${text}
174387
175315
  }
174388
175316
  write3(`${colors.green}\u2713${colors.reset} Removed ${framework}Directory from absolute.config.ts
174389
175317
  `);
174390
- write3(` ${colors.dim}Kept${colors.reset} ${relative7(cwd, frameworkDir)} \u2014 delete its source manually if no longer needed.`);
175318
+ write3(` ${colors.dim}Kept${colors.reset} ${relative9(cwd, frameworkDir)} \u2014 delete its source manually if no longer needed.`);
174391
175319
  const refs = referencingFiles(project.serverEntry, HANDLER_NAME[framework]);
174392
175320
  for (const file of refs) {
174393
- write3(` ${colors.yellow}Still references${colors.reset} ${relative7(cwd, file)} (calls ${HANDLER_NAME[framework]})`);
175321
+ write3(` ${colors.yellow}Still references${colors.reset} ${relative9(cwd, file)} (calls ${HANDLER_NAME[framework]})`);
174394
175322
  }
174395
175323
  const deps = frameworkDependencyNames(framework);
174396
175324
  if (prune && deps.length > 0) {
@@ -174478,15 +175406,15 @@ __export(exports_env, {
174478
175406
  runEnv: () => runEnv,
174479
175407
  collectEnvVars: () => collectEnvVars
174480
175408
  });
174481
- import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
174482
- import { join as join24 } from "path";
175409
+ import { existsSync as existsSync29, readFileSync as readFileSync28 } from "fs";
175410
+ import { join as join26 } from "path";
174483
175411
  var {env: env3, Glob: Glob3 } = globalThis.Bun;
174484
- var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text) => [...text.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync25(join24(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
175412
+ var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text) => [...text.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync29(join26(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
174485
175413
  const scans = scanPatterns().map((pattern) => Array.fromAsync(new Glob3(pattern).scan({ cwd: process.cwd() })));
174486
175414
  const files = (await Promise.all(scans)).flat();
174487
175415
  const usage = new Map;
174488
175416
  files.forEach((file) => {
174489
- keysInFile(readFileSync25(file, "utf-8")).forEach((key) => {
175417
+ keysInFile(readFileSync28(file, "utf-8")).forEach((key) => {
174490
175418
  usage.set(key, [...usage.get(key) ?? [], file]);
174491
175419
  });
174492
175420
  });
@@ -174537,6 +175465,215 @@ var init_env = __esm(() => {
174537
175465
  STATUS_WIDTH2 = "missing".length;
174538
175466
  });
174539
175467
 
175468
+ // src/cli/scripts/db.ts
175469
+ var exports_db = {};
175470
+ __export(exports_db, {
175471
+ runDb: () => runDb,
175472
+ quoteIdent: () => quoteIdent,
175473
+ encodeValue: () => encodeValue,
175474
+ dependencyOrder: () => dependencyOrder,
175475
+ conflictClause: () => conflictClause,
175476
+ chunkRows: () => chunkRows
175477
+ });
175478
+ import { existsSync as existsSync30, mkdirSync as mkdirSync13, readFileSync as readFileSync29, writeFileSync as writeFileSync16 } from "fs";
175479
+ import { join as join27 } from "path";
175480
+ var {env: env4, spawn: spawn2, SQL } = globalThis.Bun;
175481
+ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA_TYPES, SEED_CANDIDATES, VALUE_FLAGS, paint = (text, color) => `${color}${text}${colors.reset}`, chunkRows = (items, size) => Array.from({ length: Math.ceil(items.length / size) }, (_, idx) => items.slice(idx * size, idx * size + size)), quoteIdent = (name) => `"${name.replace(/"/g, '""')}"`, resolveUrl = (explicit) => {
175482
+ const found = explicit ?? URL_ENV_KEYS.map((key) => env4[key]).find((value) => typeof value === "string" && value !== "");
175483
+ if (found === undefined || found === "")
175484
+ throw new Error(`No database URL found. Set ${URL_ENV_KEYS.join(" or ")}, or pass --url <url>.`);
175485
+ return found;
175486
+ }, keepTable = (name, options) => (options.only.length === 0 || options.only.includes(name)) && !options.exclude.includes(name), listTables = async (sql) => {
175487
+ const rows = await sql`select table_name from information_schema.tables where table_schema = ${"public"} and table_type = ${"BASE TABLE"} order by table_name`;
175488
+ return rows.map((row) => row.table_name);
175489
+ }, columnsFor = async (sql, name) => {
175490
+ const rows = await sql.unsafe(`select column_name, data_type from information_schema.columns where table_schema = $1 and table_name = $2 order by ordinal_position`, ["public", name]);
175491
+ return rows.map((row) => ({
175492
+ isJson: JSON_DATA_TYPES.includes(row.data_type),
175493
+ name: row.column_name
175494
+ }));
175495
+ }, primaryKeyFor = async (sql, name) => {
175496
+ const rows = await sql.unsafe(`select a.attname as col from pg_index i join pg_attribute a on a.attrelid = i.indrelid and a.attnum = any(i.indkey) where i.indrelid = $1::regclass and i.indisprimary order by a.attnum`, [`public.${quoteIdent(name)}`]);
175497
+ return rows.map((row) => row.col);
175498
+ }, tableMeta = async (sql, name) => {
175499
+ const [columns, primaryKey] = await Promise.all([
175500
+ columnsFor(sql, name),
175501
+ primaryKeyFor(sql, name)
175502
+ ]);
175503
+ return { columns, name, primaryKey };
175504
+ }, foreignLinks = async (sql) => {
175505
+ const rows = await sql.unsafe(`select tc.table_name as child, ccu.table_name as parent from information_schema.table_constraints tc join information_schema.constraint_column_usage ccu on ccu.constraint_name = tc.constraint_name and ccu.table_schema = tc.table_schema where tc.constraint_type = 'FOREIGN KEY' and tc.table_schema = $1`, ["public"]);
175506
+ return rows.map((row) => ({
175507
+ from: row.child,
175508
+ to: row.parent
175509
+ }));
175510
+ }, conflictClause = (meta) => {
175511
+ if (meta.primaryKey.length === 0)
175512
+ return "on conflict do nothing";
175513
+ const target = meta.primaryKey.map(quoteIdent).join(", ");
175514
+ const updatable = meta.columns.map((col) => col.name).filter((name) => !meta.primaryKey.includes(name));
175515
+ if (updatable.length === 0)
175516
+ return `on conflict (${target}) do nothing`;
175517
+ const sets = updatable.map((name) => `${quoteIdent(name)} = excluded.${quoteIdent(name)}`).join(", ");
175518
+ return `on conflict (${target}) do update set ${sets}`;
175519
+ }, dependencyOrder = (names, links) => {
175520
+ const present = new Set(names);
175521
+ const edges = links.filter((link) => present.has(link.from) && present.has(link.to) && link.from !== link.to);
175522
+ const indegree = new Map(names.map((name) => [name, 0]));
175523
+ edges.forEach((link) => indegree.set(link.from, (indegree.get(link.from) ?? 0) + 1));
175524
+ const ready = names.filter((name) => (indegree.get(name) ?? 0) === 0);
175525
+ const ordered = [];
175526
+ const release = (parent) => edges.filter((link) => link.to === parent).forEach((link) => {
175527
+ const next = (indegree.get(link.from) ?? 0) - 1;
175528
+ indegree.set(link.from, next);
175529
+ if (next === 0)
175530
+ ready.push(link.from);
175531
+ });
175532
+ const drain = () => {
175533
+ const head = ready.shift();
175534
+ if (head === undefined)
175535
+ return;
175536
+ ordered.push(head);
175537
+ release(head);
175538
+ drain();
175539
+ };
175540
+ drain();
175541
+ names.forEach((name) => {
175542
+ if (!ordered.includes(name))
175543
+ ordered.push(name);
175544
+ });
175545
+ return ordered;
175546
+ }, encodeValue = (col, value) => {
175547
+ if (value === null || value === undefined)
175548
+ return null;
175549
+ if (col.isJson)
175550
+ return JSON.stringify(value);
175551
+ return value;
175552
+ }, insertChunk = async (sql, meta, rows) => {
175553
+ const colNames = meta.columns.map((col) => col.name);
175554
+ const groups = rows.map((_, rowIdx) => {
175555
+ const base = rowIdx * colNames.length;
175556
+ const slots = [...colNames.keys()].map((colIdx) => `$${base + colIdx + 1}`);
175557
+ return `(${slots.join(", ")})`;
175558
+ });
175559
+ const params = rows.flatMap((row) => meta.columns.map((col) => encodeValue(col, row[col.name])));
175560
+ const columnList = colNames.map(quoteIdent).join(", ");
175561
+ const query = `insert into ${quoteIdent(meta.name)} (${columnList}) values ${groups.join(", ")} ${conflictClause(meta)}`;
175562
+ await sql.unsafe(query, params);
175563
+ }, restoreTable = async (sql, meta, rows) => {
175564
+ if (meta === undefined || rows.length === 0)
175565
+ return;
175566
+ await chunkRows(rows, RESTORE_CHUNK_ROWS).reduce(async (prev, part) => {
175567
+ await prev;
175568
+ return insertChunk(sql, meta, part);
175569
+ }, Promise.resolve());
175570
+ }, truncateAll = async (sql, names) => {
175571
+ if (names.length === 0)
175572
+ return;
175573
+ const list = names.map(quoteIdent).join(", ");
175574
+ await sql.unsafe(`truncate ${list} restart identity cascade`);
175575
+ }, runBackup = async (options) => {
175576
+ const sql = new SQL(options.url);
175577
+ const chosen = (await listTables(sql)).filter((name) => keepTable(name, options));
175578
+ const dumps = await Promise.all(chosen.map(async (name) => {
175579
+ const rows = await sql.unsafe(`select * from ${quoteIdent(name)}`);
175580
+ return [name, rows];
175581
+ }));
175582
+ await sql.end();
175583
+ const tables = Object.fromEntries(dumps);
175584
+ const payload = {
175585
+ at: new Date().toISOString(),
175586
+ tables,
175587
+ v: BACKUP_FORMAT_VERSION
175588
+ };
175589
+ const dir = options.out ?? join27(process.cwd(), "backups");
175590
+ mkdirSync13(dir, { recursive: true });
175591
+ const json = JSON.stringify(payload, (_, value) => typeof value === "bigint" ? value.toString() : value);
175592
+ const file = join27(dir, `backup-${payload.at.replace(/[:.]/g, "-")}.json`);
175593
+ writeFileSync16(file, json);
175594
+ writeFileSync16(join27(dir, "latest.json"), json);
175595
+ const total = chosen.reduce((sum, name) => sum + (tables[name]?.length ?? 0), 0);
175596
+ console.log(paint(`\u2713 backup \u2192 ${file}`, colors.green));
175597
+ console.log(paint(` ${chosen.length} tables, ${total} rows`, colors.dim));
175598
+ }, runRestore = async (file, options) => {
175599
+ if (!existsSync30(file))
175600
+ throw new Error(`Backup not found: ${file}`);
175601
+ const payload = JSON.parse(readFileSync29(file, "utf-8"));
175602
+ const names = Object.keys(payload.tables).filter((name) => keepTable(name, options));
175603
+ const sql = new SQL(options.url);
175604
+ const order = dependencyOrder(names, await foreignLinks(sql));
175605
+ const metas = await Promise.all(order.map((name) => tableMeta(sql, name)));
175606
+ const metaByName = new Map(metas.map((meta) => [meta.name, meta]));
175607
+ const aborted = options.truncate && !options.yes && prompt(paint(`\u26A0 TRUNCATE ${order.length} tables before restore? type "yes": `, colors.yellow)) !== "yes";
175608
+ if (aborted) {
175609
+ await sql.end();
175610
+ console.log(paint("aborted", colors.yellow));
175611
+ return;
175612
+ }
175613
+ if (options.truncate)
175614
+ await truncateAll(sql, [...order].reverse());
175615
+ await order.reduce(async (prev, name) => {
175616
+ await prev;
175617
+ return restoreTable(sql, metaByName.get(name), payload.tables[name] ?? []);
175618
+ }, Promise.resolve());
175619
+ await sql.end();
175620
+ const total = order.reduce((sum, name) => sum + (payload.tables[name]?.length ?? 0), 0);
175621
+ console.log(paint(`\u2713 restored ${order.length} tables, ${total} rows (idempotent upsert by primary key)`, colors.green));
175622
+ }, runSeed = async (entry) => {
175623
+ const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync30(join27(process.cwd(), candidate)));
175624
+ if (target === undefined)
175625
+ throw new Error(`No seed script found (looked for ${SEED_CANDIDATES.join(", ")}). Pass a path: absolute db seed <file>.`);
175626
+ console.log(paint(`seeding via ${target}\u2026`, colors.cyan));
175627
+ const proc = spawn2(["bun", "run", target], {
175628
+ stderr: "inherit",
175629
+ stdin: "inherit",
175630
+ stdout: "inherit"
175631
+ });
175632
+ const code = await proc.exited;
175633
+ if (code !== 0)
175634
+ throw new Error(`Seed failed (exit ${code}).`);
175635
+ }, flagValue = (rest, flag) => {
175636
+ const idx = rest.indexOf(flag);
175637
+ return idx === UNFOUND_INDEX ? undefined : rest[idx + 1];
175638
+ }, listValue = (rest, flag) => (flagValue(rest, flag) ?? "").split(",").map((part) => part.trim()).filter((part) => part !== ""), parseOptions = (rest) => ({
175639
+ exclude: listValue(rest, "--exclude"),
175640
+ only: listValue(rest, "--only"),
175641
+ out: flagValue(rest, "--out"),
175642
+ truncate: rest.includes("--truncate"),
175643
+ url: resolveUrl(flagValue(rest, "--url")),
175644
+ yes: rest.includes("--yes") || rest.includes("-y")
175645
+ }), positionalArgs = (rest) => rest.filter((arg, idx) => !arg.startsWith("-") && !VALUE_FLAGS.includes(rest[idx - 1] ?? "")), usage = () => {
175646
+ console.error("Usage: absolute db <backup|restore|seed> [options]");
175647
+ console.error(" backup [--out <dir>] [--only a,b] [--exclude a,b] [--url <url>] Dump tables \u2192 JSON (+ latest.json)");
175648
+ console.error(" restore [file] [--truncate] [--only a,b] [--exclude a,b] [-y] Idempotent upsert by primary key");
175649
+ console.error(" seed [file] Run the project\u2019s seed script");
175650
+ process.exit(1);
175651
+ }, runDb = async (args) => {
175652
+ const [sub, ...rest] = args;
175653
+ if (sub === "backup") {
175654
+ await runBackup(parseOptions(rest));
175655
+ return;
175656
+ }
175657
+ if (sub === "restore") {
175658
+ const file = positionalArgs(rest)[0] ?? join27(process.cwd(), "backups", "latest.json");
175659
+ await runRestore(file, parseOptions(rest));
175660
+ return;
175661
+ }
175662
+ if (sub === "seed") {
175663
+ await runSeed(positionalArgs(rest)[0]);
175664
+ return;
175665
+ }
175666
+ usage();
175667
+ };
175668
+ var init_db = __esm(() => {
175669
+ init_constants();
175670
+ init_tuiPrimitives();
175671
+ URL_ENV_KEYS = ["DATABASE_URL", "POSTGRES_URL", "DATABASE_URL_UNPOOLED"];
175672
+ JSON_DATA_TYPES = ["json", "jsonb"];
175673
+ SEED_CANDIDATES = ["db/seed.ts", "src/db/seed.ts", "seed.ts"];
175674
+ VALUE_FLAGS = ["--out", "--url", "--only", "--exclude"];
175675
+ });
175676
+
174540
175677
  // src/cli/scripts/logs.ts
174541
175678
  var exports_logs = {};
174542
175679
  __export(exports_logs, {
@@ -174544,10 +175681,10 @@ __export(exports_logs, {
174544
175681
  });
174545
175682
  import {
174546
175683
  closeSync as closeSync2,
174547
- existsSync as existsSync26,
175684
+ existsSync as existsSync31,
174548
175685
  openSync as openSync4,
174549
175686
  readSync as readSync2,
174550
- statSync as statSync3,
175687
+ statSync as statSync4,
174551
175688
  watchFile
174552
175689
  } from "fs";
174553
175690
  var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, start2, length) => {
@@ -174562,7 +175699,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
174562
175699
  closeSync2(descriptor);
174563
175700
  }
174564
175701
  }, tailLines = (path, maxLines) => {
174565
- const { size } = statSync3(path);
175702
+ const { size } = statSync4(path);
174566
175703
  const start2 = Math.max(0, size - LIST_LOG_TAIL_MAX_BYTES);
174567
175704
  const lines = readFrom(path, start2, size - start2).split(`
174568
175705
  `);
@@ -174579,7 +175716,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
174579
175716
  const cleaned = index === UNFOUND_INDEX ? args : [...args.slice(0, index), ...args.slice(index + LINES_FLAG_SPAN)];
174580
175717
  return cleaned.find((arg) => !arg.startsWith("-"));
174581
175718
  }, followFile = (path) => {
174582
- let offset = statSync3(path).size;
175719
+ let offset = statSync4(path).size;
174583
175720
  watchFile(path, { interval: POLL_MS }, (current) => {
174584
175721
  if (current.size > offset) {
174585
175722
  process.stdout.write(readFrom(path, offset, current.size - offset));
@@ -174611,7 +175748,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
174611
175748
  printAvailable(instances);
174612
175749
  return;
174613
175750
  }
174614
- if (match.logFile === null || !existsSync26(match.logFile)) {
175751
+ if (match.logFile === null || !existsSync31(match.logFile)) {
174615
175752
  printDim3(`"${name}" has no captured log (untracked, or started outside the CLI).`);
174616
175753
  return;
174617
175754
  }
@@ -174634,10 +175771,10 @@ var exports_doctor = {};
174634
175771
  __export(exports_doctor, {
174635
175772
  runDoctor: () => runDoctor
174636
175773
  });
174637
- import { existsSync as existsSync27, mkdirSync as mkdirSync12, readFileSync as readFileSync26, writeFileSync as writeFileSync14 } from "fs";
175774
+ import { existsSync as existsSync32, mkdirSync as mkdirSync14, readFileSync as readFileSync30, writeFileSync as writeFileSync17 } from "fs";
174638
175775
  import { createRequire } from "module";
174639
175776
  import { arch as arch4, platform as platform5 } from "os";
174640
- import { join as join25 } from "path";
175777
+ import { join as join28 } from "path";
174641
175778
  var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
174642
175779
  detail,
174643
175780
  label,
@@ -174672,7 +175809,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
174672
175809
  return [];
174673
175810
  const label = `${field.replace("Directory", "")} pages`;
174674
175811
  return [
174675
- existsSync27(join25(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
175812
+ existsSync32(join28(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
174676
175813
  ];
174677
175814
  }), envCheck = async () => {
174678
175815
  const vars = await collectEnvVars();
@@ -174705,7 +175842,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
174705
175842
  }, gatherChecks = async () => {
174706
175843
  const config = await loadConfigOrNull();
174707
175844
  const configCheck = config === null ? check("fail", "Config", "absolute.config.ts not found or invalid") : check("ok", "Config", "absolute.config.ts loaded");
174708
- const [env4, port] = await Promise.all([
175845
+ const [env5, port] = await Promise.all([
174709
175846
  envCheck(),
174710
175847
  config === null ? check("warn", "Dev port", "skipped (no config)") : portCheck(config)
174711
175848
  ]);
@@ -174715,16 +175852,16 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
174715
175852
  checkNative(),
174716
175853
  configCheck,
174717
175854
  ...config === null ? [] : frameworkChecks(config),
174718
- env4,
175855
+ env5,
174719
175856
  port
174720
175857
  ];
174721
175858
  }, fixFrameworkDirs = (cwd, config) => {
174722
175859
  const fixes = [];
174723
175860
  for (const field of FRAMEWORK_FIELDS2) {
174724
175861
  const dir = readString(config, field);
174725
- if (dir === undefined || existsSync27(join25(cwd, dir)))
175862
+ if (dir === undefined || existsSync32(join28(cwd, dir)))
174726
175863
  continue;
174727
- mkdirSync12(join25(cwd, dir, "pages"), { recursive: true });
175864
+ mkdirSync14(join28(cwd, dir, "pages"), { recursive: true });
174728
175865
  fixes.push(`created ${dir}/pages`);
174729
175866
  }
174730
175867
  return fixes;
@@ -174732,8 +175869,8 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
174732
175869
  const missing = (await collectEnvVars()).filter((entry) => !entry.set);
174733
175870
  if (missing.length === 0)
174734
175871
  return null;
174735
- const envExample = join25(cwd, ".env.example");
174736
- const existing = existsSync27(envExample) ? readFileSync26(envExample, "utf-8") : "";
175872
+ const envExample = join28(cwd, ".env.example");
175873
+ const existing = existsSync32(envExample) ? readFileSync30(envExample, "utf-8") : "";
174737
175874
  const existingKeys = new Set(existing.split(`
174738
175875
  `).map((line) => line.split("=")[0]?.trim()));
174739
175876
  const toAdd = missing.filter((entry) => !existingKeys.has(entry.key));
@@ -174742,7 +175879,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
174742
175879
  const prefix = existing === "" || existing.endsWith(`
174743
175880
  `) ? existing : `${existing}
174744
175881
  `;
174745
- writeFileSync14(envExample, `${prefix}${toAdd.map((entry) => `${entry.key}=`).join(`
175882
+ writeFileSync17(envExample, `${prefix}${toAdd.map((entry) => `${entry.key}=`).join(`
174746
175883
  `)}
174747
175884
  `);
174748
175885
  return `added ${toAdd.length} key(s) to .env.example`;
@@ -174788,7 +175925,7 @@ var init_doctor = __esm(() => {
174788
175925
  "htmlDirectory",
174789
175926
  "htmxDirectory"
174790
175927
  ];
174791
- projectRequire = createRequire(join25(process.cwd(), "package.json"));
175928
+ projectRequire = createRequire(join28(process.cwd(), "package.json"));
174792
175929
  STATUS_MARK = {
174793
175930
  fail: `${colors.red}\u2717${colors.reset}`,
174794
175931
  ok: `${colors.green}\u2713${colors.reset}`,
@@ -175092,10 +176229,10 @@ var init_inspect = __esm(() => {
175092
176229
  });
175093
176230
 
175094
176231
  // src/build/scanEntryPoints.ts
175095
- import { existsSync as existsSync28 } from "fs";
176232
+ import { existsSync as existsSync33 } from "fs";
175096
176233
  var {Glob: Glob4 } = globalThis.Bun;
175097
176234
  var scanEntryPoints = async (dir, pattern) => {
175098
- if (!existsSync28(dir))
176235
+ if (!existsSync33(dir))
175099
176236
  return [];
175100
176237
  const entryPaths = [];
175101
176238
  const glob = new Glob4(pattern);
@@ -175125,10 +176262,10 @@ var islandFrameworks, islandHydrationModes, isIslandFramework = (value) => islan
175125
176262
  framework,
175126
176263
  hydrate: hydrateCandidate && isIslandHydrate(hydrateCandidate) ? hydrateCandidate : undefined
175127
176264
  };
175128
- }, normalizeUsage = (usage) => `${usage.framework}:${usage.component}:${usage.hydrate ?? ""}`, addUsage = (usageMap, usage) => {
175129
- if (!usage)
176265
+ }, normalizeUsage = (usage2) => `${usage2.framework}:${usage2.component}:${usage2.hydrate ?? ""}`, addUsage = (usageMap, usage2) => {
176266
+ if (!usage2)
175130
176267
  return;
175131
- usageMap.set(normalizeUsage(usage), usage);
176268
+ usageMap.set(normalizeUsage(usage2), usage2);
175132
176269
  }, addRenderCallUsage = (usageMap, match) => {
175133
176270
  const [, framework, component, hydrate] = match;
175134
176271
  if (!framework || !component || !isIslandFramework(framework)) {
@@ -175177,8 +176314,8 @@ var init_sourceMetadata = __esm(() => {
175177
176314
  });
175178
176315
 
175179
176316
  // src/islands/pageMetadata.ts
175180
- import { readFileSync as readFileSync27 } from "fs";
175181
- import { dirname as dirname11, resolve as resolve14 } from "path";
176317
+ import { readFileSync as readFileSync31 } from "fs";
176318
+ import { dirname as dirname12, resolve as resolve18 } from "path";
175182
176319
  var pagePatterns, getPageDirs = (config) => [
175183
176320
  { dir: config.angularDirectory, framework: "angular" },
175184
176321
  { dir: config.emberDirectory, framework: "ember" },
@@ -175198,27 +176335,27 @@ var pagePatterns, getPageDirs = (config) => [
175198
176335
  const source = definition.buildReference?.source;
175199
176336
  if (!source)
175200
176337
  continue;
175201
- const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve14(dirname11(buildInfo.resolvedRegistryPath), source);
175202
- lookup.set(`${definition.framework}:${definition.component}`, resolve14(resolvedSource));
176338
+ const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve18(dirname12(buildInfo.resolvedRegistryPath), source);
176339
+ lookup.set(`${definition.framework}:${definition.component}`, resolve18(resolvedSource));
175203
176340
  }
175204
176341
  return lookup;
175205
- }, resolveIslandUsages = (islands, islandSourceLookup) => islands.map((usage) => {
175206
- const sourcePath = islandSourceLookup.get(`${usage.framework}:${usage.component}`);
176342
+ }, resolveIslandUsages = (islands, islandSourceLookup) => islands.map((usage2) => {
176343
+ const sourcePath = islandSourceLookup.get(`${usage2.framework}:${usage2.component}`);
175207
176344
  return sourcePath ? {
175208
- ...usage,
176345
+ ...usage2,
175209
176346
  source: sourcePath
175210
- } : usage;
176347
+ } : usage2;
175211
176348
  }), loadPageIslandFiles = async (entry, islandSourceLookup, pageMetadata) => {
175212
176349
  const pattern = pagePatterns[entry.framework];
175213
176350
  if (!pattern)
175214
176351
  return;
175215
- const files = await scanEntryPoints(resolve14(entry.dir), pattern);
176352
+ const files = await scanEntryPoints(resolve18(entry.dir), pattern);
175216
176353
  for (const filePath of files) {
175217
- const source = readFileSync27(filePath, "utf-8");
176354
+ const source = readFileSync31(filePath, "utf-8");
175218
176355
  const islands = extractIslandUsagesFromSource(source);
175219
- pageMetadata.set(resolve14(filePath), {
176356
+ pageMetadata.set(resolve18(filePath), {
175220
176357
  islands: resolveIslandUsages(islands, islandSourceLookup),
175221
- pagePath: resolve14(filePath)
176358
+ pagePath: resolve18(filePath)
175222
176359
  });
175223
176360
  }
175224
176361
  }, loadPageIslandMetadata = async (config) => {
@@ -175247,49 +176384,49 @@ var exports_islands = {};
175247
176384
  __export(exports_islands, {
175248
176385
  runIslands: () => runIslands
175249
176386
  });
175250
- import { existsSync as existsSync29, readFileSync as readFileSync28, statSync as statSync4 } from "fs";
175251
- import { join as join26, relative as relative8, resolve as resolve15 } from "path";
176387
+ import { existsSync as existsSync34, readFileSync as readFileSync32, statSync as statSync5 } from "fs";
176388
+ import { join as join29, relative as relative10, resolve as resolve19 } from "path";
175252
176389
  var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.write(`${colors.dim}${message}${colors.reset}
175253
176390
  `), hostFrameworkOf = (pagePath, cwd, config) => {
175254
- const resolved = resolve15(cwd, pagePath);
176391
+ const resolved = resolve19(cwd, pagePath);
175255
176392
  for (const [framework, key] of Object.entries(FRAMEWORK_DIR_KEY)) {
175256
176393
  const dir = config[key];
175257
- if (typeof dir === "string" && resolved.startsWith(resolve15(cwd, dir))) {
176394
+ if (typeof dir === "string" && resolved.startsWith(resolve19(cwd, dir))) {
175258
176395
  return framework;
175259
176396
  }
175260
176397
  }
175261
176398
  return null;
175262
176399
  }, fileSize3 = (path) => {
175263
176400
  try {
175264
- return statSync4(path).size;
176401
+ return statSync5(path).size;
175265
176402
  } catch {
175266
176403
  return 0;
175267
176404
  }
175268
176405
  }, readManifestSizes2 = (manifestDir) => {
175269
- const manifestPath = join26(manifestDir, "manifest.json");
175270
- if (!existsSync29(manifestPath))
176406
+ const manifestPath = join29(manifestDir, "manifest.json");
176407
+ if (!existsSync34(manifestPath))
175271
176408
  return null;
175272
- const manifest = JSON.parse(readFileSync28(manifestPath, "utf-8"));
176409
+ const manifest = JSON.parse(readFileSync32(manifestPath, "utf-8"));
175273
176410
  const sizes = new Map;
175274
176411
  for (const [key, value] of Object.entries(manifest)) {
175275
- sizes.set(key, fileSize3(join26(manifestDir, value.replace(/^\//, ""))));
176412
+ sizes.set(key, fileSize3(join29(manifestDir, value.replace(/^\//, ""))));
175276
176413
  }
175277
176414
  return sizes;
175278
176415
  }, collectIslands = async (cwd, config, sizes) => {
175279
176416
  const registryPath = config.islands?.registry;
175280
176417
  if (typeof registryPath !== "string")
175281
176418
  return null;
175282
- const buildInfo = await loadIslandRegistryBuildInfo(resolve15(cwd, registryPath));
176419
+ const buildInfo = await loadIslandRegistryBuildInfo(resolve19(cwd, registryPath));
175283
176420
  const pageMetadata = await loadPageIslandMetadata(config);
175284
176421
  const usages = [...pageMetadata.values()].flatMap((meta) => meta.islands.map((island) => ({ ...island, page: meta.pagePath })));
175285
176422
  return buildInfo.definitions.map((definition) => {
175286
- const mounts = usages.filter((usage) => usage.framework === definition.framework && usage.component === definition.component).map((usage) => {
175287
- const hostFramework = hostFrameworkOf(usage.page, cwd, config);
176423
+ const mounts = usages.filter((usage2) => usage2.framework === definition.framework && usage2.component === definition.component).map((usage2) => {
176424
+ const hostFramework = hostFrameworkOf(usage2.page, cwd, config);
175288
176425
  return {
175289
176426
  crossFramework: hostFramework !== null && hostFramework !== definition.framework,
175290
176427
  hostFramework,
175291
- hydrate: usage.hydrate ?? "load",
175292
- page: relative8(cwd, resolve15(cwd, usage.page))
176428
+ hydrate: usage2.hydrate ?? "load",
176429
+ page: relative10(cwd, resolve19(cwd, usage2.page))
175293
176430
  };
175294
176431
  });
175295
176432
  const key = getIslandManifestKey(definition.framework, definition.component);
@@ -175328,7 +176465,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
175328
176465
  ` ${color}\u2B21${colors.reset} ${colors.bold}${island.component}${colors.reset} ${meta}${sizeText}`
175329
176466
  ];
175330
176467
  if (island.source) {
175331
- lines.push(` ${colors.dim}${relative8(cwd, island.source)}${colors.reset}`);
176468
+ lines.push(` ${colors.dim}${relative10(cwd, island.source)}${colors.reset}`);
175332
176469
  }
175333
176470
  if (pages.length === 0) {
175334
176471
  lines.push(` ${colors.dim}(registered but not mounted on any page)${colors.reset}`);
@@ -175358,7 +176495,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
175358
176495
  }
175359
176496
  const outdirIndex = args.indexOf("--outdir");
175360
176497
  const outdir = outdirIndex >= 0 ? args[outdirIndex + 1] : config.buildDirectory;
175361
- const sizes = args.includes("--sizes") ? readManifestSizes2(resolve15(cwd, outdir ?? "build")) : null;
176498
+ const sizes = args.includes("--sizes") ? readManifestSizes2(resolve19(cwd, outdir ?? "build")) : null;
175362
176499
  const islands = await collectIslands(cwd, config, sizes);
175363
176500
  if (islands === null) {
175364
176501
  printDim6('No island registry configured. Set `islands: { registry: "..." }` in absolute.config.ts.');
@@ -175407,13 +176544,13 @@ var init_islands2 = __esm(() => {
175407
176544
  });
175408
176545
 
175409
176546
  // src/build/externalAssetPlugin.ts
175410
- import { copyFileSync as copyFileSync2, existsSync as existsSync30, mkdirSync as mkdirSync13, statSync as statSync5 } from "fs";
175411
- import { basename as basename6, dirname as dirname12, join as join27, resolve as resolve16 } from "path";
176547
+ import { copyFileSync as copyFileSync2, existsSync as existsSync35, mkdirSync as mkdirSync15, statSync as statSync6 } from "fs";
176548
+ import { basename as basename6, dirname as dirname13, join as join30, resolve as resolve20 } from "path";
175412
176549
  var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
175413
176550
  name: "absolute-external-asset",
175414
176551
  setup(bld) {
175415
176552
  const urlPattern = /new\s+URL\(\s*["'](\.\.?\/[^"']+)["']\s*,\s*import\.meta\.url\s*\)/g;
175416
- const skipRoots = userSourceRoots.map((root) => resolve16(root));
176553
+ const skipRoots = userSourceRoots.map((root) => resolve20(root));
175417
176554
  const isUserSource = (path) => skipRoots.some((root) => path.startsWith(`${root}/`));
175418
176555
  bld.onLoad({ filter: /\.[mc]?[jt]sx?$/ }, async (args) => {
175419
176556
  if (isUserSource(args.path))
@@ -175423,20 +176560,20 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
175423
176560
  return;
175424
176561
  urlPattern.lastIndex = 0;
175425
176562
  let match;
175426
- const sourceDir = dirname12(args.path);
176563
+ const sourceDir = dirname13(args.path);
175427
176564
  while ((match = urlPattern.exec(source)) !== null) {
175428
176565
  const relPath = match[1];
175429
176566
  if (!relPath)
175430
176567
  continue;
175431
- const assetPath = resolve16(sourceDir, relPath);
175432
- if (!existsSync30(assetPath))
176568
+ const assetPath = resolve20(sourceDir, relPath);
176569
+ if (!existsSync35(assetPath))
175433
176570
  continue;
175434
- if (!statSync5(assetPath).isFile())
176571
+ if (!statSync6(assetPath).isFile())
175435
176572
  continue;
175436
- const targetPath = join27(outDir, basename6(assetPath));
175437
- if (existsSync30(targetPath))
176573
+ const targetPath = join30(outDir, basename6(assetPath));
176574
+ if (existsSync35(targetPath))
175438
176575
  continue;
175439
- mkdirSync13(dirname12(targetPath), { recursive: true });
176576
+ mkdirSync15(dirname13(targetPath), { recursive: true });
175440
176577
  copyFileSync2(assetPath, targetPath);
175441
176578
  }
175442
176579
  return;
@@ -175451,19 +176588,19 @@ __export(exports_compile, {
175451
176588
  shouldEmbedCompiledAsset: () => shouldEmbedCompiledAsset,
175452
176589
  compile: () => compile
175453
176590
  });
175454
- var {env: env4 } = globalThis.Bun;
176591
+ var {env: env5 } = globalThis.Bun;
175455
176592
  import {
175456
176593
  cpSync,
175457
- existsSync as existsSync31,
175458
- mkdirSync as mkdirSync14,
175459
- readdirSync as readdirSync6,
175460
- readFileSync as readFileSync29,
176594
+ existsSync as existsSync36,
176595
+ mkdirSync as mkdirSync16,
176596
+ readdirSync as readdirSync7,
176597
+ readFileSync as readFileSync33,
175461
176598
  rmSync as rmSync5,
175462
- statSync as statSync6,
176599
+ statSync as statSync7,
175463
176600
  unlinkSync as unlinkSync4,
175464
- writeFileSync as writeFileSync15
176601
+ writeFileSync as writeFileSync18
175465
176602
  } from "fs";
175466
- import { basename as basename7, dirname as dirname13, join as join28, relative as relative9, resolve as resolve17 } from "path";
176603
+ import { basename as basename7, dirname as dirname14, join as join31, relative as relative11, resolve as resolve21 } from "path";
175467
176604
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
175468
176605
  const resolvedVersion = version2 || "unknown";
175469
176606
  console.log("");
@@ -175471,14 +176608,14 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175471
176608
  console.log("");
175472
176609
  }, collectFiles2 = (dir) => {
175473
176610
  const result = [];
175474
- let pending = readdirSync6(dir, { withFileTypes: true });
176611
+ let pending = readdirSync7(dir, { withFileTypes: true });
175475
176612
  while (pending.length > 0) {
175476
176613
  const entry = pending.pop();
175477
176614
  if (!entry)
175478
176615
  continue;
175479
- const fullPath = join28(entry.parentPath, entry.name);
176616
+ const fullPath = join31(entry.parentPath, entry.name);
175480
176617
  if (entry.isDirectory())
175481
- pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
176618
+ pending = pending.concat(readdirSync7(fullPath, { withFileTypes: true }));
175482
176619
  else
175483
176620
  result.push(fullPath);
175484
176621
  }
@@ -175491,16 +176628,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175491
176628
  return `./${parts.join("/")}`;
175492
176629
  }, collectProjectSourceFiles = (dir) => {
175493
176630
  const result = [];
175494
- let pending = readdirSync6(dir, { withFileTypes: true });
176631
+ let pending = readdirSync7(dir, { withFileTypes: true });
175495
176632
  while (pending.length > 0) {
175496
176633
  const entry = pending.pop();
175497
176634
  if (!entry)
175498
176635
  continue;
175499
- const fullPath = join28(entry.parentPath, entry.name);
176636
+ const fullPath = join31(entry.parentPath, entry.name);
175500
176637
  if (entry.isDirectory()) {
175501
176638
  if (SERVER_RUNTIME_SCAN_SKIP_DIRS.has(entry.name))
175502
176639
  continue;
175503
- pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
176640
+ pending = pending.concat(readdirSync7(fullPath, { withFileTypes: true }));
175504
176641
  } else if (hasSourceExtension(fullPath)) {
175505
176642
  result.push(fullPath);
175506
176643
  }
@@ -175508,22 +176645,22 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175508
176645
  return result;
175509
176646
  }, copyServerRuntimeAssetReferences = (outdir) => {
175510
176647
  const copied = new Set;
175511
- const normalizedOutdir = resolve17(outdir);
176648
+ const normalizedOutdir = resolve21(outdir);
175512
176649
  const copyReference = (filePath, relPath) => {
175513
- const assetSource = resolve17(dirname13(filePath), relPath);
175514
- if (!existsSync31(assetSource) || !statSync6(assetSource).isFile())
176650
+ const assetSource = resolve21(dirname14(filePath), relPath);
176651
+ if (!existsSync36(assetSource) || !statSync7(assetSource).isFile())
175515
176652
  return;
175516
- const assetTarget = resolve17(normalizedOutdir, relPath.replace(/^\.\//, ""));
176653
+ const assetTarget = resolve21(normalizedOutdir, relPath.replace(/^\.\//, ""));
175517
176654
  if (assetTarget !== normalizedOutdir && !assetTarget.startsWith(`${normalizedOutdir}/`))
175518
176655
  return;
175519
176656
  if (copied.has(assetTarget))
175520
176657
  return;
175521
176658
  copied.add(assetTarget);
175522
- mkdirSync14(dirname13(assetTarget), { recursive: true });
176659
+ mkdirSync16(dirname14(assetTarget), { recursive: true });
175523
176660
  cpSync(assetSource, assetTarget, { force: true });
175524
176661
  };
175525
176662
  for (const filePath of collectProjectSourceFiles(process.cwd())) {
175526
- const source = readFileSync29(filePath, "utf-8");
176663
+ const source = readFileSync33(filePath, "utf-8");
175527
176664
  SERVER_RUNTIME_ASSET_RE.lastIndex = 0;
175528
176665
  let match;
175529
176666
  while ((match = SERVER_RUNTIME_ASSET_RE.exec(source)) !== null) {
@@ -175552,7 +176689,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175552
176689
  }
175553
176690
  }, readPackageVersion4 = (candidate) => {
175554
176691
  try {
175555
- const pkg = JSON.parse(readFileSync29(candidate, "utf-8"));
176692
+ const pkg = JSON.parse(readFileSync33(candidate, "utf-8"));
175556
176693
  if (pkg.name !== "@absolutejs/absolute")
175557
176694
  return null;
175558
176695
  const ver = pkg.version;
@@ -175587,18 +176724,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175587
176724
  return resolveBuildModule3(remaining);
175588
176725
  }, resolveJsxDevRuntimeCompatPath2 = () => {
175589
176726
  const candidates = [
175590
- resolve17(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
175591
- resolve17(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
175592
- resolve17(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
175593
- resolve17(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
175594
- resolve17(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
175595
- resolve17(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
176727
+ resolve21(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
176728
+ resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
176729
+ resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
176730
+ resolve21(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
176731
+ resolve21(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
176732
+ resolve21(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
175596
176733
  ];
175597
176734
  for (const candidate of candidates) {
175598
- if (existsSync31(candidate))
176735
+ if (existsSync36(candidate))
175599
176736
  return candidate;
175600
176737
  }
175601
- return resolve17(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
176738
+ return resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
175602
176739
  }, jsxDevRuntimeCompatPath2, shouldEmbedCompiledAsset = (relativePath, skip = new Set) => {
175603
176740
  if (skip.has(relativePath))
175604
176741
  return false;
@@ -175611,11 +176748,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175611
176748
  return true;
175612
176749
  }, tryReadNodePackageJson = (packageDir) => {
175613
176750
  try {
175614
- return JSON.parse(readFileSync29(join28(packageDir, "package.json"), "utf-8"));
176751
+ return JSON.parse(readFileSync33(join31(packageDir, "package.json"), "utf-8"));
175615
176752
  } catch {
175616
176753
  return null;
175617
176754
  }
175618
- }, resolveProjectPackageDir = (specifier) => resolve17(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
176755
+ }, resolveProjectPackageDir = (specifier) => resolve21(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
175619
176756
  if (seen.has(specifier))
175620
176757
  return;
175621
176758
  const srcDir = resolveProjectPackageDir(specifier);
@@ -175623,13 +176760,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175623
176760
  if (!pkg)
175624
176761
  return;
175625
176762
  seen.add(specifier);
175626
- const destDir = join28(outdir, "node_modules", ...specifier.split("/"));
176763
+ const destDir = join31(outdir, "node_modules", ...specifier.split("/"));
175627
176764
  rmSync5(destDir, { force: true, recursive: true });
175628
176765
  cpSync(srcDir, destDir, {
175629
176766
  force: true,
175630
176767
  recursive: true,
175631
176768
  filter(source) {
175632
- const rel = relative9(srcDir, source);
176769
+ const rel = relative11(srcDir, source);
175633
176770
  const [firstSegment] = rel.split(/[\\/]/);
175634
176771
  return firstSegment !== "node_modules" && firstSegment !== ".git";
175635
176772
  }
@@ -175645,8 +176782,8 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175645
176782
  }, copyAngularRuntimePackages = (buildConfig, outdir) => {
175646
176783
  if (!buildConfig.angularDirectory)
175647
176784
  return;
175648
- const angularScopeDir = resolve17(process.cwd(), "node_modules", "@angular");
175649
- const angularPackages = existsSync31(angularScopeDir) ? readdirSync6(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
176785
+ const angularScopeDir = resolve21(process.cwd(), "node_modules", "@angular");
176786
+ const angularPackages = existsSync36(angularScopeDir) ? readdirSync7(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
175650
176787
  const roots = new Set([...angularPackages, "rxjs", "tslib", "typescript"]);
175651
176788
  const seen = new Set;
175652
176789
  for (const specifier of roots) {
@@ -175664,16 +176801,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175664
176801
  copyAngularRuntimePackages(buildConfig, outdir);
175665
176802
  copyChunkReferencedPackages(outdir, seen);
175666
176803
  }, collectRuntimePackageSpecifiers = (distDir) => {
175667
- const nodeModulesDir = join28(distDir, "node_modules");
175668
- if (!existsSync31(nodeModulesDir))
176804
+ const nodeModulesDir = join31(distDir, "node_modules");
176805
+ if (!existsSync36(nodeModulesDir))
175669
176806
  return [];
175670
176807
  const specifiers = [];
175671
- for (const entry of readdirSync6(nodeModulesDir, { withFileTypes: true })) {
176808
+ for (const entry of readdirSync7(nodeModulesDir, { withFileTypes: true })) {
175672
176809
  if (!entry.isDirectory())
175673
176810
  continue;
175674
176811
  if (entry.name.startsWith("@")) {
175675
- const scopeDir = join28(nodeModulesDir, entry.name);
175676
- for (const scopedEntry of readdirSync6(scopeDir, {
176812
+ const scopeDir = join31(nodeModulesDir, entry.name);
176813
+ for (const scopedEntry of readdirSync7(scopeDir, {
175677
176814
  withFileTypes: true
175678
176815
  })) {
175679
176816
  if (scopedEntry.isDirectory()) {
@@ -175686,7 +176823,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175686
176823
  }
175687
176824
  return specifiers.sort((a, b) => b.length - a.length);
175688
176825
  }, ensureRelativeModuleSpecifier = (fromFile, toFile) => {
175689
- const rel = relative9(dirname13(fromFile), toFile).replace(/\\/g, "/");
176826
+ const rel = relative11(dirname14(fromFile), toFile).replace(/\\/g, "/");
175690
176827
  return rel.startsWith(".") ? rel : `./${rel}`;
175691
176828
  }, pickExportEntry = (value) => {
175692
176829
  if (typeof value === "string")
@@ -175704,21 +176841,21 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175704
176841
  const packageSpecifier = packageSpecifiers.find((root) => specifier === root || specifier.startsWith(`${root}/`));
175705
176842
  if (!packageSpecifier)
175706
176843
  return null;
175707
- const packageDir = join28(distDir, "node_modules", ...packageSpecifier.split("/"));
176844
+ const packageDir = join31(distDir, "node_modules", ...packageSpecifier.split("/"));
175708
176845
  const subpath = specifier.slice(packageSpecifier.length);
175709
- const subPackageDir = subpath ? join28(packageDir, ...subpath.slice(1).split("/")) : null;
175710
- const resolvedPackageDir = subPackageDir && existsSync31(join28(subPackageDir, "package.json")) ? subPackageDir : packageDir;
175711
- const packageJsonPath = join28(resolvedPackageDir, "package.json");
175712
- if (!existsSync31(packageJsonPath))
176846
+ const subPackageDir = subpath ? join31(packageDir, ...subpath.slice(1).split("/")) : null;
176847
+ const resolvedPackageDir = subPackageDir && existsSync36(join31(subPackageDir, "package.json")) ? subPackageDir : packageDir;
176848
+ const packageJsonPath = join31(resolvedPackageDir, "package.json");
176849
+ if (!existsSync36(packageJsonPath))
175713
176850
  return null;
175714
- const pkg = JSON.parse(readFileSync29(packageJsonPath, "utf-8"));
176851
+ const pkg = JSON.parse(readFileSync33(packageJsonPath, "utf-8"));
175715
176852
  const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
175716
176853
  const rootExport = pkg.exports?.[exportKey];
175717
176854
  const entry = pickExportEntry(rootExport) ?? (resolvedPackageDir === subPackageDir || !subpath ? pkg.module ?? pkg.main ?? "index.js" : `.${subpath}`);
175718
- return join28(resolvedPackageDir, entry);
176855
+ return join31(resolvedPackageDir, entry);
175719
176856
  }, RUNTIME_JS_EXTENSIONS, MODULE_SPECIFIER_RE, isRuntimeJsFile = (filePath) => RUNTIME_JS_EXTENSIONS.some((extension) => filePath.endsWith(extension)), isNodeModulesPath = (filePath) => filePath.split(/[\\/]/).includes("node_modules"), isFile = (filePath) => {
175720
176857
  try {
175721
- return statSync6(filePath).isFile();
176858
+ return statSync7(filePath).isFile();
175722
176859
  } catch {
175723
176860
  return false;
175724
176861
  }
@@ -175728,16 +176865,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175728
176865
  const candidates = [
175729
176866
  candidate,
175730
176867
  ...RUNTIME_JS_EXTENSIONS.map((extension) => `${candidate}${extension}`),
175731
- ...RUNTIME_JS_EXTENSIONS.map((extension) => join28(candidate, `index${extension}`))
176868
+ ...RUNTIME_JS_EXTENSIONS.map((extension) => join31(candidate, `index${extension}`))
175732
176869
  ];
175733
176870
  return candidates.find((filePath) => isRuntimeJsFile(filePath) && isFile(filePath)) ?? null;
175734
176871
  }, findContainingRuntimePackageDir = (filePath) => {
175735
- let dir = dirname13(filePath);
175736
- while (dir !== dirname13(dir)) {
175737
- if (isNodeModulesPath(dir) && existsSync31(join28(dir, "package.json"))) {
176872
+ let dir = dirname14(filePath);
176873
+ while (dir !== dirname14(dir)) {
176874
+ if (isNodeModulesPath(dir) && existsSync36(join31(dir, "package.json"))) {
175738
176875
  return dir;
175739
176876
  }
175740
- dir = dirname13(dir);
176877
+ dir = dirname14(dir);
175741
176878
  }
175742
176879
  return null;
175743
176880
  }, resolvePackageImportEntryFile = (fromFile, specifier) => {
@@ -175750,13 +176887,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175750
176887
  const entry = pickExportEntry(pkg?.imports?.[specifier]);
175751
176888
  if (!entry)
175752
176889
  return null;
175753
- return join28(packageDir, entry);
176890
+ return join31(packageDir, entry);
175754
176891
  }, collectRuntimeRewriteRoots = (distDir) => collectFiles2(distDir).filter((filePath) => isRuntimeJsFile(filePath) && !isNodeModulesPath(filePath)), toTopLevelPackage = (specifier) => specifier.split("/").slice(0, specifier.startsWith("@") ? 2 : 1).join("/"), FRAMEWORK_PACKAGE_NAME = "@absolutejs/absolute", copyChunkReferencedPackages = (distDir, seen) => {
175755
- const distRoot = resolve17(distDir);
176892
+ const distRoot = resolve21(distDir);
175756
176893
  for (const filePath of collectRuntimeRewriteRoots(distDir)) {
175757
- if (resolve17(dirname13(filePath)) === distRoot)
176894
+ if (resolve21(dirname14(filePath)) === distRoot)
175758
176895
  continue;
175759
- const source = readFileSync29(filePath, "utf-8");
176896
+ const source = readFileSync33(filePath, "utf-8");
175760
176897
  for (const match of source.matchAll(MODULE_SPECIFIER_RE)) {
175761
176898
  const specifier = match[3];
175762
176899
  if (!specifier || specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("#") || specifier.startsWith("node:") || specifier.startsWith("bun:")) {
@@ -175786,10 +176923,10 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175786
176923
  if (!filePath || seen.has(filePath))
175787
176924
  continue;
175788
176925
  seen.add(filePath);
175789
- const source = readFileSync29(filePath, "utf-8");
176926
+ const source = readFileSync33(filePath, "utf-8");
175790
176927
  const rewritten = source.replace(MODULE_SPECIFIER_RE, (match, prefix, quote, specifier) => {
175791
176928
  if (typeof specifier === "string" && specifier.startsWith(".")) {
175792
- enqueue(resolveRuntimeJsFile(resolve17(dirname13(filePath), specifier)));
176929
+ enqueue(resolveRuntimeJsFile(resolve21(dirname14(filePath), specifier)));
175793
176930
  return match;
175794
176931
  }
175795
176932
  const packageImportTarget = resolveRuntimeJsFile(resolvePackageImportEntryFile(filePath, specifier) ?? "");
@@ -175804,7 +176941,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175804
176941
  return `${prefix}${quote}${ensureRelativeModuleSpecifier(filePath, target)}${quote}`;
175805
176942
  });
175806
176943
  if (rewritten !== source) {
175807
- writeFileSync15(filePath, rewritten);
176944
+ writeFileSync18(filePath, rewritten);
175808
176945
  }
175809
176946
  }
175810
176947
  }, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2, buildConfig) => {
@@ -175817,25 +176954,25 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175817
176954
  "_compile_entrypoint.ts"
175818
176955
  ]);
175819
176956
  const embeddedFiles = allFiles.filter((file) => {
175820
- const rel = relative9(distDir, file);
176957
+ const rel = relative11(distDir, file);
175821
176958
  if (embeddedSkip.has(rel))
175822
176959
  return false;
175823
176960
  return true;
175824
176961
  });
175825
- const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative9(distDir, file), assetSkip));
176962
+ const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative11(distDir, file), assetSkip));
175826
176963
  const imports = [];
175827
176964
  const embeddedMappings = [];
175828
176965
  const mappings = [];
175829
176966
  const embeddedVarMap = new Map;
175830
176967
  embeddedFiles.forEach((filePath, idx) => {
175831
- const rel = relative9(distDir, filePath).replace(/\\/g, "/");
176968
+ const rel = relative11(distDir, filePath).replace(/\\/g, "/");
175832
176969
  const varName = `__a${idx}`;
175833
176970
  embeddedVarMap.set(rel, varName);
175834
176971
  imports.push(`import ${varName} from "./${rel}" with { type: "file" };`);
175835
176972
  embeddedMappings.push(` ["${rel}", ${varName}],`);
175836
176973
  });
175837
176974
  clientFiles.forEach((filePath) => {
175838
- const rel = relative9(distDir, filePath).replace(/\\/g, "/");
176975
+ const rel = relative11(distDir, filePath).replace(/\\/g, "/");
175839
176976
  const varName = embeddedVarMap.get(rel);
175840
176977
  if (!varName)
175841
176978
  return;
@@ -175849,7 +176986,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175849
176986
  const pageVarMap = new Map;
175850
176987
  const prerenderEntries = Array.from(prerenderMap.entries());
175851
176988
  prerenderEntries.forEach(([route, filePath]) => {
175852
- const rel = relative9(distDir, filePath).replace(/\\/g, "/");
176989
+ const rel = relative11(distDir, filePath).replace(/\\/g, "/");
175853
176990
  const varName = embeddedVarMap.get(rel);
175854
176991
  if (varName)
175855
176992
  pageVarMap.set(route, varName);
@@ -175878,7 +177015,7 @@ import { websocket as elysiaWebsocket } from "elysia/ws";
175878
177015
  const SERVER_MODULE = (runtimeDir: string) => import(pathToFileURL(join(runtimeDir, ${JSON.stringify(serverBundleName)})).href);
175879
177016
  const RUNTIME_BUILD_ID = ${JSON.stringify(runtimeBuildId)};
175880
177017
  const RUNTIME_CONFIG_SOURCE = ${JSON.stringify(runtimeConfigSource)};
175881
- const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve17(distDir))};
177018
+ const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve21(distDir))};
175882
177019
  const ORIGINAL_BUILD_DIR_NORMALIZED = ORIGINAL_BUILD_DIR.replace(/\\\\/g, "/");
175883
177020
 
175884
177021
  // \u2500\u2500 Asset URL \u2192 embedded path map \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
@@ -176255,16 +177392,16 @@ console.log(\`
176255
177392
  }),
176256
177393
  ...collectUserServerExternals(buildConfig)
176257
177394
  ], compile = async (serverEntry, outdir, outfile, configPath2) => {
176258
- const resolvedOutdir = resolve17(outdir ?? "dist");
177395
+ const resolvedOutdir = resolve21(outdir ?? "dist");
176259
177396
  await withBuildDirectoryLock(resolvedOutdir, () => compileUnlocked(serverEntry, resolvedOutdir, outfile, configPath2));
176260
177397
  }, compileUnlocked = async (serverEntry, resolvedOutdir, outfile, configPath2) => {
176261
- const prerenderPort = Number(env4.COMPILE_PORT) || Number(env4.PORT) || DEFAULT_PORT + 1;
177398
+ const prerenderPort = Number(env5.COMPILE_PORT) || Number(env5.PORT) || DEFAULT_PORT + 1;
176262
177399
  killStaleProcesses(prerenderPort);
176263
177400
  const entryName = basename7(serverEntry).replace(/\.[^.]+$/, "");
176264
- const resolvedOutfile = resolve17(outfile ?? "compiled-server");
177401
+ const resolvedOutfile = resolve21(outfile ?? "compiled-server");
176265
177402
  const absoluteVersion = resolvePackageVersion3([
176266
- resolve17(import.meta.dir, "..", "..", "..", "package.json"),
176267
- resolve17(import.meta.dir, "..", "..", "package.json")
177403
+ resolve21(import.meta.dir, "..", "..", "..", "package.json"),
177404
+ resolve21(import.meta.dir, "..", "..", "package.json")
176268
177405
  ]);
176269
177406
  compileBanner(absoluteVersion);
176270
177407
  const totalStart = performance.now();
@@ -176275,8 +177412,8 @@ console.log(\`
176275
177412
  buildConfig.mode = "production";
176276
177413
  try {
176277
177414
  const build2 = await resolveBuildModule3([
176278
- resolve17(import.meta.dir, "..", "..", "core", "build"),
176279
- resolve17(import.meta.dir, "..", "build")
177415
+ resolve21(import.meta.dir, "..", "..", "core", "build"),
177416
+ resolve21(import.meta.dir, "..", "build")
176280
177417
  ]);
176281
177418
  if (!build2)
176282
177419
  throw new Error("Could not locate build module");
@@ -176298,10 +177435,10 @@ console.log(\`
176298
177435
  buildConfig.htmxDirectory
176299
177436
  ].filter((dir) => Boolean(dir));
176300
177437
  const islandRegistrySpec = buildConfig.islands?.registry;
176301
- const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve17(islandRegistrySpec))) : undefined;
177438
+ const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve21(islandRegistrySpec))) : undefined;
176302
177439
  const serverBundle = await Bun.build({
176303
177440
  define: { "process.env.NODE_ENV": '"production"' },
176304
- entrypoints: [resolve17(serverEntry)],
177441
+ entrypoints: [resolve21(serverEntry)],
176305
177442
  external: resolveServerBundleExternals(buildConfig),
176306
177443
  outdir: resolvedOutdir,
176307
177444
  plugins: [
@@ -176322,14 +177459,14 @@ console.log(\`
176322
177459
  console.error(cliTag4("\x1B[31m", "Server bundle failed."));
176323
177460
  process.exit(1);
176324
177461
  }
176325
- const outputPath = resolve17(resolvedOutdir, `${entryName}.js`);
176326
- if (!existsSync31(outputPath)) {
177462
+ const outputPath = resolve21(resolvedOutdir, `${entryName}.js`);
177463
+ if (!existsSync36(outputPath)) {
176327
177464
  console.error(cliTag4("\x1B[31m", `Expected output not found: ${outputPath}`));
176328
177465
  process.exit(1);
176329
177466
  }
176330
- if (existsSync31(resolve17(resolvedOutdir, "angular", "vendor", "server"))) {
176331
- const vendorDir = resolve17(resolvedOutdir, "angular", "vendor", "server");
176332
- const vendorEntries = readdirSync6(vendorDir).filter((f) => f.endsWith(".js"));
177467
+ if (existsSync36(resolve21(resolvedOutdir, "angular", "vendor", "server"))) {
177468
+ const vendorDir = resolve21(resolvedOutdir, "angular", "vendor", "server");
177469
+ const vendorEntries = readdirSync7(vendorDir).filter((f) => f.endsWith(".js"));
176333
177470
  const angularServerVendorPaths = {};
176334
177471
  for (const file of vendorEntries) {
176335
177472
  const stem = file.replace(/\.js$/, "");
@@ -176337,7 +177474,7 @@ console.log(\`
176337
177474
  if (scope !== "angular" || rest.length === 0)
176338
177475
  continue;
176339
177476
  const specifier = `@angular/${rest.join("/")}`;
176340
- const relPath = relative9(dirname13(outputPath), resolve17(vendorDir, file));
177477
+ const relPath = relative11(dirname14(outputPath), resolve21(vendorDir, file));
176341
177478
  angularServerVendorPaths[specifier] = relPath.startsWith(".") ? relPath : `./${relPath}`;
176342
177479
  }
176343
177480
  if (Object.keys(angularServerVendorPaths).length > 0) {
@@ -176349,7 +177486,7 @@ console.log(\`
176349
177486
  copyServerRuntimeAssetReferences(resolvedOutdir);
176350
177487
  const prerenderStart = performance.now();
176351
177488
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
176352
- rmSync5(join28(resolvedOutdir, "_prerendered"), {
177489
+ rmSync5(join31(resolvedOutdir, "_prerendered"), {
176353
177490
  force: true,
176354
177491
  recursive: true
176355
177492
  });
@@ -176368,9 +177505,9 @@ console.log(\`
176368
177505
  const compileStart = performance.now();
176369
177506
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
176370
177507
  const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
176371
- const entrypointPath = join28(resolvedOutdir, "_compile_entrypoint.ts");
177508
+ const entrypointPath = join31(resolvedOutdir, "_compile_entrypoint.ts");
176372
177509
  await Bun.write(entrypointPath, entrypointCode);
176373
- mkdirSync14(dirname13(resolvedOutfile), { recursive: true });
177510
+ mkdirSync16(dirname14(resolvedOutfile), { recursive: true });
176374
177511
  const result = await Bun.build({
176375
177512
  compile: { outfile: resolvedOutfile },
176376
177513
  define: { "process.env.NODE_ENV": '"production"' },
@@ -176464,11 +177601,11 @@ var exports_typecheck = {};
176464
177601
  __export(exports_typecheck, {
176465
177602
  typecheck: () => typecheck
176466
177603
  });
176467
- import { resolve as resolve18, join as join29 } from "path";
176468
- import { existsSync as existsSync32, readFileSync as readFileSync30 } from "fs";
177604
+ import { resolve as resolve22, join as join32 } from "path";
177605
+ import { existsSync as existsSync37, readFileSync as readFileSync34 } from "fs";
176469
177606
  import { mkdir as mkdir2, writeFile } from "fs/promises";
176470
- var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve18(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
176471
- if (!existsSync32(resolveConfigPath(configPath2))) {
177607
+ var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve22(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
177608
+ if (!existsSync37(resolveConfigPath(configPath2))) {
176472
177609
  return [{}];
176473
177610
  }
176474
177611
  const rawConfig = await loadRawConfig(configPath2);
@@ -176488,8 +177625,8 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
176488
177625
  const exitCode = await proc.exited;
176489
177626
  return { exitCode, name, output: (stdout + stderr).trim() };
176490
177627
  }, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
176491
- const local = resolve18("node_modules", ".bin", name);
176492
- return existsSync32(local) ? local : null;
177628
+ const local = resolve22("node_modules", ".bin", name);
177629
+ return existsSync37(local) ? local : null;
176493
177630
  }, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi3 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
176494
177631
  const cwd = `${process.cwd()}/`;
176495
177632
  const summaryMatch = stripAnsi3(output).match(/svelte-check found (\d+) error/);
@@ -176536,15 +177673,15 @@ Found ${errorCount} error${suffix}.`;
176536
177673
  return formatted;
176537
177674
  }, ABSOLUTE_INTERNAL_EXCLUDES, resolveAbsoluteTypeFile = (fileName) => {
176538
177675
  const candidates = [
176539
- resolve18("node_modules/@absolutejs/absolute/dist/types", fileName),
176540
- resolve18(import.meta.dir, "../types", fileName),
176541
- resolve18(import.meta.dir, "../../types", fileName),
176542
- resolve18(import.meta.dir, "../../../types", fileName)
177676
+ resolve22("node_modules/@absolutejs/absolute/dist/types", fileName),
177677
+ resolve22(import.meta.dir, "../types", fileName),
177678
+ resolve22(import.meta.dir, "../../types", fileName),
177679
+ resolve22(import.meta.dir, "../../../types", fileName)
176543
177680
  ];
176544
- return candidates.find((candidate) => existsSync32(candidate)) ?? candidates[0];
177681
+ return candidates.find((candidate) => existsSync37(candidate)) ?? candidates[0];
176545
177682
  }, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
176546
177683
  try {
176547
- return JSON.parse(readFileSync30(resolve18("tsconfig.json"), "utf-8"));
177684
+ return JSON.parse(readFileSync34(resolve22("tsconfig.json"), "utf-8"));
176548
177685
  } catch {
176549
177686
  return {};
176550
177687
  }
@@ -176572,22 +177709,22 @@ Found ${errorCount} error${suffix}.`;
176572
177709
  console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
176573
177710
  process.exit(1);
176574
177711
  }
176575
- const vueTsconfigPath = join29(cacheDir, "tsconfig.vue-check.json");
177712
+ const vueTsconfigPath = join32(cacheDir, "tsconfig.vue-check.json");
176576
177713
  return writeFile(vueTsconfigPath, JSON.stringify({
176577
177714
  compilerOptions: {
176578
177715
  rootDir: ".."
176579
177716
  },
176580
177717
  exclude: getProjectTypecheckExcludes(),
176581
- extends: resolve18("tsconfig.json"),
177718
+ extends: resolve22("tsconfig.json"),
176582
177719
  include: getProjectTypecheckIncludes()
176583
177720
  }, null, "\t")).then(() => run("vue-tsc", [
176584
177721
  vueTscBin,
176585
177722
  "--noEmit",
176586
177723
  "--project",
176587
- resolve18(vueTsconfigPath),
177724
+ resolve22(vueTsconfigPath),
176588
177725
  "--incremental",
176589
177726
  "--tsBuildInfoFile",
176590
- join29(cacheDir, "vue-tsc.tsbuildinfo"),
177727
+ join32(cacheDir, "vue-tsc.tsbuildinfo"),
176591
177728
  "--pretty"
176592
177729
  ]));
176593
177730
  }, buildAngularCheck = async (cacheDir, angularDir) => {
@@ -176596,7 +177733,7 @@ Found ${errorCount} error${suffix}.`;
176596
177733
  console.error("\x1B[31m\u2717\x1B[0m @angular/compiler-cli is required for Angular type checking. Install it: bun add -d @angular/compiler-cli");
176597
177734
  process.exit(1);
176598
177735
  }
176599
- const angularTsconfigPath = join29(cacheDir, "tsconfig.angular-check.json");
177736
+ const angularTsconfigPath = join32(cacheDir, "tsconfig.angular-check.json");
176600
177737
  await writeFile(angularTsconfigPath, JSON.stringify({
176601
177738
  angularCompilerOptions: {
176602
177739
  strictTemplates: true
@@ -176606,32 +177743,32 @@ Found ${errorCount} error${suffix}.`;
176606
177743
  rootDir: ".."
176607
177744
  },
176608
177745
  exclude: ABSOLUTE_INTERNAL_EXCLUDES.map(toGeneratedConfigPath),
176609
- extends: resolve18("tsconfig.json"),
177746
+ extends: resolve22("tsconfig.json"),
176610
177747
  include: [`../${angularDir}/**/*`]
176611
177748
  }, null, "\t"));
176612
- return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve18(angularTsconfigPath))}`);
177749
+ return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve22(angularTsconfigPath))}`);
176613
177750
  }, buildTscCheck = (cacheDir) => {
176614
177751
  const tscBin = findBin("tsc");
176615
177752
  if (!tscBin) {
176616
177753
  console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
176617
177754
  process.exit(1);
176618
177755
  }
176619
- const tscConfigPath = join29(cacheDir, "tsconfig.typecheck.json");
177756
+ const tscConfigPath = join32(cacheDir, "tsconfig.typecheck.json");
176620
177757
  return writeFile(tscConfigPath, JSON.stringify({
176621
177758
  compilerOptions: {
176622
177759
  rootDir: ".."
176623
177760
  },
176624
177761
  exclude: getProjectTypecheckExcludes(),
176625
- extends: resolve18("tsconfig.json"),
177762
+ extends: resolve22("tsconfig.json"),
176626
177763
  include: getProjectTypecheckIncludes()
176627
177764
  }, null, "\t")).then(() => run("tsc", [
176628
177765
  tscBin,
176629
177766
  "--noEmit",
176630
177767
  "--project",
176631
- resolve18(tscConfigPath),
177768
+ resolve22(tscConfigPath),
176632
177769
  "--incremental",
176633
177770
  "--tsBuildInfoFile",
176634
- join29(cacheDir, "tsc.tsbuildinfo"),
177771
+ join32(cacheDir, "tsc.tsbuildinfo"),
176635
177772
  "--pretty"
176636
177773
  ]));
176637
177774
  }, buildSvelteCheck = async (cacheDir, svelteDir) => {
@@ -176640,16 +177777,16 @@ Found ${errorCount} error${suffix}.`;
176640
177777
  console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
176641
177778
  process.exit(1);
176642
177779
  }
176643
- const svelteTsconfigPath = join29(cacheDir, "tsconfig.svelte-check.json");
177780
+ const svelteTsconfigPath = join32(cacheDir, "tsconfig.svelte-check.json");
176644
177781
  await writeFile(svelteTsconfigPath, JSON.stringify({
176645
- extends: resolve18("tsconfig.json"),
177782
+ extends: resolve22("tsconfig.json"),
176646
177783
  files: ABSOLUTE_TYPECHECK_FILES,
176647
177784
  include: [`../${svelteDir}/**/*`]
176648
177785
  }, null, "\t"));
176649
177786
  return run("svelte-check", [
176650
177787
  svelteBin,
176651
177788
  "--tsconfig",
176652
- resolve18(svelteTsconfigPath),
177789
+ resolve22(svelteTsconfigPath),
176653
177790
  "--threshold",
176654
177791
  "error",
176655
177792
  "--compiler-warnings",
@@ -176838,11 +177975,11 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
176838
177975
  url: url.pathname + url.search,
176839
177976
  ...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
176840
177977
  };
176841
- const responsePromise = new Promise((resolve19) => {
176842
- pending.set(id, resolve19);
177978
+ const responsePromise = new Promise((resolve23) => {
177979
+ pending.set(id, resolve23);
176843
177980
  });
176844
177981
  client.send(encodeTunnelMessage(message));
176845
- const timeout = new Promise((resolve19) => setTimeout(() => resolve19({ id, message: "timeout", type: "error" }), requestTimeoutMs));
177982
+ const timeout = new Promise((resolve23) => setTimeout(() => resolve23({ id, message: "timeout", type: "error" }), requestTimeoutMs));
176846
177983
  const result = await Promise.race([responsePromise, timeout]);
176847
177984
  pending.delete(id);
176848
177985
  if (result.type === "error") {
@@ -180298,15 +181435,15 @@ var stripNamedArgs = (...flags) => args.filter((_, idx) => flags.every((flag) =>
180298
181435
  if (command === "dev") {
180299
181436
  sendTelemetryEvent("cli:command", { command });
180300
181437
  const configPath2 = parseNamedArg("--config");
180301
- const positionalArgs = stripNamedArgs("--config");
180302
- const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
181438
+ const positionalArgs2 = stripNamedArgs("--config");
181439
+ const serverEntry = positionalArgs2[0] ?? DEFAULT_SERVER_ENTRY;
180303
181440
  await dev(serverEntry, configPath2);
180304
181441
  } else if (command === "start") {
180305
181442
  sendTelemetryEvent("cli:command", { command });
180306
181443
  const outdir = parseNamedArg("--outdir");
180307
181444
  const configPath2 = parseNamedArg("--config");
180308
- const positionalArgs = stripNamedArgs("--outdir", "--config");
180309
- const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
181445
+ const positionalArgs2 = stripNamedArgs("--outdir", "--config");
181446
+ const serverEntry = positionalArgs2[0] ?? DEFAULT_SERVER_ENTRY;
180310
181447
  await start(serverEntry, outdir, configPath2);
180311
181448
  } else if (command === "build") {
180312
181449
  sendTelemetryEvent("cli:command", { command });
@@ -180374,6 +181511,12 @@ if (command === "dev") {
180374
181511
  sendTelemetryEvent("cli:command", { command: "env" });
180375
181512
  const { runEnv: runEnv2 } = await Promise.resolve().then(() => (init_env(), exports_env));
180376
181513
  await runEnv2(args);
181514
+ } else if (command === "db") {
181515
+ sendTelemetryEvent("cli:command", {
181516
+ command: `db:${workspaceCommand ?? "unknown"}`
181517
+ });
181518
+ const { runDb: runDb2 } = await Promise.resolve().then(() => (init_db(), exports_db));
181519
+ await runDb2(args);
180377
181520
  } else if (command === "logs") {
180378
181521
  sendTelemetryEvent("cli:command", { command: "logs" });
180379
181522
  const { runLogs: runLogs2 } = await Promise.resolve().then(() => (init_logs(), exports_logs));
@@ -180405,8 +181548,8 @@ if (command === "dev") {
180405
181548
  const outdir = parseNamedArg("--outdir");
180406
181549
  const outfile = parseNamedArg("--outfile");
180407
181550
  const configPath2 = parseNamedArg("--config");
180408
- const positionalArgs = stripNamedArgs("--outdir", "--outfile", "--config");
180409
- const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
181551
+ const positionalArgs2 = stripNamedArgs("--outdir", "--outfile", "--config");
181552
+ const serverEntry = positionalArgs2[0] ?? DEFAULT_SERVER_ENTRY;
180410
181553
  const { compile: compile2 } = await Promise.resolve().then(() => (init_compile(), exports_compile));
180411
181554
  await compile2(serverEntry, outdir, outfile, configPath2);
180412
181555
  } else if (command === "typecheck") {
@@ -180433,6 +181576,7 @@ if (command === "dev") {
180433
181576
  console.error(" start [entry] [--outdir dir] Start production server");
180434
181577
  console.error(" compile [entry] [--outdir dir] [--outfile path] Compile standalone executable");
180435
181578
  console.error(" config [--port n] Open the unified config UI (ESLint, tsconfig, Prettier)");
181579
+ console.error(" db <backup|restore|seed> Backup/restore any Postgres DB (ORM-agnostic, upsert by PK) or run the seed script");
180436
181580
  console.error(" doctor [--fix] [--json] Diagnose the project (bun, config, framework dirs, env, port)");
180437
181581
  console.error(" env [--check] [--json] Report env vars the app reads (getEnv) and which are missing");
180438
181582
  console.error(" add <framework> [--no-install] Add a framework (deps, config, starter page)");