litestar-vite-plugin 0.15.0-beta.5 → 0.15.0-beta.6
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/js/astro.d.ts +27 -3
- package/dist/js/astro.js +55 -28
- package/dist/js/helpers/htmx.js +48 -15
- package/dist/js/helpers/index.d.ts +1 -1
- package/dist/js/helpers/index.js +1 -1
- package/dist/js/index.d.ts +26 -49
- package/dist/js/index.js +38 -374
- package/dist/js/inertia-helpers/index.d.ts +3 -4
- package/dist/js/inertia-helpers/index.js +3 -8
- package/dist/js/nuxt.d.ts +29 -32
- package/dist/js/nuxt.js +59 -35
- package/dist/js/shared/bridge-schema.d.ts +51 -0
- package/dist/js/shared/bridge-schema.js +178 -0
- package/dist/js/shared/emit-page-props-types.d.ts +4 -0
- package/dist/js/shared/emit-page-props-types.js +209 -0
- package/dist/js/shared/format-path.d.ts +0 -9
- package/dist/js/shared/format-path.js +1 -5
- package/dist/js/shared/typegen-plugin.d.ts +35 -0
- package/dist/js/shared/typegen-plugin.js +178 -0
- package/dist/js/sveltekit.d.ts +30 -6
- package/dist/js/sveltekit.js +35 -26
- package/package.json +3 -5
- package/dist/js/shared/create-type-gen-plugin.d.ts +0 -99
- package/dist/js/shared/create-type-gen-plugin.js +0 -110
- package/dist/js/shared/emit-route-types.d.ts +0 -41
- package/dist/js/shared/emit-route-types.js +0 -151
package/dist/js/index.js
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import { exec } from "node:child_process";
|
|
2
1
|
import fs from "node:fs";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { promisify } from "node:util";
|
|
6
4
|
import colors from "picocolors";
|
|
7
5
|
import { loadEnv } from "vite";
|
|
8
6
|
import fullReload from "vite-plugin-full-reload";
|
|
9
|
-
import { resolveInstallHint, resolvePackageExecutor } from "./install-hint.js";
|
|
10
7
|
import { checkBackendAvailability, loadLitestarMeta } from "./litestar-meta.js";
|
|
11
|
-
import {
|
|
12
|
-
import { emitRouteTypes } from "./shared/emit-route-types.js";
|
|
13
|
-
import { formatPath } from "./shared/format-path.js";
|
|
8
|
+
import { readBridgeConfig } from "./shared/bridge-schema.js";
|
|
14
9
|
import { createLogger } from "./shared/logger.js";
|
|
15
|
-
|
|
10
|
+
import { createLitestarTypeGenPlugin } from "./shared/typegen-plugin.js";
|
|
16
11
|
let exitHandlersBound = false;
|
|
17
12
|
let warnedMissingRuntimeConfig = false;
|
|
18
13
|
const refreshPaths = ["src/**", "resources/**", "assets/**"].filter((path2) => fs.existsSync(path2.replace(/\*\*$/, "")));
|
|
@@ -20,7 +15,15 @@ function litestar(config) {
|
|
|
20
15
|
const pluginConfig = resolvePluginConfig(config);
|
|
21
16
|
const plugins = [resolveLitestarPlugin(pluginConfig), ...resolveFullReloadConfig(pluginConfig)];
|
|
22
17
|
if (pluginConfig.types !== false && pluginConfig.types.enabled) {
|
|
23
|
-
plugins.push(
|
|
18
|
+
plugins.push(
|
|
19
|
+
createLitestarTypeGenPlugin(pluginConfig.types, {
|
|
20
|
+
pluginName: "litestar-vite-types",
|
|
21
|
+
frameworkName: "litestar-vite",
|
|
22
|
+
sdkClientPlugin: "@hey-api/client-axios",
|
|
23
|
+
executor: pluginConfig.executor,
|
|
24
|
+
hasPythonConfig: pluginConfig.hasPythonConfig
|
|
25
|
+
})
|
|
26
|
+
);
|
|
24
27
|
}
|
|
25
28
|
return plugins;
|
|
26
29
|
}
|
|
@@ -36,7 +39,7 @@ async function findIndexHtmlPath(server, pluginConfig) {
|
|
|
36
39
|
path.join(root, "index.html"),
|
|
37
40
|
path.join(root, pluginConfig.resourceDir.replace(/^\//, ""), "index.html"),
|
|
38
41
|
// Ensure resourceDir path is relative to root
|
|
39
|
-
path.join(root, pluginConfig.
|
|
42
|
+
path.join(root, pluginConfig.staticDir.replace(/^\//, ""), "index.html"),
|
|
40
43
|
path.join(root, pluginConfig.bundleDir.replace(/^\//, ""), "index.html")
|
|
41
44
|
];
|
|
42
45
|
for (const indexPath of possiblePaths) {
|
|
@@ -67,7 +70,6 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
67
70
|
let litestarMeta = {};
|
|
68
71
|
let shuttingDown = false;
|
|
69
72
|
const pythonDefaults = loadPythonDefaults();
|
|
70
|
-
const proxyMode = pythonDefaults?.proxyMode ?? "vite_proxy";
|
|
71
73
|
const logger = createLogger(pythonDefaults?.logging);
|
|
72
74
|
const defaultAliases = {
|
|
73
75
|
"@": `/${pluginConfig.resourceDir.replace(/^\/+/, "").replace(/\/+$/, "")}/`
|
|
@@ -113,7 +115,7 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
113
115
|
ensureCommandShouldRunInEnvironment(command, env, mode);
|
|
114
116
|
return {
|
|
115
117
|
base: userConfig.base ?? (command === "build" ? resolveBase(pluginConfig, assetUrl) : devBase),
|
|
116
|
-
publicDir: userConfig.publicDir ?? pluginConfig.
|
|
118
|
+
publicDir: userConfig.publicDir ?? pluginConfig.staticDir ?? false,
|
|
117
119
|
clearScreen: false,
|
|
118
120
|
build: {
|
|
119
121
|
manifest: userConfig.build?.manifest ?? (ssr ? false : "manifest.json"),
|
|
@@ -230,10 +232,8 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
230
232
|
const isAddressInfo = (x) => typeof x === "object";
|
|
231
233
|
if (isAddressInfo(address)) {
|
|
232
234
|
viteDevServerUrl = userConfig.server?.origin ? userConfig.server.origin : resolveDevServerUrl(address, server.config, userConfig);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
fs.writeFileSync(pluginConfig.hotFile, viteDevServerUrl);
|
|
236
|
-
}
|
|
235
|
+
fs.mkdirSync(path.dirname(pluginConfig.hotFile), { recursive: true });
|
|
236
|
+
fs.writeFileSync(pluginConfig.hotFile, viteDevServerUrl);
|
|
237
237
|
setTimeout(async () => {
|
|
238
238
|
if (logger.config.level === "quiet") return;
|
|
239
239
|
const litestarVersion = litestarMeta.litestarVersion ?? process.env.LITESTAR_VERSION ?? "unknown";
|
|
@@ -292,7 +292,7 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
292
292
|
}, 100);
|
|
293
293
|
}
|
|
294
294
|
});
|
|
295
|
-
if (!exitHandlersBound
|
|
295
|
+
if (!exitHandlersBound) {
|
|
296
296
|
const clean = () => {
|
|
297
297
|
if (pluginConfig.hotFile && fs.existsSync(pluginConfig.hotFile)) {
|
|
298
298
|
fs.rmSync(pluginConfig.hotFile);
|
|
@@ -369,26 +369,12 @@ function ensureCommandShouldRunInEnvironment(command, env, mode) {
|
|
|
369
369
|
}
|
|
370
370
|
function loadPythonDefaults() {
|
|
371
371
|
const isTestEnv = Boolean(process.env.VITEST || process.env.VITE_TEST || process.env.NODE_ENV === "test");
|
|
372
|
-
|
|
373
|
-
if (!
|
|
374
|
-
|
|
375
|
-
if (fs.existsSync(defaultPath)) {
|
|
376
|
-
configPath = defaultPath;
|
|
377
|
-
} else {
|
|
378
|
-
warnMissingRuntimeConfig("env", isTestEnv);
|
|
379
|
-
return null;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
if (!fs.existsSync(configPath)) {
|
|
383
|
-
warnMissingRuntimeConfig("file", isTestEnv);
|
|
384
|
-
return null;
|
|
385
|
-
}
|
|
386
|
-
try {
|
|
387
|
-
const data = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
388
|
-
return data;
|
|
389
|
-
} catch {
|
|
372
|
+
const defaults = readBridgeConfig();
|
|
373
|
+
if (!defaults) {
|
|
374
|
+
warnMissingRuntimeConfig("env", isTestEnv);
|
|
390
375
|
return null;
|
|
391
376
|
}
|
|
377
|
+
return defaults;
|
|
392
378
|
}
|
|
393
379
|
function formatMissingConfigWarning() {
|
|
394
380
|
const y = colors.yellow;
|
|
@@ -453,10 +439,10 @@ function resolvePluginConfig(config) {
|
|
|
453
439
|
throw new Error("litestar-vite-plugin: bundleDir must be a subdirectory. E.g. 'public'.");
|
|
454
440
|
}
|
|
455
441
|
}
|
|
456
|
-
if (typeof resolvedConfig.
|
|
457
|
-
resolvedConfig.
|
|
458
|
-
if (resolvedConfig.
|
|
459
|
-
throw new Error("litestar-vite-plugin:
|
|
442
|
+
if (typeof resolvedConfig.staticDir === "string") {
|
|
443
|
+
resolvedConfig.staticDir = resolvedConfig.staticDir.trim().replace(/^\/+/, "").replace(/\/+$/, "");
|
|
444
|
+
if (resolvedConfig.staticDir === "") {
|
|
445
|
+
throw new Error("litestar-vite-plugin: staticDir must be a subdirectory. E.g. 'src/public'.");
|
|
460
446
|
}
|
|
461
447
|
}
|
|
462
448
|
if (typeof resolvedConfig.ssrOutDir === "string") {
|
|
@@ -476,6 +462,8 @@ function resolvePluginConfig(config) {
|
|
|
476
462
|
pagePropsPath: "src/generated/inertia-pages.json",
|
|
477
463
|
generateZod: false,
|
|
478
464
|
generateSdk: false,
|
|
465
|
+
generateRoutes: true,
|
|
466
|
+
generatePageProps: true,
|
|
479
467
|
globalRoute: false,
|
|
480
468
|
debounce: 300
|
|
481
469
|
};
|
|
@@ -486,10 +474,12 @@ function resolvePluginConfig(config) {
|
|
|
486
474
|
output: pythonDefaults.types.output,
|
|
487
475
|
openapiPath: pythonDefaults.types.openapiPath,
|
|
488
476
|
routesPath: pythonDefaults.types.routesPath,
|
|
489
|
-
pagePropsPath: pythonDefaults.types.pagePropsPath
|
|
477
|
+
pagePropsPath: pythonDefaults.types.pagePropsPath,
|
|
490
478
|
generateZod: pythonDefaults.types.generateZod,
|
|
491
479
|
generateSdk: pythonDefaults.types.generateSdk,
|
|
492
|
-
|
|
480
|
+
generateRoutes: pythonDefaults.types.generateRoutes,
|
|
481
|
+
generatePageProps: pythonDefaults.types.generatePageProps,
|
|
482
|
+
globalRoute: pythonDefaults.types.globalRoute,
|
|
493
483
|
debounce: 300
|
|
494
484
|
};
|
|
495
485
|
}
|
|
@@ -505,6 +495,8 @@ function resolvePluginConfig(config) {
|
|
|
505
495
|
pagePropsPath: resolvedConfig.types.pagePropsPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "inertia-pages.json") : "src/generated/inertia-pages.json"),
|
|
506
496
|
generateZod: resolvedConfig.types.generateZod ?? false,
|
|
507
497
|
generateSdk: resolvedConfig.types.generateSdk ?? false,
|
|
498
|
+
generateRoutes: resolvedConfig.types.generateRoutes ?? true,
|
|
499
|
+
generatePageProps: resolvedConfig.types.generatePageProps ?? true,
|
|
508
500
|
globalRoute: resolvedConfig.types.globalRoute ?? false,
|
|
509
501
|
debounce: resolvedConfig.types.debounce ?? 300
|
|
510
502
|
};
|
|
@@ -519,14 +511,15 @@ function resolvePluginConfig(config) {
|
|
|
519
511
|
}
|
|
520
512
|
}
|
|
521
513
|
const inertiaMode = resolvedConfig.inertiaMode ?? pythonDefaults?.mode === "inertia";
|
|
514
|
+
const effectiveResourceDir = resolvedConfig.resourceDir ?? pythonDefaults?.resourceDir ?? "src";
|
|
522
515
|
const result = {
|
|
523
516
|
input: resolvedConfig.input,
|
|
524
517
|
assetUrl: normalizeAssetUrl(resolvedConfig.assetUrl ?? pythonDefaults?.assetUrl ?? "/static/"),
|
|
525
|
-
resourceDir:
|
|
518
|
+
resourceDir: effectiveResourceDir,
|
|
526
519
|
bundleDir: resolvedConfig.bundleDir ?? pythonDefaults?.bundleDir ?? "public",
|
|
527
|
-
|
|
520
|
+
staticDir: resolvedConfig.staticDir ?? pythonDefaults?.staticDir ?? path.join(effectiveResourceDir, "public"),
|
|
528
521
|
ssr: resolvedConfig.ssr ?? resolvedConfig.input,
|
|
529
|
-
ssrOutDir: resolvedConfig.ssrOutDir ?? pythonDefaults?.ssrOutDir ?? path.join(
|
|
522
|
+
ssrOutDir: resolvedConfig.ssrOutDir ?? pythonDefaults?.ssrOutDir ?? path.join(effectiveResourceDir, "bootstrap/ssr"),
|
|
530
523
|
refresh: resolvedConfig.refresh ?? false,
|
|
531
524
|
hotFile: resolvedConfig.hotFile ?? path.join(resolvedConfig.bundleDir ?? "public", "hot"),
|
|
532
525
|
detectTls: resolvedConfig.detectTls ?? false,
|
|
@@ -553,8 +546,8 @@ function validateAgainstPythonDefaults(resolved, pythonDefaults, userConfig) {
|
|
|
553
546
|
if (userConfig.resourceDir !== void 0 && hasPythonValue(pythonDefaults.resourceDir) && resolved.resourceDir !== pythonDefaults.resourceDir) {
|
|
554
547
|
warnings.push(`resourceDir: vite.config.ts="${resolved.resourceDir}" differs from Python="${pythonDefaults.resourceDir}"`);
|
|
555
548
|
}
|
|
556
|
-
if (userConfig.
|
|
557
|
-
warnings.push(`
|
|
549
|
+
if (userConfig.staticDir !== void 0 && hasPythonValue(pythonDefaults.staticDir) && resolved.staticDir !== pythonDefaults.staticDir) {
|
|
550
|
+
warnings.push(`staticDir: vite.config.ts="${resolved.staticDir}" differs from Python="${pythonDefaults.staticDir}"`);
|
|
558
551
|
}
|
|
559
552
|
if (pythonDefaults.ssrEnabled && userConfig.ssrOutDir !== void 0 && hasPythonValue(pythonDefaults.ssrOutDir) && resolved.ssrOutDir !== pythonDefaults.ssrOutDir) {
|
|
560
553
|
warnings.push(`ssrOutDir: vite.config.ts="${resolved.ssrOutDir}" differs from Python="${pythonDefaults.ssrOutDir}"`);
|
|
@@ -609,335 +602,6 @@ function resolveFullReloadConfig({ refresh: config }) {
|
|
|
609
602
|
return plugin;
|
|
610
603
|
});
|
|
611
604
|
}
|
|
612
|
-
async function emitPagePropsTypes(pagesPath, outputDir) {
|
|
613
|
-
const contents = await fs.promises.readFile(pagesPath, "utf-8");
|
|
614
|
-
const json = JSON.parse(contents);
|
|
615
|
-
const outDir = path.resolve(process.cwd(), outputDir);
|
|
616
|
-
await fs.promises.mkdir(outDir, { recursive: true });
|
|
617
|
-
const outFile = path.join(outDir, "page-props.ts");
|
|
618
|
-
const { includeDefaultAuth, includeDefaultFlash } = json.typeGenConfig;
|
|
619
|
-
let userTypes = "";
|
|
620
|
-
let authTypes = "";
|
|
621
|
-
let flashTypes = "";
|
|
622
|
-
if (includeDefaultAuth) {
|
|
623
|
-
userTypes = `/**
|
|
624
|
-
* Default User interface - minimal baseline for common auth patterns.
|
|
625
|
-
* Users extend this via module augmentation with their full user model.
|
|
626
|
-
*
|
|
627
|
-
* @example
|
|
628
|
-
* declare module 'litestar-vite/inertia' {
|
|
629
|
-
* interface User {
|
|
630
|
-
* avatarUrl?: string | null
|
|
631
|
-
* roles: Role[]
|
|
632
|
-
* teams: Team[]
|
|
633
|
-
* }
|
|
634
|
-
* }
|
|
635
|
-
*/
|
|
636
|
-
export interface User {
|
|
637
|
-
id: string
|
|
638
|
-
email: string
|
|
639
|
-
name?: string | null
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
`;
|
|
643
|
-
authTypes = `/**
|
|
644
|
-
* Default AuthData interface - mirrors Laravel Jetstream pattern.
|
|
645
|
-
* isAuthenticated + optional user is the universal pattern.
|
|
646
|
-
*/
|
|
647
|
-
export interface AuthData {
|
|
648
|
-
isAuthenticated: boolean
|
|
649
|
-
user?: User
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
`;
|
|
653
|
-
} else {
|
|
654
|
-
userTypes = `/**
|
|
655
|
-
* User interface - define via module augmentation.
|
|
656
|
-
* Default auth types are disabled.
|
|
657
|
-
*
|
|
658
|
-
* @example
|
|
659
|
-
* declare module 'litestar-vite/inertia' {
|
|
660
|
-
* interface User {
|
|
661
|
-
* uuid: string
|
|
662
|
-
* username: string
|
|
663
|
-
* }
|
|
664
|
-
* }
|
|
665
|
-
*/
|
|
666
|
-
export interface User {}
|
|
667
|
-
|
|
668
|
-
`;
|
|
669
|
-
authTypes = `/**
|
|
670
|
-
* AuthData interface - define via module augmentation.
|
|
671
|
-
* Default auth types are disabled.
|
|
672
|
-
*/
|
|
673
|
-
export interface AuthData {}
|
|
674
|
-
|
|
675
|
-
`;
|
|
676
|
-
}
|
|
677
|
-
if (includeDefaultFlash) {
|
|
678
|
-
flashTypes = `/**
|
|
679
|
-
* Default FlashMessages interface - category to messages mapping.
|
|
680
|
-
* Standard categories: success, error, info, warning.
|
|
681
|
-
*/
|
|
682
|
-
export interface FlashMessages {
|
|
683
|
-
[category: string]: string[]
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
`;
|
|
687
|
-
} else {
|
|
688
|
-
flashTypes = `/**
|
|
689
|
-
* FlashMessages interface - define via module augmentation.
|
|
690
|
-
* Default flash types are disabled.
|
|
691
|
-
*/
|
|
692
|
-
export interface FlashMessages {}
|
|
693
|
-
|
|
694
|
-
`;
|
|
695
|
-
}
|
|
696
|
-
const sharedPropsContent = includeDefaultAuth || includeDefaultFlash ? ` auth?: AuthData
|
|
697
|
-
flash?: FlashMessages` : "";
|
|
698
|
-
const pageEntries = [];
|
|
699
|
-
for (const [component, data] of Object.entries(json.pages)) {
|
|
700
|
-
const propsType = data.propsType ? data.propsType : "Record<string, unknown>";
|
|
701
|
-
pageEntries.push(` "${component}": ${propsType} & FullSharedProps`);
|
|
702
|
-
}
|
|
703
|
-
const body = `// AUTO-GENERATED by litestar-vite. Do not edit.
|
|
704
|
-
/* eslint-disable */
|
|
705
|
-
|
|
706
|
-
${userTypes}${authTypes}${flashTypes}/**
|
|
707
|
-
* Generated shared props (always present).
|
|
708
|
-
* Includes built-in props + static config props.
|
|
709
|
-
*/
|
|
710
|
-
export interface GeneratedSharedProps {
|
|
711
|
-
errors?: Record<string, string[]>
|
|
712
|
-
csrf_token?: string
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/**
|
|
716
|
-
* User-defined shared props for dynamic share() calls in guards/middleware.
|
|
717
|
-
* Extend this interface via module augmentation.
|
|
718
|
-
*
|
|
719
|
-
* @example
|
|
720
|
-
* declare module 'litestar-vite/inertia' {
|
|
721
|
-
* interface User {
|
|
722
|
-
* avatarUrl?: string | null
|
|
723
|
-
* roles: Role[]
|
|
724
|
-
* teams: Team[]
|
|
725
|
-
* }
|
|
726
|
-
* interface SharedProps {
|
|
727
|
-
* locale?: string
|
|
728
|
-
* currentTeam?: CurrentTeam
|
|
729
|
-
* }
|
|
730
|
-
* }
|
|
731
|
-
*/
|
|
732
|
-
export interface SharedProps {
|
|
733
|
-
${sharedPropsContent}
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
/** Full shared props = generated + user-defined */
|
|
737
|
-
export type FullSharedProps = GeneratedSharedProps & SharedProps
|
|
738
|
-
|
|
739
|
-
/** Page props mapped by component name */
|
|
740
|
-
export interface PageProps {
|
|
741
|
-
${pageEntries.join("\n")}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
/** Component name union type */
|
|
745
|
-
export type ComponentName = keyof PageProps
|
|
746
|
-
|
|
747
|
-
/** Type-safe props for a specific component */
|
|
748
|
-
export type InertiaPageProps<C extends ComponentName> = PageProps[C]
|
|
749
|
-
|
|
750
|
-
/** Get props type for a specific page component */
|
|
751
|
-
export type PagePropsFor<C extends ComponentName> = PageProps[C]
|
|
752
|
-
|
|
753
|
-
// Re-export for module augmentation
|
|
754
|
-
declare module "litestar-vite/inertia" {
|
|
755
|
-
export { User, AuthData, FlashMessages, SharedProps, GeneratedSharedProps, FullSharedProps, PageProps, ComponentName, InertiaPageProps, PagePropsFor }
|
|
756
|
-
}
|
|
757
|
-
`;
|
|
758
|
-
await fs.promises.writeFile(outFile, body, "utf-8");
|
|
759
|
-
}
|
|
760
|
-
function resolveTypeGenerationPlugin(typesConfig, executor, hasPythonConfig) {
|
|
761
|
-
let lastTypesHash = null;
|
|
762
|
-
let lastRoutesHash = null;
|
|
763
|
-
let lastPagePropsHash = null;
|
|
764
|
-
let server = null;
|
|
765
|
-
let isGenerating = false;
|
|
766
|
-
let resolvedConfig = null;
|
|
767
|
-
let chosenConfigPath = null;
|
|
768
|
-
async function runTypeGeneration() {
|
|
769
|
-
if (isGenerating) {
|
|
770
|
-
return false;
|
|
771
|
-
}
|
|
772
|
-
isGenerating = true;
|
|
773
|
-
const startTime = Date.now();
|
|
774
|
-
try {
|
|
775
|
-
const projectRoot = resolvedConfig?.root ?? process.cwd();
|
|
776
|
-
const openapiPath = path.resolve(projectRoot, typesConfig.openapiPath);
|
|
777
|
-
const routesPath = path.resolve(projectRoot, typesConfig.routesPath);
|
|
778
|
-
const pagePropsPath = path.resolve(projectRoot, typesConfig.pagePropsPath);
|
|
779
|
-
let generated = false;
|
|
780
|
-
const candidates = [path.resolve(projectRoot, "openapi-ts.config.ts"), path.resolve(projectRoot, "hey-api.config.ts"), path.resolve(projectRoot, ".hey-api.config.ts")];
|
|
781
|
-
const configPath = candidates.find((p) => fs.existsSync(p)) || null;
|
|
782
|
-
chosenConfigPath = configPath;
|
|
783
|
-
const shouldRunOpenApiTs = configPath || typesConfig.generateSdk;
|
|
784
|
-
if (fs.existsSync(openapiPath) && shouldRunOpenApiTs) {
|
|
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}`);
|
|
789
|
-
}
|
|
790
|
-
const sdkOutput = path.join(typesConfig.output, "api");
|
|
791
|
-
let args;
|
|
792
|
-
if (configPath) {
|
|
793
|
-
args = ["@hey-api/openapi-ts", "--file", configPath];
|
|
794
|
-
} else {
|
|
795
|
-
args = ["@hey-api/openapi-ts", "-i", typesConfig.openapiPath, "-o", sdkOutput];
|
|
796
|
-
const plugins = ["@hey-api/typescript", "@hey-api/schemas"];
|
|
797
|
-
if (typesConfig.generateSdk) {
|
|
798
|
-
plugins.push("@hey-api/sdk", "@hey-api/client-axios");
|
|
799
|
-
}
|
|
800
|
-
if (typesConfig.generateZod) {
|
|
801
|
-
plugins.push("zod");
|
|
802
|
-
}
|
|
803
|
-
if (plugins.length) {
|
|
804
|
-
args.push("--plugins", ...plugins);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
if (typesConfig.generateZod) {
|
|
808
|
-
try {
|
|
809
|
-
require.resolve("zod", { paths: [process.cwd()] });
|
|
810
|
-
} catch {
|
|
811
|
-
resolvedConfig?.logger.warn(`${colors.yellow("!")} zod not installed - run: ${resolveInstallHint()} zod`);
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
await execAsync(resolvePackageExecutor(args.join(" "), executor), {
|
|
815
|
-
cwd: projectRoot
|
|
816
|
-
});
|
|
817
|
-
generated = true;
|
|
818
|
-
}
|
|
819
|
-
if (fs.existsSync(routesPath)) {
|
|
820
|
-
await emitRouteTypes(routesPath, typesConfig.output, { globalRoute: typesConfig.globalRoute ?? false });
|
|
821
|
-
generated = true;
|
|
822
|
-
}
|
|
823
|
-
if (fs.existsSync(pagePropsPath)) {
|
|
824
|
-
await emitPagePropsTypes(pagePropsPath, typesConfig.output);
|
|
825
|
-
generated = true;
|
|
826
|
-
}
|
|
827
|
-
if (generated && resolvedConfig) {
|
|
828
|
-
const duration = Date.now() - startTime;
|
|
829
|
-
resolvedConfig.logger.info(`${colors.green("\u2713")} TypeScript artifacts updated ${colors.dim(`(${duration}ms)`)}`);
|
|
830
|
-
}
|
|
831
|
-
if (generated && server) {
|
|
832
|
-
server.ws.send({
|
|
833
|
-
type: "custom",
|
|
834
|
-
event: "litestar:types-updated",
|
|
835
|
-
data: {
|
|
836
|
-
output: typesConfig.output,
|
|
837
|
-
timestamp: Date.now()
|
|
838
|
-
}
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
return true;
|
|
842
|
-
} catch (error) {
|
|
843
|
-
if (resolvedConfig) {
|
|
844
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
845
|
-
if (message.includes("not found") || message.includes("ENOENT")) {
|
|
846
|
-
const zodHint = typesConfig.generateZod ? " zod" : "";
|
|
847
|
-
resolvedConfig.logger.warn(
|
|
848
|
-
`${colors.cyan("litestar-vite")} ${colors.yellow("@hey-api/openapi-ts not installed")} - run: ${resolveInstallHint()} -D @hey-api/openapi-ts${zodHint}`
|
|
849
|
-
);
|
|
850
|
-
} else {
|
|
851
|
-
resolvedConfig.logger.error(`${colors.cyan("litestar-vite")} ${colors.red("type generation failed:")} ${message}`);
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
return false;
|
|
855
|
-
} finally {
|
|
856
|
-
isGenerating = false;
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
const debouncedRunTypeGeneration = debounce(runTypeGeneration, typesConfig.debounce);
|
|
860
|
-
return {
|
|
861
|
-
name: "litestar-vite-types",
|
|
862
|
-
enforce: "pre",
|
|
863
|
-
configResolved(config) {
|
|
864
|
-
resolvedConfig = config;
|
|
865
|
-
},
|
|
866
|
-
configureServer(devServer) {
|
|
867
|
-
server = devServer;
|
|
868
|
-
if (typesConfig.enabled) {
|
|
869
|
-
const root = resolvedConfig?.root ?? process.cwd();
|
|
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)}`);
|
|
873
|
-
if (chosenConfigPath) {
|
|
874
|
-
const relConfigPath = formatPath(chosenConfigPath, root);
|
|
875
|
-
resolvedConfig?.logger.info(`${colors.cyan("\u2022")} openapi-ts config: ${colors.yellow(relConfigPath)}`);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
},
|
|
879
|
-
async buildStart() {
|
|
880
|
-
if (typesConfig.enabled && !hasPythonConfig) {
|
|
881
|
-
const projectRoot = resolvedConfig?.root ?? process.cwd();
|
|
882
|
-
const openapiPath = path.resolve(projectRoot, typesConfig.openapiPath);
|
|
883
|
-
if (!fs.existsSync(openapiPath)) {
|
|
884
|
-
this.warn(
|
|
885
|
-
`Type generation is enabled but .litestar.json was not found.
|
|
886
|
-
The Litestar backend generates this file on startup.
|
|
887
|
-
|
|
888
|
-
Solutions:
|
|
889
|
-
1. Start the backend first: ${colors.cyan("litestar run")}
|
|
890
|
-
2. Use integrated dev: ${colors.cyan("litestar assets serve")}
|
|
891
|
-
3. Disable types: ${colors.cyan("litestar({ input: [...], types: false })")}
|
|
892
|
-
`
|
|
893
|
-
);
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
if (typesConfig.enabled) {
|
|
897
|
-
const projectRoot = resolvedConfig?.root ?? process.cwd();
|
|
898
|
-
const openapiPath = path.resolve(projectRoot, typesConfig.openapiPath);
|
|
899
|
-
const routesPath = path.resolve(projectRoot, typesConfig.routesPath);
|
|
900
|
-
if (fs.existsSync(openapiPath) || fs.existsSync(routesPath)) {
|
|
901
|
-
await runTypeGeneration();
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
},
|
|
905
|
-
async handleHotUpdate({ file }) {
|
|
906
|
-
if (!typesConfig.enabled) {
|
|
907
|
-
return;
|
|
908
|
-
}
|
|
909
|
-
const root = resolvedConfig?.root ?? process.cwd();
|
|
910
|
-
const relativePath = path.relative(root, file);
|
|
911
|
-
const openapiPath = typesConfig.openapiPath.replace(/^\.\//, "");
|
|
912
|
-
const routesPath = typesConfig.routesPath.replace(/^\.\//, "");
|
|
913
|
-
const pagePropsPath = typesConfig.pagePropsPath.replace(/^\.\//, "");
|
|
914
|
-
const isOpenapi = relativePath === openapiPath || file.endsWith(openapiPath);
|
|
915
|
-
const isRoutes = relativePath === routesPath || file.endsWith(routesPath);
|
|
916
|
-
const isPageProps = relativePath === pagePropsPath || file.endsWith(pagePropsPath);
|
|
917
|
-
if (isOpenapi || isRoutes || isPageProps) {
|
|
918
|
-
if (resolvedConfig) {
|
|
919
|
-
resolvedConfig.logger.info(`${colors.cyan("litestar-vite")} ${colors.dim("schema changed:")} ${colors.yellow(relativePath)}`);
|
|
920
|
-
}
|
|
921
|
-
const newHash = await getFileMtime(file);
|
|
922
|
-
if (isOpenapi) {
|
|
923
|
-
if (lastTypesHash === newHash) return;
|
|
924
|
-
lastTypesHash = newHash;
|
|
925
|
-
} else if (isRoutes) {
|
|
926
|
-
if (lastRoutesHash === newHash) return;
|
|
927
|
-
lastRoutesHash = newHash;
|
|
928
|
-
} else if (isPageProps) {
|
|
929
|
-
if (lastPagePropsHash === newHash) return;
|
|
930
|
-
lastPagePropsHash = newHash;
|
|
931
|
-
}
|
|
932
|
-
debouncedRunTypeGeneration();
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
};
|
|
936
|
-
}
|
|
937
|
-
async function getFileMtime(filePath) {
|
|
938
|
-
const stat = await fs.promises.stat(filePath);
|
|
939
|
-
return stat.mtimeMs.toString();
|
|
940
|
-
}
|
|
941
605
|
function resolveDevServerUrl(address, config, userConfig) {
|
|
942
606
|
const configHmrProtocol = typeof config.server.hmr === "object" ? config.server.hmr.protocol : null;
|
|
943
607
|
const clientProtocol = configHmrProtocol ? configHmrProtocol === "wss" ? "https" : "http" : null;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inertia.js helpers for Litestar applications.
|
|
3
3
|
*
|
|
4
|
-
* This module
|
|
5
|
-
*
|
|
4
|
+
* This module provides Inertia-specific runtime utilities.
|
|
5
|
+
* For CSRF utilities, import from `litestar-vite-plugin/helpers`.
|
|
6
6
|
*
|
|
7
7
|
* For type-safe routing, import from your generated routes file:
|
|
8
8
|
* ```ts
|
|
9
|
-
* import { route,
|
|
9
|
+
* import { route, routeDefinitions, type RouteName } from '@/generated/routes'
|
|
10
10
|
* ```
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
|
-
export { csrfFetch, csrfHeaders, getCsrfToken, } from "litestar-vite-plugin/helpers";
|
|
15
14
|
/**
|
|
16
15
|
* Unwrap page props that may have content nested under "content" key.
|
|
17
16
|
*
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inertia.js helpers for Litestar applications.
|
|
3
3
|
*
|
|
4
|
-
* This module
|
|
5
|
-
*
|
|
4
|
+
* This module provides Inertia-specific runtime utilities.
|
|
5
|
+
* For CSRF utilities, import from `litestar-vite-plugin/helpers`.
|
|
6
6
|
*
|
|
7
7
|
* For type-safe routing, import from your generated routes file:
|
|
8
8
|
* ```ts
|
|
9
|
-
* import { route,
|
|
9
|
+
* import { route, routeDefinitions, type RouteName } from '@/generated/routes'
|
|
10
10
|
* ```
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
|
-
// Re-export all helpers from the main helpers module
|
|
15
|
-
// Note: Using package path instead of relative import to ensure proper build output structure
|
|
16
|
-
export { csrfFetch, csrfHeaders,
|
|
17
|
-
// CSRF utilities
|
|
18
|
-
getCsrfToken, } from "litestar-vite-plugin/helpers";
|
|
19
14
|
/**
|
|
20
15
|
* Unwrap page props that may have content nested under "content" key.
|
|
21
16
|
*
|
package/dist/js/nuxt.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* apiPrefix: '/api',
|
|
18
18
|
* types: {
|
|
19
19
|
* enabled: true,
|
|
20
|
-
* output: '
|
|
20
|
+
* output: 'generated',
|
|
21
21
|
* },
|
|
22
22
|
* },
|
|
23
23
|
* });
|
|
@@ -40,7 +40,7 @@ export interface NuxtTypesConfig {
|
|
|
40
40
|
* Path to output generated TypeScript types.
|
|
41
41
|
* Relative to the Nuxt project root.
|
|
42
42
|
*
|
|
43
|
-
* @default '
|
|
43
|
+
* @default 'generated'
|
|
44
44
|
*/
|
|
45
45
|
output?: string;
|
|
46
46
|
/**
|
|
@@ -55,6 +55,12 @@ export interface NuxtTypesConfig {
|
|
|
55
55
|
* @default 'routes.json'
|
|
56
56
|
*/
|
|
57
57
|
routesPath?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Path where Inertia page props metadata is exported by Litestar.
|
|
60
|
+
*
|
|
61
|
+
* @default 'inertia-pages.json'
|
|
62
|
+
*/
|
|
63
|
+
pagePropsPath?: string;
|
|
58
64
|
/**
|
|
59
65
|
* Generate Zod schemas in addition to TypeScript types.
|
|
60
66
|
*
|
|
@@ -67,6 +73,24 @@ export interface NuxtTypesConfig {
|
|
|
67
73
|
* @default true
|
|
68
74
|
*/
|
|
69
75
|
generateSdk?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Generate typed routes.ts from routes.json metadata.
|
|
78
|
+
*
|
|
79
|
+
* @default true
|
|
80
|
+
*/
|
|
81
|
+
generateRoutes?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Generate Inertia page props types from inertia-pages.json metadata.
|
|
84
|
+
*
|
|
85
|
+
* @default true
|
|
86
|
+
*/
|
|
87
|
+
generatePageProps?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Register route() globally on window object.
|
|
90
|
+
*
|
|
91
|
+
* @default false
|
|
92
|
+
*/
|
|
93
|
+
globalRoute?: boolean;
|
|
70
94
|
/**
|
|
71
95
|
* Debounce time in milliseconds for type regeneration.
|
|
72
96
|
*
|
|
@@ -116,33 +140,6 @@ export interface LitestarNuxtConfig {
|
|
|
116
140
|
*/
|
|
117
141
|
executor?: "node" | "bun" | "deno" | "yarn" | "pnpm";
|
|
118
142
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Litestar Vite plugins for Nuxt.
|
|
121
|
-
*
|
|
122
|
-
* This function returns an array of Vite plugins that can be added to Nuxt's
|
|
123
|
-
* vite configuration. For the full Nuxt module experience, use the module
|
|
124
|
-
* directly in your nuxt.config.ts.
|
|
125
|
-
*
|
|
126
|
-
* @param userConfig - Configuration options
|
|
127
|
-
* @returns Array of Vite plugins
|
|
128
|
-
*
|
|
129
|
-
* @example Using as Vite plugins in nuxt.config.ts
|
|
130
|
-
* ```typescript
|
|
131
|
-
* import { litestarPlugins } from 'litestar-vite-plugin/nuxt';
|
|
132
|
-
*
|
|
133
|
-
* export default defineNuxtConfig({
|
|
134
|
-
* vite: {
|
|
135
|
-
* plugins: [
|
|
136
|
-
* ...litestarPlugins({
|
|
137
|
-
* apiProxy: 'http://localhost:8000',
|
|
138
|
-
* types: true,
|
|
139
|
-
* }),
|
|
140
|
-
* ],
|
|
141
|
-
* },
|
|
142
|
-
* });
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
export declare function litestarPlugins(userConfig?: LitestarNuxtConfig): Plugin[];
|
|
146
143
|
/**
|
|
147
144
|
* Nuxt module definition for Litestar integration.
|
|
148
145
|
*
|
|
@@ -158,7 +155,7 @@ export declare function litestarPlugins(userConfig?: LitestarNuxtConfig): Plugin
|
|
|
158
155
|
* apiPrefix: '/api',
|
|
159
156
|
* types: {
|
|
160
157
|
* enabled: true,
|
|
161
|
-
* output: '
|
|
158
|
+
* output: 'generated',
|
|
162
159
|
* },
|
|
163
160
|
* },
|
|
164
161
|
* });
|
|
@@ -167,8 +164,8 @@ export declare function litestarPlugins(userConfig?: LitestarNuxtConfig): Plugin
|
|
|
167
164
|
* @example Using generated types in a composable
|
|
168
165
|
* ```typescript
|
|
169
166
|
* // composables/useApi.ts
|
|
170
|
-
* import type { User } from '~/
|
|
171
|
-
* import { route } from '~/
|
|
167
|
+
* import type { User } from '~/generated/api/types.gen';
|
|
168
|
+
* import { route } from '~/generated/routes';
|
|
172
169
|
*
|
|
173
170
|
* export async function useUser(id: string) {
|
|
174
171
|
* const { data } = await useFetch<User>(route('users.show', { id }));
|