@absolutejs/absolute 0.19.0-beta.1037 → 0.19.0-beta.1039

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
@@ -170805,8 +170805,35 @@ var exports_build = {};
170805
170805
  __export(exports_build, {
170806
170806
  build: () => build
170807
170807
  });
170808
- import { resolve as resolve10 } from "path";
170809
- var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, tryImportBuild2 = async (candidate) => {
170808
+ import { existsSync as existsSync10, readdirSync as readdirSync3, readFileSync as readFileSync13 } from "fs";
170809
+ import { join as join12, resolve as resolve10 } from "path";
170810
+ var PROFILE_TOP = 15, PROFILE_COL = 8, FRAMEWORK_KEYS, cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, printProfile = (buildDir) => {
170811
+ const traceDir = join12(buildDir, ".absolute-trace");
170812
+ if (!existsSync10(traceDir))
170813
+ return;
170814
+ const files = readdirSync3(traceDir).filter((file) => file.endsWith(".json")).sort();
170815
+ const latest = files[files.length - 1];
170816
+ if (latest === undefined)
170817
+ return;
170818
+ const trace = JSON.parse(readFileSync13(join12(traceDir, latest), "utf-8"));
170819
+ const events = Array.isArray(trace.events) ? trace.events : [];
170820
+ if (events.length === 0)
170821
+ return;
170822
+ const slowest = [...events].sort((left, right) => right.durationMs - left.durationMs).slice(0, PROFILE_TOP);
170823
+ const byFramework = FRAMEWORK_KEYS.map((key) => ({
170824
+ ms: events.filter((event) => event.name.includes(key)).reduce((total, event) => total + event.durationMs, 0),
170825
+ name: key
170826
+ })).filter((entry) => entry.ms > 0);
170827
+ const lines = [
170828
+ `
170829
+ \x1B[1mbuild profile\x1B[0m \x1B[2m\xB7 slowest phases\x1B[0m`,
170830
+ ...slowest.map((event) => ` \x1B[2m${getDurationString(event.durationMs).padStart(PROFILE_COL)}\x1B[0m ${event.name}`),
170831
+ `
170832
+ \x1B[2mby framework: ${byFramework.map((entry) => `${entry.name} ${getDurationString(entry.ms)}`).join(" \xB7 ")}\x1B[0m`
170833
+ ];
170834
+ console.log(lines.join(`
170835
+ `));
170836
+ }, tryImportBuild2 = async (candidate) => {
170810
170837
  try {
170811
170838
  const mod = await import(candidate);
170812
170839
  const buildFn = mod.build;
@@ -170824,9 +170851,11 @@ var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
170824
170851
  return mod;
170825
170852
  }
170826
170853
  return resolveBuildModule2(remaining);
170827
- }, build = async (outdir, configPath2) => {
170854
+ }, build = async (outdir, configPath2, profile = false) => {
170828
170855
  const resolvedOutdir = resolve10(outdir ?? "build");
170829
170856
  const buildStart = performance.now();
170857
+ if (profile)
170858
+ process.env.ABSOLUTE_BUILD_TRACE = "1";
170830
170859
  process.stdout.write(cliTag3("\x1B[36m", "Building assets"));
170831
170860
  const buildConfig = await loadConfig(configPath2);
170832
170861
  buildConfig.buildDirectory = resolvedOutdir;
@@ -170851,18 +170880,21 @@ var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
170851
170880
  durationMs: Math.round(performance.now() - buildStart)
170852
170881
  });
170853
170882
  console.log(` \x1B[2m(${getDurationString(performance.now() - buildStart)})\x1B[0m`);
170883
+ if (profile)
170884
+ printProfile(resolvedOutdir);
170854
170885
  };
170855
170886
  var init_build = __esm(() => {
170856
170887
  init_getDurationString();
170857
170888
  init_loadConfig();
170858
170889
  init_startupBanner();
170859
170890
  init_telemetryEvent();
170891
+ FRAMEWORK_KEYS = ["react", "vue", "svelte", "angular", "html", "htmx"];
170860
170892
  });
170861
170893
 
170862
170894
  // src/build/scanConventions.ts
170863
170895
  import { basename as basename4 } from "path";
170864
170896
  var {Glob: Glob2 } = globalThis.Bun;
