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

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
  });
@@ -174544,10 +175472,10 @@ __export(exports_logs, {
174544
175472
  });
174545
175473
  import {
174546
175474
  closeSync as closeSync2,
174547
- existsSync as existsSync26,
175475
+ existsSync as existsSync30,
174548
175476
  openSync as openSync4,
174549
175477
  readSync as readSync2,
174550
- statSync as statSync3,
175478
+ statSync as statSync4,
174551
175479
  watchFile
174552
175480
  } from "fs";
174553
175481
  var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, start2, length) => {
@@ -174562,7 +175490,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
174562
175490
  closeSync2(descriptor);
174563
175491
  }
174564
175492
  }, tailLines = (path, maxLines) => {
174565
- const { size } = statSync3(path);
175493
+ const { size } = statSync4(path);
174566
175494
  const start2 = Math.max(0, size - LIST_LOG_TAIL_MAX_BYTES);
174567
175495
  const lines = readFrom(path, start2, size - start2).split(`
174568
175496
  `);
@@ -174579,7 +175507,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
174579
175507
  const cleaned = index === UNFOUND_INDEX ? args : [...args.slice(0, index), ...args.slice(index + LINES_FLAG_SPAN)];
174580
175508
  return cleaned.find((arg) => !arg.startsWith("-"));
174581
175509
  }, followFile = (path) => {
174582
- let offset = statSync3(path).size;
175510
+ let offset = statSync4(path).size;
174583
175511
  watchFile(path, { interval: POLL_MS }, (current) => {
174584
175512
  if (current.size > offset) {
174585
175513
  process.stdout.write(readFrom(path, offset, current.size - offset));
@@ -174611,7 +175539,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
174611
175539
  printAvailable(instances);
174612
175540
  return;
174613
175541
  }
174614
- if (match.logFile === null || !existsSync26(match.logFile)) {
175542
+ if (match.logFile === null || !existsSync30(match.logFile)) {
174615
175543
  printDim3(`"${name}" has no captured log (untracked, or started outside the CLI).`);
174616
175544
  return;
174617
175545
  }
@@ -174634,10 +175562,10 @@ var exports_doctor = {};
174634
175562
  __export(exports_doctor, {
174635
175563
  runDoctor: () => runDoctor
174636
175564
  });
174637
- import { existsSync as existsSync27, mkdirSync as mkdirSync12, readFileSync as readFileSync26, writeFileSync as writeFileSync14 } from "fs";
175565
+ import { existsSync as existsSync31, mkdirSync as mkdirSync13, readFileSync as readFileSync29, writeFileSync as writeFileSync16 } from "fs";
174638
175566
  import { createRequire } from "module";
174639
175567
  import { arch as arch4, platform as platform5 } from "os";
174640
- import { join as join25 } from "path";
175568
+ import { join as join27 } from "path";
174641
175569
  var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
174642
175570
  detail,
174643
175571
  label,
@@ -174672,7 +175600,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
174672
175600
  return [];
174673
175601
  const label = `${field.replace("Directory", "")} pages`;
174674
175602
  return [
174675
- existsSync27(join25(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
175603
+ existsSync31(join27(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
174676
175604
  ];
174677
175605
  }), envCheck = async () => {
174678
175606
  const vars = await collectEnvVars();
@@ -174722,9 +175650,9 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
174722
175650
  const fixes = [];
174723
175651
  for (const field of FRAMEWORK_FIELDS2) {
174724
175652
  const dir = readString(config, field);
174725
- if (dir === undefined || existsSync27(join25(cwd, dir)))
175653
+ if (dir === undefined || existsSync31(join27(cwd, dir)))
174726
175654
  continue;
174727
- mkdirSync12(join25(cwd, dir, "pages"), { recursive: true });
175655
+ mkdirSync13(join27(cwd, dir, "pages"), { recursive: true });
174728
175656
  fixes.push(`created ${dir}/pages`);
174729
175657
  }
174730
175658
  return fixes;
@@ -174732,8 +175660,8 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
174732
175660
  const missing = (await collectEnvVars()).filter((entry) => !entry.set);
174733
175661
  if (missing.length === 0)
174734
175662
  return null;
174735
- const envExample = join25(cwd, ".env.example");
174736
- const existing = existsSync27(envExample) ? readFileSync26(envExample, "utf-8") : "";
175663
+ const envExample = join27(cwd, ".env.example");
175664
+ const existing = existsSync31(envExample) ? readFileSync29(envExample, "utf-8") : "";
174737
175665
  const existingKeys = new Set(existing.split(`
174738
175666
  `).map((line) => line.split("=")[0]?.trim()));
174739
175667
  const toAdd = missing.filter((entry) => !existingKeys.has(entry.key));
@@ -174742,7 +175670,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
174742
175670
  const prefix = existing === "" || existing.endsWith(`
174743
175671
  `) ? existing : `${existing}
174744
175672
  `;
174745
- writeFileSync14(envExample, `${prefix}${toAdd.map((entry) => `${entry.key}=`).join(`
175673
+ writeFileSync16(envExample, `${prefix}${toAdd.map((entry) => `${entry.key}=`).join(`
174746
175674
  `)}
174747
175675
  `);
174748
175676
  return `added ${toAdd.length} key(s) to .env.example`;
@@ -174788,7 +175716,7 @@ var init_doctor = __esm(() => {
174788
175716
  "htmlDirectory",
174789
175717
  "htmxDirectory"
174790
175718
  ];
174791
- projectRequire = createRequire(join25(process.cwd(), "package.json"));
175719
+ projectRequire = createRequire(join27(process.cwd(), "package.json"));
174792
175720
  STATUS_MARK = {
174793
175721
  fail: `${colors.red}\u2717${colors.reset}`,
174794
175722
  ok: `${colors.green}\u2713${colors.reset}`,
@@ -175092,10 +176020,10 @@ var init_inspect = __esm(() => {
175092
176020
  });
175093
176021
 
175094
176022
  // src/build/scanEntryPoints.ts
175095
- import { existsSync as existsSync28 } from "fs";
176023
+ import { existsSync as existsSync32 } from "fs";
175096
176024
  var {Glob: Glob4 } = globalThis.Bun;
175097
176025
  var scanEntryPoints = async (dir, pattern) => {
175098
- if (!existsSync28(dir))
176026
+ if (!existsSync32(dir))
175099
176027
  return [];
175100
176028
  const entryPaths = [];
175101
176029
  const glob = new Glob4(pattern);
@@ -175177,8 +176105,8 @@ var init_sourceMetadata = __esm(() => {
175177
176105
  });
175178
176106
 
175179
176107
  // src/islands/pageMetadata.ts
175180
- import { readFileSync as readFileSync27 } from "fs";
175181
- import { dirname as dirname11, resolve as resolve14 } from "path";
176108
+ import { readFileSync as readFileSync30 } from "fs";
176109
+ import { dirname as dirname12, resolve as resolve18 } from "path";
175182
176110
  var pagePatterns, getPageDirs = (config) => [
175183
176111
  { dir: config.angularDirectory, framework: "angular" },
175184
176112
  { dir: config.emberDirectory, framework: "ember" },
@@ -175198,8 +176126,8 @@ var pagePatterns, getPageDirs = (config) => [
175198
176126
  const source = definition.buildReference?.source;
175199
176127
  if (!source)
175200
176128
  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));
176129
+ const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve18(dirname12(buildInfo.resolvedRegistryPath), source);
176130
+ lookup.set(`${definition.framework}:${definition.component}`, resolve18(resolvedSource));
175203
176131
  }
175204
176132
  return lookup;
175205
176133
  }, resolveIslandUsages = (islands, islandSourceLookup) => islands.map((usage) => {
@@ -175212,13 +176140,13 @@ var pagePatterns, getPageDirs = (config) => [
175212
176140
  const pattern = pagePatterns[entry.framework];
175213
176141
  if (!pattern)
175214
176142
  return;
175215
- const files = await scanEntryPoints(resolve14(entry.dir), pattern);
176143
+ const files = await scanEntryPoints(resolve18(entry.dir), pattern);
175216
176144
  for (const filePath of files) {
175217
- const source = readFileSync27(filePath, "utf-8");
176145
+ const source = readFileSync30(filePath, "utf-8");
175218
176146
  const islands = extractIslandUsagesFromSource(source);
175219
- pageMetadata.set(resolve14(filePath), {
176147
+ pageMetadata.set(resolve18(filePath), {
175220
176148
  islands: resolveIslandUsages(islands, islandSourceLookup),
175221
- pagePath: resolve14(filePath)
176149
+ pagePath: resolve18(filePath)
175222
176150
  });
175223
176151
  }
175224
176152
  }, loadPageIslandMetadata = async (config) => {
@@ -175247,39 +176175,39 @@ var exports_islands = {};
175247
176175
  __export(exports_islands, {
175248
176176
  runIslands: () => runIslands
175249
176177
  });
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";
176178
+ import { existsSync as existsSync33, readFileSync as readFileSync31, statSync as statSync5 } from "fs";
176179
+ import { join as join28, relative as relative10, resolve as resolve19 } from "path";
175252
176180
  var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.write(`${colors.dim}${message}${colors.reset}
175253
176181
  `), hostFrameworkOf = (pagePath, cwd, config) => {
175254
- const resolved = resolve15(cwd, pagePath);
176182
+ const resolved = resolve19(cwd, pagePath);
175255
176183
  for (const [framework, key] of Object.entries(FRAMEWORK_DIR_KEY)) {
175256
176184
  const dir = config[key];
175257
- if (typeof dir === "string" && resolved.startsWith(resolve15(cwd, dir))) {
176185
+ if (typeof dir === "string" && resolved.startsWith(resolve19(cwd, dir))) {
175258
176186
  return framework;
175259
176187
  }
175260
176188
  }
175261
176189
  return null;
175262
176190
  }, fileSize3 = (path) => {
175263
176191
  try {
175264
- return statSync4(path).size;
176192
+ return statSync5(path).size;
175265
176193
  } catch {
175266
176194
  return 0;
175267
176195
  }
175268
176196
  }, readManifestSizes2 = (manifestDir) => {
175269
- const manifestPath = join26(manifestDir, "manifest.json");
175270
- if (!existsSync29(manifestPath))
176197
+ const manifestPath = join28(manifestDir, "manifest.json");
176198
+ if (!existsSync33(manifestPath))
175271
176199
  return null;
175272
- const manifest = JSON.parse(readFileSync28(manifestPath, "utf-8"));
176200
+ const manifest = JSON.parse(readFileSync31(manifestPath, "utf-8"));
175273
176201
  const sizes = new Map;
175274
176202
  for (const [key, value] of Object.entries(manifest)) {
175275
- sizes.set(key, fileSize3(join26(manifestDir, value.replace(/^\//, ""))));
176203
+ sizes.set(key, fileSize3(join28(manifestDir, value.replace(/^\//, ""))));
175276
176204
  }
175277
176205
  return sizes;
175278
176206
  }, collectIslands = async (cwd, config, sizes) => {
175279
176207
  const registryPath = config.islands?.registry;
175280
176208
  if (typeof registryPath !== "string")
175281
176209
  return null;
175282
- const buildInfo = await loadIslandRegistryBuildInfo(resolve15(cwd, registryPath));
176210
+ const buildInfo = await loadIslandRegistryBuildInfo(resolve19(cwd, registryPath));
175283
176211
  const pageMetadata = await loadPageIslandMetadata(config);
175284
176212
  const usages = [...pageMetadata.values()].flatMap((meta) => meta.islands.map((island) => ({ ...island, page: meta.pagePath })));
175285
176213
  return buildInfo.definitions.map((definition) => {
@@ -175289,7 +176217,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
175289
176217
  crossFramework: hostFramework !== null && hostFramework !== definition.framework,
175290
176218
  hostFramework,
175291
176219
  hydrate: usage.hydrate ?? "load",
175292
- page: relative8(cwd, resolve15(cwd, usage.page))
176220
+ page: relative10(cwd, resolve19(cwd, usage.page))
175293
176221
  };
175294
176222
  });
175295
176223
  const key = getIslandManifestKey(definition.framework, definition.component);
@@ -175328,7 +176256,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
175328
176256
  ` ${color}\u2B21${colors.reset} ${colors.bold}${island.component}${colors.reset} ${meta}${sizeText}`
175329
176257
  ];
175330
176258
  if (island.source) {
175331
- lines.push(` ${colors.dim}${relative8(cwd, island.source)}${colors.reset}`);
176259
+ lines.push(` ${colors.dim}${relative10(cwd, island.source)}${colors.reset}`);
175332
176260
  }
175333
176261
  if (pages.length === 0) {
175334
176262
  lines.push(` ${colors.dim}(registered but not mounted on any page)${colors.reset}`);
@@ -175358,7 +176286,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
175358
176286
  }
175359
176287
  const outdirIndex = args.indexOf("--outdir");
175360
176288
  const outdir = outdirIndex >= 0 ? args[outdirIndex + 1] : config.buildDirectory;
175361
- const sizes = args.includes("--sizes") ? readManifestSizes2(resolve15(cwd, outdir ?? "build")) : null;
176289
+ const sizes = args.includes("--sizes") ? readManifestSizes2(resolve19(cwd, outdir ?? "build")) : null;
175362
176290
  const islands = await collectIslands(cwd, config, sizes);
175363
176291
  if (islands === null) {
175364
176292
  printDim6('No island registry configured. Set `islands: { registry: "..." }` in absolute.config.ts.');
@@ -175407,13 +176335,13 @@ var init_islands2 = __esm(() => {
175407
176335
  });
175408
176336
 
175409
176337
  // 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";
176338
+ import { copyFileSync as copyFileSync2, existsSync as existsSync34, mkdirSync as mkdirSync14, statSync as statSync6 } from "fs";
176339
+ import { basename as basename6, dirname as dirname13, join as join29, resolve as resolve20 } from "path";
175412
176340
  var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
175413
176341
  name: "absolute-external-asset",
175414
176342
  setup(bld) {
175415
176343
  const urlPattern = /new\s+URL\(\s*["'](\.\.?\/[^"']+)["']\s*,\s*import\.meta\.url\s*\)/g;
175416
- const skipRoots = userSourceRoots.map((root) => resolve16(root));
176344
+ const skipRoots = userSourceRoots.map((root) => resolve20(root));
175417
176345
  const isUserSource = (path) => skipRoots.some((root) => path.startsWith(`${root}/`));
175418
176346
  bld.onLoad({ filter: /\.[mc]?[jt]sx?$/ }, async (args) => {
175419
176347
  if (isUserSource(args.path))
@@ -175423,20 +176351,20 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
175423
176351
  return;
175424
176352
  urlPattern.lastIndex = 0;
175425
176353
  let match;
175426
- const sourceDir = dirname12(args.path);
176354
+ const sourceDir = dirname13(args.path);
175427
176355
  while ((match = urlPattern.exec(source)) !== null) {
175428
176356
  const relPath = match[1];
175429
176357
  if (!relPath)
175430
176358
  continue;
175431
- const assetPath = resolve16(sourceDir, relPath);
175432
- if (!existsSync30(assetPath))
176359
+ const assetPath = resolve20(sourceDir, relPath);
176360
+ if (!existsSync34(assetPath))
175433
176361
  continue;
175434
- if (!statSync5(assetPath).isFile())
176362
+ if (!statSync6(assetPath).isFile())
175435
176363
  continue;
175436
- const targetPath = join27(outDir, basename6(assetPath));
175437
- if (existsSync30(targetPath))
176364
+ const targetPath = join29(outDir, basename6(assetPath));
176365
+ if (existsSync34(targetPath))
175438
176366
  continue;
175439
- mkdirSync13(dirname12(targetPath), { recursive: true });
176367
+ mkdirSync14(dirname13(targetPath), { recursive: true });
175440
176368
  copyFileSync2(assetPath, targetPath);
175441
176369
  }
175442
176370
  return;
@@ -175454,16 +176382,16 @@ __export(exports_compile, {
175454
176382
  var {env: env4 } = globalThis.Bun;
175455
176383
  import {
175456
176384
  cpSync,
175457
- existsSync as existsSync31,
175458
- mkdirSync as mkdirSync14,
175459
- readdirSync as readdirSync6,
175460
- readFileSync as readFileSync29,
176385
+ existsSync as existsSync35,
176386
+ mkdirSync as mkdirSync15,
176387
+ readdirSync as readdirSync7,
176388
+ readFileSync as readFileSync32,
175461
176389
  rmSync as rmSync5,
175462
- statSync as statSync6,
176390
+ statSync as statSync7,
175463
176391
  unlinkSync as unlinkSync4,
175464
- writeFileSync as writeFileSync15
176392
+ writeFileSync as writeFileSync17
175465
176393
  } from "fs";
175466
- import { basename as basename7, dirname as dirname13, join as join28, relative as relative9, resolve as resolve17 } from "path";
176394
+ import { basename as basename7, dirname as dirname14, join as join30, relative as relative11, resolve as resolve21 } from "path";
175467
176395
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
175468
176396
  const resolvedVersion = version2 || "unknown";
175469
176397
  console.log("");
@@ -175471,14 +176399,14 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175471
176399
  console.log("");
175472
176400
  }, collectFiles2 = (dir) => {
175473
176401
  const result = [];
175474
- let pending = readdirSync6(dir, { withFileTypes: true });
176402
+ let pending = readdirSync7(dir, { withFileTypes: true });
175475
176403
  while (pending.length > 0) {
175476
176404
  const entry = pending.pop();
175477
176405
  if (!entry)
175478
176406
  continue;
175479
- const fullPath = join28(entry.parentPath, entry.name);
176407
+ const fullPath = join30(entry.parentPath, entry.name);
175480
176408
  if (entry.isDirectory())
175481
- pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
176409
+ pending = pending.concat(readdirSync7(fullPath, { withFileTypes: true }));
175482
176410
  else
175483
176411
  result.push(fullPath);
175484
176412
  }
@@ -175491,16 +176419,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175491
176419
  return `./${parts.join("/")}`;
175492
176420
  }, collectProjectSourceFiles = (dir) => {
175493
176421
  const result = [];
175494
- let pending = readdirSync6(dir, { withFileTypes: true });
176422
+ let pending = readdirSync7(dir, { withFileTypes: true });
175495
176423
  while (pending.length > 0) {
175496
176424
  const entry = pending.pop();
175497
176425
  if (!entry)
175498
176426
  continue;
175499
- const fullPath = join28(entry.parentPath, entry.name);
176427
+ const fullPath = join30(entry.parentPath, entry.name);
175500
176428
  if (entry.isDirectory()) {
175501
176429
  if (SERVER_RUNTIME_SCAN_SKIP_DIRS.has(entry.name))
175502
176430
  continue;
175503
- pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
176431
+ pending = pending.concat(readdirSync7(fullPath, { withFileTypes: true }));
175504
176432
  } else if (hasSourceExtension(fullPath)) {
175505
176433
  result.push(fullPath);
175506
176434
  }
@@ -175508,22 +176436,22 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175508
176436
  return result;
175509
176437
  }, copyServerRuntimeAssetReferences = (outdir) => {
175510
176438
  const copied = new Set;
175511
- const normalizedOutdir = resolve17(outdir);
176439
+ const normalizedOutdir = resolve21(outdir);
175512
176440
  const copyReference = (filePath, relPath) => {
175513
- const assetSource = resolve17(dirname13(filePath), relPath);
175514
- if (!existsSync31(assetSource) || !statSync6(assetSource).isFile())
176441
+ const assetSource = resolve21(dirname14(filePath), relPath);
176442
+ if (!existsSync35(assetSource) || !statSync7(assetSource).isFile())
175515
176443
  return;
175516
- const assetTarget = resolve17(normalizedOutdir, relPath.replace(/^\.\//, ""));
176444
+ const assetTarget = resolve21(normalizedOutdir, relPath.replace(/^\.\//, ""));
175517
176445
  if (assetTarget !== normalizedOutdir && !assetTarget.startsWith(`${normalizedOutdir}/`))
175518
176446
  return;
175519
176447
  if (copied.has(assetTarget))
175520
176448
  return;
175521
176449
  copied.add(assetTarget);
175522
- mkdirSync14(dirname13(assetTarget), { recursive: true });
176450
+ mkdirSync15(dirname14(assetTarget), { recursive: true });
175523
176451
  cpSync(assetSource, assetTarget, { force: true });
175524
176452
  };
175525
176453
  for (const filePath of collectProjectSourceFiles(process.cwd())) {
175526
- const source = readFileSync29(filePath, "utf-8");
176454
+ const source = readFileSync32(filePath, "utf-8");
175527
176455
  SERVER_RUNTIME_ASSET_RE.lastIndex = 0;
175528
176456
  let match;
175529
176457
  while ((match = SERVER_RUNTIME_ASSET_RE.exec(source)) !== null) {
@@ -175552,7 +176480,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175552
176480
  }
175553
176481
  }, readPackageVersion4 = (candidate) => {
175554
176482
  try {
175555
- const pkg = JSON.parse(readFileSync29(candidate, "utf-8"));
176483
+ const pkg = JSON.parse(readFileSync32(candidate, "utf-8"));
175556
176484
  if (pkg.name !== "@absolutejs/absolute")
175557
176485
  return null;
175558
176486
  const ver = pkg.version;
@@ -175587,18 +176515,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175587
176515
  return resolveBuildModule3(remaining);
175588
176516
  }, resolveJsxDevRuntimeCompatPath2 = () => {
175589
176517
  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")
176518
+ resolve21(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
176519
+ resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
176520
+ resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
176521
+ resolve21(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
176522
+ resolve21(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
176523
+ resolve21(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
175596
176524
  ];
175597
176525
  for (const candidate of candidates) {
175598
- if (existsSync31(candidate))
176526
+ if (existsSync35(candidate))
175599
176527
  return candidate;
175600
176528
  }
175601
- return resolve17(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
176529
+ return resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
175602
176530
  }, jsxDevRuntimeCompatPath2, shouldEmbedCompiledAsset = (relativePath, skip = new Set) => {
175603
176531
  if (skip.has(relativePath))
175604
176532
  return false;
@@ -175611,11 +176539,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175611
176539
  return true;
175612
176540
  }, tryReadNodePackageJson = (packageDir) => {
175613
176541
  try {
175614
- return JSON.parse(readFileSync29(join28(packageDir, "package.json"), "utf-8"));
176542
+ return JSON.parse(readFileSync32(join30(packageDir, "package.json"), "utf-8"));
175615
176543
  } catch {
175616
176544
  return null;
175617
176545
  }
175618
- }, resolveProjectPackageDir = (specifier) => resolve17(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
176546
+ }, resolveProjectPackageDir = (specifier) => resolve21(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
175619
176547
  if (seen.has(specifier))
175620
176548
  return;
175621
176549
  const srcDir = resolveProjectPackageDir(specifier);
@@ -175623,13 +176551,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175623
176551
  if (!pkg)
175624
176552
  return;
175625
176553
  seen.add(specifier);
175626
- const destDir = join28(outdir, "node_modules", ...specifier.split("/"));
176554
+ const destDir = join30(outdir, "node_modules", ...specifier.split("/"));
175627
176555
  rmSync5(destDir, { force: true, recursive: true });
175628
176556
  cpSync(srcDir, destDir, {
175629
176557
  force: true,
175630
176558
  recursive: true,
175631
176559
  filter(source) {
175632
- const rel = relative9(srcDir, source);
176560
+ const rel = relative11(srcDir, source);
175633
176561
  const [firstSegment] = rel.split(/[\\/]/);
175634
176562
  return firstSegment !== "node_modules" && firstSegment !== ".git";
175635
176563
  }
@@ -175645,8 +176573,8 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175645
176573
  }, copyAngularRuntimePackages = (buildConfig, outdir) => {
175646
176574
  if (!buildConfig.angularDirectory)
175647
176575
  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}`) : [];
176576
+ const angularScopeDir = resolve21(process.cwd(), "node_modules", "@angular");
176577
+ const angularPackages = existsSync35(angularScopeDir) ? readdirSync7(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
175650
176578
  const roots = new Set([...angularPackages, "rxjs", "tslib", "typescript"]);
175651
176579
  const seen = new Set;
175652
176580
  for (const specifier of roots) {
@@ -175664,16 +176592,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175664
176592
  copyAngularRuntimePackages(buildConfig, outdir);
175665
176593
  copyChunkReferencedPackages(outdir, seen);
175666
176594
  }, collectRuntimePackageSpecifiers = (distDir) => {
175667
- const nodeModulesDir = join28(distDir, "node_modules");
175668
- if (!existsSync31(nodeModulesDir))
176595
+ const nodeModulesDir = join30(distDir, "node_modules");
176596
+ if (!existsSync35(nodeModulesDir))
175669
176597
  return [];
175670
176598
  const specifiers = [];
175671
- for (const entry of readdirSync6(nodeModulesDir, { withFileTypes: true })) {
176599
+ for (const entry of readdirSync7(nodeModulesDir, { withFileTypes: true })) {
175672
176600
  if (!entry.isDirectory())
175673
176601
  continue;
175674
176602
  if (entry.name.startsWith("@")) {
175675
- const scopeDir = join28(nodeModulesDir, entry.name);
175676
- for (const scopedEntry of readdirSync6(scopeDir, {
176603
+ const scopeDir = join30(nodeModulesDir, entry.name);
176604
+ for (const scopedEntry of readdirSync7(scopeDir, {
175677
176605
  withFileTypes: true
175678
176606
  })) {
175679
176607
  if (scopedEntry.isDirectory()) {
@@ -175686,7 +176614,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175686
176614
  }
175687
176615
  return specifiers.sort((a, b) => b.length - a.length);
175688
176616
  }, ensureRelativeModuleSpecifier = (fromFile, toFile) => {
175689
- const rel = relative9(dirname13(fromFile), toFile).replace(/\\/g, "/");
176617
+ const rel = relative11(dirname14(fromFile), toFile).replace(/\\/g, "/");
175690
176618
  return rel.startsWith(".") ? rel : `./${rel}`;
175691
176619
  }, pickExportEntry = (value) => {
175692
176620
  if (typeof value === "string")
@@ -175704,21 +176632,21 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175704
176632
  const packageSpecifier = packageSpecifiers.find((root) => specifier === root || specifier.startsWith(`${root}/`));
175705
176633
  if (!packageSpecifier)
175706
176634
  return null;
175707
- const packageDir = join28(distDir, "node_modules", ...packageSpecifier.split("/"));
176635
+ const packageDir = join30(distDir, "node_modules", ...packageSpecifier.split("/"));
175708
176636
  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))
176637
+ const subPackageDir = subpath ? join30(packageDir, ...subpath.slice(1).split("/")) : null;
176638
+ const resolvedPackageDir = subPackageDir && existsSync35(join30(subPackageDir, "package.json")) ? subPackageDir : packageDir;
176639
+ const packageJsonPath = join30(resolvedPackageDir, "package.json");
176640
+ if (!existsSync35(packageJsonPath))
175713
176641
  return null;
175714
- const pkg = JSON.parse(readFileSync29(packageJsonPath, "utf-8"));
176642
+ const pkg = JSON.parse(readFileSync32(packageJsonPath, "utf-8"));
175715
176643
  const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
175716
176644
  const rootExport = pkg.exports?.[exportKey];
175717
176645
  const entry = pickExportEntry(rootExport) ?? (resolvedPackageDir === subPackageDir || !subpath ? pkg.module ?? pkg.main ?? "index.js" : `.${subpath}`);
175718
- return join28(resolvedPackageDir, entry);
176646
+ return join30(resolvedPackageDir, entry);
175719
176647
  }, 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
176648
  try {
175721
- return statSync6(filePath).isFile();
176649
+ return statSync7(filePath).isFile();
175722
176650
  } catch {
175723
176651
  return false;
175724
176652
  }
@@ -175728,16 +176656,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175728
176656
  const candidates = [
175729
176657
  candidate,
175730
176658
  ...RUNTIME_JS_EXTENSIONS.map((extension) => `${candidate}${extension}`),
175731
- ...RUNTIME_JS_EXTENSIONS.map((extension) => join28(candidate, `index${extension}`))
176659
+ ...RUNTIME_JS_EXTENSIONS.map((extension) => join30(candidate, `index${extension}`))
175732
176660
  ];
175733
176661
  return candidates.find((filePath) => isRuntimeJsFile(filePath) && isFile(filePath)) ?? null;
175734
176662
  }, findContainingRuntimePackageDir = (filePath) => {
175735
- let dir = dirname13(filePath);
175736
- while (dir !== dirname13(dir)) {
175737
- if (isNodeModulesPath(dir) && existsSync31(join28(dir, "package.json"))) {
176663
+ let dir = dirname14(filePath);
176664
+ while (dir !== dirname14(dir)) {
176665
+ if (isNodeModulesPath(dir) && existsSync35(join30(dir, "package.json"))) {
175738
176666
  return dir;
175739
176667
  }
175740
- dir = dirname13(dir);
176668
+ dir = dirname14(dir);
175741
176669
  }
175742
176670
  return null;
175743
176671
  }, resolvePackageImportEntryFile = (fromFile, specifier) => {
@@ -175750,13 +176678,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175750
176678
  const entry = pickExportEntry(pkg?.imports?.[specifier]);
175751
176679
  if (!entry)
175752
176680
  return null;
175753
- return join28(packageDir, entry);
176681
+ return join30(packageDir, entry);
175754
176682
  }, 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);
176683
+ const distRoot = resolve21(distDir);
175756
176684
  for (const filePath of collectRuntimeRewriteRoots(distDir)) {
175757
- if (resolve17(dirname13(filePath)) === distRoot)
176685
+ if (resolve21(dirname14(filePath)) === distRoot)
175758
176686
  continue;
175759
- const source = readFileSync29(filePath, "utf-8");
176687
+ const source = readFileSync32(filePath, "utf-8");
175760
176688
  for (const match of source.matchAll(MODULE_SPECIFIER_RE)) {
175761
176689
  const specifier = match[3];
175762
176690
  if (!specifier || specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("#") || specifier.startsWith("node:") || specifier.startsWith("bun:")) {
@@ -175786,10 +176714,10 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175786
176714
  if (!filePath || seen.has(filePath))
175787
176715
  continue;
175788
176716
  seen.add(filePath);
175789
- const source = readFileSync29(filePath, "utf-8");
176717
+ const source = readFileSync32(filePath, "utf-8");
175790
176718
  const rewritten = source.replace(MODULE_SPECIFIER_RE, (match, prefix, quote, specifier) => {
175791
176719
  if (typeof specifier === "string" && specifier.startsWith(".")) {
175792
- enqueue(resolveRuntimeJsFile(resolve17(dirname13(filePath), specifier)));
176720
+ enqueue(resolveRuntimeJsFile(resolve21(dirname14(filePath), specifier)));
175793
176721
  return match;
175794
176722
  }
175795
176723
  const packageImportTarget = resolveRuntimeJsFile(resolvePackageImportEntryFile(filePath, specifier) ?? "");
@@ -175804,7 +176732,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175804
176732
  return `${prefix}${quote}${ensureRelativeModuleSpecifier(filePath, target)}${quote}`;
175805
176733
  });
175806
176734
  if (rewritten !== source) {
175807
- writeFileSync15(filePath, rewritten);
176735
+ writeFileSync17(filePath, rewritten);
175808
176736
  }
175809
176737
  }
175810
176738
  }, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2, buildConfig) => {
@@ -175817,25 +176745,25 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175817
176745
  "_compile_entrypoint.ts"
175818
176746
  ]);
175819
176747
  const embeddedFiles = allFiles.filter((file) => {
175820
- const rel = relative9(distDir, file);
176748
+ const rel = relative11(distDir, file);
175821
176749
  if (embeddedSkip.has(rel))
175822
176750
  return false;
175823
176751
  return true;
175824
176752
  });
175825
- const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative9(distDir, file), assetSkip));
176753
+ const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative11(distDir, file), assetSkip));
175826
176754
  const imports = [];
175827
176755
  const embeddedMappings = [];
175828
176756
  const mappings = [];
175829
176757
  const embeddedVarMap = new Map;
175830
176758
  embeddedFiles.forEach((filePath, idx) => {
175831
- const rel = relative9(distDir, filePath).replace(/\\/g, "/");
176759
+ const rel = relative11(distDir, filePath).replace(/\\/g, "/");
175832
176760
  const varName = `__a${idx}`;
175833
176761
  embeddedVarMap.set(rel, varName);
175834
176762
  imports.push(`import ${varName} from "./${rel}" with { type: "file" };`);
175835
176763
  embeddedMappings.push(` ["${rel}", ${varName}],`);
175836
176764
  });
175837
176765
  clientFiles.forEach((filePath) => {
175838
- const rel = relative9(distDir, filePath).replace(/\\/g, "/");
176766
+ const rel = relative11(distDir, filePath).replace(/\\/g, "/");
175839
176767
  const varName = embeddedVarMap.get(rel);
175840
176768
  if (!varName)
175841
176769
  return;
@@ -175849,7 +176777,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
175849
176777
  const pageVarMap = new Map;
175850
176778
  const prerenderEntries = Array.from(prerenderMap.entries());
175851
176779
  prerenderEntries.forEach(([route, filePath]) => {
175852
- const rel = relative9(distDir, filePath).replace(/\\/g, "/");
176780
+ const rel = relative11(distDir, filePath).replace(/\\/g, "/");
175853
176781
  const varName = embeddedVarMap.get(rel);
175854
176782
  if (varName)
175855
176783
  pageVarMap.set(route, varName);
@@ -175878,7 +176806,7 @@ import { websocket as elysiaWebsocket } from "elysia/ws";
175878
176806
  const SERVER_MODULE = (runtimeDir: string) => import(pathToFileURL(join(runtimeDir, ${JSON.stringify(serverBundleName)})).href);
175879
176807
  const RUNTIME_BUILD_ID = ${JSON.stringify(runtimeBuildId)};
175880
176808
  const RUNTIME_CONFIG_SOURCE = ${JSON.stringify(runtimeConfigSource)};
175881
- const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve17(distDir))};
176809
+ const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve21(distDir))};
175882
176810
  const ORIGINAL_BUILD_DIR_NORMALIZED = ORIGINAL_BUILD_DIR.replace(/\\\\/g, "/");
175883
176811
 
175884
176812
  // \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 +177183,16 @@ console.log(\`
176255
177183
  }),
176256
177184
  ...collectUserServerExternals(buildConfig)
176257
177185
  ], compile = async (serverEntry, outdir, outfile, configPath2) => {
176258
- const resolvedOutdir = resolve17(outdir ?? "dist");
177186
+ const resolvedOutdir = resolve21(outdir ?? "dist");
176259
177187
  await withBuildDirectoryLock(resolvedOutdir, () => compileUnlocked(serverEntry, resolvedOutdir, outfile, configPath2));
176260
177188
  }, compileUnlocked = async (serverEntry, resolvedOutdir, outfile, configPath2) => {
176261
177189
  const prerenderPort = Number(env4.COMPILE_PORT) || Number(env4.PORT) || DEFAULT_PORT + 1;
176262
177190
  killStaleProcesses(prerenderPort);
176263
177191
  const entryName = basename7(serverEntry).replace(/\.[^.]+$/, "");
176264
- const resolvedOutfile = resolve17(outfile ?? "compiled-server");
177192
+ const resolvedOutfile = resolve21(outfile ?? "compiled-server");
176265
177193
  const absoluteVersion = resolvePackageVersion3([
176266
- resolve17(import.meta.dir, "..", "..", "..", "package.json"),
176267
- resolve17(import.meta.dir, "..", "..", "package.json")
177194
+ resolve21(import.meta.dir, "..", "..", "..", "package.json"),
177195
+ resolve21(import.meta.dir, "..", "..", "package.json")
176268
177196
  ]);
176269
177197
  compileBanner(absoluteVersion);
176270
177198
  const totalStart = performance.now();
@@ -176275,8 +177203,8 @@ console.log(\`
176275
177203
  buildConfig.mode = "production";
176276
177204
  try {
176277
177205
  const build2 = await resolveBuildModule3([
176278
- resolve17(import.meta.dir, "..", "..", "core", "build"),
176279
- resolve17(import.meta.dir, "..", "build")
177206
+ resolve21(import.meta.dir, "..", "..", "core", "build"),
177207
+ resolve21(import.meta.dir, "..", "build")
176280
177208
  ]);
176281
177209
  if (!build2)
176282
177210
  throw new Error("Could not locate build module");
@@ -176298,10 +177226,10 @@ console.log(\`
176298
177226
  buildConfig.htmxDirectory
176299
177227
  ].filter((dir) => Boolean(dir));
176300
177228
  const islandRegistrySpec = buildConfig.islands?.registry;
176301
- const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve17(islandRegistrySpec))) : undefined;
177229
+ const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve21(islandRegistrySpec))) : undefined;
176302
177230
  const serverBundle = await Bun.build({
176303
177231
  define: { "process.env.NODE_ENV": '"production"' },
176304
- entrypoints: [resolve17(serverEntry)],
177232
+ entrypoints: [resolve21(serverEntry)],
176305
177233
  external: resolveServerBundleExternals(buildConfig),
176306
177234
  outdir: resolvedOutdir,
176307
177235
  plugins: [
@@ -176322,14 +177250,14 @@ console.log(\`
176322
177250
  console.error(cliTag4("\x1B[31m", "Server bundle failed."));
176323
177251
  process.exit(1);
176324
177252
  }
176325
- const outputPath = resolve17(resolvedOutdir, `${entryName}.js`);
176326
- if (!existsSync31(outputPath)) {
177253
+ const outputPath = resolve21(resolvedOutdir, `${entryName}.js`);
177254
+ if (!existsSync35(outputPath)) {
176327
177255
  console.error(cliTag4("\x1B[31m", `Expected output not found: ${outputPath}`));
176328
177256
  process.exit(1);
176329
177257
  }
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"));
177258
+ if (existsSync35(resolve21(resolvedOutdir, "angular", "vendor", "server"))) {
177259
+ const vendorDir = resolve21(resolvedOutdir, "angular", "vendor", "server");
177260
+ const vendorEntries = readdirSync7(vendorDir).filter((f) => f.endsWith(".js"));
176333
177261
  const angularServerVendorPaths = {};
176334
177262
  for (const file of vendorEntries) {
176335
177263
  const stem = file.replace(/\.js$/, "");
@@ -176337,7 +177265,7 @@ console.log(\`
176337
177265
  if (scope !== "angular" || rest.length === 0)
176338
177266
  continue;
176339
177267
  const specifier = `@angular/${rest.join("/")}`;
176340
- const relPath = relative9(dirname13(outputPath), resolve17(vendorDir, file));
177268
+ const relPath = relative11(dirname14(outputPath), resolve21(vendorDir, file));
176341
177269
  angularServerVendorPaths[specifier] = relPath.startsWith(".") ? relPath : `./${relPath}`;
176342
177270
  }
176343
177271
  if (Object.keys(angularServerVendorPaths).length > 0) {
@@ -176349,7 +177277,7 @@ console.log(\`
176349
177277
  copyServerRuntimeAssetReferences(resolvedOutdir);
176350
177278
  const prerenderStart = performance.now();
176351
177279
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
176352
- rmSync5(join28(resolvedOutdir, "_prerendered"), {
177280
+ rmSync5(join30(resolvedOutdir, "_prerendered"), {
176353
177281
  force: true,
176354
177282
  recursive: true
176355
177283
  });
@@ -176368,9 +177296,9 @@ console.log(\`
176368
177296
  const compileStart = performance.now();
176369
177297
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
176370
177298
  const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
176371
- const entrypointPath = join28(resolvedOutdir, "_compile_entrypoint.ts");
177299
+ const entrypointPath = join30(resolvedOutdir, "_compile_entrypoint.ts");
176372
177300
  await Bun.write(entrypointPath, entrypointCode);
176373
- mkdirSync14(dirname13(resolvedOutfile), { recursive: true });
177301
+ mkdirSync15(dirname14(resolvedOutfile), { recursive: true });
176374
177302
  const result = await Bun.build({
176375
177303
  compile: { outfile: resolvedOutfile },
176376
177304
  define: { "process.env.NODE_ENV": '"production"' },
@@ -176464,11 +177392,11 @@ var exports_typecheck = {};
176464
177392
  __export(exports_typecheck, {
176465
177393
  typecheck: () => typecheck
176466
177394
  });
176467
- import { resolve as resolve18, join as join29 } from "path";
176468
- import { existsSync as existsSync32, readFileSync as readFileSync30 } from "fs";
177395
+ import { resolve as resolve22, join as join31 } from "path";
177396
+ import { existsSync as existsSync36, readFileSync as readFileSync33 } from "fs";
176469
177397
  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))) {
177398
+ var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve22(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
177399
+ if (!existsSync36(resolveConfigPath(configPath2))) {
176472
177400
  return [{}];
176473
177401
  }
176474
177402
  const rawConfig = await loadRawConfig(configPath2);
@@ -176488,8 +177416,8 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
176488
177416
  const exitCode = await proc.exited;
176489
177417
  return { exitCode, name, output: (stdout + stderr).trim() };
176490
177418
  }, 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;
177419
+ const local = resolve22("node_modules", ".bin", name);
177420
+ return existsSync36(local) ? local : null;
176493
177421
  }, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi3 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
176494
177422
  const cwd = `${process.cwd()}/`;
176495
177423
  const summaryMatch = stripAnsi3(output).match(/svelte-check found (\d+) error/);
@@ -176536,15 +177464,15 @@ Found ${errorCount} error${suffix}.`;
176536
177464
  return formatted;
176537
177465
  }, ABSOLUTE_INTERNAL_EXCLUDES, resolveAbsoluteTypeFile = (fileName) => {
176538
177466
  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)
177467
+ resolve22("node_modules/@absolutejs/absolute/dist/types", fileName),
177468
+ resolve22(import.meta.dir, "../types", fileName),
177469
+ resolve22(import.meta.dir, "../../types", fileName),
177470
+ resolve22(import.meta.dir, "../../../types", fileName)
176543
177471
  ];
176544
- return candidates.find((candidate) => existsSync32(candidate)) ?? candidates[0];
177472
+ return candidates.find((candidate) => existsSync36(candidate)) ?? candidates[0];
176545
177473
  }, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
176546
177474
  try {
176547
- return JSON.parse(readFileSync30(resolve18("tsconfig.json"), "utf-8"));
177475
+ return JSON.parse(readFileSync33(resolve22("tsconfig.json"), "utf-8"));
176548
177476
  } catch {
176549
177477
  return {};
176550
177478
  }
@@ -176572,22 +177500,22 @@ Found ${errorCount} error${suffix}.`;
176572
177500
  console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
176573
177501
  process.exit(1);
176574
177502
  }
176575
- const vueTsconfigPath = join29(cacheDir, "tsconfig.vue-check.json");
177503
+ const vueTsconfigPath = join31(cacheDir, "tsconfig.vue-check.json");
176576
177504
  return writeFile(vueTsconfigPath, JSON.stringify({
176577
177505
  compilerOptions: {
176578
177506
  rootDir: ".."
176579
177507
  },
176580
177508
  exclude: getProjectTypecheckExcludes(),
176581
- extends: resolve18("tsconfig.json"),
177509
+ extends: resolve22("tsconfig.json"),
176582
177510
  include: getProjectTypecheckIncludes()
176583
177511
  }, null, "\t")).then(() => run("vue-tsc", [
176584
177512
  vueTscBin,
176585
177513
  "--noEmit",
176586
177514
  "--project",
176587
- resolve18(vueTsconfigPath),
177515
+ resolve22(vueTsconfigPath),
176588
177516
  "--incremental",
176589
177517
  "--tsBuildInfoFile",
176590
- join29(cacheDir, "vue-tsc.tsbuildinfo"),
177518
+ join31(cacheDir, "vue-tsc.tsbuildinfo"),
176591
177519
  "--pretty"
176592
177520
  ]));
176593
177521
  }, buildAngularCheck = async (cacheDir, angularDir) => {
@@ -176596,7 +177524,7 @@ Found ${errorCount} error${suffix}.`;
176596
177524
  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
177525
  process.exit(1);
176598
177526
  }
176599
- const angularTsconfigPath = join29(cacheDir, "tsconfig.angular-check.json");
177527
+ const angularTsconfigPath = join31(cacheDir, "tsconfig.angular-check.json");
176600
177528
  await writeFile(angularTsconfigPath, JSON.stringify({
176601
177529
  angularCompilerOptions: {
176602
177530
  strictTemplates: true
@@ -176606,32 +177534,32 @@ Found ${errorCount} error${suffix}.`;
176606
177534
  rootDir: ".."
176607
177535
  },
176608
177536
  exclude: ABSOLUTE_INTERNAL_EXCLUDES.map(toGeneratedConfigPath),
176609
- extends: resolve18("tsconfig.json"),
177537
+ extends: resolve22("tsconfig.json"),
176610
177538
  include: [`../${angularDir}/**/*`]
176611
177539
  }, null, "\t"));
176612
- return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve18(angularTsconfigPath))}`);
177540
+ return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve22(angularTsconfigPath))}`);
176613
177541
  }, buildTscCheck = (cacheDir) => {
176614
177542
  const tscBin = findBin("tsc");
176615
177543
  if (!tscBin) {
176616
177544
  console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
176617
177545
  process.exit(1);
176618
177546
  }
176619
- const tscConfigPath = join29(cacheDir, "tsconfig.typecheck.json");
177547
+ const tscConfigPath = join31(cacheDir, "tsconfig.typecheck.json");
176620
177548
  return writeFile(tscConfigPath, JSON.stringify({
176621
177549
  compilerOptions: {
176622
177550
  rootDir: ".."
176623
177551
  },
176624
177552
  exclude: getProjectTypecheckExcludes(),
176625
- extends: resolve18("tsconfig.json"),
177553
+ extends: resolve22("tsconfig.json"),
176626
177554
  include: getProjectTypecheckIncludes()
176627
177555
  }, null, "\t")).then(() => run("tsc", [
176628
177556
  tscBin,
176629
177557
  "--noEmit",
176630
177558
  "--project",
176631
- resolve18(tscConfigPath),
177559
+ resolve22(tscConfigPath),
176632
177560
  "--incremental",
176633
177561
  "--tsBuildInfoFile",
176634
- join29(cacheDir, "tsc.tsbuildinfo"),
177562
+ join31(cacheDir, "tsc.tsbuildinfo"),
176635
177563
  "--pretty"
176636
177564
  ]));
176637
177565
  }, buildSvelteCheck = async (cacheDir, svelteDir) => {
@@ -176640,16 +177568,16 @@ Found ${errorCount} error${suffix}.`;
176640
177568
  console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
176641
177569
  process.exit(1);
176642
177570
  }
176643
- const svelteTsconfigPath = join29(cacheDir, "tsconfig.svelte-check.json");
177571
+ const svelteTsconfigPath = join31(cacheDir, "tsconfig.svelte-check.json");
176644
177572
  await writeFile(svelteTsconfigPath, JSON.stringify({
176645
- extends: resolve18("tsconfig.json"),
177573
+ extends: resolve22("tsconfig.json"),
176646
177574
  files: ABSOLUTE_TYPECHECK_FILES,
176647
177575
  include: [`../${svelteDir}/**/*`]
176648
177576
  }, null, "\t"));
176649
177577
  return run("svelte-check", [
176650
177578
  svelteBin,
176651
177579
  "--tsconfig",
176652
- resolve18(svelteTsconfigPath),
177580
+ resolve22(svelteTsconfigPath),
176653
177581
  "--threshold",
176654
177582
  "error",
176655
177583
  "--compiler-warnings",
@@ -176838,11 +177766,11 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
176838
177766
  url: url.pathname + url.search,
176839
177767
  ...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
176840
177768
  };
176841
- const responsePromise = new Promise((resolve19) => {
176842
- pending.set(id, resolve19);
177769
+ const responsePromise = new Promise((resolve23) => {
177770
+ pending.set(id, resolve23);
176843
177771
  });
176844
177772
  client.send(encodeTunnelMessage(message));
176845
- const timeout = new Promise((resolve19) => setTimeout(() => resolve19({ id, message: "timeout", type: "error" }), requestTimeoutMs));
177773
+ const timeout = new Promise((resolve23) => setTimeout(() => resolve23({ id, message: "timeout", type: "error" }), requestTimeoutMs));
176846
177774
  const result = await Promise.race([responsePromise, timeout]);
176847
177775
  pending.delete(id);
176848
177776
  if (result.type === "error") {