@absolutejs/absolute 0.19.0-beta.1038 → 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
@@ -172046,6 +172046,1151 @@ var init_mem = __esm(() => {
172046
172046
  HEADERS = ["NAME", "SOURCE", "PORT", "RSS", "% SYS"];
172047
172047
  });
172048
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
+
172049
173194
  // src/cli/scripts/env.ts
172050
173195
  var exports_env = {};
172051
173196
  __export(exports_env, {
@@ -172053,15 +173198,15 @@ __export(exports_env, {
172053
173198
  runEnv: () => runEnv,
172054
173199
  collectEnvVars: () => collectEnvVars
172055
173200
  });
172056
- import { existsSync as existsSync13, readFileSync as readFileSync15 } from "fs";
172057
- import { join as join14 } from "path";
173201
+ import { existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
173202
+ import { join as join20 } from "path";
172058
173203
  var {env: env3, Glob: Glob3 } = globalThis.Bun;
172059
- 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 = () => existsSync13(join14(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 () => {
172060
173205
  const scans = scanPatterns().map((pattern) => Array.fromAsync(new Glob3(pattern).scan({ cwd: process.cwd() })));
172061
173206
  const files = (await Promise.all(scans)).flat();
172062
173207
  const usage = new Map;
172063
173208
  files.forEach((file) => {
172064
- keysInFile(readFileSync15(file, "utf-8")).forEach((key) => {
173209
+ keysInFile(readFileSync19(file, "utf-8")).forEach((key) => {
172065
173210
  usage.set(key, [...usage.get(key) ?? [], file]);
172066
173211
  });
172067
173212
  });
@@ -172119,7 +173264,7 @@ __export(exports_logs, {
172119
173264
  });
172120
173265
  import {
172121
173266
  closeSync as closeSync2,
172122
- existsSync as existsSync14,
173267
+ existsSync as existsSync21,
172123
173268
  openSync as openSync4,
172124
173269
  readSync as readSync2,
172125
173270
  statSync as statSync2,
@@ -172186,7 +173331,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
172186
173331
  printAvailable(instances);
172187
173332
  return;
172188
173333
  }
172189
- if (match.logFile === null || !existsSync14(match.logFile)) {
173334
+ if (match.logFile === null || !existsSync21(match.logFile)) {
172190
173335
  printDim2(`"${name}" has no captured log (untracked, or started outside the CLI).`);
172191
173336
  return;
172192
173337
  }
@@ -172209,10 +173354,10 @@ var exports_doctor = {};
172209
173354
  __export(exports_doctor, {
172210
173355
  runDoctor: () => runDoctor
172211
173356
  });
172212
- import { existsSync as existsSync15 } from "fs";
173357
+ import { existsSync as existsSync22 } from "fs";
172213
173358
  import { createRequire } from "module";
172214
173359
  import { arch as arch4, platform as platform5 } from "os";
172215
- import { join as join15 } from "path";
173360
+ import { join as join21 } from "path";
172216
173361
  var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
172217
173362
  detail,
172218
173363
  label,
@@ -172247,7 +173392,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
172247
173392
  return [];
172248
173393
  const label = `${field.replace("Directory", "")} pages`;
172249
173394
  return [
172250
- existsSync15(join15(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)`)
172251
173396
  ];
172252
173397
  }), envCheck = async () => {
172253
173398
  const vars = await collectEnvVars();
@@ -172317,7 +173462,7 @@ var init_doctor = __esm(() => {
172317
173462
  "htmlDirectory",
172318
173463
  "htmxDirectory"
172319
173464
  ];
172320
- projectRequire = createRequire(join15(process.cwd(), "package.json"));
173465
+ projectRequire = createRequire(join21(process.cwd(), "package.json"));
172321
173466
  STATUS_MARK = {
172322
173467
  fail: `${colors.red}\u2717${colors.reset}`,
172323
173468
  ok: `${colors.green}\u2713${colors.reset}`,
@@ -172398,13 +173543,13 @@ var init_routes = __esm(() => {
172398
173543
  });
172399
173544
 
172400
173545
  // src/build/externalAssetPlugin.ts
172401
- import { copyFileSync as copyFileSync2, existsSync as existsSync16, mkdirSync as mkdirSync7, statSync as statSync3 } from "fs";
172402
- import { basename as basename6, dirname as dirname4, join as join16, 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";
172403
173548
  var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
172404
173549
  name: "absolute-external-asset",
172405
173550
  setup(bld) {
172406
173551
  const urlPattern = /new\s+URL\(\s*["'](\.\.?\/[^"']+)["']\s*,\s*import\.meta\.url\s*\)/g;
172407
- const skipRoots = userSourceRoots.map((root) => resolve11(root));
173552
+ const skipRoots = userSourceRoots.map((root) => resolve13(root));
172408
173553
  const isUserSource = (path) => skipRoots.some((root) => path.startsWith(`${root}/`));
172409
173554
  bld.onLoad({ filter: /\.[mc]?[jt]sx?$/ }, async (args) => {
172410
173555
  if (isUserSource(args.path))
@@ -172414,20 +173559,20 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
172414
173559
  return;
172415
173560
  urlPattern.lastIndex = 0;
172416
173561
  let match;
172417
- const sourceDir = dirname4(args.path);
173562
+ const sourceDir = dirname10(args.path);
172418
173563
  while ((match = urlPattern.exec(source)) !== null) {
172419
173564
  const relPath = match[1];
172420
173565
  if (!relPath)
172421
173566
  continue;
172422
- const assetPath = resolve11(sourceDir, relPath);
172423
- if (!existsSync16(assetPath))
173567
+ const assetPath = resolve13(sourceDir, relPath);
173568
+ if (!existsSync23(assetPath))
172424
173569
  continue;
172425
173570
  if (!statSync3(assetPath).isFile())
172426
173571
  continue;
172427
- const targetPath = join16(outDir, basename6(assetPath));
172428
- if (existsSync16(targetPath))
173572
+ const targetPath = join22(outDir, basename6(assetPath));
173573
+ if (existsSync23(targetPath))
172429
173574
  continue;
172430
- mkdirSync7(dirname4(targetPath), { recursive: true });
173575
+ mkdirSync11(dirname10(targetPath), { recursive: true });
172431
173576
  copyFileSync2(assetPath, targetPath);
172432
173577
  }
172433
173578
  return;
@@ -172445,16 +173590,16 @@ __export(exports_compile, {
172445
173590
  var {env: env4 } = globalThis.Bun;
172446
173591
  import {
172447
173592
  cpSync,
172448
- existsSync as existsSync17,
172449
- mkdirSync as mkdirSync8,
172450
- readdirSync as readdirSync4,
172451
- readFileSync as readFileSync16,
173593
+ existsSync as existsSync24,
173594
+ mkdirSync as mkdirSync12,
173595
+ readdirSync as readdirSync6,
173596
+ readFileSync as readFileSync20,
172452
173597
  rmSync as rmSync5,
172453
173598
  statSync as statSync4,
172454
173599
  unlinkSync as unlinkSync4,
172455
- writeFileSync as writeFileSync6
173600
+ writeFileSync as writeFileSync11
172456
173601
  } from "fs";
172457
- import { basename as basename7, dirname as dirname5, join as join17, 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";
172458
173603
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
172459
173604
  const resolvedVersion = version2 || "unknown";
172460
173605
  console.log("");
@@ -172462,14 +173607,14 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172462
173607
  console.log("");
172463
173608
  }, collectFiles2 = (dir) => {
172464
173609
  const result = [];
172465
- let pending = readdirSync4(dir, { withFileTypes: true });
173610
+ let pending = readdirSync6(dir, { withFileTypes: true });
172466
173611
  while (pending.length > 0) {
172467
173612
  const entry = pending.pop();
172468
173613
  if (!entry)
172469
173614
  continue;
172470
- const fullPath = join17(entry.parentPath, entry.name);
173615
+ const fullPath = join23(entry.parentPath, entry.name);
172471
173616
  if (entry.isDirectory())
172472
- pending = pending.concat(readdirSync4(fullPath, { withFileTypes: true }));
173617
+ pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
172473
173618
  else
172474
173619
  result.push(fullPath);
172475
173620
  }
@@ -172482,16 +173627,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172482
173627
  return `./${parts.join("/")}`;
172483
173628
  }, collectProjectSourceFiles = (dir) => {
172484
173629
  const result = [];
172485
- let pending = readdirSync4(dir, { withFileTypes: true });
173630
+ let pending = readdirSync6(dir, { withFileTypes: true });
172486
173631
  while (pending.length > 0) {
172487
173632
  const entry = pending.pop();
172488
173633
  if (!entry)
172489
173634
  continue;
172490
- const fullPath = join17(entry.parentPath, entry.name);
173635
+ const fullPath = join23(entry.parentPath, entry.name);
172491
173636
  if (entry.isDirectory()) {
172492
173637
  if (SERVER_RUNTIME_SCAN_SKIP_DIRS.has(entry.name))
172493
173638
  continue;
172494
- pending = pending.concat(readdirSync4(fullPath, { withFileTypes: true }));
173639
+ pending = pending.concat(readdirSync6(fullPath, { withFileTypes: true }));
172495
173640
  } else if (hasSourceExtension(fullPath)) {
172496
173641
  result.push(fullPath);
172497
173642
  }
@@ -172499,22 +173644,22 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172499
173644
  return result;
172500
173645
  }, copyServerRuntimeAssetReferences = (outdir) => {
172501
173646
  const copied = new Set;
172502
- const normalizedOutdir = resolve12(outdir);
173647
+ const normalizedOutdir = resolve14(outdir);
172503
173648
  const copyReference = (filePath, relPath) => {
172504
- const assetSource = resolve12(dirname5(filePath), relPath);
172505
- if (!existsSync17(assetSource) || !statSync4(assetSource).isFile())
173649
+ const assetSource = resolve14(dirname11(filePath), relPath);
173650
+ if (!existsSync24(assetSource) || !statSync4(assetSource).isFile())
172506
173651
  return;
172507
- const assetTarget = resolve12(normalizedOutdir, relPath.replace(/^\.\//, ""));
173652
+ const assetTarget = resolve14(normalizedOutdir, relPath.replace(/^\.\//, ""));
172508
173653
  if (assetTarget !== normalizedOutdir && !assetTarget.startsWith(`${normalizedOutdir}/`))
172509
173654
  return;
172510
173655
  if (copied.has(assetTarget))
172511
173656
  return;
172512
173657
  copied.add(assetTarget);
172513
- mkdirSync8(dirname5(assetTarget), { recursive: true });
173658
+ mkdirSync12(dirname11(assetTarget), { recursive: true });
172514
173659
  cpSync(assetSource, assetTarget, { force: true });
172515
173660
  };
172516
173661
  for (const filePath of collectProjectSourceFiles(process.cwd())) {
172517
- const source = readFileSync16(filePath, "utf-8");
173662
+ const source = readFileSync20(filePath, "utf-8");
172518
173663
  SERVER_RUNTIME_ASSET_RE.lastIndex = 0;
172519
173664
  let match;
172520
173665
  while ((match = SERVER_RUNTIME_ASSET_RE.exec(source)) !== null) {
@@ -172543,7 +173688,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172543
173688
  }
172544
173689
  }, readPackageVersion4 = (candidate) => {
172545
173690
  try {
172546
- const pkg = JSON.parse(readFileSync16(candidate, "utf-8"));
173691
+ const pkg = JSON.parse(readFileSync20(candidate, "utf-8"));
172547
173692
  if (pkg.name !== "@absolutejs/absolute")
172548
173693
  return null;
172549
173694
  const ver = pkg.version;
@@ -172578,18 +173723,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172578
173723
  return resolveBuildModule3(remaining);
172579
173724
  }, resolveJsxDevRuntimeCompatPath2 = () => {
172580
173725
  const candidates = [
172581
- resolve12(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
172582
- resolve12(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
172583
- resolve12(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
172584
- resolve12(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
172585
- resolve12(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
172586
- 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")
172587
173732
  ];
172588
173733
  for (const candidate of candidates) {
172589
- if (existsSync17(candidate))
173734
+ if (existsSync24(candidate))
172590
173735
  return candidate;
172591
173736
  }
172592
- return resolve12(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
173737
+ return resolve14(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
172593
173738
  }, jsxDevRuntimeCompatPath2, shouldEmbedCompiledAsset = (relativePath, skip = new Set) => {
172594
173739
  if (skip.has(relativePath))
172595
173740
  return false;
@@ -172602,11 +173747,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172602
173747
  return true;
172603
173748
  }, tryReadNodePackageJson = (packageDir) => {
172604
173749
  try {
172605
- return JSON.parse(readFileSync16(join17(packageDir, "package.json"), "utf-8"));
173750
+ return JSON.parse(readFileSync20(join23(packageDir, "package.json"), "utf-8"));
172606
173751
  } catch {
172607
173752
  return null;
172608
173753
  }
172609
- }, 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) => {
172610
173755
  if (seen.has(specifier))
172611
173756
  return;
172612
173757
  const srcDir = resolveProjectPackageDir(specifier);
@@ -172614,13 +173759,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172614
173759
  if (!pkg)
172615
173760
  return;
172616
173761
  seen.add(specifier);
172617
- const destDir = join17(outdir, "node_modules", ...specifier.split("/"));
173762
+ const destDir = join23(outdir, "node_modules", ...specifier.split("/"));
172618
173763
  rmSync5(destDir, { force: true, recursive: true });
172619
173764
  cpSync(srcDir, destDir, {
172620
173765
  force: true,
172621
173766
  recursive: true,
172622
173767
  filter(source) {
172623
- const rel = relative3(srcDir, source);
173768
+ const rel = relative6(srcDir, source);
172624
173769
  const [firstSegment] = rel.split(/[\\/]/);
172625
173770
  return firstSegment !== "node_modules" && firstSegment !== ".git";
172626
173771
  }
@@ -172636,8 +173781,8 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172636
173781
  }, copyAngularRuntimePackages = (buildConfig, outdir) => {
172637
173782
  if (!buildConfig.angularDirectory)
172638
173783
  return;
172639
- const angularScopeDir = resolve12(process.cwd(), "node_modules", "@angular");
172640
- const angularPackages = existsSync17(angularScopeDir) ? readdirSync4(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}`) : [];
172641
173786
  const roots = new Set([...angularPackages, "rxjs", "tslib", "typescript"]);
172642
173787
  const seen = new Set;
172643
173788
  for (const specifier of roots) {
@@ -172654,16 +173799,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172654
173799
  }
172655
173800
  copyAngularRuntimePackages(buildConfig, outdir);
172656
173801
  }, collectRuntimePackageSpecifiers = (distDir) => {
172657
- const nodeModulesDir = join17(distDir, "node_modules");
172658
- if (!existsSync17(nodeModulesDir))
173802
+ const nodeModulesDir = join23(distDir, "node_modules");
173803
+ if (!existsSync24(nodeModulesDir))
172659
173804
  return [];
172660
173805
  const specifiers = [];
172661
- for (const entry of readdirSync4(nodeModulesDir, { withFileTypes: true })) {
173806
+ for (const entry of readdirSync6(nodeModulesDir, { withFileTypes: true })) {
172662
173807
  if (!entry.isDirectory())
172663
173808
  continue;
172664
173809
  if (entry.name.startsWith("@")) {
172665
- const scopeDir = join17(nodeModulesDir, entry.name);
172666
- for (const scopedEntry of readdirSync4(scopeDir, {
173810
+ const scopeDir = join23(nodeModulesDir, entry.name);
173811
+ for (const scopedEntry of readdirSync6(scopeDir, {
172667
173812
  withFileTypes: true
172668
173813
  })) {
172669
173814
  if (scopedEntry.isDirectory()) {
@@ -172676,7 +173821,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172676
173821
  }
172677
173822
  return specifiers.sort((a, b) => b.length - a.length);
172678
173823
  }, ensureRelativeModuleSpecifier = (fromFile, toFile) => {
172679
- const rel = relative3(dirname5(fromFile), toFile).replace(/\\/g, "/");
173824
+ const rel = relative6(dirname11(fromFile), toFile).replace(/\\/g, "/");
172680
173825
  return rel.startsWith(".") ? rel : `./${rel}`;
172681
173826
  }, pickExportEntry = (value) => {
172682
173827
  if (typeof value === "string")
@@ -172694,18 +173839,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172694
173839
  const packageSpecifier = packageSpecifiers.find((root) => specifier === root || specifier.startsWith(`${root}/`));
172695
173840
  if (!packageSpecifier)
172696
173841
  return null;
172697
- const packageDir = join17(distDir, "node_modules", ...packageSpecifier.split("/"));
173842
+ const packageDir = join23(distDir, "node_modules", ...packageSpecifier.split("/"));
172698
173843
  const subpath = specifier.slice(packageSpecifier.length);
172699
- const subPackageDir = subpath ? join17(packageDir, ...subpath.slice(1).split("/")) : null;
172700
- const resolvedPackageDir = subPackageDir && existsSync17(join17(subPackageDir, "package.json")) ? subPackageDir : packageDir;
172701
- const packageJsonPath = join17(resolvedPackageDir, "package.json");
172702
- if (!existsSync17(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))
172703
173848
  return null;
172704
- const pkg = JSON.parse(readFileSync16(packageJsonPath, "utf-8"));
173849
+ const pkg = JSON.parse(readFileSync20(packageJsonPath, "utf-8"));
172705
173850
  const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
172706
173851
  const rootExport = pkg.exports?.[exportKey];
172707
173852
  const entry = pickExportEntry(rootExport) ?? (resolvedPackageDir === subPackageDir || !subpath ? pkg.module ?? pkg.main ?? "index.js" : `.${subpath}`);
172708
- return join17(resolvedPackageDir, entry);
173853
+ return join23(resolvedPackageDir, entry);
172709
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) => {
172710
173855
  try {
172711
173856
  return statSync4(filePath).isFile();
@@ -172718,16 +173863,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172718
173863
  const candidates = [
172719
173864
  candidate,
172720
173865
  ...RUNTIME_JS_EXTENSIONS.map((extension) => `${candidate}${extension}`),
172721
- ...RUNTIME_JS_EXTENSIONS.map((extension) => join17(candidate, `index${extension}`))
173866
+ ...RUNTIME_JS_EXTENSIONS.map((extension) => join23(candidate, `index${extension}`))
172722
173867
  ];
172723
173868
  return candidates.find((filePath) => isRuntimeJsFile(filePath) && isFile(filePath)) ?? null;
172724
173869
  }, findContainingRuntimePackageDir = (filePath) => {
172725
- let dir = dirname5(filePath);
172726
- while (dir !== dirname5(dir)) {
172727
- if (isNodeModulesPath(dir) && existsSync17(join17(dir, "package.json"))) {
173870
+ let dir = dirname11(filePath);
173871
+ while (dir !== dirname11(dir)) {
173872
+ if (isNodeModulesPath(dir) && existsSync24(join23(dir, "package.json"))) {
172728
173873
  return dir;
172729
173874
  }
172730
- dir = dirname5(dir);
173875
+ dir = dirname11(dir);
172731
173876
  }
172732
173877
  return null;
172733
173878
  }, resolvePackageImportEntryFile = (fromFile, specifier) => {
@@ -172740,7 +173885,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172740
173885
  const entry = pickExportEntry(pkg?.imports?.[specifier]);
172741
173886
  if (!entry)
172742
173887
  return null;
172743
- return join17(packageDir, entry);
173888
+ return join23(packageDir, entry);
172744
173889
  }, collectRuntimeRewriteRoots = (distDir) => collectFiles2(distDir).filter((filePath) => isRuntimeJsFile(filePath) && !isNodeModulesPath(filePath)), rewriteRuntimeModuleSpecifiers = (distDir) => {
172745
173890
  const packageSpecifiers = collectRuntimePackageSpecifiers(distDir);
172746
173891
  if (packageSpecifiers.length === 0)
@@ -172759,10 +173904,10 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172759
173904
  if (!filePath || seen.has(filePath))
172760
173905
  continue;
172761
173906
  seen.add(filePath);
172762
- const source = readFileSync16(filePath, "utf-8");
173907
+ const source = readFileSync20(filePath, "utf-8");
172763
173908
  const rewritten = source.replace(MODULE_SPECIFIER_RE, (match, prefix, quote, specifier) => {
172764
173909
  if (typeof specifier === "string" && specifier.startsWith(".")) {
172765
- enqueue(resolveRuntimeJsFile(resolve12(dirname5(filePath), specifier)));
173910
+ enqueue(resolveRuntimeJsFile(resolve14(dirname11(filePath), specifier)));
172766
173911
  return match;
172767
173912
  }
172768
173913
  const packageImportTarget = resolveRuntimeJsFile(resolvePackageImportEntryFile(filePath, specifier) ?? "");
@@ -172777,7 +173922,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172777
173922
  return `${prefix}${quote}${ensureRelativeModuleSpecifier(filePath, target)}${quote}`;
172778
173923
  });
172779
173924
  if (rewritten !== source) {
172780
- writeFileSync6(filePath, rewritten);
173925
+ writeFileSync11(filePath, rewritten);
172781
173926
  }
172782
173927
  }
172783
173928
  }, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2, buildConfig) => {
@@ -172790,25 +173935,25 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172790
173935
  "_compile_entrypoint.ts"
172791
173936
  ]);
172792
173937
  const embeddedFiles = allFiles.filter((file) => {
172793
- const rel = relative3(distDir, file);
173938
+ const rel = relative6(distDir, file);
172794
173939
  if (embeddedSkip.has(rel))
172795
173940
  return false;
172796
173941
  return true;
172797
173942
  });
172798
- const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative3(distDir, file), assetSkip));
173943
+ const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative6(distDir, file), assetSkip));
172799
173944
  const imports = [];
172800
173945
  const embeddedMappings = [];
172801
173946
  const mappings = [];
172802
173947
  const embeddedVarMap = new Map;
172803
173948
  embeddedFiles.forEach((filePath, idx) => {
172804
- const rel = relative3(distDir, filePath).replace(/\\/g, "/");
173949
+ const rel = relative6(distDir, filePath).replace(/\\/g, "/");
172805
173950
  const varName = `__a${idx}`;
172806
173951
  embeddedVarMap.set(rel, varName);
172807
173952
  imports.push(`import ${varName} from "./${rel}" with { type: "file" };`);
172808
173953
  embeddedMappings.push(` ["${rel}", ${varName}],`);
172809
173954
  });
172810
173955
  clientFiles.forEach((filePath) => {
172811
- const rel = relative3(distDir, filePath).replace(/\\/g, "/");
173956
+ const rel = relative6(distDir, filePath).replace(/\\/g, "/");
172812
173957
  const varName = embeddedVarMap.get(rel);
172813
173958
  if (!varName)
172814
173959
  return;
@@ -172822,7 +173967,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
172822
173967
  const pageVarMap = new Map;
172823
173968
  const prerenderEntries = Array.from(prerenderMap.entries());
172824
173969
  prerenderEntries.forEach(([route, filePath]) => {
172825
- const rel = relative3(distDir, filePath).replace(/\\/g, "/");
173970
+ const rel = relative6(distDir, filePath).replace(/\\/g, "/");
172826
173971
  const varName = embeddedVarMap.get(rel);
172827
173972
  if (varName)
172828
173973
  pageVarMap.set(route, varName);
@@ -172851,7 +173996,7 @@ import { websocket as elysiaWebsocket } from "elysia/ws";
172851
173996
  const SERVER_MODULE = (runtimeDir: string) => import(pathToFileURL(join(runtimeDir, ${JSON.stringify(serverBundleName)})).href);
172852
173997
  const RUNTIME_BUILD_ID = ${JSON.stringify(runtimeBuildId)};
172853
173998
  const RUNTIME_CONFIG_SOURCE = ${JSON.stringify(runtimeConfigSource)};
172854
- const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve12(distDir))};
173999
+ const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve14(distDir))};
172855
174000
  const ORIGINAL_BUILD_DIR_NORMALIZED = ORIGINAL_BUILD_DIR.replace(/\\\\/g, "/");
172856
174001
 
172857
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
@@ -173229,16 +174374,16 @@ console.log(\`
173229
174374
  }),
173230
174375
  ...collectUserServerExternals(buildConfig)
173231
174376
  ], compile = async (serverEntry, outdir, outfile, configPath2) => {
173232
- const resolvedOutdir = resolve12(outdir ?? "dist");
174377
+ const resolvedOutdir = resolve14(outdir ?? "dist");
173233
174378
  await withBuildDirectoryLock(resolvedOutdir, () => compileUnlocked(serverEntry, resolvedOutdir, outfile, configPath2));
173234
174379
  }, compileUnlocked = async (serverEntry, resolvedOutdir, outfile, configPath2) => {
173235
174380
  const prerenderPort = Number(env4.COMPILE_PORT) || Number(env4.PORT) || DEFAULT_PORT + 1;
173236
174381
  killStaleProcesses(prerenderPort);
173237
174382
  const entryName = basename7(serverEntry).replace(/\.[^.]+$/, "");
173238
- const resolvedOutfile = resolve12(outfile ?? "compiled-server");
174383
+ const resolvedOutfile = resolve14(outfile ?? "compiled-server");
173239
174384
  const absoluteVersion = resolvePackageVersion3([
173240
- resolve12(import.meta.dir, "..", "..", "..", "package.json"),
173241
- resolve12(import.meta.dir, "..", "..", "package.json")
174385
+ resolve14(import.meta.dir, "..", "..", "..", "package.json"),
174386
+ resolve14(import.meta.dir, "..", "..", "package.json")
173242
174387
  ]);
173243
174388
  compileBanner(absoluteVersion);
173244
174389
  const totalStart = performance.now();
@@ -173249,8 +174394,8 @@ console.log(\`
173249
174394
  buildConfig.mode = "production";
173250
174395
  try {
173251
174396
  const build2 = await resolveBuildModule3([
173252
- resolve12(import.meta.dir, "..", "..", "core", "build"),
173253
- resolve12(import.meta.dir, "..", "build")
174397
+ resolve14(import.meta.dir, "..", "..", "core", "build"),
174398
+ resolve14(import.meta.dir, "..", "build")
173254
174399
  ]);
173255
174400
  if (!build2)
173256
174401
  throw new Error("Could not locate build module");
@@ -173272,10 +174417,10 @@ console.log(\`
173272
174417
  buildConfig.htmxDirectory
173273
174418
  ].filter((dir) => Boolean(dir));
173274
174419
  const islandRegistrySpec = buildConfig.islands?.registry;
173275
- const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve12(islandRegistrySpec))) : undefined;
174420
+ const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve14(islandRegistrySpec))) : undefined;
173276
174421
  const serverBundle = await Bun.build({
173277
174422
  define: { "process.env.NODE_ENV": '"production"' },
173278
- entrypoints: [resolve12(serverEntry)],
174423
+ entrypoints: [resolve14(serverEntry)],
173279
174424
  external: resolveServerBundleExternals(buildConfig),
173280
174425
  outdir: resolvedOutdir,
173281
174426
  plugins: [
@@ -173296,14 +174441,14 @@ console.log(\`
173296
174441
  console.error(cliTag4("\x1B[31m", "Server bundle failed."));
173297
174442
  process.exit(1);
173298
174443
  }
173299
- const outputPath = resolve12(resolvedOutdir, `${entryName}.js`);
173300
- if (!existsSync17(outputPath)) {
174444
+ const outputPath = resolve14(resolvedOutdir, `${entryName}.js`);
174445
+ if (!existsSync24(outputPath)) {
173301
174446
  console.error(cliTag4("\x1B[31m", `Expected output not found: ${outputPath}`));
173302
174447
  process.exit(1);
173303
174448
  }
173304
- if (existsSync17(resolve12(resolvedOutdir, "angular", "vendor", "server"))) {
173305
- const vendorDir = resolve12(resolvedOutdir, "angular", "vendor", "server");
173306
- const vendorEntries = readdirSync4(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"));
173307
174452
  const angularServerVendorPaths = {};
173308
174453
  for (const file of vendorEntries) {
173309
174454
  const stem = file.replace(/\.js$/, "");
@@ -173311,7 +174456,7 @@ console.log(\`
173311
174456
  if (scope !== "angular" || rest.length === 0)
173312
174457
  continue;
173313
174458
  const specifier = `@angular/${rest.join("/")}`;
173314
- const relPath = relative3(dirname5(outputPath), resolve12(vendorDir, file));
174459
+ const relPath = relative6(dirname11(outputPath), resolve14(vendorDir, file));
173315
174460
  angularServerVendorPaths[specifier] = relPath.startsWith(".") ? relPath : `./${relPath}`;
173316
174461
  }
173317
174462
  if (Object.keys(angularServerVendorPaths).length > 0) {
@@ -173323,7 +174468,7 @@ console.log(\`
173323
174468
  copyServerRuntimeAssetReferences(resolvedOutdir);
173324
174469
  const prerenderStart = performance.now();
173325
174470
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
173326
- rmSync5(join17(resolvedOutdir, "_prerendered"), {
174471
+ rmSync5(join23(resolvedOutdir, "_prerendered"), {
173327
174472
  force: true,
173328
174473
  recursive: true
173329
174474
  });
@@ -173342,9 +174487,9 @@ console.log(\`
173342
174487
  const compileStart = performance.now();
173343
174488
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
173344
174489
  const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
173345
- const entrypointPath = join17(resolvedOutdir, "_compile_entrypoint.ts");
174490
+ const entrypointPath = join23(resolvedOutdir, "_compile_entrypoint.ts");
173346
174491
  await Bun.write(entrypointPath, entrypointCode);
173347
- mkdirSync8(dirname5(resolvedOutfile), { recursive: true });
174492
+ mkdirSync12(dirname11(resolvedOutfile), { recursive: true });
173348
174493
  const result = await Bun.build({
173349
174494
  compile: { outfile: resolvedOutfile },
173350
174495
  define: { "process.env.NODE_ENV": '"production"' },
@@ -173438,11 +174583,11 @@ var exports_typecheck = {};
173438
174583
  __export(exports_typecheck, {
173439
174584
  typecheck: () => typecheck
173440
174585
  });
173441
- import { resolve as resolve13, join as join18 } from "path";
173442
- import { existsSync as existsSync18, readFileSync as readFileSync17 } from "fs";
174586
+ import { resolve as resolve15, join as join24 } from "path";
174587
+ import { existsSync as existsSync25, readFileSync as readFileSync21 } from "fs";
173443
174588
  import { mkdir as mkdir2, writeFile } from "fs/promises";
173444
- var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve13(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
173445
- if (!existsSync18(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))) {
173446
174591
  return [{}];
173447
174592
  }
173448
174593
  const rawConfig = await loadRawConfig(configPath2);
@@ -173462,8 +174607,8 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
173462
174607
  const exitCode = await proc.exited;
173463
174608
  return { exitCode, name, output: (stdout + stderr).trim() };
173464
174609
  }, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
173465
- const local = resolve13("node_modules", ".bin", name);
173466
- return existsSync18(local) ? local : null;
174610
+ const local = resolve15("node_modules", ".bin", name);
174611
+ return existsSync25(local) ? local : null;
173467
174612
  }, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi3 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
173468
174613
  const cwd = `${process.cwd()}/`;
173469
174614
  const summaryMatch = stripAnsi3(output).match(/svelte-check found (\d+) error/);
@@ -173510,15 +174655,15 @@ Found ${errorCount} error${suffix}.`;
173510
174655
  return formatted;
173511
174656
  }, ABSOLUTE_INTERNAL_EXCLUDES, resolveAbsoluteTypeFile = (fileName) => {
173512
174657
  const candidates = [
173513
- resolve13("node_modules/@absolutejs/absolute/dist/types", fileName),
173514
- resolve13(import.meta.dir, "../types", fileName),
173515
- resolve13(import.meta.dir, "../../types", fileName),
173516
- 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)
173517
174662
  ];
173518
- return candidates.find((candidate) => existsSync18(candidate)) ?? candidates[0];
174663
+ return candidates.find((candidate) => existsSync25(candidate)) ?? candidates[0];
173519
174664
  }, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
173520
174665
  try {
173521
- return JSON.parse(readFileSync17(resolve13("tsconfig.json"), "utf-8"));
174666
+ return JSON.parse(readFileSync21(resolve15("tsconfig.json"), "utf-8"));
173522
174667
  } catch {
173523
174668
  return {};
173524
174669
  }
@@ -173546,22 +174691,22 @@ Found ${errorCount} error${suffix}.`;
173546
174691
  console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
173547
174692
  process.exit(1);
173548
174693
  }
173549
- const vueTsconfigPath = join18(cacheDir, "tsconfig.vue-check.json");
174694
+ const vueTsconfigPath = join24(cacheDir, "tsconfig.vue-check.json");
173550
174695
  return writeFile(vueTsconfigPath, JSON.stringify({
173551
174696
  compilerOptions: {
173552
174697
  rootDir: ".."
173553
174698
  },
173554
174699
  exclude: getProjectTypecheckExcludes(),
173555
- extends: resolve13("tsconfig.json"),
174700
+ extends: resolve15("tsconfig.json"),
173556
174701
  include: getProjectTypecheckIncludes()
173557
174702
  }, null, "\t")).then(() => run("vue-tsc", [
173558
174703
  vueTscBin,
173559
174704
  "--noEmit",
173560
174705
  "--project",
173561
- resolve13(vueTsconfigPath),
174706
+ resolve15(vueTsconfigPath),
173562
174707
  "--incremental",
173563
174708
  "--tsBuildInfoFile",
173564
- join18(cacheDir, "vue-tsc.tsbuildinfo"),
174709
+ join24(cacheDir, "vue-tsc.tsbuildinfo"),
173565
174710
  "--pretty"
173566
174711
  ]));
173567
174712
  }, buildAngularCheck = async (cacheDir, angularDir) => {
@@ -173570,7 +174715,7 @@ Found ${errorCount} error${suffix}.`;
173570
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");
173571
174716
  process.exit(1);
173572
174717
  }
173573
- const angularTsconfigPath = join18(cacheDir, "tsconfig.angular-check.json");
174718
+ const angularTsconfigPath = join24(cacheDir, "tsconfig.angular-check.json");
173574
174719
  await writeFile(angularTsconfigPath, JSON.stringify({
173575
174720
  angularCompilerOptions: {
173576
174721
  strictTemplates: true
@@ -173580,32 +174725,32 @@ Found ${errorCount} error${suffix}.`;
173580
174725
  rootDir: ".."
173581
174726
  },
173582
174727
  exclude: ABSOLUTE_INTERNAL_EXCLUDES.map(toGeneratedConfigPath),
173583
- extends: resolve13("tsconfig.json"),
174728
+ extends: resolve15("tsconfig.json"),
173584
174729
  include: [`../${angularDir}/**/*`]
173585
174730
  }, null, "\t"));
173586
- return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve13(angularTsconfigPath))}`);
174731
+ return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve15(angularTsconfigPath))}`);
173587
174732
  }, buildTscCheck = (cacheDir) => {
173588
174733
  const tscBin = findBin("tsc");
173589
174734
  if (!tscBin) {
173590
174735
  console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
173591
174736
  process.exit(1);
173592
174737
  }
173593
- const tscConfigPath = join18(cacheDir, "tsconfig.typecheck.json");
174738
+ const tscConfigPath = join24(cacheDir, "tsconfig.typecheck.json");
173594
174739
  return writeFile(tscConfigPath, JSON.stringify({
173595
174740
  compilerOptions: {
173596
174741
  rootDir: ".."
173597
174742
  },
173598
174743
  exclude: getProjectTypecheckExcludes(),
173599
- extends: resolve13("tsconfig.json"),
174744
+ extends: resolve15("tsconfig.json"),
173600
174745
  include: getProjectTypecheckIncludes()
173601
174746
  }, null, "\t")).then(() => run("tsc", [
173602
174747
  tscBin,
173603
174748
  "--noEmit",
173604
174749
  "--project",
173605
- resolve13(tscConfigPath),
174750
+ resolve15(tscConfigPath),
173606
174751
  "--incremental",
173607
174752
  "--tsBuildInfoFile",
173608
- join18(cacheDir, "tsc.tsbuildinfo"),
174753
+ join24(cacheDir, "tsc.tsbuildinfo"),
173609
174754
  "--pretty"
173610
174755
  ]));
173611
174756
  }, buildSvelteCheck = async (cacheDir, svelteDir) => {
@@ -173614,16 +174759,16 @@ Found ${errorCount} error${suffix}.`;
173614
174759
  console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
173615
174760
  process.exit(1);
173616
174761
  }
173617
- const svelteTsconfigPath = join18(cacheDir, "tsconfig.svelte-check.json");
174762
+ const svelteTsconfigPath = join24(cacheDir, "tsconfig.svelte-check.json");
173618
174763
  await writeFile(svelteTsconfigPath, JSON.stringify({
173619
- extends: resolve13("tsconfig.json"),
174764
+ extends: resolve15("tsconfig.json"),
173620
174765
  files: ABSOLUTE_TYPECHECK_FILES,
173621
174766
  include: [`../${svelteDir}/**/*`]
173622
174767
  }, null, "\t"));
173623
174768
  return run("svelte-check", [
173624
174769
  svelteBin,
173625
174770
  "--tsconfig",
173626
- resolve13(svelteTsconfigPath),
174771
+ resolve15(svelteTsconfigPath),
173627
174772
  "--threshold",
173628
174773
  "error",
173629
174774
  "--compiler-warnings",
@@ -173812,11 +174957,11 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
173812
174957
  url: url.pathname + url.search,
173813
174958
  ...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
173814
174959
  };
173815
- const responsePromise = new Promise((resolve14) => {
173816
- pending.set(id, resolve14);
174960
+ const responsePromise = new Promise((resolve16) => {
174961
+ pending.set(id, resolve16);
173817
174962
  });
173818
174963
  client.send(encodeTunnelMessage(message));
173819
- 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));
173820
174965
  const result = await Promise.race([responsePromise, timeout]);
173821
174966
  pending.delete(id);
173822
174967
  if (result.type === "error") {
@@ -177321,6 +178466,10 @@ if (command === "dev") {
177321
178466
  sendTelemetryEvent("cli:command", { command: "mem" });
177322
178467
  const { runMem: runMem2 } = await Promise.resolve().then(() => (init_mem(), exports_mem));
177323
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);
177324
178473
  } else if (command === "env") {
177325
178474
  sendTelemetryEvent("cli:command", { command: "env" });
177326
178475
  const { runEnv: runEnv2 } = await Promise.resolve().then(() => (init_env(), exports_env));
@@ -177379,6 +178528,7 @@ if (command === "dev") {
177379
178528
  console.error(" doctor [--json] Diagnose the project (bun, config, framework dirs, env, port)");
177380
178529
  console.error(" env [--check] [--json] Report env vars the app reads (getEnv) and which are missing");
177381
178530
  console.error(" eslint Run ESLint (cached)");
178531
+ console.error(" generate <page|api|component> <name> [--framework <fw>] Scaffold a page, API plugin, or component");
177382
178532
  console.error(" info Print system info for bug reports");
177383
178533
  console.error(" logs <name> [-f] [-n <lines>] Tail a running server's log by name");
177384
178534
  console.error(" ls [--sizes] [--budget <size>] [--json] List the project's pages by framework");