litestar-vite-plugin 0.15.0-alpha.7 → 0.15.0-beta.2
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/README.md +19 -1
- package/dist/js/astro.js +8 -230
- package/dist/js/helpers/htmx.d.ts +6 -1
- package/dist/js/helpers/htmx.js +9 -4
- package/dist/js/index.d.ts +72 -7
- package/dist/js/index.js +100 -183
- package/dist/js/nuxt.js +9 -229
- package/dist/js/shared/create-type-gen-plugin.d.ts +99 -0
- package/dist/js/shared/create-type-gen-plugin.js +110 -0
- package/dist/js/shared/emit-route-types.d.ts +41 -0
- package/dist/js/shared/emit-route-types.js +151 -0
- package/dist/js/shared/format-path.d.ts +22 -0
- package/dist/js/shared/format-path.js +24 -0
- package/dist/js/shared/logger.d.ts +43 -0
- package/dist/js/shared/logger.js +59 -0
- package/dist/js/sveltekit.js +9 -229
- package/package.json +2 -2
package/dist/js/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { exec } from "node:child_process";
|
|
2
|
-
import { createHash } from "node:crypto";
|
|
3
2
|
import fs from "node:fs";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -10,6 +9,9 @@ import fullReload from "vite-plugin-full-reload";
|
|
|
10
9
|
import { resolveInstallHint, resolvePackageExecutor } from "./install-hint.js";
|
|
11
10
|
import { checkBackendAvailability, loadLitestarMeta } from "./litestar-meta.js";
|
|
12
11
|
import { debounce } from "./shared/debounce.js";
|
|
12
|
+
import { emitRouteTypes } from "./shared/emit-route-types.js";
|
|
13
|
+
import { formatPath } from "./shared/format-path.js";
|
|
14
|
+
import { createLogger } from "./shared/logger.js";
|
|
13
15
|
const execAsync = promisify(exec);
|
|
14
16
|
let exitHandlersBound = false;
|
|
15
17
|
let warnedMissingRuntimeConfig = false;
|
|
@@ -23,16 +25,19 @@ function litestar(config) {
|
|
|
23
25
|
return plugins;
|
|
24
26
|
}
|
|
25
27
|
async function findIndexHtmlPath(server, pluginConfig) {
|
|
28
|
+
if (pluginConfig.inertiaMode) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
26
31
|
if (!pluginConfig.autoDetectIndex) {
|
|
27
32
|
return null;
|
|
28
33
|
}
|
|
29
34
|
const root = server.config.root;
|
|
30
35
|
const possiblePaths = [
|
|
31
36
|
path.join(root, "index.html"),
|
|
32
|
-
path.join(root, pluginConfig.
|
|
33
|
-
// Ensure
|
|
37
|
+
path.join(root, pluginConfig.resourceDir.replace(/^\//, ""), "index.html"),
|
|
38
|
+
// Ensure resourceDir path is relative to root
|
|
34
39
|
path.join(root, pluginConfig.publicDir.replace(/^\//, ""), "index.html"),
|
|
35
|
-
path.join(root, pluginConfig.
|
|
40
|
+
path.join(root, pluginConfig.bundleDir.replace(/^\//, ""), "index.html")
|
|
36
41
|
];
|
|
37
42
|
for (const indexPath of possiblePaths) {
|
|
38
43
|
try {
|
|
@@ -63,8 +68,9 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
63
68
|
let shuttingDown = false;
|
|
64
69
|
const pythonDefaults = loadPythonDefaults();
|
|
65
70
|
const proxyMode = pythonDefaults?.proxyMode ?? "vite_proxy";
|
|
71
|
+
const logger = createLogger(pythonDefaults?.logging);
|
|
66
72
|
const defaultAliases = {
|
|
67
|
-
"@": `/${pluginConfig.
|
|
73
|
+
"@": `/${pluginConfig.resourceDir.replace(/^\/+/, "").replace(/\/+$/, "")}/`
|
|
68
74
|
};
|
|
69
75
|
return {
|
|
70
76
|
name: "litestar",
|
|
@@ -195,9 +201,9 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
195
201
|
resolvedConfig.logger.warn(formatMissingConfigWarning());
|
|
196
202
|
}
|
|
197
203
|
}
|
|
198
|
-
const
|
|
199
|
-
if (!fs.existsSync(
|
|
200
|
-
resolvedConfig.logger.warn(`${colors.cyan("litestar-vite")} ${colors.yellow("Resource directory not found:")} ${pluginConfig.
|
|
204
|
+
const resourceDirPath = path.resolve(resolvedConfig.root, pluginConfig.resourceDir);
|
|
205
|
+
if (!fs.existsSync(resourceDirPath) && typeof resolvedConfig.logger?.warn === "function") {
|
|
206
|
+
resolvedConfig.logger.warn(`${colors.cyan("litestar-vite")} ${colors.yellow("Resource directory not found:")} ${pluginConfig.resourceDir}`);
|
|
201
207
|
}
|
|
202
208
|
const hint = pluginConfig.types !== false ? pluginConfig.types.routesPath : void 0;
|
|
203
209
|
litestarMeta = await loadLitestarMeta(resolvedConfig, hint);
|
|
@@ -229,19 +235,20 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
229
235
|
fs.writeFileSync(pluginConfig.hotFile, viteDevServerUrl);
|
|
230
236
|
}
|
|
231
237
|
setTimeout(async () => {
|
|
232
|
-
|
|
238
|
+
if (logger.config.level === "quiet") return;
|
|
239
|
+
const litestarVersion = litestarMeta.litestarVersion ?? process.env.LITESTAR_VERSION ?? "unknown";
|
|
233
240
|
const backendStatus = await checkBackendAvailability(appUrl);
|
|
234
241
|
resolvedConfig.logger.info(`
|
|
235
|
-
${colors.red(`${colors.bold("LITESTAR")} ${
|
|
242
|
+
${colors.red(`${colors.bold("LITESTAR")} ${litestarVersion}`)}`);
|
|
236
243
|
resolvedConfig.logger.info("");
|
|
237
244
|
if (initialIndexPath) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
245
|
+
const relIndexPath = logger.path(initialIndexPath, server.config.root);
|
|
246
|
+
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("Mode")}: SPA (${colors.cyan(relIndexPath)})`);
|
|
247
|
+
} else if (pluginConfig.inertiaMode) {
|
|
248
|
+
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("Mode")}: Inertia`);
|
|
241
249
|
} else {
|
|
242
|
-
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("
|
|
250
|
+
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("Mode")}: Litestar`);
|
|
243
251
|
}
|
|
244
|
-
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("Dev Server")}: ${colors.cyan(viteDevServerUrl)}`);
|
|
245
252
|
if (backendStatus.available) {
|
|
246
253
|
resolvedConfig.logger.info(
|
|
247
254
|
` ${colors.green("\u279C")} ${colors.bold("App URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))} ${colors.green("\u2713")}`
|
|
@@ -251,12 +258,13 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
251
258
|
` ${colors.yellow("\u279C")} ${colors.bold("App URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))} ${colors.yellow("\u26A0")}`
|
|
252
259
|
);
|
|
253
260
|
}
|
|
254
|
-
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("
|
|
261
|
+
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("Dev Server")}: ${colors.cyan(viteDevServerUrl)}`);
|
|
255
262
|
if (pluginConfig.types !== false && pluginConfig.types.enabled) {
|
|
256
263
|
const openapiExists = fs.existsSync(path.resolve(process.cwd(), pluginConfig.types.openapiPath));
|
|
257
264
|
const routesExists = fs.existsSync(path.resolve(process.cwd(), pluginConfig.types.routesPath));
|
|
265
|
+
const relTypesOutput = logger.path(pluginConfig.types.output, process.cwd());
|
|
258
266
|
if (openapiExists || routesExists) {
|
|
259
|
-
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("Type Gen")}: ${colors.
|
|
267
|
+
resolvedConfig.logger.info(` ${colors.green("\u279C")} ${colors.bold("Type Gen")}: ${colors.dim(`${relTypesOutput}/`)}`);
|
|
260
268
|
} else {
|
|
261
269
|
resolvedConfig.logger.info(` ${colors.yellow("\u279C")} ${colors.bold("Type Gen")}: ${colors.yellow("waiting")} ${colors.dim("(no schema files yet)")}`);
|
|
262
270
|
}
|
|
@@ -359,13 +367,6 @@ function ensureCommandShouldRunInEnvironment(command, env, mode) {
|
|
|
359
367
|
);
|
|
360
368
|
}
|
|
361
369
|
}
|
|
362
|
-
function _pluginVersion() {
|
|
363
|
-
try {
|
|
364
|
-
return JSON.parse(fs.readFileSync(path.join(dirname(), "../package.json")).toString())?.version;
|
|
365
|
-
} catch {
|
|
366
|
-
return "";
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
370
|
function loadPythonDefaults() {
|
|
370
371
|
const isTestEnv = Boolean(process.env.VITEST || process.env.VITE_TEST || process.env.NODE_ENV === "test");
|
|
371
372
|
let configPath = process.env.LITESTAR_VITE_CONFIG_PATH;
|
|
@@ -413,7 +414,7 @@ function formatMissingConfigWarning() {
|
|
|
413
414
|
`${y("\u2502")} ${d("litestar({")} ${y("\u2502")}`,
|
|
414
415
|
`${y("\u2502")} ${d(' input: ["src/main.tsx"],')} ${y("\u2502")}`,
|
|
415
416
|
`${y("\u2502")} ${d(' assetUrl: "/static/",')} ${y("\u2502")}`,
|
|
416
|
-
`${y("\u2502")} ${d('
|
|
417
|
+
`${y("\u2502")} ${d(' bundleDir: "public",')} ${y("\u2502")}`,
|
|
417
418
|
`${y("\u2502")} ${d(" types: false,")} ${y("\u2502")}`,
|
|
418
419
|
`${y("\u2502")} ${d("})")} ${y("\u2502")}`,
|
|
419
420
|
`${y("\u2502")} ${y("\u2502")}`,
|
|
@@ -440,16 +441,16 @@ function resolvePluginConfig(config) {
|
|
|
440
441
|
if (typeof resolvedConfig.input === "undefined") {
|
|
441
442
|
throw new Error('litestar-vite-plugin: missing configuration for "input".');
|
|
442
443
|
}
|
|
443
|
-
if (typeof resolvedConfig.
|
|
444
|
-
resolvedConfig.
|
|
445
|
-
if (resolvedConfig.
|
|
446
|
-
throw new Error("litestar-vite-plugin:
|
|
444
|
+
if (typeof resolvedConfig.resourceDir === "string") {
|
|
445
|
+
resolvedConfig.resourceDir = resolvedConfig.resourceDir.trim().replace(/^\/+/, "").replace(/\/+$/, "");
|
|
446
|
+
if (resolvedConfig.resourceDir === "") {
|
|
447
|
+
throw new Error("litestar-vite-plugin: resourceDir must be a subdirectory. E.g. 'resources'.");
|
|
447
448
|
}
|
|
448
449
|
}
|
|
449
|
-
if (typeof resolvedConfig.
|
|
450
|
-
resolvedConfig.
|
|
451
|
-
if (resolvedConfig.
|
|
452
|
-
throw new Error("litestar-vite-plugin:
|
|
450
|
+
if (typeof resolvedConfig.bundleDir === "string") {
|
|
451
|
+
resolvedConfig.bundleDir = resolvedConfig.bundleDir.trim().replace(/^\/+/, "").replace(/\/+$/, "");
|
|
452
|
+
if (resolvedConfig.bundleDir === "") {
|
|
453
|
+
throw new Error("litestar-vite-plugin: bundleDir must be a subdirectory. E.g. 'public'.");
|
|
453
454
|
}
|
|
454
455
|
}
|
|
455
456
|
if (typeof resolvedConfig.publicDir === "string") {
|
|
@@ -458,8 +459,8 @@ function resolvePluginConfig(config) {
|
|
|
458
459
|
throw new Error("litestar-vite-plugin: publicDir must be a subdirectory. E.g. 'public'.");
|
|
459
460
|
}
|
|
460
461
|
}
|
|
461
|
-
if (typeof resolvedConfig.
|
|
462
|
-
resolvedConfig.
|
|
462
|
+
if (typeof resolvedConfig.ssrOutDir === "string") {
|
|
463
|
+
resolvedConfig.ssrOutDir = resolvedConfig.ssrOutDir.trim().replace(/^\/+/, "").replace(/\/+$/, "");
|
|
463
464
|
}
|
|
464
465
|
if (resolvedConfig.refresh === true) {
|
|
465
466
|
resolvedConfig.refresh = [{ paths: refreshPaths }];
|
|
@@ -475,6 +476,7 @@ function resolvePluginConfig(config) {
|
|
|
475
476
|
pagePropsPath: "src/generated/inertia-pages.json",
|
|
476
477
|
generateZod: false,
|
|
477
478
|
generateSdk: false,
|
|
479
|
+
globalRoute: false,
|
|
478
480
|
debounce: 300
|
|
479
481
|
};
|
|
480
482
|
} else if (resolvedConfig.types === "auto" || typeof resolvedConfig.types === "undefined") {
|
|
@@ -487,6 +489,7 @@ function resolvePluginConfig(config) {
|
|
|
487
489
|
pagePropsPath: pythonDefaults.types.pagePropsPath ?? path.join(pythonDefaults.types.output, "inertia-pages.json"),
|
|
488
490
|
generateZod: pythonDefaults.types.generateZod,
|
|
489
491
|
generateSdk: pythonDefaults.types.generateSdk,
|
|
492
|
+
globalRoute: pythonDefaults.types.globalRoute ?? false,
|
|
490
493
|
debounce: 300
|
|
491
494
|
};
|
|
492
495
|
}
|
|
@@ -502,6 +505,7 @@ function resolvePluginConfig(config) {
|
|
|
502
505
|
pagePropsPath: resolvedConfig.types.pagePropsPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "inertia-pages.json") : "src/generated/inertia-pages.json"),
|
|
503
506
|
generateZod: resolvedConfig.types.generateZod ?? false,
|
|
504
507
|
generateSdk: resolvedConfig.types.generateSdk ?? false,
|
|
508
|
+
globalRoute: resolvedConfig.types.globalRoute ?? false,
|
|
505
509
|
debounce: resolvedConfig.types.debounce ?? 300
|
|
506
510
|
};
|
|
507
511
|
if (!userProvidedOpenapi && resolvedConfig.types.output) {
|
|
@@ -514,23 +518,55 @@ function resolvePluginConfig(config) {
|
|
|
514
518
|
typesConfig.pagePropsPath = path.join(typesConfig.output, "inertia-pages.json");
|
|
515
519
|
}
|
|
516
520
|
}
|
|
517
|
-
|
|
521
|
+
const inertiaMode = resolvedConfig.inertiaMode ?? pythonDefaults?.mode === "inertia";
|
|
522
|
+
const result = {
|
|
518
523
|
input: resolvedConfig.input,
|
|
519
524
|
assetUrl: normalizeAssetUrl(resolvedConfig.assetUrl ?? pythonDefaults?.assetUrl ?? "/static/"),
|
|
520
|
-
|
|
521
|
-
|
|
525
|
+
resourceDir: resolvedConfig.resourceDir ?? pythonDefaults?.resourceDir ?? "src",
|
|
526
|
+
bundleDir: resolvedConfig.bundleDir ?? pythonDefaults?.bundleDir ?? "public",
|
|
522
527
|
publicDir: resolvedConfig.publicDir ?? pythonDefaults?.publicDir ?? "public",
|
|
523
528
|
ssr: resolvedConfig.ssr ?? resolvedConfig.input,
|
|
524
|
-
|
|
529
|
+
ssrOutDir: resolvedConfig.ssrOutDir ?? pythonDefaults?.ssrOutDir ?? path.join(resolvedConfig.resourceDir ?? pythonDefaults?.resourceDir ?? "src", "bootstrap/ssr"),
|
|
525
530
|
refresh: resolvedConfig.refresh ?? false,
|
|
526
|
-
hotFile: resolvedConfig.hotFile ?? path.join(resolvedConfig.
|
|
531
|
+
hotFile: resolvedConfig.hotFile ?? path.join(resolvedConfig.bundleDir ?? "public", "hot"),
|
|
527
532
|
detectTls: resolvedConfig.detectTls ?? false,
|
|
528
533
|
autoDetectIndex: resolvedConfig.autoDetectIndex ?? true,
|
|
534
|
+
inertiaMode,
|
|
529
535
|
transformOnServe: resolvedConfig.transformOnServe ?? ((code) => code),
|
|
530
536
|
types: typesConfig,
|
|
531
537
|
executor: resolvedConfig.executor ?? pythonDefaults?.executor,
|
|
532
538
|
hasPythonConfig: pythonDefaults !== null
|
|
533
539
|
};
|
|
540
|
+
validateAgainstPythonDefaults(result, pythonDefaults, resolvedConfig);
|
|
541
|
+
return result;
|
|
542
|
+
}
|
|
543
|
+
function validateAgainstPythonDefaults(resolved, pythonDefaults, userConfig) {
|
|
544
|
+
if (!pythonDefaults) return;
|
|
545
|
+
const warnings = [];
|
|
546
|
+
const hasPythonValue = (value) => typeof value === "string" && value.length > 0;
|
|
547
|
+
if (userConfig.assetUrl !== void 0 && hasPythonValue(pythonDefaults.assetUrl) && resolved.assetUrl !== pythonDefaults.assetUrl) {
|
|
548
|
+
warnings.push(`assetUrl: vite.config.ts="${resolved.assetUrl}" differs from Python="${pythonDefaults.assetUrl}"`);
|
|
549
|
+
}
|
|
550
|
+
if (userConfig.bundleDir !== void 0 && hasPythonValue(pythonDefaults.bundleDir) && resolved.bundleDir !== pythonDefaults.bundleDir) {
|
|
551
|
+
warnings.push(`bundleDir: vite.config.ts="${resolved.bundleDir}" differs from Python="${pythonDefaults.bundleDir}"`);
|
|
552
|
+
}
|
|
553
|
+
if (userConfig.resourceDir !== void 0 && hasPythonValue(pythonDefaults.resourceDir) && resolved.resourceDir !== pythonDefaults.resourceDir) {
|
|
554
|
+
warnings.push(`resourceDir: vite.config.ts="${resolved.resourceDir}" differs from Python="${pythonDefaults.resourceDir}"`);
|
|
555
|
+
}
|
|
556
|
+
if (userConfig.publicDir !== void 0 && hasPythonValue(pythonDefaults.publicDir) && resolved.publicDir !== pythonDefaults.publicDir) {
|
|
557
|
+
warnings.push(`publicDir: vite.config.ts="${resolved.publicDir}" differs from Python="${pythonDefaults.publicDir}"`);
|
|
558
|
+
}
|
|
559
|
+
if (pythonDefaults.ssrEnabled && userConfig.ssrOutDir !== void 0 && hasPythonValue(pythonDefaults.ssrOutDir) && resolved.ssrOutDir !== pythonDefaults.ssrOutDir) {
|
|
560
|
+
warnings.push(`ssrOutDir: vite.config.ts="${resolved.ssrOutDir}" differs from Python="${pythonDefaults.ssrOutDir}"`);
|
|
561
|
+
}
|
|
562
|
+
if (warnings.length > 0) {
|
|
563
|
+
console.warn(
|
|
564
|
+
colors.yellow("[litestar-vite] Configuration mismatch detected:\n") + warnings.map((w) => ` ${colors.dim("\u2022")} ${w}`).join("\n") + `
|
|
565
|
+
|
|
566
|
+
${colors.dim("Precedence: vite.config.ts > .litestar.json > defaults")}
|
|
567
|
+
` + colors.dim("See: https://docs.litestar.dev/vite/config-precedence\n")
|
|
568
|
+
);
|
|
569
|
+
}
|
|
534
570
|
}
|
|
535
571
|
function resolveBase(_config, assetUrl) {
|
|
536
572
|
if (process.env.NODE_ENV === "development") {
|
|
@@ -544,11 +580,15 @@ function resolveInput(config, ssr) {
|
|
|
544
580
|
}
|
|
545
581
|
return config.input;
|
|
546
582
|
}
|
|
583
|
+
function isAbsolutePath(path2) {
|
|
584
|
+
return path2.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(path2);
|
|
585
|
+
}
|
|
547
586
|
function resolveOutDir(config, ssr) {
|
|
548
|
-
|
|
549
|
-
|
|
587
|
+
const dir = ssr ? config.ssrOutDir : config.bundleDir;
|
|
588
|
+
if (isAbsolutePath(dir)) {
|
|
589
|
+
return dir.replace(/[\\/]+$/, "");
|
|
550
590
|
}
|
|
551
|
-
return
|
|
591
|
+
return dir.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
552
592
|
}
|
|
553
593
|
function resolveFullReloadConfig({ refresh: config }) {
|
|
554
594
|
if (typeof config === "boolean") {
|
|
@@ -717,128 +757,6 @@ declare module "litestar-vite/inertia" {
|
|
|
717
757
|
`;
|
|
718
758
|
await fs.promises.writeFile(outFile, body, "utf-8");
|
|
719
759
|
}
|
|
720
|
-
async function emitRouteTypes(routesPath, outputDir) {
|
|
721
|
-
const contents = await fs.promises.readFile(routesPath, "utf-8");
|
|
722
|
-
const json = JSON.parse(contents);
|
|
723
|
-
const outDir = path.resolve(process.cwd(), outputDir);
|
|
724
|
-
await fs.promises.mkdir(outDir, { recursive: true });
|
|
725
|
-
const outFile = path.join(outDir, "routes.ts");
|
|
726
|
-
const banner = `// AUTO-GENERATED by litestar-vite. Do not edit.
|
|
727
|
-
/* eslint-disable */
|
|
728
|
-
|
|
729
|
-
`;
|
|
730
|
-
const routesData = json.routes || json;
|
|
731
|
-
const routeNames = Object.keys(routesData);
|
|
732
|
-
const routeNameType = routeNames.length > 0 ? routeNames.map((n) => `"${n}"`).join(" | ") : "never";
|
|
733
|
-
const routeParamTypes = [];
|
|
734
|
-
for (const [name, data] of Object.entries(routesData)) {
|
|
735
|
-
const routeData = data;
|
|
736
|
-
if (routeData.parameters && routeData.parameters.length > 0) {
|
|
737
|
-
const params = routeData.parameters.map((p) => `${p}: string | number`).join("; ");
|
|
738
|
-
routeParamTypes.push(` "${name}": { ${params} }`);
|
|
739
|
-
} else {
|
|
740
|
-
routeParamTypes.push(` "${name}": Record<string, never>`);
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
const body = `/**
|
|
744
|
-
* AUTO-GENERATED by litestar-vite.
|
|
745
|
-
*
|
|
746
|
-
* Exports:
|
|
747
|
-
* - routesMeta: full route metadata
|
|
748
|
-
* - routes: name -> uri map
|
|
749
|
-
* - serverRoutes: alias of routes for clarity in apps
|
|
750
|
-
* - route(): type-safe URL generator
|
|
751
|
-
* - hasRoute(): type guard
|
|
752
|
-
* - csrf helpers re-exported from litestar-vite-plugin/helpers
|
|
753
|
-
*
|
|
754
|
-
* @see https://litestar-vite.litestar.dev/
|
|
755
|
-
*/
|
|
756
|
-
export const routesMeta = ${JSON.stringify(json, null, 2)} as const
|
|
757
|
-
|
|
758
|
-
/**
|
|
759
|
-
* Route name to URI mapping.
|
|
760
|
-
*/
|
|
761
|
-
export const routes = ${JSON.stringify(Object.fromEntries(Object.entries(routesData).map(([name, data]) => [name, data.uri])), null, 2)} as const
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
* Alias for server-injected route map (more descriptive for consumers).
|
|
765
|
-
*/
|
|
766
|
-
export const serverRoutes = routes
|
|
767
|
-
|
|
768
|
-
/**
|
|
769
|
-
* All available route names.
|
|
770
|
-
*/
|
|
771
|
-
export type RouteName = ${routeNameType}
|
|
772
|
-
|
|
773
|
-
/**
|
|
774
|
-
* Parameter types for each route.
|
|
775
|
-
*/
|
|
776
|
-
export interface RouteParams {
|
|
777
|
-
${routeParamTypes.join("\n")}
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
/**
|
|
781
|
-
* Generate a URL for a named route with type-safe parameters.
|
|
782
|
-
*
|
|
783
|
-
* @param name - The route name
|
|
784
|
-
* @param params - Route parameters (required if route has path parameters)
|
|
785
|
-
* @returns The generated URL
|
|
786
|
-
*
|
|
787
|
-
* @example
|
|
788
|
-
* \`\`\`ts
|
|
789
|
-
* import { route } from '@/generated/routes'
|
|
790
|
-
*
|
|
791
|
-
* // Route without parameters
|
|
792
|
-
* route('home') // "/"
|
|
793
|
-
*
|
|
794
|
-
* // Route with parameters
|
|
795
|
-
* route('user:detail', { user_id: 123 }) // "/users/123"
|
|
796
|
-
* \`\`\`
|
|
797
|
-
*/
|
|
798
|
-
export function route<T extends RouteName>(
|
|
799
|
-
name: T,
|
|
800
|
-
...args: RouteParams[T] extends Record<string, never> ? [] : [params: RouteParams[T]]
|
|
801
|
-
): string {
|
|
802
|
-
let uri = routes[name] as string
|
|
803
|
-
const params = args[0] as Record<string, string | number> | undefined
|
|
804
|
-
|
|
805
|
-
if (params) {
|
|
806
|
-
for (const [key, value] of Object.entries(params)) {
|
|
807
|
-
// Handle both {param} and {param:type} syntax
|
|
808
|
-
uri = uri.replace(new RegExp(\`\\\\{\${key}(?::[^}]+)?\\\\}\`, "g"), String(value))
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
return uri
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* Check if a route name exists.
|
|
817
|
-
*/
|
|
818
|
-
export function hasRoute(name: string): name is RouteName {
|
|
819
|
-
return name in routes
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
declare global {
|
|
823
|
-
interface Window {
|
|
824
|
-
/**
|
|
825
|
-
* Fully-typed route metadata injected by Litestar.
|
|
826
|
-
*/
|
|
827
|
-
__LITESTAR_ROUTES__?: typeof routesMeta
|
|
828
|
-
/**
|
|
829
|
-
* Simple route map (name -> uri) for legacy consumers.
|
|
830
|
-
*/
|
|
831
|
-
routes?: Record<string, string>
|
|
832
|
-
serverRoutes?: Record<string, string>
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
// Re-export helper functions from litestar-vite-plugin
|
|
837
|
-
// These work with the routes defined above
|
|
838
|
-
export { getCsrfToken, csrfHeaders, csrfFetch } from "litestar-vite-plugin/helpers"
|
|
839
|
-
`;
|
|
840
|
-
await fs.promises.writeFile(outFile, `${banner}${body}`, "utf-8");
|
|
841
|
-
}
|
|
842
760
|
function resolveTypeGenerationPlugin(typesConfig, executor, hasPythonConfig) {
|
|
843
761
|
let lastTypesHash = null;
|
|
844
762
|
let lastRoutesHash = null;
|
|
@@ -864,10 +782,10 @@ function resolveTypeGenerationPlugin(typesConfig, executor, hasPythonConfig) {
|
|
|
864
782
|
chosenConfigPath = configPath;
|
|
865
783
|
const shouldRunOpenApiTs = configPath || typesConfig.generateSdk;
|
|
866
784
|
if (fs.existsSync(openapiPath) && shouldRunOpenApiTs) {
|
|
867
|
-
resolvedConfig?.logger.info(`${colors.cyan("
|
|
868
|
-
if (resolvedConfig) {
|
|
869
|
-
const relConfigPath = configPath
|
|
870
|
-
resolvedConfig.logger.info(`${colors.cyan("
|
|
785
|
+
resolvedConfig?.logger.info(`${colors.cyan("\u2022")} Generating TypeScript types...`);
|
|
786
|
+
if (resolvedConfig && configPath) {
|
|
787
|
+
const relConfigPath = formatPath(configPath, resolvedConfig.root);
|
|
788
|
+
resolvedConfig.logger.info(`${colors.cyan("\u2022")} openapi-ts config: ${relConfigPath}`);
|
|
871
789
|
}
|
|
872
790
|
const sdkOutput = path.join(typesConfig.output, "api");
|
|
873
791
|
let args;
|
|
@@ -890,7 +808,7 @@ function resolveTypeGenerationPlugin(typesConfig, executor, hasPythonConfig) {
|
|
|
890
808
|
try {
|
|
891
809
|
require.resolve("zod", { paths: [process.cwd()] });
|
|
892
810
|
} catch {
|
|
893
|
-
resolvedConfig?.logger.warn(`${colors.
|
|
811
|
+
resolvedConfig?.logger.warn(`${colors.yellow("!")} zod not installed - run: ${resolveInstallHint()} zod`);
|
|
894
812
|
}
|
|
895
813
|
}
|
|
896
814
|
await execAsync(resolvePackageExecutor(args.join(" "), executor), {
|
|
@@ -899,7 +817,7 @@ function resolveTypeGenerationPlugin(typesConfig, executor, hasPythonConfig) {
|
|
|
899
817
|
generated = true;
|
|
900
818
|
}
|
|
901
819
|
if (fs.existsSync(routesPath)) {
|
|
902
|
-
await emitRouteTypes(routesPath, typesConfig.output);
|
|
820
|
+
await emitRouteTypes(routesPath, typesConfig.output, { globalRoute: typesConfig.globalRoute ?? false });
|
|
903
821
|
generated = true;
|
|
904
822
|
}
|
|
905
823
|
if (fs.existsSync(pagePropsPath)) {
|
|
@@ -908,7 +826,7 @@ function resolveTypeGenerationPlugin(typesConfig, executor, hasPythonConfig) {
|
|
|
908
826
|
}
|
|
909
827
|
if (generated && resolvedConfig) {
|
|
910
828
|
const duration = Date.now() - startTime;
|
|
911
|
-
resolvedConfig.logger.info(`${colors.
|
|
829
|
+
resolvedConfig.logger.info(`${colors.green("\u2713")} TypeScript artifacts updated ${colors.dim(`(${duration}ms)`)}`);
|
|
912
830
|
}
|
|
913
831
|
if (generated && server) {
|
|
914
832
|
server.ws.send({
|
|
@@ -949,12 +867,12 @@ function resolveTypeGenerationPlugin(typesConfig, executor, hasPythonConfig) {
|
|
|
949
867
|
server = devServer;
|
|
950
868
|
if (typesConfig.enabled) {
|
|
951
869
|
const root = resolvedConfig?.root ?? process.cwd();
|
|
952
|
-
const openapiRel = typesConfig.openapiPath;
|
|
953
|
-
const routesRel = typesConfig.routesPath;
|
|
954
|
-
resolvedConfig?.logger.info(`${colors.cyan("
|
|
870
|
+
const openapiRel = path.basename(typesConfig.openapiPath);
|
|
871
|
+
const routesRel = path.basename(typesConfig.routesPath);
|
|
872
|
+
resolvedConfig?.logger.info(`${colors.cyan("\u2022")} Watching: ${colors.yellow(openapiRel)}, ${colors.yellow(routesRel)}`);
|
|
955
873
|
if (chosenConfigPath) {
|
|
956
|
-
const relConfigPath =
|
|
957
|
-
resolvedConfig?.logger.info(`${colors.cyan("
|
|
874
|
+
const relConfigPath = formatPath(chosenConfigPath, root);
|
|
875
|
+
resolvedConfig?.logger.info(`${colors.cyan("\u2022")} openapi-ts config: ${colors.yellow(relConfigPath)}`);
|
|
958
876
|
}
|
|
959
877
|
}
|
|
960
878
|
},
|
|
@@ -1000,7 +918,7 @@ Solutions:
|
|
|
1000
918
|
if (resolvedConfig) {
|
|
1001
919
|
resolvedConfig.logger.info(`${colors.cyan("litestar-vite")} ${colors.dim("schema changed:")} ${colors.yellow(relativePath)}`);
|
|
1002
920
|
}
|
|
1003
|
-
const newHash = await
|
|
921
|
+
const newHash = await getFileMtime(file);
|
|
1004
922
|
if (isOpenapi) {
|
|
1005
923
|
if (lastTypesHash === newHash) return;
|
|
1006
924
|
lastTypesHash = newHash;
|
|
@@ -1016,9 +934,9 @@ Solutions:
|
|
|
1016
934
|
}
|
|
1017
935
|
};
|
|
1018
936
|
}
|
|
1019
|
-
async function
|
|
1020
|
-
const
|
|
1021
|
-
return
|
|
937
|
+
async function getFileMtime(filePath) {
|
|
938
|
+
const stat = await fs.promises.stat(filePath);
|
|
939
|
+
return stat.mtimeMs.toString();
|
|
1022
940
|
}
|
|
1023
941
|
function resolveDevServerUrl(address, config, userConfig) {
|
|
1024
942
|
const configHmrProtocol = typeof config.server.hmr === "object" ? config.server.hmr.protocol : null;
|
|
@@ -1146,6 +1064,5 @@ function normalizeAssetUrl(url) {
|
|
|
1146
1064
|
return withTrailing;
|
|
1147
1065
|
}
|
|
1148
1066
|
export {
|
|
1149
|
-
litestar as default
|
|
1150
|
-
refreshPaths
|
|
1067
|
+
litestar as default
|
|
1151
1068
|
};
|