170865
- import { existsSync as existsSync10 } from "fs";
170897
+ import { existsSync as existsSync11 } from "fs";
170866
170898
  var CONVENTION_RE, classifyFile = (file, pageFiles, defaults, pages) => {
170867
170899
  const fileName = basename4(file);
170868
170900
  const match = CONVENTION_RE.exec(fileName);
@@ -170887,7 +170919,7 @@ var CONVENTION_RE, classifyFile = (file, pageFiles, defaults, pages) => {
170887
170919
  else if (kind === "loading")
170888
170920
  pages[pageName].loading = file;
170889
170921
  }, scanConventions = async (pagesDir, pattern) => {
170890
- if (!existsSync10(pagesDir)) {
170922
+ if (!existsSync11(pagesDir)) {
170891
170923
  const pageFiles2 = [];
170892
170924
  return { conventions: undefined, pageFiles: pageFiles2 };
170893
170925
  }
@@ -170922,8 +170954,8 @@ var exports_ls = {};
170922
170954
  __export(exports_ls, {
170923
170955
  runLs: () => runLs
170924
170956
  });
170925
- import { existsSync as existsSync11, readFileSync as readFileSync13, statSync } from "fs";
170926
- import { basename as basename5, extname as extname2, join as join12, relative as relative2 } from "path";
170957
+ import { existsSync as existsSync12, readFileSync as readFileSync14, statSync } from "fs";
170958
+ import { basename as basename5, extname as extname2, join as join13, relative as relative2 } from "path";
170927
170959
  var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELDS, readStringField = (source, key) => {
170928
170960
  const value = Reflect.get(source, key);
170929
170961
  return typeof value === "string" ? value : undefined;
@@ -170945,13 +170977,13 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
170945
170977
  const dir = readStringField(source, framework.field);
170946
170978
  return dir === undefined ? [] : [
170947
170979
  {
170948
- dir: join12(baseDir, dir),
170980
+ dir: join13(baseDir, dir),
170949
170981
  label: framework.label,
170950
170982
  pattern: framework.pattern
170951
170983
  }
170952
170984
  ];
170953
170985
  }), scanFramework = async (spec) => {
170954
- const { pageFiles } = await scanConventions(join12(spec.dir, "pages"), spec.pattern);
170986
+ const { pageFiles } = await scanConventions(join13(spec.dir, "pages"), spec.pattern);
170955
170987
  if (pageFiles.length === 0)
170956
170988
  return null;
170957
170989
  const pages = pageFiles.map((file) => ({
@@ -170973,12 +171005,12 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
170973
171005
  return pages ? [{ label, pages: sortPages(pages) }] : [];
170974
171006
  });
170975
171007
  }, resolveDiskPath = (buildDir, value) => {
170976
- if (existsSync11(value))
171008
+ if (existsSync12(value))
170977
171009
  return value;
170978
- const underBuild = join12(buildDir, value);
170979
- if (existsSync11(underBuild))
171010
+ const underBuild = join13(buildDir, value);
171011
+ if (existsSync12(underBuild))
170980
171012
  return underBuild;
170981
- return join12(process.cwd(), value);
171013
+ return join13(process.cwd(), value);
170982
171014
  }, fileSize = (diskPath) => {
170983
171015
  try {
170984
171016
  return statSync(diskPath).size;
@@ -170986,7 +171018,7 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
170986
171018
  return 0;
170987
171019
  }
170988
171020
  }, readManifestSizes = (manifestDir) => {
170989
- const manifest = JSON.parse(readFileSync13(join12(manifestDir, "manifest.json"), "utf-8"));
171021
+ const manifest = JSON.parse(readFileSync14(join13(manifestDir, "manifest.json"), "utf-8"));
170990
171022
  const sizes = new Map;
170991
171023
  Object.entries(manifest).forEach(([key, value]) => {
170992
171024
  sizes.set(key, fileSize(resolveDiskPath(manifestDir, value)));
@@ -171005,7 +171037,7 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
171005
171037
  }))
171006
171038
  })), manifestAge = (manifestPath) => getDurationString(Date.now() - statSync(manifestPath).mtimeMs), firstBuildDir = (candidates) => candidates.map((candidate) => {
171007
171039
  const dir = readStringField(candidate.source, "buildDirectory");
171008
- return dir === undefined ? undefined : join12(candidate.baseDir, dir);
171040
+ return dir === undefined ? undefined : join13(candidate.baseDir, dir);
171009
171041
  }).find((dir) => dir !== undefined), resolveSizesDir = (args, candidates) => parseFlagValue(args, "--outdir") ?? firstBuildDir(candidates) ?? DEFAULT_BUILD_DIR, formatSize = (bytes) => {
171010
171042
  if (bytes === null || bytes === 0)
171011
171043
  return "-";
@@ -171057,6 +171089,25 @@ ${colors.dim}${frameworkCount} ${frameworkCount === 1 ? "framework" : "framework
171057
171089
  }, printDim = (message) => {
171058
171090
  process.stdout.write(`${colors.dim}${message}${colors.reset}
171059
171091
  `);
171092
+ }, SIZE_UNITS, parseBudget = (args) => {
171093
+ const value = parseFlagValue(args, "--budget");
171094
+ if (value === undefined)
171095
+ return null;
171096
+ const match = value.toLowerCase().match(/^([\d.]+)\s*(gb|mb|kb|b)?$/);
171097
+ const amount = match ? Number(match[1]) : NaN;
171098
+ if (!Number.isFinite(amount))
171099
+ return null;
171100
+ return amount * (SIZE_UNITS[match?.[2] ?? "b"] ?? 1);
171101
+ }, reportBudget = (groups, budget) => {
171102
+ const over = groups.flatMap((group) => group.pages).filter((page) => (page.sizeBytes ?? 0) > budget);
171103
+ if (over.length === 0) {
171104
+ printDim(`\u2713 all pages within ${formatSize(budget)} budget`);
171105
+ return;
171106
+ }
171107
+ over.forEach((page) => process.stdout.write(` ${colors.red}\u2717 ${page.name} ${formatSize(page.sizeBytes)} > ${formatSize(budget)}${colors.reset}
171108
+ `));
171109
+ printDim(`${over.length} page${over.length === 1 ? "" : "s"} over budget`);
171110
+ process.exitCode = 1;
171060
171111
  }, guardBrokenPipe = () => {
171061
171112
  process.stdout.on("error", (error) => {
171062
171113
  if (error instanceof Error && "code" in error && error.code === "EPIPE") {
@@ -171084,14 +171135,17 @@ ${colors.dim}${frameworkCount} ${frameworkCount === 1 ? "framework" : "framework
171084
171135
  return;
171085
171136
  }
171086
171137
  const sizesDir = resolveSizesDir(args, candidates);
171087
- const manifestPath = join12(sizesDir, "manifest.json");
171088
- if (!existsSync11(manifestPath)) {
171138
+ const manifestPath = join13(sizesDir, "manifest.json");
171139
+ if (!existsSync12(manifestPath)) {
171089
171140
  printDim(`No build at ${relativeOrSelf(manifestPath)}. Run \`absolute build\` first, or pass \`--outdir <dir>\`.`);
171090
171141
  return;
171091
171142
  }
171092
171143
  const sized = withSizes(groups, pageSizer(readManifestSizes(sizesDir)));
171093
171144
  const note = `${relativeOrSelf(manifestPath)} \xB7 built ${manifestAge(manifestPath)} ago`;
171094
171145
  emit(sized, true, note, wantsJson);
171146
+ const budget = parseBudget(args);
171147
+ if (budget !== null && !wantsJson)
171148
+ reportBudget(sized, budget);
171095
171149
  };
171096
171150
  var init_ls = __esm(() => {
171097
171151
  init_scanConventions();
@@ -171117,6 +171171,12 @@ var init_ls = __esm(() => {
171117
171171
  { field: "htmlDirectory", label: "HTML", pattern: "*.html" },
171118
171172
  { field: "htmxDirectory", label: "HTMX", pattern: "*.html" }
171119
171173
  ];
171174
+ SIZE_UNITS = {
171175
+ b: 1,
171176
+ gb: BYTES_PER_KILOBYTE * BYTES_PER_KILOBYTE * BYTES_PER_KILOBYTE,
171177
+ kb: BYTES_PER_KILOBYTE,
171178
+ mb: BYTES_PER_KILOBYTE * BYTES_PER_KILOBYTE
171179
+ };
171120
171180
  });
171121
171181
 
171122
171182
  // src/utils/formatBytes.ts
@@ -171986,6 +172046,1151 @@ var init_mem = __esm(() => {
171986
172046
  HEADERS = ["NAME", "SOURCE", "PORT", "RSS", "% SYS"];
171987
172047
  });
171988
172048
 
172049
+ // src/cli/config/schema/fromType.ts
172050
+ var import_typescript3, cache;
172051
+ var init_fromType = __esm(() => {
172052
+ import_typescript3 = __toESM(require_typescript(), 1);
172053
+ cache = new Map;
172054
+ });
172055
+
172056
+ // src/cli/config/absolute/resolveAbsoluteConfig.ts
172057
+ import { existsSync as existsSync13, readFileSync as readFileSync15 } from "fs";
172058
+ import { resolve as resolve11 } from "path";
172059
+ var import_typescript4, CONFIG_CANDIDATES2, RUNTIME_FIELDS, findConfigPath2 = (cwd, override) => {
172060
+ if (override) {
172061
+ const resolved = resolve11(cwd, override);
172062
+ return existsSync13(resolved) ? resolved : null;
172063
+ }
172064
+ for (const name of CONFIG_CANDIDATES2) {
172065
+ const candidate = resolve11(cwd, name);
172066
+ if (existsSync13(candidate))
172067
+ return candidate;
172068
+ }
172069
+ return null;
172070
+ };
172071
+ var init_resolveAbsoluteConfig = __esm(() => {
172072
+ init_fromType();
172073
+ import_typescript4 = __toESM(require_typescript(), 1);
172074
+ CONFIG_CANDIDATES2 = [
172075
+ "absolute.config.ts",
172076
+ "absolute.config.js",
172077
+ "absolute.config.mjs"
172078
+ ];
172079
+ RUNTIME_FIELDS = new Set([
172080
+ "cwd",
172081
+ "config",
172082
+ "entry",
172083
+ "mode",
172084
+ "incrementalFiles"
172085
+ ]);
172086
+ });
172087
+
172088
+ // src/cli/generate/frameworkKey.ts
172089
+ var FRAMEWORK_KEYS2, isFrameworkKey = (value) => FRAMEWORK_KEYS2.some((key) => key === value);
172090
+ var init_frameworkKey = __esm(() => {
172091
+ FRAMEWORK_KEYS2 = [
172092
+ "angular",
172093
+ "html",
172094
+ "htmx",
172095
+ "react",
172096
+ "svelte",
172097
+ "vue"
172098
+ ];
172099
+ });
172100
+
172101
+ // src/cli/generate/frameworks.ts
172102
+ var ABS = "@absolutejs/absolute", reactDef, svelteDef, vueDef, angularDef, htmlDef, htmxDef, frameworks2;
172103
+ var init_frameworks = __esm(() => {
172104
+ reactDef = {
172105
+ configDirKey: "reactDirectory",
172106
+ kind: "manifest",
172107
+ label: "React",
172108
+ pageImportExtension: null,
172109
+ componentFile: ({ pascal }) => `${pascal}.tsx`,
172110
+ pageFile: ({ pascal }) => `${pascal}.tsx`,
172111
+ routeExpression: (ctx) => `.get('${ctx.route}', () => handleReactPageRequest({ Page: ${ctx.pascal}, index: asset(manifest, '${ctx.indexKey}'), props: { cssPath: asset(manifest, '${ctx.cssAssetKey}') } }))`,
172112
+ routeImports: (ctx) => [
172113
+ { kind: "named", module: ABS, name: "asset" },
172114
+ {
172115
+ kind: "named",
172116
+ module: `${ABS}/react`,
172117
+ name: "handleReactPageRequest"
172118
+ },
172119
+ { kind: "named", module: ctx.pageSpecifier, name: ctx.pascal }
172120
+ ]
172121
+ };
172122
+ svelteDef = {
172123
+ configDirKey: "svelteDirectory",
172124
+ kind: "manifest",
172125
+ label: "Svelte",
172126
+ pageImportExtension: ".svelte",
172127
+ componentFile: ({ pascal }) => `${pascal}.svelte`,
172128
+ pageFile: ({ pascal }) => `${pascal}.svelte`,
172129
+ routeExpression: (ctx) => `.get('${ctx.route}', () => handleSveltePageRequest<typeof ${ctx.pascal}>({ indexPath: asset(manifest, '${ctx.indexKey}'), pagePath: asset(manifest, '${ctx.manifestKey}'), props: { cssPath: asset(manifest, '${ctx.cssAssetKey}') } }))`,
172130
+ routeImports: (ctx) => [
172131
+ { kind: "named", module: ABS, name: "asset" },
172132
+ {
172133
+ kind: "named",
172134
+ module: `${ABS}/svelte`,
172135
+ name: "handleSveltePageRequest"
172136
+ },
172137
+ { kind: "typeDefault", local: ctx.pascal, module: ctx.pageSpecifier }
172138
+ ]
172139
+ };
172140
+ vueDef = {
172141
+ configDirKey: "vueDirectory",
172142
+ kind: "manifest",
172143
+ label: "Vue",
172144
+ pageImportExtension: ".vue",
172145
+ componentFile: ({ pascal }) => `${pascal}.vue`,
172146
+ pageFile: ({ pascal }) => `${pascal}.vue`,
172147
+ routeExpression: (ctx) => `.get('${ctx.route}', () => handleVuePageRequest<typeof ${ctx.pascal}>({ headTag: generateHeadElement({ cssPath: asset(manifest, '${ctx.cssAssetKey}'), title: '${ctx.title}' }), indexPath: asset(manifest, '${ctx.indexKey}'), pagePath: asset(manifest, '${ctx.manifestKey}'), props: {} }))`,
172148
+ routeImports: (ctx) => [
172149
+ { kind: "named", module: ABS, name: "asset" },
172150
+ { kind: "named", module: ABS, name: "generateHeadElement" },
172151
+ { kind: "named", module: `${ABS}/vue`, name: "handleVuePageRequest" },
172152
+ { kind: "typeDefault", local: ctx.pascal, module: ctx.pageSpecifier }
172153
+ ]
172154
+ };
172155
+ angularDef = {
172156
+ configDirKey: "angularDirectory",
172157
+ kind: "manifest",
172158
+ label: "Angular",
172159
+ pageImportExtension: null,
172160
+ componentFile: ({ kebab }) => `${kebab}.component.ts`,
172161
+ pageFile: ({ kebab }) => `${kebab}.ts`,
172162
+ routeExpression: (ctx) => `.get('${ctx.route}', ({ request }) => handleAngularPageRequest<${ctx.pascal}Page.Context>({ headTag: generateHeadElement({ cssPath: asset(manifest, '${ctx.cssAssetKey}'), title: '${ctx.title}' }), indexPath: asset(manifest, '${ctx.indexKey}'), pagePath: asset(manifest, '${ctx.manifestKey}'), request, requestContext: {} }))`,
172163
+ routeImports: (ctx) => [
172164
+ { kind: "named", module: ABS, name: "asset" },
172165
+ { kind: "named", module: ABS, name: "generateHeadElement" },
172166
+ {
172167
+ kind: "named",
172168
+ module: `${ABS}/angular`,
172169
+ name: "handleAngularPageRequest"
172170
+ },
172171
+ {
172172
+ kind: "typeNamespace",
172173
+ local: `${ctx.pascal}Page`,
172174
+ module: ctx.pageSpecifier
172175
+ }
172176
+ ]
172177
+ };
172178
+ htmlDef = {
172179
+ configDirKey: "htmlDirectory",
172180
+ kind: "static",
172181
+ label: "HTML",
172182
+ pageImportExtension: null,
172183
+ componentFile: ({ pascal }) => `${pascal}.html`,
172184
+ pageFile: ({ pascal }) => `${pascal}.html`,
172185
+ routeExpression: (ctx) => `.get('${ctx.route}', () => handleHTMLPageRequest(asset(manifest, '${ctx.manifestKey}')))`,
172186
+ routeImports: () => [
172187
+ { kind: "named", module: ABS, name: "asset" },
172188
+ { kind: "named", module: ABS, name: "handleHTMLPageRequest" }
172189
+ ]
172190
+ };
172191
+ htmxDef = {
172192
+ configDirKey: "htmxDirectory",
172193
+ kind: "static",
172194
+ label: "HTMX",
172195
+ pageImportExtension: null,
172196
+ componentFile: ({ pascal }) => `${pascal}.html`,
172197
+ pageFile: ({ pascal }) => `${pascal}.html`,
172198
+ routeExpression: (ctx) => `.get('${ctx.route}', () => handleHTMXPageRequest(asset(manifest, '${ctx.manifestKey}')))`,
172199
+ routeImports: () => [
172200
+ { kind: "named", module: ABS, name: "asset" },
172201
+ { kind: "named", module: ABS, name: "handleHTMXPageRequest" }
172202
+ ]
172203
+ };
172204
+ frameworks2 = {
172205
+ angular: angularDef,
172206
+ html: htmlDef,
172207
+ htmx: htmxDef,
172208
+ react: reactDef,
172209
+ svelte: svelteDef,
172210
+ vue: vueDef
172211
+ };
172212
+ });
172213
+
172214
+ // src/cli/generate/context.ts
172215
+ import { dirname as dirname4, isAbsolute, join as join14, relative as relative3, resolve as resolve12 } from "path";
172216
+ 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) => {
172217
+ const styles = config.stylesConfig;
172218
+ if (typeof styles === "string")
172219
+ return resolveDir(cwd, styles);
172220
+ if (isRecord3(styles)) {
172221
+ const indexes = asString(styles.indexes);
172222
+ if (indexes)
172223
+ return resolveDir(cwd, indexes);
172224
+ }
172225
+ return resolve12(cwd, "src/frontend/styles/indexes");
172226
+ }, configuredFrameworks = (project) => FRAMEWORK_KEYS2.filter((key) => project.frameworkDirs[key] !== undefined), frontendRootFor = (project, framework) => {
172227
+ const dir = project.frameworkDirs[framework];
172228
+ return dir ? dirname4(dir) : resolve12(project.cwd, "src/frontend");
172229
+ }, resolveProject = async (cwd, configOverride) => {
172230
+ const loaded = await loadConfig(configOverride);
172231
+ const config = isRecord3(loaded) ? loaded : {};
172232
+ const frameworkDirs = {};
172233
+ for (const key of FRAMEWORK_KEYS2) {
172234
+ const dir = asString(config[frameworks2[key].configDirKey]);
172235
+ if (dir)
172236
+ frameworkDirs[key] = resolveDir(cwd, dir);
172237
+ }
172238
+ const entry = asString(config.entry) ?? DEFAULT_SERVER_ENTRY;
172239
+ return {
172240
+ config,
172241
+ configPath: findConfigPath2(cwd, configOverride),
172242
+ cwd,
172243
+ frameworkDirs,
172244
+ serverEntry: resolveDir(cwd, entry),
172245
+ stylesDir: resolveStylesDir(cwd, config)
172246
+ };
172247
+ }, selectFramework = (project, explicit) => {
172248
+ const configured = configuredFrameworks(project);
172249
+ if (explicit !== undefined) {
172250
+ if (!isFrameworkKey(explicit)) {
172251
+ return {
172252
+ message: `Unknown framework "${explicit}".`,
172253
+ ok: false
172254
+ };
172255
+ }
172256
+ if (!configured.includes(explicit)) {
172257
+ return {
172258
+ message: `Framework "${explicit}" is not configured. Add it with \`absolute add ${explicit}\`.`,
172259
+ ok: false
172260
+ };
172261
+ }
172262
+ return { framework: explicit, ok: true };
172263
+ }
172264
+ if (configured.length === 0) {
172265
+ return {
172266
+ message: "No frameworks are configured in absolute.config.ts.",
172267
+ ok: false
172268
+ };
172269
+ }
172270
+ const [only] = configured;
172271
+ if (configured.length === 1 && only) {
172272
+ return { framework: only, ok: true };
172273
+ }
172274
+ return {
172275
+ message: `Multiple frameworks configured (${configured.join(", ")}). Pass --framework <name>.`,
172276
+ ok: false
172277
+ };
172278
+ }, sharedDirFor = (project, framework) => join14(frontendRootFor(project, framework), "shared"), toModuleSpecifier = (fromDir, toFileNoExt) => {
172279
+ const rel = relative3(fromDir, toFileNoExt).split("\\").join("/");
172280
+ return rel.startsWith(".") ? rel : `./${rel}`;
172281
+ };
172282
+ var init_context = __esm(() => {
172283
+ init_loadConfig();
172284
+ init_resolveAbsoluteConfig();
172285
+ init_utils();
172286
+ init_frameworkKey();
172287
+ init_frameworks();
172288
+ });
172289
+
172290
+ // src/cli/generate/naming.ts
172291
+ var tokenize = (raw) => raw.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter((token) => token.length > 0).map((token) => token.toLowerCase()), capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1), isValidName = (raw) => typeof raw === "string" && tokenize(raw).length > 0, toCamelCase = (raw) => {
172292
+ const pascal = toPascalCase(raw);
172293
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
172294
+ }, toKebabCase = (raw) => tokenize(raw).join("-"), toPascalCase = (raw) => tokenize(raw).map(capitalize).join(""), toTitleCase = (raw) => tokenize(raw).map(capitalize).join(" ");
172295
+
172296
+ // src/cli/generate/outcome.ts
172297
+ var emptyOutcome = () => ({
172298
+ created: [],
172299
+ manual: null,
172300
+ notes: [],
172301
+ route: null,
172302
+ updated: []
172303
+ });
172304
+
172305
+ // src/cli/generate/routeWiring.ts
172306
+ import { existsSync as existsSync14, readFileSync as readFileSync16, readdirSync as readdirSync4, writeFileSync as writeFileSync6 } from "fs";
172307
+ import { dirname as dirname5, join as join15 } from "path";
172308
+ var import_typescript5, DEFAULT_SEPARATOR = `
172309
+ `, BOUNDARY_USE, applyEdits = (text, edits) => {
172310
+ const ordered = [...edits].sort((first, second) => second.start - first.start);
172311
+ let output = text;
172312
+ for (const edit of ordered) {
172313
+ output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);
172314
+ }
172315
+ return output;
172316
+ }, stripExtension = (path) => path.replace(/\.[^./\\]+$/, ""), parse2 = (path, text) => import_typescript5.default.createSourceFile(path, text, import_typescript5.default.ScriptTarget.Latest, true), findElysiaNew = (sourceFile) => {
172317
+ let found = null;
172318
+ const visit = (node) => {
172319
+ if (found)
172320
+ return;
172321
+ if (import_typescript5.default.isNewExpression(node) && import_typescript5.default.isIdentifier(node.expression) && node.expression.text === "Elysia") {
172322
+ found = node;
172323
+ return;
172324
+ }
172325
+ import_typescript5.default.forEachChild(node, visit);
172326
+ };
172327
+ visit(sourceFile);
172328
+ return found;
172329
+ }, climbChain = (start2) => {
172330
+ let top = start2;
172331
+ while (import_typescript5.default.isPropertyAccessExpression(top.parent) && top.parent.expression === top && import_typescript5.default.isCallExpression(top.parent.parent) && top.parent.parent.expression === top.parent) {
172332
+ top = top.parent.parent;
172333
+ }
172334
+ return top;
172335
+ }, collectCalls = (top) => {
172336
+ const calls = [];
172337
+ let node = top;
172338
+ while (import_typescript5.default.isCallExpression(node) && import_typescript5.default.isPropertyAccessExpression(node.expression)) {
172339
+ calls.push(node);
172340
+ node = node.expression.expression;
172341
+ }
172342
+ return calls.reverse();
172343
+ }, methodName = (call) => import_typescript5.default.isPropertyAccessExpression(call.expression) ? call.expression.name.text : null, isBoundary = (call) => {
172344
+ const name = methodName(call);
172345
+ const [arg] = call.arguments;
172346
+ if (name === "use" && arg && import_typescript5.default.isIdentifier(arg)) {
172347
+ return BOUNDARY_USE.has(arg.text);
172348
+ }
172349
+ return name === "on" && arg !== undefined && import_typescript5.default.isStringLiteralLike(arg);
172350
+ }, receiverEnd = (call) => import_typescript5.default.isPropertyAccessExpression(call.expression) ? call.expression.expression.getEnd() : call.getEnd(), separatorBefore = (text, offset) => {
172351
+ const match = text.slice(offset).match(/^(\s*\n[ \t]*)\./);
172352
+ return match ? match[1] : DEFAULT_SEPARATOR;
172353
+ }, findRouteInsertion = (text, top) => {
172354
+ const calls = collectCalls(top);
172355
+ const boundary = calls.find(isBoundary);
172356
+ if (boundary) {
172357
+ const offset2 = receiverEnd(boundary);
172358
+ return { offset: offset2, separator: separatorBefore(text, offset2) };
172359
+ }
172360
+ const last = calls[calls.length - 1];
172361
+ const offset = last ? last.getEnd() : top.getEnd();
172362
+ const sepProbe = last ? receiverEnd(last) : top.getEnd();
172363
+ return { offset, separator: separatorBefore(text, sepProbe) };
172364
+ }, namedImportDecl = (sourceFile, module) => sourceFile.statements.find((statement) => import_typescript5.default.isImportDeclaration(statement) && import_typescript5.default.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === module && statement.importClause !== undefined && !statement.importClause.isTypeOnly && statement.importClause.namedBindings !== undefined && import_typescript5.default.isNamedImports(statement.importClause.namedBindings)), importedNames = (decl) => {
172365
+ const bindings = decl.importClause?.namedBindings;
172366
+ if (!bindings || !import_typescript5.default.isNamedImports(bindings))
172367
+ return new Set;
172368
+ return new Set(bindings.elements.map((element) => (element.propertyName ?? element.name).text));
172369
+ }, lastImportEnd = (sourceFile) => {
172370
+ let end = 0;
172371
+ for (const statement of sourceFile.statements) {
172372
+ if (import_typescript5.default.isImportDeclaration(statement))
172373
+ end = statement.getEnd();
172374
+ }
172375
+ return end;
172376
+ }, hasTypeImport = (sourceFile, module, local) => sourceFile.statements.some((statement) => import_typescript5.default.isImportDeclaration(statement) && import_typescript5.default.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === module && statement.getText().includes(local)), renderTypeImport = (spec) => {
172377
+ if (spec.kind === "typeDefault") {
172378
+ return `import type ${spec.local} from '${spec.module}';`;
172379
+ }
172380
+ if (spec.kind === "typeNamespace") {
172381
+ return `import type * as ${spec.local} from '${spec.module}';`;
172382
+ }
172383
+ return "";
172384
+ }, groupNamed = (specs) => {
172385
+ const byModule = new Map;
172386
+ for (const spec of specs) {
172387
+ if (spec.kind !== "named")
172388
+ continue;
172389
+ const set = byModule.get(spec.module) ?? new Set;
172390
+ set.add(spec.name);
172391
+ byModule.set(spec.module, set);
172392
+ }
172393
+ return byModule;
172394
+ }, mergeNamedEdit = (decl, sourceFile, missing) => {
172395
+ const bindings = decl.importClause?.namedBindings;
172396
+ if (!bindings || !import_typescript5.default.isNamedImports(bindings))
172397
+ return null;
172398
+ const { elements } = bindings;
172399
+ const additions = missing.join(", ");
172400
+ if (elements.length === 0) {
172401
+ const insertAt2 = bindings.getStart(sourceFile) + 1;
172402
+ return { end: insertAt2, start: insertAt2, text: additions };
172403
+ }
172404
+ const last = elements[elements.length - 1];
172405
+ if (!last)
172406
+ return null;
172407
+ const insertAt = last.getEnd();
172408
+ return { end: insertAt, start: insertAt, text: `, ${additions}` };
172409
+ }, missingNamesEdit = (decl, sourceFile, names) => {
172410
+ const existing = importedNames(decl);
172411
+ const missing = [...names].filter((name) => !existing.has(name));
172412
+ return missing.length ? mergeNamedEdit(decl, sourceFile, missing) : null;
172413
+ }, buildImportEdits = (sourceFile, specs) => {
172414
+ const edits = [];
172415
+ const newLines = [];
172416
+ for (const [module, names] of groupNamed(specs)) {
172417
+ const decl = namedImportDecl(sourceFile, module);
172418
+ const edit = decl ? missingNamesEdit(decl, sourceFile, names) : null;
172419
+ if (edit)
172420
+ edits.push(edit);
172421
+ const fresh = `import { ${[...names].join(", ")} } from '${module}';`;
172422
+ if (!decl)
172423
+ newLines.push(fresh);
172424
+ }
172425
+ for (const spec of specs) {
172426
+ if (spec.kind === "named")
172427
+ continue;
172428
+ if (hasTypeImport(sourceFile, spec.module, spec.local))
172429
+ continue;
172430
+ newLines.push(renderTypeImport(spec));
172431
+ }
172432
+ if (newLines.length > 0) {
172433
+ const insertAt = lastImportEnd(sourceFile);
172434
+ edits.push({
172435
+ end: insertAt,
172436
+ start: insertAt,
172437
+ text: `
172438
+ ${newLines.join(`
172439
+ `)}`
172440
+ });
172441
+ }
172442
+ return edits;
172443
+ }, renderImportBlock = (specs) => {
172444
+ const lines = [];
172445
+ for (const [module, names] of groupNamed(specs)) {
172446
+ lines.push(`import { ${[...names].join(", ")} } from '${module}';`);
172447
+ }
172448
+ for (const spec of specs) {
172449
+ if (spec.kind !== "named")
172450
+ lines.push(renderTypeImport(spec));
172451
+ }
172452
+ return lines.join(`
172453
+ `);
172454
+ }, hasChain = (path) => {
172455
+ if (!existsSync14(path))
172456
+ return false;
172457
+ const sourceFile = parse2(path, readFileSync16(path, "utf-8"));
172458
+ const found = findElysiaNew(sourceFile);
172459
+ return found !== null;
172460
+ }, firstChainFile = (pluginsDir) => {
172461
+ if (!existsSync14(pluginsDir))
172462
+ return null;
172463
+ for (const name of readdirSync4(pluginsDir)) {
172464
+ if (!name.endsWith(".ts"))
172465
+ continue;
172466
+ const candidate = join15(pluginsDir, name);
172467
+ if (hasChain(candidate))
172468
+ return candidate;
172469
+ }
172470
+ return null;
172471
+ }, findRoutingFile = (serverEntry) => {
172472
+ const pluginsDir = join15(dirname5(serverEntry), "plugins");
172473
+ const preferred = join15(pluginsDir, "pagesPlugin.ts");
172474
+ if (hasChain(preferred))
172475
+ return preferred;
172476
+ const scanned = firstChainFile(pluginsDir);
172477
+ if (scanned)
172478
+ return scanned;
172479
+ if (hasChain(serverEntry))
172480
+ return serverEntry;
172481
+ return null;
172482
+ }, buildRouteContext = (input, routingFile) => {
172483
+ const specifier = `${toModuleSpecifier(dirname5(routingFile), stripExtension(input.pageFileAbs))}${input.def.pageImportExtension ?? ""}`;
172484
+ return {
172485
+ cssAssetKey: input.cssAssetKey,
172486
+ indexKey: input.indexKey,
172487
+ manifestKey: input.manifestKey,
172488
+ pageSpecifier: specifier,
172489
+ pascal: input.pascal,
172490
+ route: input.route,
172491
+ title: input.title
172492
+ };
172493
+ }, wirePluginUse = (serverEntry, pluginName, moduleSpecifier) => {
172494
+ const specs = [
172495
+ { kind: "named", module: moduleSpecifier, name: pluginName }
172496
+ ];
172497
+ const fallback = {
172498
+ kind: "manual",
172499
+ reason: "could not find an Elysia chain in the server entry",
172500
+ snippet: `import { ${pluginName} } from '${moduleSpecifier}';
172501
+
172502
+ .use(${pluginName})`
172503
+ };
172504
+ if (!hasChain(serverEntry))
172505
+ return fallback;
172506
+ const text = readFileSync16(serverEntry, "utf-8");
172507
+ const sourceFile = parse2(serverEntry, text);
172508
+ const newExpr = findElysiaNew(sourceFile);
172509
+ if (!newExpr)
172510
+ return fallback;
172511
+ const top = climbChain(newExpr);
172512
+ const { offset, separator } = findRouteInsertion(text, top);
172513
+ const edits = buildImportEdits(sourceFile, specs);
172514
+ edits.push({
172515
+ end: offset,
172516
+ start: offset,
172517
+ text: `${separator}.use(${pluginName})`
172518
+ });
172519
+ writeFileSync6(serverEntry, applyEdits(text, edits), "utf-8");
172520
+ return { kind: "edited", routingFile: serverEntry };
172521
+ }, wireRoute = (input) => {
172522
+ const routingFile = findRoutingFile(input.serverEntry);
172523
+ const ctx = routingFile ? buildRouteContext(input, routingFile) : buildRouteContext(input, input.serverEntry);
172524
+ const specs = input.def.routeImports(ctx);
172525
+ const routeExpr = input.def.routeExpression(ctx);
172526
+ if (!routingFile) {
172527
+ return {
172528
+ kind: "manual",
172529
+ reason: "could not find an Elysia route chain",
172530
+ snippet: `${renderImportBlock(specs)}
172531
+
172532
+ ${routeExpr}`
172533
+ };
172534
+ }
172535
+ const text = readFileSync16(routingFile, "utf-8");
172536
+ const sourceFile = parse2(routingFile, text);
172537
+ const newExpr = findElysiaNew(sourceFile);
172538
+ if (!newExpr) {
172539
+ return {
172540
+ kind: "manual",
172541
+ reason: "could not find an Elysia route chain",
172542
+ snippet: `${renderImportBlock(specs)}
172543
+
172544
+ ${routeExpr}`
172545
+ };
172546
+ }
172547
+ const top = climbChain(newExpr);
172548
+ const { offset, separator } = findRouteInsertion(text, top);
172549
+ const edits = buildImportEdits(sourceFile, specs);
172550
+ edits.push({
172551
+ end: offset,
172552
+ start: offset,
172553
+ text: `${separator}${routeExpr}`
172554
+ });
172555
+ writeFileSync6(routingFile, applyEdits(text, edits), "utf-8");
172556
+ return { kind: "edited", routingFile };
172557
+ };
172558
+ var init_routeWiring = __esm(() => {
172559
+ init_context();
172560
+ import_typescript5 = __toESM(require_typescript(), 1);
172561
+ BOUNDARY_USE = new Set(["absolutejs", "networking"]);
172562
+ });
172563
+
172564
+ // src/cli/generate/generateApi.ts
172565
+ import { existsSync as existsSync15, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "fs";
172566
+ import { dirname as dirname6, join as join16 } from "path";
172567
+ var apiPluginTemplate = (pluginName, base) => `import { Elysia } from 'elysia';
172568
+
172569
+ export const ${pluginName} = new Elysia()
172570
+ .get('${base}', () => [])
172571
+ .post('${base}', ({ body }) => body);
172572
+ `, generateApi = (project, rawName) => {
172573
+ const camel = toCamelCase(rawName);
172574
+ const kebab = toKebabCase(rawName);
172575
+ const pluginName = `${camel}Plugin`;
172576
+ const base = `/api/${kebab}`;
172577
+ const outcome = { ...emptyOutcome(), route: base };
172578
+ const pluginsDir = join16(dirname6(project.serverEntry), "plugins");
172579
+ const fileAbs = join16(pluginsDir, `${pluginName}.ts`);
172580
+ if (existsSync15(fileAbs)) {
172581
+ outcome.notes.push(`${pluginName} already exists at ${fileAbs} \u2014 skipped.`);
172582
+ return outcome;
172583
+ }
172584
+ mkdirSync7(pluginsDir, { recursive: true });
172585
+ writeFileSync7(fileAbs, apiPluginTemplate(pluginName, base), "utf-8");
172586
+ outcome.created.push(fileAbs);
172587
+ const specifier = toModuleSpecifier(dirname6(project.serverEntry), fileAbs.replace(/\.ts$/, ""));
172588
+ const wired = wirePluginUse(project.serverEntry, pluginName, specifier);
172589
+ if (wired.kind === "edited")
172590
+ outcome.updated.push(wired.routingFile);
172591
+ else
172592
+ outcome.manual = { reason: wired.reason, snippet: wired.snippet };
172593
+ return outcome;
172594
+ };
172595
+ var init_generateApi = __esm(() => {
172596
+ init_context();
172597
+ init_routeWiring();
172598
+ });
172599
+
172600
+ // src/cli/generate/componentTemplates.ts
172601
+ var reactComponent = (ctx) => `type ${ctx.pascal}Props = {
172602
+ label: string;
172603
+ };
172604
+
172605
+ export const ${ctx.pascal} = ({ label }: ${ctx.pascal}Props) => (
172606
+ <button type="button">{label}</button>
172607
+ );
172608
+ `, svelteComponent = (ctx) => `<script lang="ts">
172609
+ type ${ctx.pascal}Props = {
172610
+ label: string;
172611
+ };
172612
+
172613
+ let { label }: ${ctx.pascal}Props = $props();
172614
+ </script>
172615
+
172616
+ <button type="button">{label}</button>
172617
+ `, vueComponent = () => `<script setup lang="ts">
172618
+ defineProps<{
172619
+ label: string;
172620
+ }>();
172621
+ </script>
172622
+
172623
+ <template>
172624
+ <button type="button">{{ label }}</button>
172625
+ </template>
172626
+ `, angularComponent = (ctx) => `import { Component, input } from '@angular/core';
172627
+
172628
+ @Component({
172629
+ selector: 'app-${ctx.kebab}',
172630
+ standalone: true,
172631
+ template: \`<button type="button">{{ label() }}</button>\`
172632
+ })
172633
+ export class ${ctx.pascal}Component {
172634
+ label = input('');
172635
+ }
172636
+ `, htmlComponent = (ctx) => `<button type="button">${ctx.title}</button>
172637
+ `, htmxComponent = (ctx) => `<button type="button" hx-get="/api/${ctx.kebab}" hx-swap="outerHTML">
172638
+ ${ctx.title}
172639
+ </button>
172640
+ `, componentTemplates;
172641
+ var init_componentTemplates = __esm(() => {
172642
+ componentTemplates = {
172643
+ angular: angularComponent,
172644
+ html: htmlComponent,
172645
+ htmx: htmxComponent,
172646
+ react: reactComponent,
172647
+ svelte: svelteComponent,
172648
+ vue: vueComponent
172649
+ };
172650
+ });
172651
+
172652
+ // src/cli/generate/generateComponent.ts
172653
+ import { existsSync as existsSync16, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
172654
+ import { dirname as dirname7, join as join17 } from "path";
172655
+ var generateComponent = (project, framework, rawName) => {
172656
+ const def = frameworks2[framework];
172657
+ const pascal = toPascalCase(rawName);
172658
+ const kebab = toKebabCase(rawName);
172659
+ const outcome = emptyOutcome();
172660
+ const frameworkDir = project.frameworkDirs[framework];
172661
+ if (!frameworkDir) {
172662
+ outcome.manual = { reason: "framework directory missing", snippet: "" };
172663
+ return outcome;
172664
+ }
172665
+ const fileAbs = join17(frameworkDir, "components", def.componentFile({ kebab, pascal }));
172666
+ if (existsSync16(fileAbs)) {
172667
+ outcome.notes.push(`${pascal} already exists at ${fileAbs} \u2014 skipped.`);
172668
+ return outcome;
172669
+ }
172670
+ mkdirSync8(dirname7(fileAbs), { recursive: true });
172671
+ writeFileSync8(fileAbs, componentTemplates[framework]({
172672
+ kebab,
172673
+ pascal,
172674
+ title: toTitleCase(rawName)
172675
+ }), "utf-8");
172676
+ outcome.created.push(fileAbs);
172677
+ return outcome;
172678
+ };
172679
+ var init_generateComponent = __esm(() => {
172680
+ init_componentTemplates();
172681
+ init_frameworks();
172682
+ });
172683
+
172684
+ // src/cli/generate/cssStrategy.ts
172685
+ import { existsSync as existsSync17 } from "fs";
172686
+ import { join as join18 } from "path";
172687
+ var import_typescript6, CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
172688
+ margin: 0 auto;
172689
+ max-width: 64rem;
172690
+ padding: 2rem;
172691
+ }
172692
+ `, cssAssetArg = (node) => {
172693
+ if (!import_typescript6.default.isCallExpression(node) || !import_typescript6.default.isIdentifier(node.expression) || node.expression.text !== "asset") {
172694
+ return null;
172695
+ }
172696
+ const [, arg] = node.arguments;
172697
+ if (arg && import_typescript6.default.isStringLiteralLike(arg) && arg.text.endsWith(CSS_SUFFIX)) {
172698
+ return arg.text;
172699
+ }
172700
+ return null;
172701
+ }, detectSharedKey = (routingText) => {
172702
+ const sourceFile = import_typescript6.default.createSourceFile("routing.ts", routingText, import_typescript6.default.ScriptTarget.Latest, true);
172703
+ let hoisted = null;
172704
+ const inlineCounts = new Map;
172705
+ const visit = (node) => {
172706
+ const key = cssAssetArg(node);
172707
+ if (key) {
172708
+ if (import_typescript6.default.isVariableDeclaration(node.parent))
172709
+ hoisted ??= key;
172710
+ else
172711
+ inlineCounts.set(key, (inlineCounts.get(key) ?? 0) + 1);
172712
+ }
172713
+ import_typescript6.default.forEachChild(node, visit);
172714
+ };
172715
+ visit(sourceFile);
172716
+ if (hoisted)
172717
+ return hoisted;
172718
+ for (const [key, count] of inlineCounts) {
172719
+ if (count >= SHARED_MIN_USES)
172720
+ return key;
172721
+ }
172722
+ return null;
172723
+ }, fileForKey = (stylesDir, assetKey) => {
172724
+ const base = assetKey.endsWith(CSS_SUFFIX) ? assetKey.slice(0, -CSS_SUFFIX.length) : assetKey;
172725
+ return join18(stylesDir, `${toKebabCase(base)}.css`);
172726
+ }, planCss = (routingText, stylesDir, pascal, kebab) => {
172727
+ const sharedKey = detectSharedKey(routingText);
172728
+ if (sharedKey) {
172729
+ const cssFileAbs2 = fileForKey(stylesDir, sharedKey);
172730
+ return {
172731
+ assetKey: sharedKey,
172732
+ contents: DEFAULT_CSS,
172733
+ create: !existsSync17(cssFileAbs2),
172734
+ cssFileAbs: cssFileAbs2,
172735
+ shared: true
172736
+ };
172737
+ }
172738
+ const cssFileAbs = join18(stylesDir, `${kebab}.css`);
172739
+ return {
172740
+ assetKey: `${pascal}${CSS_SUFFIX}`,
172741
+ contents: DEFAULT_CSS,
172742
+ create: !existsSync17(cssFileAbs),
172743
+ cssFileAbs,
172744
+ shared: false
172745
+ };
172746
+ };
172747
+ var init_cssStrategy = __esm(() => {
172748
+ import_typescript6 = __toESM(require_typescript(), 1);
172749
+ });
172750
+
172751
+ // src/cli/generate/navData.ts
172752
+ import { existsSync as existsSync18, mkdirSync as mkdirSync9, readFileSync as readFileSync17, writeFileSync as writeFileSync9 } from "fs";
172753
+ import { dirname as dirname8 } from "path";
172754
+ var import_typescript7, NAV_DATA_TEMPLATE = `type NavItem = {
172755
+ href: string;
172756
+ label: string;
172757
+ };
172758
+
172759
+ export const navData: NavItem[] = [];
172760
+ `, findNavArray = (sourceFile) => {
172761
+ let found = null;
172762
+ const visit = (node) => {
172763
+ if (found)
172764
+ return;
172765
+ if (import_typescript7.default.isVariableDeclaration(node) && import_typescript7.default.isIdentifier(node.name) && node.name.text === "navData" && node.initializer && import_typescript7.default.isArrayLiteralExpression(node.initializer)) {
172766
+ found = node.initializer;
172767
+ return;
172768
+ }
172769
+ import_typescript7.default.forEachChild(node, visit);
172770
+ };
172771
+ visit(sourceFile);
172772
+ return found;
172773
+ }, readStringProperty = (object, name) => {
172774
+ const property = object.properties.find((candidate) => import_typescript7.default.isPropertyAssignment(candidate) && import_typescript7.default.isIdentifier(candidate.name) && candidate.name.text === name);
172775
+ if (!property || !import_typescript7.default.isStringLiteralLike(property.initializer)) {
172776
+ return null;
172777
+ }
172778
+ return property.initializer.text;
172779
+ }, parseNavItems = (array) => {
172780
+ const items = [];
172781
+ for (const element of array.elements) {
172782
+ if (!import_typescript7.default.isObjectLiteralExpression(element))
172783
+ continue;
172784
+ const href = readStringProperty(element, "href");
172785
+ const label = readStringProperty(element, "label");
172786
+ if (href !== null && label !== null)
172787
+ items.push({ href, label });
172788
+ }
172789
+ return items;
172790
+ }, readNavItems = (navDataPath) => {
172791
+ if (!existsSync18(navDataPath))
172792
+ return [];
172793
+ const text = readFileSync17(navDataPath, "utf-8");
172794
+ const sourceFile = import_typescript7.default.createSourceFile(navDataPath, text, import_typescript7.default.ScriptTarget.Latest, true);
172795
+ const array = findNavArray(sourceFile);
172796
+ return array ? parseNavItems(array) : [];
172797
+ }, indentOf = (text, position) => {
172798
+ let index = position;
172799
+ while (index > 0 && text[index - 1] !== `
172800
+ `)
172801
+ index -= 1;
172802
+ let end = index;
172803
+ while (text[end] === " " || text[end] === "\t")
172804
+ end += 1;
172805
+ return text.slice(index, end);
172806
+ }, insertElement = (text, array, sourceFile, entry) => {
172807
+ const { elements } = array;
172808
+ if (elements.length === 0) {
172809
+ const insertAt2 = array.getStart(sourceFile) + 1;
172810
+ const indent2 = `${indentOf(text, array.getStart(sourceFile))} `;
172811
+ const insertion2 = `
172812
+ ${indent2}${entry}
172813
+ ${indentOf(text, array.getStart(sourceFile))}`;
172814
+ return text.slice(0, insertAt2) + insertion2 + text.slice(insertAt2);
172815
+ }
172816
+ const last = elements[elements.length - 1];
172817
+ if (!last)
172818
+ return text;
172819
+ const indent = indentOf(text, last.getStart(sourceFile));
172820
+ let insertAt = last.getEnd();
172821
+ const hasComma = text[insertAt] === ",";
172822
+ if (hasComma)
172823
+ insertAt += 1;
172824
+ const insertion = `${hasComma ? "" : ","}
172825
+ ${indent}${entry}`;
172826
+ return text.slice(0, insertAt) + insertion + text.slice(insertAt);
172827
+ }, upsertNavItem = (navDataPath, item) => {
172828
+ const created = !existsSync18(navDataPath);
172829
+ if (created) {
172830
+ mkdirSync9(dirname8(navDataPath), { recursive: true });
172831
+ writeFileSync9(navDataPath, NAV_DATA_TEMPLATE, "utf-8");
172832
+ }
172833
+ const existing = readNavItems(navDataPath);
172834
+ if (existing.some((candidate) => candidate.href === item.href)) {
172835
+ return { changed: created, created, items: existing };
172836
+ }
172837
+ const text = readFileSync17(navDataPath, "utf-8");
172838
+ const sourceFile = import_typescript7.default.createSourceFile(navDataPath, text, import_typescript7.default.ScriptTarget.Latest, true);
172839
+ const array = findNavArray(sourceFile);
172840
+ if (!array)
172841
+ return { changed: created, created, items: existing };
172842
+ const entry = `{ href: '${item.href}', label: '${item.label}' }`;
172843
+ writeFileSync9(navDataPath, insertElement(text, array, sourceFile, entry), "utf-8");
172844
+ return { changed: true, created, items: [...existing, item] };
172845
+ };
172846
+ var init_navData = __esm(() => {
172847
+ import_typescript7 = __toESM(require_typescript(), 1);
172848
+ });
172849
+
172850
+ // src/cli/generate/staticNav.ts
172851
+ var NAV_MARKER_END = "<!-- /absolute:nav -->", NAV_MARKER_START = "<!-- absolute:nav -->", escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), indentBefore = (text, position) => {
172852
+ let index = position;
172853
+ while (index > 0 && text[index - 1] !== `
172854
+ `)
172855
+ index -= 1;
172856
+ return text.slice(index, position);
172857
+ }, renderNavBlock = (items, indent) => {
172858
+ const links = items.map((item) => `${indent} <a href="${escapeHtml(item.href)}">${escapeHtml(item.label)}</a>`).join(`
172859
+ `);
172860
+ const body = links.length > 0 ? `
172861
+ ${links}
172862
+ ${indent}` : "";
172863
+ return `${NAV_MARKER_START}
172864
+ ${indent}<nav>${body}</nav>
172865
+ ${indent}${NAV_MARKER_END}`;
172866
+ }, syncStaticNav = (html, items) => {
172867
+ const startIdx = html.indexOf(NAV_MARKER_START);
172868
+ const endIdx = html.indexOf(NAV_MARKER_END);
172869
+ if (startIdx < 0 || endIdx < 0 || endIdx < startIdx)
172870
+ return null;
172871
+ const indent = indentBefore(html, startIdx);
172872
+ const end = endIdx + NAV_MARKER_END.length;
172873
+ return html.slice(0, startIdx) + renderNavBlock(items, indent) + html.slice(end);
172874
+ };
172875
+
172876
+ // src/cli/generate/pageTemplates.ts
172877
+ var reactPage = (ctx) => `import { Head } from '@absolutejs/absolute/react/components';
172878
+ import { navData } from '${ctx.navImportPath}';
172879
+
172880
+ type ${ctx.pascal}Props = {
172881
+ cssPath?: string;
172882
+ };
172883
+
172884
+ export const ${ctx.pascal} = ({ cssPath }: ${ctx.pascal}Props) => (
172885
+ <html lang="en">
172886
+ <Head cssPath={cssPath} title="${ctx.title}" />
172887
+ <body>
172888
+ <nav>
172889
+ {navData.map((item) => (
172890
+ <a key={item.href} href={item.href}>
172891
+ {item.label}
172892
+ </a>
172893
+ ))}
172894
+ </nav>
172895
+ <main>
172896
+ <h1>${ctx.title}</h1>
172897
+ </main>
172898
+ </body>
172899
+ </html>
172900
+ );
172901
+ `, sveltePage = (ctx) => `<script lang="ts">
172902
+ import { navData } from '${ctx.navImportPath}';
172903
+
172904
+ type ${ctx.pascal}Props = {
172905
+ cssPath?: string;
172906
+ };
172907
+
172908
+ let { cssPath }: ${ctx.pascal}Props = $props();
172909
+ </script>
172910
+
172911
+ <svelte:head>
172912
+ {#if cssPath}
172913
+ <link rel="stylesheet" href={cssPath} />
172914
+ {/if}
172915
+ <title>${ctx.title}</title>
172916
+ </svelte:head>
172917
+
172918
+ <nav>
172919
+ {#each navData as item (item.href)}
172920
+ <a href={item.href}>{item.label}</a>
172921
+ {/each}
172922
+ </nav>
172923
+
172924
+ <main>
172925
+ <h1>${ctx.title}</h1>
172926
+ </main>
172927
+ `, vuePage = (ctx) => `<script setup lang="ts">
172928
+ import { navData } from '${ctx.navImportPath}';
172929
+ </script>
172930
+
172931
+ <template>
172932
+ <nav>
172933
+ <a v-for="item in navData" :key="item.href" :href="item.href">
172934
+ {{ item.label }}
172935
+ </a>
172936
+ </nav>
172937
+ <main>
172938
+ <h1>${ctx.title}</h1>
172939
+ </main>
172940
+ </template>
172941
+ `, angularPage = (ctx) => `import { Component } from '@angular/core';
172942
+ import { navData } from '${ctx.navImportPath}';
172943
+
172944
+ // This page has no per-request DI context, so the SSR handler's
172945
+ // \`requestContext\` is an empty object.
172946
+ export type Context = Record<string, never>;
172947
+
172948
+ @Component({
172949
+ imports: [],
172950
+ selector: '${ctx.kebab}-page',
172951
+ standalone: true,
172952
+ template: \`
172953
+ <nav>
172954
+ @for (item of navItems; track item.href) {
172955
+ <a [href]="item.href">{{ item.label }}</a>
172956
+ }
172957
+ </nav>
172958
+ <main>
172959
+ <h1>${ctx.title}</h1>
172960
+ </main>
172961
+ \`
172962
+ })
172963
+ export class ${ctx.pascal}Component {
172964
+ navItems = navData;
172965
+ }
172966
+ `, htmlHead = (ctx, extraHead) => `<!doctype html>
172967
+ <html lang="en">
172968
+ <head>
172969
+ <meta charset="utf-8" />
172970
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
172971
+ <title>${ctx.title}</title>
172972
+ <link rel="stylesheet" href="${ctx.cssHref}" />${extraHead}
172973
+ </head>
172974
+ <body>
172975
+ ${renderNavBlock(ctx.navItems, "\t\t")}
172976
+ <main>
172977
+ <h1>${ctx.title}</h1>
172978
+ </main>
172979
+ </body>
172980
+ </html>
172981
+ `, htmlPage = (ctx) => htmlHead(ctx, ""), htmxPage = (ctx) => htmlHead(ctx, `
172982
+ <script src="/htmx/htmx.min.js"></script>`), pageTemplates;
172983
+ var init_pageTemplates = __esm(() => {
172984
+ pageTemplates = {
172985
+ angular: angularPage,
172986
+ html: htmlPage,
172987
+ htmx: htmxPage,
172988
+ react: reactPage,
172989
+ svelte: sveltePage,
172990
+ vue: vuePage
172991
+ };
172992
+ });
172993
+
172994
+ // src/cli/generate/generatePage.ts
172995
+ import {
172996
+ existsSync as existsSync19,
172997
+ mkdirSync as mkdirSync10,
172998
+ readFileSync as readFileSync18,
172999
+ readdirSync as readdirSync5,
173000
+ writeFileSync as writeFileSync10
173001
+ } from "fs";
173002
+ import { dirname as dirname9, join as join19, relative as relative4 } from "path";
173003
+ var writeNew = (path, contents) => {
173004
+ mkdirSync10(dirname9(path), { recursive: true });
173005
+ writeFileSync10(path, contents, "utf-8");
173006
+ }, toHref = (fromDir, toFile) => {
173007
+ const rel = relative4(fromDir, toFile).split("\\").join("/");
173008
+ return rel.startsWith(".") ? rel : `./${rel}`;
173009
+ }, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join19(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync19(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join19(pagesDir, name))), resyncPage = (file, items) => {
173010
+ const html = readFileSync18(file, "utf-8");
173011
+ const synced = syncStaticNav(html, items);
173012
+ if (synced === null || synced === html)
173013
+ return false;
173014
+ writeFileSync10(file, synced, "utf-8");
173015
+ return true;
173016
+ }, resyncStaticPages = (project, items, skipFile) => {
173017
+ const updated = [];
173018
+ for (const file of staticPageFiles(project)) {
173019
+ if (file === skipFile)
173020
+ continue;
173021
+ if (resyncPage(file, items))
173022
+ updated.push(file);
173023
+ }
173024
+ return updated;
173025
+ }, generatePage = (project, framework, rawName) => {
173026
+ const def = frameworks2[framework];
173027
+ const pascal = toPascalCase(rawName);
173028
+ const kebab = toKebabCase(rawName);
173029
+ const title = toTitleCase(rawName);
173030
+ const route = `/${kebab}`;
173031
+ const frameworkDir = project.frameworkDirs[framework];
173032
+ const outcome = { ...emptyOutcome(), route };
173033
+ if (!frameworkDir) {
173034
+ outcome.manual = { reason: "framework directory missing", snippet: "" };
173035
+ return outcome;
173036
+ }
173037
+ const pageFileAbs = join19(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
173038
+ if (existsSync19(pageFileAbs)) {
173039
+ outcome.notes.push(`${pascal} already exists at ${pageFileAbs} \u2014 skipped.`);
173040
+ return outcome;
173041
+ }
173042
+ const routingFile = findRoutingFile(project.serverEntry);
173043
+ const routingText = routingFile ? readFileSync18(routingFile, "utf-8") : "";
173044
+ const css = planCss(routingText, project.stylesDir, pascal, kebab);
173045
+ const navDataPath = join19(sharedDirFor(project, framework), "navData.ts");
173046
+ const nav = upsertNavItem(navDataPath, { href: route, label: title });
173047
+ const navImportPath = toModuleSpecifier(dirname9(pageFileAbs), navDataPath.replace(/\.ts$/, ""));
173048
+ writeNew(pageFileAbs, pageTemplates[framework]({
173049
+ cssHref: toHref(dirname9(pageFileAbs), css.cssFileAbs),
173050
+ kebab,
173051
+ navImportPath,
173052
+ navItems: nav.items,
173053
+ pascal,
173054
+ title
173055
+ }));
173056
+ outcome.created.push(pageFileAbs);
173057
+ if (css.create) {
173058
+ writeNew(css.cssFileAbs, css.contents);
173059
+ outcome.created.push(css.cssFileAbs);
173060
+ } else if (css.shared) {
173061
+ outcome.notes.push(`Reusing shared stylesheet ${css.assetKey}.`);
173062
+ }
173063
+ if (nav.created)
173064
+ outcome.created.push(navDataPath);
173065
+ else if (nav.changed)
173066
+ outcome.updated.push(navDataPath);
173067
+ outcome.updated.push(...resyncStaticPages(project, nav.items, pageFileAbs));
173068
+ const wired = wireRoute({
173069
+ cssAssetKey: css.assetKey,
173070
+ def,
173071
+ indexKey: `${pascal}Index`,
173072
+ manifestKey: pascal,
173073
+ pageFileAbs,
173074
+ pascal,
173075
+ route,
173076
+ serverEntry: project.serverEntry,
173077
+ title
173078
+ });
173079
+ if (wired.kind === "edited")
173080
+ outcome.updated.push(wired.routingFile);
173081
+ else
173082
+ outcome.manual = { reason: wired.reason, snippet: wired.snippet };
173083
+ return outcome;
173084
+ };
173085
+ var init_generatePage = __esm(() => {
173086
+ init_context();
173087
+ init_cssStrategy();
173088
+ init_frameworks();
173089
+ init_navData();
173090
+ init_pageTemplates();
173091
+ init_routeWiring();
173092
+ });
173093
+
173094
+ // src/cli/scripts/generate.ts
173095
+ var exports_generate = {};
173096
+ __export(exports_generate, {
173097
+ runGenerate: () => runGenerate
173098
+ });
173099
+ import { relative as relative5 } from "path";
173100
+ var SUBCOMMANDS, write = (text) => process.stdout.write(`${text}
173101
+ `), fail = (message) => {
173102
+ process.stdout.write(`${colors.red}${message}${colors.reset}
173103
+ `);
173104
+ process.exitCode = 1;
173105
+ }, readArgs = (args) => {
173106
+ const consumed = new Set;
173107
+ const valueFlags = ["--config", "--framework"];
173108
+ for (const flag of valueFlags) {
173109
+ const idx = args.indexOf(flag);
173110
+ if (idx < 0)
173111
+ continue;
173112
+ consumed.add(idx);
173113
+ consumed.add(idx + 1);
173114
+ }
173115
+ const positionals = args.filter((value, idx) => !consumed.has(idx) && !value.startsWith("--"));
173116
+ const flagValue = (flag) => {
173117
+ const idx = args.indexOf(flag);
173118
+ return idx >= 0 ? args[idx + 1] : undefined;
173119
+ };
173120
+ return {
173121
+ config: flagValue("--config"),
173122
+ framework: flagValue("--framework"),
173123
+ name: positionals[1],
173124
+ subcommand: positionals[0]
173125
+ };
173126
+ }, printList = (label, paths, cwd) => {
173127
+ if (paths.length === 0)
173128
+ return;
173129
+ write(` ${colors.dim}${label}${colors.reset}`);
173130
+ for (const path of paths)
173131
+ write(` ${relative5(cwd, path)}`);
173132
+ }, printSummary = (title, outcome, cwd) => {
173133
+ for (const note of outcome.notes) {
173134
+ write(`${colors.yellow}!${colors.reset} ${note}`);
173135
+ }
173136
+ if (outcome.created.length === 0 && outcome.updated.length === 0)
173137
+ return;
173138
+ write(`${colors.green}\u2713${colors.reset} Generated ${title}
173139
+ `);
173140
+ printList("Created", outcome.created, cwd);
173141
+ printList("Updated", outcome.updated, cwd);
173142
+ if (outcome.route)
173143
+ write(`
173144
+ ${colors.dim}Route${colors.reset} ${outcome.route}`);
173145
+ if (outcome.manual) {
173146
+ write(`
173147
+ ${colors.yellow}Couldn't auto-wire the route${colors.reset} (${outcome.manual.reason}). Add manually:
173148
+ `);
173149
+ for (const line of outcome.manual.snippet.split(`
173150
+ `))
173151
+ write(` ${line}`);
173152
+ }
173153
+ write(`
173154
+ ${colors.dim}Next${colors.reset} run \`absolute prettier --write\` to format edits, then \`absolute dev\``);
173155
+ }, runGenerate = async (args) => {
173156
+ const { config, framework, name, subcommand } = readArgs(args);
173157
+ if (!subcommand || !SUBCOMMANDS.has(subcommand)) {
173158
+ fail("Usage: absolute generate <page|api|component> <name> [--framework <name>]");
173159
+ return;
173160
+ }
173161
+ if (!isValidName(name)) {
173162
+ fail(`Provide a name, e.g. \`absolute generate ${subcommand} dashboard\`.`);
173163
+ return;
173164
+ }
173165
+ const cwd = process.cwd();
173166
+ let project;
173167
+ try {
173168
+ project = await resolveProject(cwd, config);
173169
+ } catch (error) {
173170
+ fail(error instanceof Error ? error.message : String(error));
173171
+ return;
173172
+ }
173173
+ if (subcommand === "api") {
173174
+ printSummary(`api ${name}`, generateApi(project, name), cwd);
173175
+ return;
173176
+ }
173177
+ const selected = selectFramework(project, framework);
173178
+ if (!selected.ok) {
173179
+ fail(selected.message);
173180
+ return;
173181
+ }
173182
+ const outcome = subcommand === "page" ? generatePage(project, selected.framework, name) : generateComponent(project, selected.framework, name);
173183
+ printSummary(`${subcommand} ${name} (${selected.framework})`, outcome, cwd);
173184
+ };
173185
+ var init_generate = __esm(() => {
173186
+ init_context();
173187
+ init_generateApi();
173188
+ init_generateComponent();
173189
+ init_generatePage();
173190
+ init_tuiPrimitives();
173191
+ SUBCOMMANDS = new Set(["api", "component", "page"]);
173192
+ });
173193
+
171989
173194
  // src/cli/scripts/env.ts
171990
173195
  var exports_env = {};
171991
173196
  __export(exports_env, {
@@ -171993,15 +173198,15 @@ __export(exports_env, {
171993
173198
  runEnv: () => runEnv,
171994
173199
  collectEnvVars: () => collectEnvVars
171995
173200
  });
171996
- import { existsSync as existsSync12, readFileSync as readFileSync14 } from "fs";
171997
- import { join as join13 } from "path";
173201
+ import { existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
173202
+ import { join as join20 } from "path";
171998
173203
  var {env: env3, Glob: Glob3 } = globalThis.Bun;
171999
- var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH, keysInFile = (text) => [...text.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync12(join13(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
173204
+ var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH, keysInFile = (text) => [...text.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync20(join20(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
172000
173205
  const scans = scanPatterns().map((pattern) => Array.fromAsync(new Glob3(pattern).scan({ cwd: process.cwd() })));
172001
173206
  const files = (await Promise.all(scans)).flat();
172002
173207
  const usage = new Map;
172003
173208
  files.forEach((file) => {
172004
- keysInFile(readFileSync14(file, "utf-8")).forEach((key) => {
173209
+ keysInFile(readFileSync19(file, "utf-8")).forEach((key) => {
172005
173210
  usage.set(key, [...usage.get(key) ?? [], file]);
172006
173211
  });
172007
173212
  });
@@ -172059,7 +173264,7 @@ __export(exports_logs, {
172059
173264
  });
172060
173265
  import {
172061
173266
  closeSync as closeSync2,
172062
- existsSync as existsSync13,
173267
+ existsSync as existsSync21,
172063
173268
  openSync as openSync4,
172064
173269
  readSync as readSync2,
172065
173270
  statSync as statSync2,
@@ -172126,7 +173331,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
172126
173331
  printAvailable(instances);
172127
173332
  return;
172128
173333
  }
172129
- if (match.logFile === null || !existsSync13(match.logFile)) {
173334
+ if (match.logFile === null || !existsSync21(match.logFile)) {
172130
173335
  printDim2(`"${name}" has no captured log (untracked, or started outside the CLI).`);
172131
173336
  return;
172132
173337
  }
@@ -172149,10 +173354,10 @@ var exports_doctor = {};
172149
173354
  __export(exports_doctor, {
172150
173355
  runDoctor: () => runDoctor
172151
173356
  });
172152
- import { existsSync as existsSync14 } from "fs";
173357
+ import { existsSync as existsSync22 } from "fs";
172153
173358
  import { createRequire } from "module";
172154
173359
  import { arch as arch4, platform as platform5 } from "os";
172155
- import { join as join14 } from "path";
173360
+ import { join as join21 } from "path";
172156
173361
  var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
172157
173362
  detail,
172158
173363
  label,
@@ -172187,7 +173392,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
172187
173392
  return [];
172188
173393
  const label = `${field.replace("Directory", "")} pages`;
172189
173394
  return [
172190
- existsSync14(join14(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
173395
+ existsSync22(join21(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
172191
173396
  ];
172192
173397
  }), envCheck = async () => {
172193
173398
  const vars = await collectEnvVars();
@@ -172257,7 +173462,7 @@ var init_doctor = __esm(() => {
172257
173462
  "htmlDirectory",
172258
173463
  "htmxDirectory"
172259
173464
  ];
172260
- projectRequire = createRequire(join14(process.cwd(), "package.json"));
173465
+ projectRequire = createRequire(join21(process.cwd(), "package.json"));
172261
173466
  STATUS_MARK = {
172262
173467
  fail: `${colors.red}\u2717${colors.reset}`,
172263
173468
  ok: `${colors.green}\u2713${colors.reset}`,
@@ -172265,14 +173470,86 @@ var init_doctor = __esm(() => {
172265
173470
  };
172266
173471
  });
172267
173472
 
173473
+ // src/cli/scripts/routes.ts
173474
+ var exports_routes = {};
173475
+ __export(exports_routes, {
173476
+ runRoutes: () => runRoutes
173477
+ });
173478
+ var METHOD_COLOR, printDim3 = (message) => {
173479
+ process.stdout.write(`${colors.dim}${message}${colors.reset}
173480
+ `);
173481
+ }, pickServer = (instances) => {
173482
+ const withUrl = instances.filter((instance) => instance.url !== null);
173483
+ return withUrl.find((instance) => instance.source === "dev") ?? withUrl.find((instance) => instance.source !== "untracked") ?? withUrl[0];
173484
+ }, fetchRoutes = async (url) => {
173485
+ try {
173486
+ const response = await fetch(`${url}__absolute/routes`);
173487
+ if (!response.ok)
173488
+ return null;
173489
+ const data = await response.json();
173490
+ if (!Array.isArray(data))
173491
+ return null;
173492
+ return data.map((entry) => ({
173493
+ method: String(entry.method ?? "").toUpperCase(),
173494
+ path: String(entry.path ?? "")
173495
+ }));
173496
+ } catch {
173497
+ return null;
173498
+ }
173499
+ }, runRoutes = async (args) => {
173500
+ const instances = await enrichInstances(await discoverInstances());
173501
+ const server2 = pickServer(instances);
173502
+ if (!server2 || server2.url === null) {
173503
+ printDim3("No running server found. Start one with `absolute dev`, then run `absolute routes`.");
173504
+ return;
173505
+ }
173506
+ const routes = await fetchRoutes(server2.url);
173507
+ if (!routes) {
173508
+ printDim3(`Could not read routes from ${server2.name} \u2014 route introspection needs a dev server.`);
173509
+ return;
173510
+ }
173511
+ const sorted = routes.filter((route) => route.path !== "/__absolute/routes").sort((left, right) => left.path.localeCompare(right.path) || left.method.localeCompare(right.method));
173512
+ if (args.includes("--json")) {
173513
+ process.stdout.write(`${JSON.stringify(sorted, null, 2)}
173514
+ `);
173515
+ return;
173516
+ }
173517
+ if (sorted.length === 0) {
173518
+ printDim3("No routes registered.");
173519
+ return;
173520
+ }
173521
+ const methodWidth = Math.max(...sorted.map((route) => route.method.length));
173522
+ const lines = sorted.map((route) => {
173523
+ const color = METHOD_COLOR[route.method] ?? colors.dim;
173524
+ return ` ${color}${padLine(route.method, methodWidth)}${colors.reset} ${route.path}`;
173525
+ });
173526
+ process.stdout.write(`${lines.join(`
173527
+ `)}
173528
+
173529
+ ${colors.dim}${sorted.length} routes \xB7 ${server2.name}${colors.reset}
173530
+ `);
173531
+ };
173532
+ var init_routes = __esm(() => {
173533
+ init_discoverInstances();
173534
+ init_instanceStatus();
173535
+ init_tuiPrimitives();
173536
+ METHOD_COLOR = {
173537
+ DELETE: colors.red,
173538
+ GET: colors.green,
173539
+ PATCH: colors.yellow,
173540
+ POST: colors.cyan,
173541
+ PUT: colors.yellow
173542
+ };
173543
+ });
173544
+
172268
173545
  // src/build/externalAssetPlugin.ts
172269
- import { copyFileSync as copyFileSync2, existsSync as existsSync15, mkdirSync as mkdirSync7, statSync as statSync3 } from "fs";
172270
- import { basename as basename6, dirname as dirname4, join as join15, resolve as resolve11 } from "path";
173546
+ import { copyFileSync as copyFileSync2, existsSync as existsSync23, mkdirSync as mkdirSync11, statSync as statSync3 } from "fs";
173547
+ import { basename as basename6, dirname as dirname10, join as join22, resolve as resolve13 } from "path";
172271
173548
  var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
172272
173549
  name: "absolute-external-asset",
172273
173550
  setup(bld) {
172274
173551
  const urlPattern = /new\s+URL\(\s*["'](\.\.?\/[^"']+)["']\s*,\s*import\.meta\.url\s*\)/g;
172275
- const skipRoots = userSourceRoots.map((root) => resolve11(root));
173552
+ const skipRoots = userSourceRoots.map((root) => resolve13(root));
172276
173553
  const isUserSource = (path) => skipRoots.some((root) => path.startsWith(`${root}/`));
172277
173554
  bld.onLoad({ filter: /\.[mc]?[jt]sx?$/ }, async (args) => {
172278
173555
  if (isUserSource(args.path))
@@ -172282,20 +173559,20 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
172282
173559
  return;
172283
173560
  urlPattern.lastIndex = 0;
172284
173561
  let match;
172285
- const sourceDir = dirname4(args.path);
173562
+ const sourceDir = dirname10(args.path);
172286
173563
  while ((match = urlPattern.exec(source)) !== null) {
172287
173564
  const relPath = match[1];
172288
173565
  if (!relPath)
172289
173566
  continue;
172290
- const assetPath = resolve11(sourceDir, relPath);
172291
- if (!existsSync15(assetPath))
173567
+ const assetPath = resolve13(sourceDir, relPath);
173568
+ if (!existsSync23(assetPath))
172292
173569
  continue;
172293
173570
  if (!statSync3(assetPath).isFile())
172294
173571
  continue;
172295
- const targetPath = join15(outDir, basename6(assetPath));
172296
- if (existsSync15(targetPath))
173572
+ const targetPath = join22(outDir, basename6(assetPath));
173573
+ if (existsSync23(targetPath))
172297
173574
  continue;
172298
- mkdirSync7(dirname4(targetPath), { recursive: true });
173575
+ mkdirSync11(dirname10(targetPath), { recursive: true });
172299
173576
  copyFileSync2(assetPath, targetPath);
172300
173577
  }
172301
173578
  return;
@@ -172313,16 +173590,16 @@ __export(exports_compile, {
172313
173590
  var {env: env4 } = globalThis.Bun;
172314
173591
  import {
172315
173592
  cpSync,
172316
- existsSync as existsSync16,
172317
- mkdirSync as mkdirSync8,
172318
- readdirSync as readdirSync3,
172319
- readFileSync as readFileSync15,
173593
+ existsSync as existsSync24,
173594
+ mkdirSync as mkdirSync12,
173595
+ readdirSync as readdirSync6,
173596
+ readFileSync as readFileSync20,
172320
173597
  rmSync as rmSync5,
172321
173598
  statSync as statSync4,
172322
173599
  unlinkSync as unlinkSync4,
172323
- writeFileSync as writeFileSync6
173600
+ writeFileSync as writeFileSync11
172324
173601
  } from "fs";
172325
- import { basename as basename7, dirname as dirname5, join as join16, relative as relative3, resolve as resolve12 } from "path";
173602
+ import { basename as basename7, dirname as dirname11, join as join23, relative as relative6, resolve as resolve14 } from "path";
172326
173603
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
172327
173604
  const resolvedVersion = version2 || "unknown";
172328
173605
  console.log("");
@@ -172330,14 +173607,14 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172330
173607
  console.log("");
172331
173608
  }, collectFiles2 = (dir) => {
172332
173609
  const result = [];
172333
- let pending = readdirSync3(dir, { withFileTypes: true });
173610
+ let pending = readdirSync6(dir, { withFileTypes: true });
172334
173611
  while (pending.length > 0) {
172335
173612
  const entry = pending.pop();
172336
173613
  if (!entry)
172337
173614
  continue;
172338
- const fullPath = join16(entry.parentPath, entry.name);
173615
+ const fullPath = join23(entry.parentPath, entry.name);
172339
173616
  if (entry.isDirectory())
172340
- pending = pending.concat(readdirSync3(fullPath, { withFileTypes: true }));
173617
+ pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
172341
173618
  else
172342
173619
  result.push(fullPath);
172343
173620
  }
@@ -172350,16 +173627,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172350
173627
  return `./${parts.join("/")}`;
172351
173628
  }, collectProjectSourceFiles = (dir) => {
172352
173629
  const result = [];
172353
- let pending = readdirSync3(dir, { withFileTypes: true });
173630
+ let pending = readdirSync6(dir, { withFileTypes: true });
172354
173631
  while (pending.length > 0) {
172355
173632
  const entry = pending.pop();
172356
173633
  if (!entry)
172357
173634
  continue;
172358
- const fullPath = join16(entry.parentPath, entry.name);
173635
+ const fullPath = join23(entry.parentPath, entry.name);
172359
173636
  if (entry.isDirectory()) {
172360
173637
  if (SERVER_RUNTIME_SCAN_SKIP_DIRS.has(entry.name))
172361
173638
  continue;
172362
- pending = pending.concat(readdirSync3(fullPath, { withFileTypes: true }));
173639
+ pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
172363
173640
  } else if (hasSourceExtension(fullPath)) {
172364
173641
  result.push(fullPath);
172365
173642
  }
@@ -172367,22 +173644,22 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172367
173644
  return result;
172368
173645
  }, copyServerRuntimeAssetReferences = (outdir) => {
172369
173646
  const copied = new Set;
172370
- const normalizedOutdir = resolve12(outdir);
173647
+ const normalizedOutdir = resolve14(outdir);
172371
173648
  const copyReference = (filePath, relPath) => {
172372
- const assetSource = resolve12(dirname5(filePath), relPath);
172373
- if (!existsSync16(assetSource) || !statSync4(assetSource).isFile())
173649
+ const assetSource = resolve14(dirname11(filePath), relPath);
173650
+ if (!existsSync24(assetSource) || !statSync4(assetSource).isFile())
172374
173651
  return;
172375
- const assetTarget = resolve12(normalizedOutdir, relPath.replace(/^\.\//, ""));
173652
+ const assetTarget = resolve14(normalizedOutdir, relPath.replace(/^\.\//, ""));
172376
173653
  if (assetTarget !== normalizedOutdir && !assetTarget.startsWith(`${normalizedOutdir}/`))
172377
173654
  return;
172378
173655
  if (copied.has(assetTarget))
172379
173656
  return;
172380
173657
  copied.add(assetTarget);
172381
- mkdirSync8(dirname5(assetTarget), { recursive: true });
173658
+ mkdirSync12(dirname11(assetTarget), { recursive: true });
172382
173659
  cpSync(assetSource, assetTarget, { force: true });
172383
173660
  };
172384
173661
  for (const filePath of collectProjectSourceFiles(process.cwd())) {
172385
- const source = readFileSync15(filePath, "utf-8");
173662
+ const source = readFileSync20(filePath, "utf-8");
172386
173663
  SERVER_RUNTIME_ASSET_RE.lastIndex = 0;
172387
173664
  let match;
172388
173665
  while ((match = SERVER_RUNTIME_ASSET_RE.exec(source)) !== null) {
@@ -172411,7 +173688,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172411
173688
  }
172412
173689
  }, readPackageVersion4 = (candidate) => {
172413
173690
  try {
172414
- const pkg = JSON.parse(readFileSync15(candidate, "utf-8"));
173691
+ const pkg = JSON.parse(readFileSync20(candidate, "utf-8"));
172415
173692
  if (pkg.name !== "@absolutejs/absolute")
172416
173693
  return null;
172417
173694
  const ver = pkg.version;
@@ -172446,18 +173723,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172446
173723
  return resolveBuildModule3(remaining);
172447
173724
  }, resolveJsxDevRuntimeCompatPath2 = () => {
172448
173725
  const candidates = [
172449
- resolve12(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
172450
- resolve12(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
172451
- resolve12(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
172452
- resolve12(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
172453
- resolve12(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
172454
- resolve12(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
173726
+ resolve14(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
173727
+ resolve14(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
173728
+ resolve14(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
173729
+ resolve14(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
173730
+ resolve14(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
173731
+ resolve14(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
172455
173732
  ];
172456
173733
  for (const candidate of candidates) {
172457
- if (existsSync16(candidate))
173734
+ if (existsSync24(candidate))
172458
173735
  return candidate;
172459
173736
  }
172460
- return resolve12(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
173737
+ return resolve14(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
172461
173738
  }, jsxDevRuntimeCompatPath2, shouldEmbedCompiledAsset = (relativePath, skip = new Set) => {
172462
173739
  if (skip.has(relativePath))
172463
173740
  return false;
@@ -172470,11 +173747,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172470
173747
  return true;
172471
173748
  }, tryReadNodePackageJson = (packageDir) => {
172472
173749
  try {
172473
- return JSON.parse(readFileSync15(join16(packageDir, "package.json"), "utf-8"));
173750
+ return JSON.parse(readFileSync20(join23(packageDir, "package.json"), "utf-8"));
172474
173751
  } catch {
172475
173752
  return null;
172476
173753
  }
172477
- }, resolveProjectPackageDir = (specifier) => resolve12(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
173754
+ }, resolveProjectPackageDir = (specifier) => resolve14(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
172478
173755
  if (seen.has(specifier))
172479
173756
  return;
172480
173757
  const srcDir = resolveProjectPackageDir(specifier);
@@ -172482,13 +173759,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172482
173759
  if (!pkg)
172483
173760
  return;
172484
173761
  seen.add(specifier);
172485
- const destDir = join16(outdir, "node_modules", ...specifier.split("/"));
173762
+ const destDir = join23(outdir, "node_modules", ...specifier.split("/"));
172486
173763
  rmSync5(destDir, { force: true, recursive: true });
172487
173764
  cpSync(srcDir, destDir, {
172488
173765
  force: true,
172489
173766
  recursive: true,
172490
173767
  filter(source) {
172491
- const rel = relative3(srcDir, source);
173768
+ const rel = relative6(srcDir, source);
172492
173769
  const [firstSegment] = rel.split(/[\\/]/);
172493
173770
  return firstSegment !== "node_modules" && firstSegment !== ".git";
172494
173771
  }
@@ -172504,8 +173781,8 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172504
173781
  }, copyAngularRuntimePackages = (buildConfig, outdir) => {
172505
173782
  if (!buildConfig.angularDirectory)
172506
173783
  return;
172507
- const angularScopeDir = resolve12(process.cwd(), "node_modules", "@angular");
172508
- const angularPackages = existsSync16(angularScopeDir) ? readdirSync3(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
173784
+ const angularScopeDir = resolve14(process.cwd(), "node_modules", "@angular");
173785
+ const angularPackages = existsSync24(angularScopeDir) ? readdirSync6(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
172509
173786
  const roots = new Set([...angularPackages, "rxjs", "tslib", "typescript"]);
172510
173787
  const seen = new Set;
172511
173788
  for (const specifier of roots) {
@@ -172522,16 +173799,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172522
173799
  }
172523
173800
  copyAngularRuntimePackages(buildConfig, outdir);
172524
173801
  }, collectRuntimePackageSpecifiers = (distDir) => {
172525
- const nodeModulesDir = join16(distDir, "node_modules");
172526
- if (!existsSync16(nodeModulesDir))
173802
+ const nodeModulesDir = join23(distDir, "node_modules");
173803
+ if (!existsSync24(nodeModulesDir))
172527
173804
  return [];
172528
173805
  const specifiers = [];
172529
- for (const entry of readdirSync3(nodeModulesDir, { withFileTypes: true })) {
173806
+ for (const entry of readdirSync6(nodeModulesDir, { withFileTypes: true })) {
172530
173807
  if (!entry.isDirectory())
172531
173808
  continue;
172532
173809
  if (entry.name.startsWith("@")) {
172533
- const scopeDir = join16(nodeModulesDir, entry.name);
172534
- for (const scopedEntry of readdirSync3(scopeDir, {
173810
+ const scopeDir = join23(nodeModulesDir, entry.name);
173811
+ for (const scopedEntry of readdirSync6(scopeDir, {
172535
173812
  withFileTypes: true
172536
173813
  })) {
172537
173814
  if (scopedEntry.isDirectory()) {
@@ -172544,7 +173821,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172544
173821
  }
172545
173822
  return specifiers.sort((a, b) => b.length - a.length);
172546
173823
  }, ensureRelativeModuleSpecifier = (fromFile, toFile) => {
172547
- const rel = relative3(dirname5(fromFile), toFile).replace(/\\/g, "/");
173824
+ const rel = relative6(dirname11(fromFile), toFile).replace(/\\/g, "/");
172548
173825
  return rel.startsWith(".") ? rel : `./${rel}`;
172549
173826
  }, pickExportEntry = (value) => {
172550
173827
  if (typeof value === "string")
@@ -172562,18 +173839,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172562
173839
  const packageSpecifier = packageSpecifiers.find((root) => specifier === root || specifier.startsWith(`${root}/`));
172563
173840
  if (!packageSpecifier)
172564
173841
  return null;
172565
- const packageDir = join16(distDir, "node_modules", ...packageSpecifier.split("/"));
173842
+ const packageDir = join23(distDir, "node_modules", ...packageSpecifier.split("/"));
172566
173843
  const subpath = specifier.slice(packageSpecifier.length);
172567
- const subPackageDir = subpath ? join16(packageDir, ...subpath.slice(1).split("/")) : null;
172568
- const resolvedPackageDir = subPackageDir && existsSync16(join16(subPackageDir, "package.json")) ? subPackageDir : packageDir;
172569
- const packageJsonPath = join16(resolvedPackageDir, "package.json");
172570
- if (!existsSync16(packageJsonPath))
173844
+ const subPackageDir = subpath ? join23(packageDir, ...subpath.slice(1).split("/")) : null;
173845
+ const resolvedPackageDir = subPackageDir && existsSync24(join23(subPackageDir, "package.json")) ? subPackageDir : packageDir;
173846
+ const packageJsonPath = join23(resolvedPackageDir, "package.json");
173847
+ if (!existsSync24(packageJsonPath))
172571
173848
  return null;
172572
- const pkg = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
173849
+ const pkg = JSON.parse(readFileSync20(packageJsonPath, "utf-8"));
172573
173850
  const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
172574
173851
  const rootExport = pkg.exports?.[exportKey];
172575
173852
  const entry = pickExportEntry(rootExport) ?? (resolvedPackageDir === subPackageDir || !subpath ? pkg.module ?? pkg.main ?? "index.js" : `.${subpath}`);
172576
- return join16(resolvedPackageDir, entry);
173853
+ return join23(resolvedPackageDir, entry);
172577
173854
  }, 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) => {
172578
173855
  try {
172579
173856
  return statSync4(filePath).isFile();
@@ -172586,16 +173863,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172586
173863
  const candidates = [
172587
173864
  candidate,
172588
173865
  ...RUNTIME_JS_EXTENSIONS.map((extension) => `${candidate}${extension}`),
172589
- ...RUNTIME_JS_EXTENSIONS.map((extension) => join16(candidate, `index${extension}`))
173866
+ ...RUNTIME_JS_EXTENSIONS.map((extension) => join23(candidate, `index${extension}`))
172590
173867
  ];
172591
173868
  return candidates.find((filePath) => isRuntimeJsFile(filePath) && isFile(filePath)) ?? null;
172592
173869
  }, findContainingRuntimePackageDir = (filePath) => {
172593
- let dir = dirname5(filePath);
172594
- while (dir !== dirname5(dir)) {
172595
- if (isNodeModulesPath(dir) && existsSync16(join16(dir, "package.json"))) {
173870
+ let dir = dirname11(filePath);
173871
+ while (dir !== dirname11(dir)) {
173872
+ if (isNodeModulesPath(dir) && existsSync24(join23(dir, "package.json"))) {
172596
173873
  return dir;
172597
173874
  }
172598
- dir = dirname5(dir);
173875
+ dir = dirname11(dir);
172599
173876
  }
172600
173877
  return null;
172601
173878
  }, resolvePackageImportEntryFile = (fromFile, specifier) => {
@@ -172608,7 +173885,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172608
173885
  const entry = pickExportEntry(pkg?.imports?.[specifier]);
172609
173886
  if (!entry)
172610
173887
  return null;
172611
- return join16(packageDir, entry);
173888
+ return join23(packageDir, entry);
172612
173889
  }, collectRuntimeRewriteRoots = (distDir) => collectFiles2(distDir).filter((filePath) => isRuntimeJsFile(filePath) && !isNodeModulesPath(filePath)), rewriteRuntimeModuleSpecifiers = (distDir) => {
172613
173890
  const packageSpecifiers = collectRuntimePackageSpecifiers(distDir);
172614
173891
  if (packageSpecifiers.length === 0)
@@ -172627,10 +173904,10 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172627
173904
  if (!filePath || seen.has(filePath))
172628
173905
  continue;
172629
173906
  seen.add(filePath);
172630
- const source = readFileSync15(filePath, "utf-8");
173907
+ const source = readFileSync20(filePath, "utf-8");
172631
173908
  const rewritten = source.replace(MODULE_SPECIFIER_RE, (match, prefix, quote, specifier) => {
172632
173909
  if (typeof specifier === "string" && specifier.startsWith(".")) {
172633
- enqueue(resolveRuntimeJsFile(resolve12(dirname5(filePath), specifier)));
173910
+ enqueue(resolveRuntimeJsFile(resolve14(dirname11(filePath), specifier)));
172634
173911
  return match;
172635
173912
  }
172636
173913
  const packageImportTarget = resolveRuntimeJsFile(resolvePackageImportEntryFile(filePath, specifier) ?? "");
@@ -172645,7 +173922,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172645
173922
  return `${prefix}${quote}${ensureRelativeModuleSpecifier(filePath, target)}${quote}`;
172646
173923
  });
172647
173924
  if (rewritten !== source) {
172648
- writeFileSync6(filePath, rewritten);
173925
+ writeFileSync11(filePath, rewritten);
172649
173926
  }
172650
173927
  }
172651
173928
  }, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2, buildConfig) => {
@@ -172658,25 +173935,25 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172658
173935
  "_compile_entrypoint.ts"
172659
173936
  ]);
172660
173937
  const embeddedFiles = allFiles.filter((file) => {
172661
- const rel = relative3(distDir, file);
173938
+ const rel = relative6(distDir, file);
172662
173939
  if (embeddedSkip.has(rel))
172663
173940
  return false;
172664
173941
  return true;
172665
173942
  });
172666
- const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative3(distDir, file), assetSkip));
173943
+ const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative6(distDir, file), assetSkip));
172667
173944
  const imports = [];
172668
173945
  const embeddedMappings = [];
172669
173946
  const mappings = [];
172670
173947
  const embeddedVarMap = new Map;
172671
173948
  embeddedFiles.forEach((filePath, idx) => {
172672
- const rel = relative3(distDir, filePath).replace(/\\/g, "/");
173949
+ const rel = relative6(distDir, filePath).replace(/\\/g, "/");
172673
173950
  const varName = `__a${idx}`;
172674
173951
  embeddedVarMap.set(rel, varName);
172675
173952
  imports.push(`import ${varName} from "./${rel}" with { type: "file" };`);
172676
173953
  embeddedMappings.push(` ["${rel}", ${varName}],`);
172677
173954
  });
172678
173955
  clientFiles.forEach((filePath) => {
172679
- const rel = relative3(distDir, filePath).replace(/\\/g, "/");
173956
+ const rel = relative6(distDir, filePath).replace(/\\/g, "/");
172680
173957
  const varName = embeddedVarMap.get(rel);
172681
173958
  if (!varName)
172682
173959
  return;
@@ -172690,7 +173967,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172690
173967
  const pageVarMap = new Map;
172691
173968
  const prerenderEntries = Array.from(prerenderMap.entries());
172692
173969
  prerenderEntries.forEach(([route, filePath]) => {
172693
- const rel = relative3(distDir, filePath).replace(/\\/g, "/");
173970
+ const rel = relative6(distDir, filePath).replace(/\\/g, "/");
172694
173971
  const varName = embeddedVarMap.get(rel);
172695
173972
  if (varName)
172696
173973
  pageVarMap.set(route, varName);
@@ -172719,7 +173996,7 @@ import { websocket as elysiaWebsocket } from "elysia/ws";
172719
173996
  const SERVER_MODULE = (runtimeDir: string) => import(pathToFileURL(join(runtimeDir, ${JSON.stringify(serverBundleName)})).href);
172720
173997
  const RUNTIME_BUILD_ID = ${JSON.stringify(runtimeBuildId)};
172721
173998
  const RUNTIME_CONFIG_SOURCE = ${JSON.stringify(runtimeConfigSource)};
172722
- const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve12(distDir))};
173999
+ const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve14(distDir))};
172723
174000
  const ORIGINAL_BUILD_DIR_NORMALIZED = ORIGINAL_BUILD_DIR.replace(/\\\\/g, "/");
172724
174001
 
172725
174002
  // \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
@@ -173097,16 +174374,16 @@ console.log(\`
173097
174374
  }),
173098
174375
  ...collectUserServerExternals(buildConfig)
173099
174376
  ], compile = async (serverEntry, outdir, outfile, configPath2) => {
173100
- const resolvedOutdir = resolve12(outdir ?? "dist");
174377
+ const resolvedOutdir = resolve14(outdir ?? "dist");
173101
174378
  await withBuildDirectoryLock(resolvedOutdir, () => compileUnlocked(serverEntry, resolvedOutdir, outfile, configPath2));
173102
174379
  }, compileUnlocked = async (serverEntry, resolvedOutdir, outfile, configPath2) => {
173103
174380
  const prerenderPort = Number(env4.COMPILE_PORT) || Number(env4.PORT) || DEFAULT_PORT + 1;
173104
174381
  killStaleProcesses(prerenderPort);
173105
174382
  const entryName = basename7(serverEntry).replace(/\.[^.]+$/, "");
173106
- const resolvedOutfile = resolve12(outfile ?? "compiled-server");
174383
+ const resolvedOutfile = resolve14(outfile ?? "compiled-server");
173107
174384
  const absoluteVersion = resolvePackageVersion3([
173108
- resolve12(import.meta.dir, "..", "..", "..", "package.json"),
173109
- resolve12(import.meta.dir, "..", "..", "package.json")
174385
+ resolve14(import.meta.dir, "..", "..", "..", "package.json"),
174386
+ resolve14(import.meta.dir, "..", "..", "package.json")
173110
174387
  ]);
173111
174388
  compileBanner(absoluteVersion);
173112
174389
  const totalStart = performance.now();
@@ -173117,8 +174394,8 @@ console.log(\`
173117
174394
  buildConfig.mode = "production";
173118
174395
  try {
173119
174396
  const build2 = await resolveBuildModule3([
173120
- resolve12(import.meta.dir, "..", "..", "core", "build"),
173121
- resolve12(import.meta.dir, "..", "build")
174397
+ resolve14(import.meta.dir, "..", "..", "core", "build"),
174398
+ resolve14(import.meta.dir, "..", "build")
173122
174399
  ]);
173123
174400
  if (!build2)
173124
174401
  throw new Error("Could not locate build module");
@@ -173140,10 +174417,10 @@ console.log(\`
173140
174417
  buildConfig.htmxDirectory
173141
174418
  ].filter((dir) => Boolean(dir));
173142
174419
  const islandRegistrySpec = buildConfig.islands?.registry;
173143
- const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve12(islandRegistrySpec))) : undefined;
174420
+ const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve14(islandRegistrySpec))) : undefined;
173144
174421
  const serverBundle = await Bun.build({
173145
174422
  define: { "process.env.NODE_ENV": '"production"' },
173146
- entrypoints: [resolve12(serverEntry)],
174423
+ entrypoints: [resolve14(serverEntry)],
173147
174424
  external: resolveServerBundleExternals(buildConfig),
173148
174425
  outdir: resolvedOutdir,
173149
174426
  plugins: [
@@ -173164,14 +174441,14 @@ console.log(\`
173164
174441
  console.error(cliTag4("\x1B[31m", "Server bundle failed."));
173165
174442
  process.exit(1);
173166
174443
  }
173167
- const outputPath = resolve12(resolvedOutdir, `${entryName}.js`);
173168
- if (!existsSync16(outputPath)) {
174444
+ const outputPath = resolve14(resolvedOutdir, `${entryName}.js`);
174445
+ if (!existsSync24(outputPath)) {
173169
174446
  console.error(cliTag4("\x1B[31m", `Expected output not found: ${outputPath}`));
173170
174447
  process.exit(1);
173171
174448
  }
173172
- if (existsSync16(resolve12(resolvedOutdir, "angular", "vendor", "server"))) {
173173
- const vendorDir = resolve12(resolvedOutdir, "angular", "vendor", "server");
173174
- const vendorEntries = readdirSync3(vendorDir).filter((f) => f.endsWith(".js"));
174449
+ if (existsSync24(resolve14(resolvedOutdir, "angular", "vendor", "server"))) {
174450
+ const vendorDir = resolve14(resolvedOutdir, "angular", "vendor", "server");
174451
+ const vendorEntries = readdirSync6(vendorDir).filter((f) => f.endsWith(".js"));
173175
174452
  const angularServerVendorPaths = {};
173176
174453
  for (const file of vendorEntries) {
173177
174454
  const stem = file.replace(/\.js$/, "");
@@ -173179,7 +174456,7 @@ console.log(\`
173179
174456
  if (scope !== "angular" || rest.length === 0)
173180
174457
  continue;
173181
174458
  const specifier = `@angular/${rest.join("/")}`;
173182
- const relPath = relative3(dirname5(outputPath), resolve12(vendorDir, file));
174459
+ const relPath = relative6(dirname11(outputPath), resolve14(vendorDir, file));
173183
174460
  angularServerVendorPaths[specifier] = relPath.startsWith(".") ? relPath : `./${relPath}`;
173184
174461
  }
173185
174462
  if (Object.keys(angularServerVendorPaths).length > 0) {
@@ -173191,7 +174468,7 @@ console.log(\`
173191
174468
  copyServerRuntimeAssetReferences(resolvedOutdir);
173192
174469
  const prerenderStart = performance.now();
173193
174470
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
173194
- rmSync5(join16(resolvedOutdir, "_prerendered"), {
174471
+ rmSync5(join23(resolvedOutdir, "_prerendered"), {
173195
174472
  force: true,
173196
174473
  recursive: true
173197
174474
  });
@@ -173210,9 +174487,9 @@ console.log(\`
173210
174487
  const compileStart = performance.now();
173211
174488
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
173212
174489
  const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
173213
- const entrypointPath = join16(resolvedOutdir, "_compile_entrypoint.ts");
174490
+ const entrypointPath = join23(resolvedOutdir, "_compile_entrypoint.ts");
173214
174491
  await Bun.write(entrypointPath, entrypointCode);
173215
- mkdirSync8(dirname5(resolvedOutfile), { recursive: true });
174492
+ mkdirSync12(dirname11(resolvedOutfile), { recursive: true });
173216
174493
  const result = await Bun.build({
173217
174494
  compile: { outfile: resolvedOutfile },
173218
174495
  define: { "process.env.NODE_ENV": '"production"' },
@@ -173306,11 +174583,11 @@ var exports_typecheck = {};
173306
174583
  __export(exports_typecheck, {
173307
174584
  typecheck: () => typecheck
173308
174585
  });
173309
- import { resolve as resolve13, join as join17 } from "path";
173310
- import { existsSync as existsSync17, readFileSync as readFileSync16 } from "fs";
174586
+ import { resolve as resolve15, join as join24 } from "path";
174587
+ import { existsSync as existsSync25, readFileSync as readFileSync21 } from "fs";
173311
174588
  import { mkdir as mkdir2, writeFile } from "fs/promises";
173312
- var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve13(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
173313
- if (!existsSync17(resolveConfigPath(configPath2))) {
174589
+ var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve15(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
174590
+ if (!existsSync25(resolveConfigPath(configPath2))) {
173314
174591
  return [{}];
173315
174592
  }
173316
174593
  const rawConfig = await loadRawConfig(configPath2);
@@ -173330,8 +174607,8 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
173330
174607
  const exitCode = await proc.exited;
173331
174608
  return { exitCode, name, output: (stdout + stderr).trim() };
173332
174609
  }, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
173333
- const local = resolve13("node_modules", ".bin", name);
173334
- return existsSync17(local) ? local : null;
174610
+ const local = resolve15("node_modules", ".bin", name);
174611
+ return existsSync25(local) ? local : null;
173335
174612
  }, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi3 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
173336
174613
  const cwd = `${process.cwd()}/`;
173337
174614
  const summaryMatch = stripAnsi3(output).match(/svelte-check found (\d+) error/);
@@ -173378,15 +174655,15 @@ Found ${errorCount} error${suffix}.`;
173378
174655
  return formatted;
173379
174656
  }, ABSOLUTE_INTERNAL_EXCLUDES, resolveAbsoluteTypeFile = (fileName) => {
173380
174657
  const candidates = [
173381
- resolve13("node_modules/@absolutejs/absolute/dist/types", fileName),
173382
- resolve13(import.meta.dir, "../types", fileName),
173383
- resolve13(import.meta.dir, "../../types", fileName),
173384
- resolve13(import.meta.dir, "../../../types", fileName)
174658
+ resolve15("node_modules/@absolutejs/absolute/dist/types", fileName),
174659
+ resolve15(import.meta.dir, "../types", fileName),
174660
+ resolve15(import.meta.dir, "../../types", fileName),
174661
+ resolve15(import.meta.dir, "../../../types", fileName)
173385
174662
  ];
173386
- return candidates.find((candidate) => existsSync17(candidate)) ?? candidates[0];
174663
+ return candidates.find((candidate) => existsSync25(candidate)) ?? candidates[0];
173387
174664
  }, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
173388
174665
  try {
173389
- return JSON.parse(readFileSync16(resolve13("tsconfig.json"), "utf-8"));
174666
+ return JSON.parse(readFileSync21(resolve15("tsconfig.json"), "utf-8"));
173390
174667
  } catch {
173391
174668
  return {};
173392
174669
  }
@@ -173414,22 +174691,22 @@ Found ${errorCount} error${suffix}.`;
173414
174691
  console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
173415
174692
  process.exit(1);
173416
174693
  }
173417
- const vueTsconfigPath = join17(cacheDir, "tsconfig.vue-check.json");
174694
+ const vueTsconfigPath = join24(cacheDir, "tsconfig.vue-check.json");
173418
174695
  return writeFile(vueTsconfigPath, JSON.stringify({
173419
174696
  compilerOptions: {
173420
174697
  rootDir: ".."
173421
174698
  },
173422
174699
  exclude: getProjectTypecheckExcludes(),
173423
- extends: resolve13("tsconfig.json"),
174700
+ extends: resolve15("tsconfig.json"),
173424
174701
  include: getProjectTypecheckIncludes()
173425
174702
  }, null, "\t")).then(() => run("vue-tsc", [
173426
174703
  vueTscBin,
173427
174704
  "--noEmit",
173428
174705
  "--project",
173429
- resolve13(vueTsconfigPath),
174706
+ resolve15(vueTsconfigPath),
173430
174707
  "--incremental",
173431
174708
  "--tsBuildInfoFile",
173432
- join17(cacheDir, "vue-tsc.tsbuildinfo"),
174709
+ join24(cacheDir, "vue-tsc.tsbuildinfo"),
173433
174710
  "--pretty"
173434
174711
  ]));
173435
174712
  }, buildAngularCheck = async (cacheDir, angularDir) => {
@@ -173438,7 +174715,7 @@ Found ${errorCount} error${suffix}.`;
173438
174715
  console.error("\x1B[31m\u2717\x1B[0m @angular/compiler-cli is required for Angular type checking. Install it: bun add -d @angular/compiler-cli");
173439
174716
  process.exit(1);
173440
174717
  }
173441
- const angularTsconfigPath = join17(cacheDir, "tsconfig.angular-check.json");
174718
+ const angularTsconfigPath = join24(cacheDir, "tsconfig.angular-check.json");
173442
174719
  await writeFile(angularTsconfigPath, JSON.stringify({
173443
174720
  angularCompilerOptions: {
173444
174721
  strictTemplates: true
@@ -173448,32 +174725,32 @@ Found ${errorCount} error${suffix}.`;
173448
174725
  rootDir: ".."
173449
174726
  },
173450
174727
  exclude: ABSOLUTE_INTERNAL_EXCLUDES.map(toGeneratedConfigPath),
173451
- extends: resolve13("tsconfig.json"),
174728
+ extends: resolve15("tsconfig.json"),
173452
174729
  include: [`../${angularDir}/**/*`]
173453
174730
  }, null, "\t"));
173454
- return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve13(angularTsconfigPath))}`);
174731
+ return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve15(angularTsconfigPath))}`);
173455
174732
  }, buildTscCheck = (cacheDir) => {
173456
174733
  const tscBin = findBin("tsc");
173457
174734
  if (!tscBin) {
173458
174735
  console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
173459
174736
  process.exit(1);
173460
174737
  }
173461
- const tscConfigPath = join17(cacheDir, "tsconfig.typecheck.json");
174738
+ const tscConfigPath = join24(cacheDir, "tsconfig.typecheck.json");
173462
174739
  return writeFile(tscConfigPath, JSON.stringify({
173463
174740
  compilerOptions: {
173464
174741
  rootDir: ".."
173465
174742
  },
173466
174743
  exclude: getProjectTypecheckExcludes(),
173467
- extends: resolve13("tsconfig.json"),
174744
+ extends: resolve15("tsconfig.json"),
173468
174745
  include: getProjectTypecheckIncludes()
173469
174746
  }, null, "\t")).then(() => run("tsc", [
173470
174747
  tscBin,
173471
174748
  "--noEmit",
173472
174749
  "--project",
173473
- resolve13(tscConfigPath),
174750
+ resolve15(tscConfigPath),
173474
174751
  "--incremental",
173475
174752
  "--tsBuildInfoFile",
173476
- join17(cacheDir, "tsc.tsbuildinfo"),
174753
+ join24(cacheDir, "tsc.tsbuildinfo"),
173477
174754
  "--pretty"
173478
174755
  ]));
173479
174756
  }, buildSvelteCheck = async (cacheDir, svelteDir) => {
@@ -173482,16 +174759,16 @@ Found ${errorCount} error${suffix}.`;
173482
174759
  console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
173483
174760
  process.exit(1);
173484
174761
  }
173485
- const svelteTsconfigPath = join17(cacheDir, "tsconfig.svelte-check.json");
174762
+ const svelteTsconfigPath = join24(cacheDir, "tsconfig.svelte-check.json");
173486
174763
  await writeFile(svelteTsconfigPath, JSON.stringify({
173487
- extends: resolve13("tsconfig.json"),
174764
+ extends: resolve15("tsconfig.json"),
173488
174765
  files: ABSOLUTE_TYPECHECK_FILES,
173489
174766
  include: [`../${svelteDir}/**/*`]
173490
174767
  }, null, "\t"));
173491
174768
  return run("svelte-check", [
173492
174769
  svelteBin,
173493
174770
  "--tsconfig",
173494
- resolve13(svelteTsconfigPath),
174771
+ resolve15(svelteTsconfigPath),
173495
174772
  "--threshold",
173496
174773
  "error",
173497
174774
  "--compiler-warnings",
@@ -173680,11 +174957,11 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
173680
174957
  url: url.pathname + url.search,
173681
174958
  ...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
173682
174959
  };
173683
- const responsePromise = new Promise((resolve14) => {
173684
- pending.set(id, resolve14);
174960
+ const responsePromise = new Promise((resolve16) => {
174961
+ pending.set(id, resolve16);
173685
174962
  });
173686
174963
  client.send(encodeTunnelMessage(message));
173687
- const timeout = new Promise((resolve14) => setTimeout(() => resolve14({ id, message: "timeout", type: "error" }), requestTimeoutMs));
174964
+ const timeout = new Promise((resolve16) => setTimeout(() => resolve16({ id, message: "timeout", type: "error" }), requestTimeoutMs));
173688
174965
  const result = await Promise.race([responsePromise, timeout]);
173689
174966
  pending.delete(id);
173690
174967
  if (result.type === "error") {
@@ -177156,7 +178433,7 @@ if (command === "dev") {
177156
178433
  const outdir = parseNamedArg("--outdir");
177157
178434
  const configPath2 = parseNamedArg("--config");
177158
178435
  const { build: build2 } = await Promise.resolve().then(() => (init_build(), exports_build));
177159
- await build2(outdir, configPath2);
178436
+ await build2(outdir, configPath2, args.includes("--profile"));
177160
178437
  } else if (command === "workspace") {
177161
178438
  sendTelemetryEvent("cli:command", {
177162
178439
  command: `workspace:${workspaceCommand ?? "unknown"}`
@@ -177189,6 +178466,10 @@ if (command === "dev") {
177189
178466
  sendTelemetryEvent("cli:command", { command: "mem" });
177190
178467
  const { runMem: runMem2 } = await Promise.resolve().then(() => (init_mem(), exports_mem));
177191
178468
  await runMem2(args);
178469
+ } else if (command === "generate" || command === "g") {
178470
+ sendTelemetryEvent("cli:command", { command: "generate" });
178471
+ const { runGenerate: runGenerate2 } = await Promise.resolve().then(() => (init_generate(), exports_generate));
178472
+ await runGenerate2(args);
177192
178473
  } else if (command === "env") {
177193
178474
  sendTelemetryEvent("cli:command", { command: "env" });
177194
178475
  const { runEnv: runEnv2 } = await Promise.resolve().then(() => (init_env(), exports_env));
@@ -177201,6 +178482,10 @@ if (command === "dev") {
177201
178482
  sendTelemetryEvent("cli:command", { command: "doctor" });
177202
178483
  const { runDoctor: runDoctor2 } = await Promise.resolve().then(() => (init_doctor(), exports_doctor));
177203
178484
  await runDoctor2(args);
178485
+ } else if (command === "routes") {
178486
+ sendTelemetryEvent("cli:command", { command: "routes" });
178487
+ const { runRoutes: runRoutes2 } = await Promise.resolve().then(() => (init_routes(), exports_routes));
178488
+ await runRoutes2(args);
177204
178489
  } else if (command === "info") {
177205
178490
  sendTelemetryEvent("cli:command", { command });
177206
178491
  info();
@@ -177236,19 +178521,21 @@ if (command === "dev") {
177236
178521
  console.error("Commands:");
177237
178522
  console.error(" dev [entry] Start development server");
177238
178523
  console.error(" workspace dev [--no-tui] Start multi-service workspace dev");
177239
- console.error(" build [--outdir dir] Build production assets");
178524
+ console.error(" build [--outdir dir] [--profile] Build production assets");
177240
178525
  console.error(" start [entry] [--outdir dir] Start production server");
177241
178526
  console.error(" compile [entry] [--outdir dir] [--outfile path] Compile standalone executable");
177242
178527
  console.error(" config [--port n] Open the unified config UI (ESLint, tsconfig, Prettier)");
177243
178528
  console.error(" doctor [--json] Diagnose the project (bun, config, framework dirs, env, port)");
177244
178529
  console.error(" env [--check] [--json] Report env vars the app reads (getEnv) and which are missing");
177245
178530
  console.error(" eslint Run ESLint (cached)");
178531
+ console.error(" generate <page|api|component> <name> [--framework <fw>] Scaffold a page, API plugin, or component");
177246
178532
  console.error(" info Print system info for bug reports");
177247
178533
  console.error(" logs <name> [-f] [-n <lines>] Tail a running server's log by name");
177248
- console.error(" ls [--sizes] [--json] List the project's pages by framework (from source)");
178534
+ console.error(" ls [--sizes] [--budget <size>] [--json] List the project's pages by framework");
177249
178535
  console.error(" mem [--json] Memory report (RSS) for running servers, plus system usage");
177250
178536
  console.error(" ps [--watch] [--json] [--kill <pid|port>] [--kill-all] List/manage running servers");
177251
178537
  console.error(" prettier Run Prettier check (cached)");
178538
+ console.error(" routes [--json] List every route (pages + API) of a running dev server");
177252
178539
  console.error(" typecheck Run type checkers for all frameworks");
177253
178540
  console.error(" telemetry Manage anonymous telemetry");
177254
178541
  console.error(" tunnel-relay Run the public reverse-tunnel relay (for webhook dev)");