litestar-vite-plugin 0.24.1 → 0.26.0
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 +6 -6
- package/dist/js/astro.d.ts +6 -0
- package/dist/js/astro.js +14 -77
- package/dist/js/dev-server-index.html +2 -2
- package/dist/js/helpers/csrf.d.ts +2 -0
- package/dist/js/helpers/csrf.js +28 -1
- package/dist/js/helpers/htmx.js +105 -2
- package/dist/js/index.d.ts +6 -0
- package/dist/js/index.js +75 -128
- package/dist/js/inertia-helpers/index.d.ts +27 -9
- package/dist/js/install-hint.d.ts +17 -0
- package/dist/js/install-hint.js +35 -1
- package/dist/js/nuxt.d.ts +6 -0
- package/dist/js/nuxt.js +12 -72
- package/dist/js/shared/bridge-schema.d.ts +1 -0
- package/dist/js/shared/bridge-schema.js +41 -9
- package/dist/js/shared/constants.d.ts +4 -18
- package/dist/js/shared/constants.js +2 -6
- package/dist/js/shared/emit-page-props-types.d.ts +1 -1
- package/dist/js/shared/emit-page-props-types.js +51 -5
- package/dist/js/shared/emit-schemas-types.d.ts +1 -1
- package/dist/js/shared/emit-schemas-types.js +86 -15
- package/dist/js/shared/emit-static-props-types.d.ts +1 -1
- package/dist/js/shared/emit-static-props-types.js +2 -2
- package/dist/js/shared/typegen-cache.d.ts +10 -11
- package/dist/js/shared/typegen-cache.js +10 -1
- package/dist/js/shared/typegen-core.d.ts +24 -0
- package/dist/js/shared/typegen-core.js +101 -45
- package/dist/js/shared/typegen-plugin.d.ts +26 -0
- package/dist/js/shared/typegen-plugin.js +191 -129
- package/dist/js/shared/vite-compat.d.ts +23 -15
- package/dist/js/shared/vite-compat.js +12 -6
- package/dist/js/sveltekit.d.ts +6 -0
- package/dist/js/sveltekit.js +14 -77
- package/package.json +14 -8
package/dist/js/index.js
CHANGED
|
@@ -6,12 +6,11 @@ import { loadEnv } from "vite";
|
|
|
6
6
|
import fullReload from "vite-plugin-full-reload";
|
|
7
7
|
import { checkBackendAvailability, loadLitestarMeta } from "./litestar-meta.js";
|
|
8
8
|
import { readBridgeConfig } from "./shared/bridge-schema.js";
|
|
9
|
-
import { DEBOUNCE_MS } from "./shared/constants.js";
|
|
10
9
|
import { createLogger } from "./shared/logger.js";
|
|
11
10
|
import { resolveLitestarPort } from "./shared/network.js";
|
|
12
11
|
import { resolveDefaultSdkClientPlugin } from "./shared/typegen-core.js";
|
|
13
|
-
import { createLitestarTypeGenPlugin } from "./shared/typegen-plugin.js";
|
|
14
|
-
import { buildInputOptions, resolveUserBuildInput } from "./shared/vite-compat.js";
|
|
12
|
+
import { createLitestarTypeGenPlugin, resolveTypesConfig } from "./shared/typegen-plugin.js";
|
|
13
|
+
import { buildInputOptions, hmrServerConfig, resolveUserBuildInput } from "./shared/vite-compat.js";
|
|
15
14
|
let exitHandlersBound = false;
|
|
16
15
|
let warnedMissingRuntimeConfig = false;
|
|
17
16
|
const MAX_TRANSFORM_PAYLOAD_BYTES = 1e6;
|
|
@@ -94,32 +93,32 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
94
93
|
const proxyHmrClientPort = pythonDefaults?.proxyMode === "vite" ? resolveLitestarPort(pythonDefaults.litestarPort, effectiveAppUrl, process.env) : null;
|
|
95
94
|
const withProxyErrorSilencer = (proxyConfig) => {
|
|
96
95
|
if (!proxyConfig) return void 0;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
configure(proxy, opts) {
|
|
109
|
-
proxy.on("error", (err) => {
|
|
110
|
-
const msg = String(err?.message ?? "");
|
|
111
|
-
if (shuttingDown || msg.includes("ECONNREFUSED") || msg.includes("ECONNRESET") || msg.includes("socket hang up")) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
if (typeof existingConfigure === "function") {
|
|
116
|
-
existingConfigure(proxy, opts);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
96
|
+
const entries = Object.entries(proxyConfig).map(([key, value]) => {
|
|
97
|
+
if (typeof value !== "object" || value === null) {
|
|
98
|
+
return [key, value];
|
|
99
|
+
}
|
|
100
|
+
const existingConfigure = value.configure;
|
|
101
|
+
const valueWithWebsocket = Object.hasOwn(value, "ws") ? value : { ...value, ws: true };
|
|
102
|
+
const configure = (proxy, opts) => {
|
|
103
|
+
proxy.on("error", (err) => {
|
|
104
|
+
const msg = err.message;
|
|
105
|
+
if (shuttingDown || msg.includes("ECONNREFUSED") || msg.includes("ECONNRESET") || msg.includes("socket hang up")) {
|
|
106
|
+
return;
|
|
119
107
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
108
|
+
});
|
|
109
|
+
if (typeof existingConfigure === "function") {
|
|
110
|
+
existingConfigure(proxy, opts);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
return [
|
|
114
|
+
key,
|
|
115
|
+
{
|
|
116
|
+
...valueWithWebsocket,
|
|
117
|
+
configure
|
|
118
|
+
}
|
|
119
|
+
];
|
|
120
|
+
});
|
|
121
|
+
return Object.fromEntries(entries);
|
|
123
122
|
};
|
|
124
123
|
const explicitServerOrigin = typeof userConfig.server?.origin === "string" && userConfig.server.origin.length > 0 ? userConfig.server.origin : void 0;
|
|
125
124
|
const shouldForceDirectServerOrigin = explicitServerOrigin !== void 0 || pythonDefaults?.proxyMode === "direct";
|
|
@@ -139,15 +138,19 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
139
138
|
},
|
|
140
139
|
server: {
|
|
141
140
|
origin: shouldForceDirectServerOrigin ? explicitServerOrigin ?? "__litestar_vite_placeholder__" : proxyOriginDefault,
|
|
142
|
-
// Auto-configure HMR to use a path that routes through Litestar proxy
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
|
|
141
|
+
// Auto-configure the HMR WebSocket to use a path that routes through the Litestar proxy.
|
|
142
|
+
// Auto-configure the HMR WebSocket to route through the Litestar proxy.
|
|
143
|
+
// Vite 8.1 moved the HMR network options (path/host/port/clientPort/protocol/timeout)
|
|
144
|
+
// from `server.hmr.*` to `server.ws.*`; on Vite 7 / 8.0 they stay under `server.hmr.*`.
|
|
145
|
+
// `hmrServerConfig` picks the right key for the running version (deprecation-free on each).
|
|
146
|
+
// Note: Vite prepends `base` to the path, so we use "vite-hmr" => "/static/vite-hmr".
|
|
147
|
+
...userConfig.server?.hmr === false || userConfig.server?.ws === false ? { hmr: false } : hmrServerConfig({
|
|
146
148
|
path: "vite-hmr",
|
|
147
149
|
...proxyHmrClientPort ? { clientPort: proxyHmrClientPort } : {},
|
|
148
|
-
...serverConfig?.
|
|
149
|
-
...userConfig.server?.
|
|
150
|
-
|
|
150
|
+
...serverConfig?.host ? { host: serverConfig.host } : {},
|
|
151
|
+
...typeof userConfig.server?.ws === "object" ? userConfig.server.ws : {},
|
|
152
|
+
...typeof userConfig.server?.hmr === "object" ? userConfig.server.hmr : {}
|
|
153
|
+
}),
|
|
151
154
|
// Auto-configure proxy to forward API requests to Litestar backend
|
|
152
155
|
// This allows the app to work when accessing Vite directly (not through Litestar proxy)
|
|
153
156
|
// Only proxies /api and /schema routes - everything else is handled by Vite
|
|
@@ -583,80 +586,11 @@ function resolvePluginConfig(config) {
|
|
|
583
586
|
if (resolvedConfig.refresh === true) {
|
|
584
587
|
resolvedConfig.refresh = [{ paths: refreshPaths }];
|
|
585
588
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const defaultPagePropsPath = path.join(defaultTypesOutput, "inertia-pages.json");
|
|
592
|
-
if (resolvedConfig.types === false) {
|
|
593
|
-
} else if (resolvedConfig.types === true) {
|
|
594
|
-
typesConfig = {
|
|
595
|
-
enabled: true,
|
|
596
|
-
output: defaultTypesOutput,
|
|
597
|
-
openapiPath: defaultOpenapiPath,
|
|
598
|
-
routesPath: defaultRoutesPath,
|
|
599
|
-
pagePropsPath: defaultPagePropsPath,
|
|
600
|
-
schemasTsPath: defaultSchemasTsPath,
|
|
601
|
-
generateZod: false,
|
|
602
|
-
generateSdk: true,
|
|
603
|
-
generateRoutes: true,
|
|
604
|
-
generatePageProps: true,
|
|
605
|
-
generateSchemas: true,
|
|
606
|
-
globalRoute: false,
|
|
607
|
-
debounce: DEBOUNCE_MS
|
|
608
|
-
};
|
|
609
|
-
} else if (resolvedConfig.types === "auto" || typeof resolvedConfig.types === "undefined") {
|
|
610
|
-
if (pythonDefaults?.types) {
|
|
611
|
-
typesConfig = {
|
|
612
|
-
enabled: pythonDefaults.types.enabled,
|
|
613
|
-
output: pythonDefaults.types.output,
|
|
614
|
-
openapiPath: pythonDefaults.types.openapiPath,
|
|
615
|
-
routesPath: pythonDefaults.types.routesPath,
|
|
616
|
-
pagePropsPath: pythonDefaults.types.pagePropsPath,
|
|
617
|
-
schemasTsPath: pythonDefaults.types.schemasTsPath ?? path.join(pythonDefaults.types.output, "schemas.ts"),
|
|
618
|
-
generateZod: pythonDefaults.types.generateZod,
|
|
619
|
-
generateSdk: pythonDefaults.types.generateSdk,
|
|
620
|
-
generateRoutes: pythonDefaults.types.generateRoutes,
|
|
621
|
-
generatePageProps: pythonDefaults.types.generatePageProps,
|
|
622
|
-
generateSchemas: pythonDefaults.types.generateSchemas ?? true,
|
|
623
|
-
globalRoute: pythonDefaults.types.globalRoute,
|
|
624
|
-
debounce: DEBOUNCE_MS
|
|
625
|
-
};
|
|
626
|
-
}
|
|
627
|
-
} else if (typeof resolvedConfig.types === "object" && resolvedConfig.types !== null) {
|
|
628
|
-
const userProvidedOpenapi = Object.hasOwn(resolvedConfig.types, "openapiPath");
|
|
629
|
-
const userProvidedRoutes = Object.hasOwn(resolvedConfig.types, "routesPath");
|
|
630
|
-
const userProvidedPageProps = Object.hasOwn(resolvedConfig.types, "pagePropsPath");
|
|
631
|
-
const userProvidedSchemasTs = Object.hasOwn(resolvedConfig.types, "schemasTsPath");
|
|
632
|
-
typesConfig = {
|
|
633
|
-
enabled: resolvedConfig.types.enabled ?? true,
|
|
634
|
-
output: resolvedConfig.types.output ?? defaultTypesOutput,
|
|
635
|
-
openapiPath: resolvedConfig.types.openapiPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "openapi.json") : defaultOpenapiPath),
|
|
636
|
-
routesPath: resolvedConfig.types.routesPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "routes.json") : defaultRoutesPath),
|
|
637
|
-
pagePropsPath: resolvedConfig.types.pagePropsPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "inertia-pages.json") : defaultPagePropsPath),
|
|
638
|
-
schemasTsPath: resolvedConfig.types.schemasTsPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "schemas.ts") : defaultSchemasTsPath),
|
|
639
|
-
generateZod: resolvedConfig.types.generateZod ?? false,
|
|
640
|
-
generateSdk: resolvedConfig.types.generateSdk ?? true,
|
|
641
|
-
generateRoutes: resolvedConfig.types.generateRoutes ?? true,
|
|
642
|
-
generatePageProps: resolvedConfig.types.generatePageProps ?? true,
|
|
643
|
-
generateSchemas: resolvedConfig.types.generateSchemas ?? true,
|
|
644
|
-
globalRoute: resolvedConfig.types.globalRoute ?? false,
|
|
645
|
-
debounce: resolvedConfig.types.debounce ?? DEBOUNCE_MS
|
|
646
|
-
};
|
|
647
|
-
if (!userProvidedOpenapi && resolvedConfig.types.output) {
|
|
648
|
-
typesConfig.openapiPath = path.join(typesConfig.output, "openapi.json");
|
|
649
|
-
}
|
|
650
|
-
if (!userProvidedRoutes && resolvedConfig.types.output) {
|
|
651
|
-
typesConfig.routesPath = path.join(typesConfig.output, "routes.json");
|
|
652
|
-
}
|
|
653
|
-
if (!userProvidedPageProps && resolvedConfig.types.output) {
|
|
654
|
-
typesConfig.pagePropsPath = path.join(typesConfig.output, "inertia-pages.json");
|
|
655
|
-
}
|
|
656
|
-
if (!userProvidedSchemasTs && resolvedConfig.types.output) {
|
|
657
|
-
typesConfig.schemasTsPath = path.join(typesConfig.output, "schemas.ts");
|
|
658
|
-
}
|
|
659
|
-
}
|
|
589
|
+
const typesConfig = resolveTypesConfig({
|
|
590
|
+
requested: resolvedConfig.types,
|
|
591
|
+
pythonConfig: pythonDefaults?.types ?? void 0,
|
|
592
|
+
defaultOutput: "src/generated"
|
|
593
|
+
});
|
|
660
594
|
const bridgeInertiaEnabled = pythonDefaults?.spa !== null && pythonDefaults?.spa !== void 0;
|
|
661
595
|
const inertiaMode = resolvedConfig.inertiaMode ?? bridgeInertiaEnabled;
|
|
662
596
|
const effectiveResourceDir = resolvedConfig.resourceDir ?? pythonDefaults?.resourceDir ?? "src";
|
|
@@ -793,34 +727,34 @@ function createStaticPropsPlugin() {
|
|
|
793
727
|
};
|
|
794
728
|
}
|
|
795
729
|
function resolveDevServerUrl(address, config, userConfig) {
|
|
796
|
-
const
|
|
797
|
-
const
|
|
730
|
+
const configHmrNet = (typeof config.server.ws === "object" ? config.server.ws : null) ?? (typeof config.server.hmr === "object" ? config.server.hmr : null);
|
|
731
|
+
const configWsProtocol = configHmrNet?.protocol ?? null;
|
|
732
|
+
const clientProtocol = configWsProtocol ? configWsProtocol === "wss" ? "https" : "http" : null;
|
|
798
733
|
const serverProtocol = config.server.https ? "https" : "http";
|
|
799
734
|
const protocol = clientProtocol ?? serverProtocol;
|
|
800
|
-
const
|
|
735
|
+
const configWsHost = configHmrNet?.host ?? null;
|
|
801
736
|
const userHost = typeof userConfig.server?.host === "string" ? userConfig.server.host : null;
|
|
802
737
|
const configHost = typeof config.server.host === "string" ? config.server.host : null;
|
|
803
738
|
const remoteHost = process.env.VITE_ALLOW_REMOTE && !userConfig.server?.host ? isIpv6(address) ? "[::1]" : "127.0.0.1" : null;
|
|
804
739
|
const serverAddress = isIpv6(address) ? `[${address.address}]` : address.address;
|
|
805
|
-
let host =
|
|
740
|
+
let host = configWsHost ?? userHost ?? remoteHost ?? configHost ?? serverAddress;
|
|
806
741
|
if (host === "0.0.0.0") {
|
|
807
742
|
host = "127.0.0.1";
|
|
808
743
|
} else if (host === "::" || host === "[::]") {
|
|
809
744
|
host = "[::1]";
|
|
810
745
|
}
|
|
811
|
-
const
|
|
812
|
-
const
|
|
746
|
+
const userHmrNet = (typeof userConfig.server?.ws === "object" ? userConfig.server.ws : null) ?? (typeof userConfig.server?.hmr === "object" ? userConfig.server.hmr : null);
|
|
747
|
+
const userWsClientPort = userHmrNet?.clientPort ?? null;
|
|
748
|
+
const port = userWsClientPort ?? address.port;
|
|
813
749
|
return `${protocol}://${host}:${port}`;
|
|
814
750
|
}
|
|
815
751
|
function isIpv6(address) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
819
|
-
// @ts-ignore-next-line
|
|
820
|
-
address.family === 6;
|
|
752
|
+
const family = address.family;
|
|
753
|
+
return family === "IPv6" || family === 6;
|
|
821
754
|
}
|
|
822
755
|
function noExternalInertiaHelpers(config) {
|
|
823
|
-
const
|
|
756
|
+
const ssrConfig = typeof config.ssr === "object" && config.ssr !== null ? config.ssr : void 0;
|
|
757
|
+
const userNoExternal = ssrConfig?.noExternal;
|
|
824
758
|
const pluginNoExternal = ["litestar-vite-plugin"];
|
|
825
759
|
if (userNoExternal === true) {
|
|
826
760
|
return true;
|
|
@@ -844,11 +778,10 @@ function resolveEnvironmentServerConfig(env) {
|
|
|
844
778
|
throw Error(`Unable to determine the host from the environment's APP_URL: [${env.APP_URL}].`);
|
|
845
779
|
}
|
|
846
780
|
return {
|
|
847
|
-
hmr: { host },
|
|
848
781
|
host,
|
|
849
782
|
https: {
|
|
850
|
-
key: fs.readFileSync(env.
|
|
851
|
-
cert: fs.readFileSync(env.
|
|
783
|
+
key: fs.readFileSync(env.VITE_SERVER_KEY),
|
|
784
|
+
cert: fs.readFileSync(env.VITE_SERVER_CERT)
|
|
852
785
|
}
|
|
853
786
|
};
|
|
854
787
|
}
|
|
@@ -877,7 +810,6 @@ function resolveDevelopmentEnvironmentServerConfig(host) {
|
|
|
877
810
|
throw Error(`Unable to find certificate files for your host [${host}] in the [${configPath}/certs] directory.`);
|
|
878
811
|
}
|
|
879
812
|
return {
|
|
880
|
-
hmr: { host: resolvedHost },
|
|
881
813
|
host: resolvedHost,
|
|
882
814
|
https: {
|
|
883
815
|
key: keyPath,
|
|
@@ -915,25 +847,40 @@ function dirname() {
|
|
|
915
847
|
}
|
|
916
848
|
return path.resolve(process.cwd(), "../dist/js");
|
|
917
849
|
}
|
|
850
|
+
let cachedDevServerPlaceholderCandidates;
|
|
851
|
+
let cachedDevServerPlaceholderPath;
|
|
918
852
|
function getDevServerPlaceholderCandidates() {
|
|
853
|
+
if (cachedDevServerPlaceholderCandidates) {
|
|
854
|
+
return cachedDevServerPlaceholderCandidates;
|
|
855
|
+
}
|
|
919
856
|
const distJsRoot = "dist/js";
|
|
920
857
|
const placeholderName = "dev-server-index.html";
|
|
921
858
|
const moduleDir = dirname();
|
|
922
859
|
const candidates = [
|
|
923
|
-
path.join(
|
|
860
|
+
path.join(moduleDir, placeholderName),
|
|
924
861
|
path.join(process.cwd(), distJsRoot, placeholderName),
|
|
925
862
|
path.join(process.cwd(), "src", "js", distJsRoot, placeholderName),
|
|
926
863
|
path.resolve(process.cwd(), "..", distJsRoot, placeholderName),
|
|
927
864
|
path.join(moduleDir, distJsRoot, placeholderName)
|
|
928
865
|
];
|
|
929
|
-
|
|
866
|
+
cachedDevServerPlaceholderCandidates = [...new Set(candidates)];
|
|
867
|
+
return cachedDevServerPlaceholderCandidates;
|
|
930
868
|
}
|
|
931
869
|
async function loadDevServerPlaceholder() {
|
|
870
|
+
if (cachedDevServerPlaceholderPath) {
|
|
871
|
+
try {
|
|
872
|
+
return await fs.promises.readFile(cachedDevServerPlaceholderPath, "utf-8");
|
|
873
|
+
} catch {
|
|
874
|
+
cachedDevServerPlaceholderPath = void 0;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
932
877
|
const candidates = getDevServerPlaceholderCandidates();
|
|
933
878
|
let lastError = new Error("Failed to load dev server placeholder index.html");
|
|
934
879
|
for (const candidatePath of candidates) {
|
|
935
880
|
try {
|
|
936
|
-
|
|
881
|
+
const content = await fs.promises.readFile(candidatePath, "utf-8");
|
|
882
|
+
cachedDevServerPlaceholderPath = candidatePath;
|
|
883
|
+
return content;
|
|
937
884
|
} catch (error) {
|
|
938
885
|
lastError = error;
|
|
939
886
|
}
|
|
@@ -64,12 +64,16 @@ export declare function resolvePageComponent<T>(path: string | string[], pages:
|
|
|
64
64
|
* Offset-based pagination props.
|
|
65
65
|
*
|
|
66
66
|
* Returned when a route returns Litestar's `OffsetPagination` type.
|
|
67
|
-
*
|
|
67
|
+
* Litestar-Vite flattens pagination metadata as top-level sibling props:
|
|
68
|
+
* the route prop contains the item array, and `total`, `limit`, and `offset`
|
|
69
|
+
* are emitted beside it.
|
|
68
70
|
*
|
|
69
71
|
* @example
|
|
70
72
|
* ```ts
|
|
71
73
|
* interface User { id: string; name: string }
|
|
72
|
-
*
|
|
74
|
+
* type UsersPageProps = { users: User[] } & Omit<OffsetPaginationProps<User>, 'items'>
|
|
75
|
+
*
|
|
76
|
+
* const { users, total, limit, offset } = props as UsersPageProps
|
|
73
77
|
* ```
|
|
74
78
|
*/
|
|
75
79
|
export interface OffsetPaginationProps<T> {
|
|
@@ -86,12 +90,16 @@ export interface OffsetPaginationProps<T> {
|
|
|
86
90
|
* Classic page-based pagination props.
|
|
87
91
|
*
|
|
88
92
|
* Returned when a route returns Litestar's `ClassicPagination` type.
|
|
89
|
-
*
|
|
93
|
+
* Litestar-Vite flattens pagination metadata as top-level sibling props:
|
|
94
|
+
* the route prop contains the item array, and `currentPage`, `totalPages`,
|
|
95
|
+
* and `pageSize` are emitted beside it.
|
|
90
96
|
*
|
|
91
97
|
* @example
|
|
92
98
|
* ```ts
|
|
93
99
|
* interface Post { id: string; title: string }
|
|
94
|
-
*
|
|
100
|
+
* type PostsPageProps = { posts: Post[] } & Omit<ClassicPaginationProps<Post>, 'items'>
|
|
101
|
+
*
|
|
102
|
+
* const { posts, currentPage, totalPages, pageSize } = props as PostsPageProps
|
|
95
103
|
* ```
|
|
96
104
|
*/
|
|
97
105
|
export interface ClassicPaginationProps<T> {
|
|
@@ -108,12 +116,16 @@ export interface ClassicPaginationProps<T> {
|
|
|
108
116
|
* Cursor-based pagination props.
|
|
109
117
|
*
|
|
110
118
|
* Used for cursor/keyset pagination, commonly with infinite scroll.
|
|
111
|
-
*
|
|
119
|
+
* Litestar-Vite flattens pagination metadata as top-level sibling props:
|
|
120
|
+
* the route prop contains the item array, and cursor metadata is emitted
|
|
121
|
+
* beside it.
|
|
112
122
|
*
|
|
113
123
|
* @example
|
|
114
124
|
* ```ts
|
|
115
125
|
* interface Message { id: string; content: string }
|
|
116
|
-
*
|
|
126
|
+
* type MessagesPageProps = { messages: Message[] } & Omit<CursorPaginationProps<Message>, 'items'>
|
|
127
|
+
*
|
|
128
|
+
* const { messages, hasMore, nextCursor } = props as MessagesPageProps
|
|
117
129
|
* if (hasMore && nextCursor) {
|
|
118
130
|
* // Fetch more with cursor
|
|
119
131
|
* }
|
|
@@ -139,6 +151,11 @@ export interface CursorPaginationProps<T> {
|
|
|
139
151
|
* Union type for any pagination props.
|
|
140
152
|
*
|
|
141
153
|
* Use when you need to handle multiple pagination styles.
|
|
154
|
+
* Because pagination metadata is flattened as sibling keys, two paginators in
|
|
155
|
+
* one response can collide on keys such as `total`, `limit`, `offset`,
|
|
156
|
+
* `currentPage`, or `pageSize`. Return one flattened paginator per response,
|
|
157
|
+
* or wrap additional paginators in explicit prop containers with distinct
|
|
158
|
+
* metadata.
|
|
142
159
|
*
|
|
143
160
|
* @example
|
|
144
161
|
* ```ts
|
|
@@ -166,11 +183,12 @@ export type PaginationProps<T> = OffsetPaginationProps<T> | ClassicPaginationPro
|
|
|
166
183
|
* import { usePage } from '@inertiajs/vue3'
|
|
167
184
|
*
|
|
168
185
|
* const page = usePage()
|
|
169
|
-
* const scrollProps = page.props.scrollProps as ScrollProps
|
|
186
|
+
* const scrollProps = page.props.scrollProps as Record<string, ScrollProps> | undefined
|
|
187
|
+
* const postsScroll = scrollProps?.posts
|
|
170
188
|
*
|
|
171
189
|
* function loadMore() {
|
|
172
|
-
* if (
|
|
173
|
-
* router.get(url, { [
|
|
190
|
+
* if (postsScroll?.nextPage) {
|
|
191
|
+
* router.get(url, { [postsScroll.pageName]: postsScroll.nextPage })
|
|
174
192
|
* }
|
|
175
193
|
* }
|
|
176
194
|
* ```
|
|
@@ -13,3 +13,20 @@ export declare function resolveInstallHint(pkg?: string): string;
|
|
|
13
13
|
* @returns The full command string (e.g., "npx @hey-api/openapi-ts ..." or "bunx @hey-api/openapi-ts ...")
|
|
14
14
|
*/
|
|
15
15
|
export declare function resolvePackageExecutor(pkg: string, executor?: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Resolves the package executor command as argv.
|
|
18
|
+
*
|
|
19
|
+
* This is used for actual process execution so package arguments are never
|
|
20
|
+
* shell-joined. The string-returning ``resolvePackageExecutor`` remains the
|
|
21
|
+
* display/back-compat helper.
|
|
22
|
+
*/
|
|
23
|
+
export interface PackageExecutorArgvOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Package spec to install for executors that support an explicit package
|
|
26
|
+
* separate from the command binary, e.g. npm exec --package.
|
|
27
|
+
*/
|
|
28
|
+
packageSpec?: string;
|
|
29
|
+
/** Binary command exposed by packageSpec. */
|
|
30
|
+
binName?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function resolvePackageExecutorArgv(args: string[], executor?: string, options?: PackageExecutorArgvOptions): string[];
|
package/dist/js/install-hint.js
CHANGED
|
@@ -63,8 +63,42 @@ function resolvePackageExecutor(pkg, executor) {
|
|
|
63
63
|
return `npx ${pkg}`;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
function getPackageNameFromSpec(packageSpec) {
|
|
67
|
+
if (packageSpec.startsWith("@")) {
|
|
68
|
+
const versionIndex2 = packageSpec.indexOf("@", packageSpec.indexOf("/") + 1);
|
|
69
|
+
return versionIndex2 === -1 ? packageSpec : packageSpec.slice(0, versionIndex2);
|
|
70
|
+
}
|
|
71
|
+
const versionIndex = packageSpec.indexOf("@");
|
|
72
|
+
return versionIndex === -1 ? packageSpec : packageSpec.slice(0, versionIndex);
|
|
73
|
+
}
|
|
74
|
+
function resolveDenoPackageSpec(packageSpec, binName) {
|
|
75
|
+
if (!binName) return packageSpec;
|
|
76
|
+
const packageName = getPackageNameFromSpec(packageSpec);
|
|
77
|
+
const defaultBinName = packageName.split("/").pop();
|
|
78
|
+
return defaultBinName === binName ? packageSpec : `${packageSpec}/${binName}`;
|
|
79
|
+
}
|
|
80
|
+
function resolvePackageExecutorArgv(args, executor, options = {}) {
|
|
81
|
+
const runtime = executor || detectExecutor();
|
|
82
|
+
const { packageSpec, binName } = options;
|
|
83
|
+
switch (runtime) {
|
|
84
|
+
case "bun":
|
|
85
|
+
return ["bunx", ...packageSpec ? [packageSpec, ...args] : args];
|
|
86
|
+
case "deno":
|
|
87
|
+
return ["deno", "run", "-A", ...packageSpec ? [`npm:${resolveDenoPackageSpec(packageSpec, binName)}`, ...args] : args];
|
|
88
|
+
case "pnpm":
|
|
89
|
+
return ["pnpm", "dlx", ...packageSpec ? [packageSpec, ...args] : args];
|
|
90
|
+
case "yarn":
|
|
91
|
+
return ["yarn", "dlx", ...packageSpec ? [packageSpec, ...args] : args];
|
|
92
|
+
default:
|
|
93
|
+
if (packageSpec && binName) {
|
|
94
|
+
return ["npm", "exec", "--yes", "--package", packageSpec, "--", binName, ...args];
|
|
95
|
+
}
|
|
96
|
+
return ["npx", ...args];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
66
99
|
export {
|
|
67
100
|
detectExecutor,
|
|
68
101
|
resolveInstallHint,
|
|
69
|
-
resolvePackageExecutor
|
|
102
|
+
resolvePackageExecutor,
|
|
103
|
+
resolvePackageExecutorArgv
|
|
70
104
|
};
|
package/dist/js/nuxt.d.ts
CHANGED
|
@@ -100,6 +100,12 @@ export interface NuxtTypesConfig {
|
|
|
100
100
|
* @default false
|
|
101
101
|
*/
|
|
102
102
|
globalRoute?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Fail Vite when type generation fails.
|
|
105
|
+
*
|
|
106
|
+
* Defaults to true during build and false during dev.
|
|
107
|
+
*/
|
|
108
|
+
failOnError?: boolean;
|
|
103
109
|
/**
|
|
104
110
|
* Debounce time in milliseconds for type regeneration.
|
|
105
111
|
*
|
package/dist/js/nuxt.js
CHANGED
|
@@ -2,9 +2,9 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import colors from "picocolors";
|
|
4
4
|
import { readBridgeConfig } from "./shared/bridge-schema.js";
|
|
5
|
-
import { DEBOUNCE_MS } from "./shared/constants.js";
|
|
6
5
|
import { normalizeHost, resolveHotFilePath, resolveLitestarPort } from "./shared/network.js";
|
|
7
|
-
import { createLitestarTypeGenPlugin } from "./shared/typegen-plugin.js";
|
|
6
|
+
import { createLitestarTypeGenPlugin, resolveTypesConfig } from "./shared/typegen-plugin.js";
|
|
7
|
+
import { hmrServerConfig } from "./shared/vite-compat.js";
|
|
8
8
|
function resolveConfig(config = {}) {
|
|
9
9
|
let hotFile;
|
|
10
10
|
let proxyMode = "vite";
|
|
@@ -38,74 +38,13 @@ function resolveConfig(config = {}) {
|
|
|
38
38
|
if (resolvedLitestarPort !== null) {
|
|
39
39
|
litestarPort = resolvedLitestarPort;
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
schemasTsPath: path.join(output, "schemas.ts")
|
|
41
|
+
const typesConfig = resolveTypesConfig({
|
|
42
|
+
requested: config.types,
|
|
43
|
+
pythonConfig: pythonTypesConfig ?? void 0,
|
|
44
|
+
defaultOutput: "generated",
|
|
45
|
+
mergePythonWhenTrue: true,
|
|
46
|
+
mergePythonForObject: true
|
|
48
47
|
});
|
|
49
|
-
if (config.types === true) {
|
|
50
|
-
const output = pythonTypesConfig?.output ?? defaultTypesOutput;
|
|
51
|
-
const defaults = buildTypeDefaults(output);
|
|
52
|
-
typesConfig = {
|
|
53
|
-
enabled: true,
|
|
54
|
-
output,
|
|
55
|
-
openapiPath: pythonTypesConfig?.openapiPath ?? defaults.openapiPath,
|
|
56
|
-
routesPath: pythonTypesConfig?.routesPath ?? defaults.routesPath,
|
|
57
|
-
pagePropsPath: pythonTypesConfig?.pagePropsPath ?? defaults.pagePropsPath,
|
|
58
|
-
schemasTsPath: pythonTypesConfig?.schemasTsPath ?? defaults.schemasTsPath,
|
|
59
|
-
generateZod: pythonTypesConfig?.generateZod ?? false,
|
|
60
|
-
generateSdk: pythonTypesConfig?.generateSdk ?? true,
|
|
61
|
-
generateRoutes: pythonTypesConfig?.generateRoutes ?? true,
|
|
62
|
-
generatePageProps: pythonTypesConfig?.generatePageProps ?? true,
|
|
63
|
-
generateSchemas: pythonTypesConfig?.generateSchemas ?? true,
|
|
64
|
-
globalRoute: pythonTypesConfig?.globalRoute ?? false,
|
|
65
|
-
debounce: DEBOUNCE_MS
|
|
66
|
-
};
|
|
67
|
-
} else if (typeof config.types === "object" && config.types !== null) {
|
|
68
|
-
const userProvidedOutput = Object.hasOwn(config.types, "output");
|
|
69
|
-
const output = config.types.output ?? pythonTypesConfig?.output ?? defaultTypesOutput;
|
|
70
|
-
const defaults = buildTypeDefaults(output);
|
|
71
|
-
const openapiFallback = userProvidedOutput ? defaults.openapiPath : pythonTypesConfig?.openapiPath ?? defaults.openapiPath;
|
|
72
|
-
const routesFallback = userProvidedOutput ? defaults.routesPath : pythonTypesConfig?.routesPath ?? defaults.routesPath;
|
|
73
|
-
const pagePropsFallback = userProvidedOutput ? defaults.pagePropsPath : pythonTypesConfig?.pagePropsPath ?? defaults.pagePropsPath;
|
|
74
|
-
const schemasFallback = userProvidedOutput ? defaults.schemasTsPath : pythonTypesConfig?.schemasTsPath ?? defaults.schemasTsPath;
|
|
75
|
-
typesConfig = {
|
|
76
|
-
enabled: config.types.enabled ?? true,
|
|
77
|
-
output,
|
|
78
|
-
openapiPath: config.types.openapiPath ?? openapiFallback,
|
|
79
|
-
routesPath: config.types.routesPath ?? routesFallback,
|
|
80
|
-
pagePropsPath: config.types.pagePropsPath ?? pagePropsFallback,
|
|
81
|
-
schemasTsPath: config.types.schemasTsPath ?? schemasFallback,
|
|
82
|
-
generateZod: config.types.generateZod ?? pythonTypesConfig?.generateZod ?? false,
|
|
83
|
-
generateSdk: config.types.generateSdk ?? pythonTypesConfig?.generateSdk ?? true,
|
|
84
|
-
generateRoutes: config.types.generateRoutes ?? pythonTypesConfig?.generateRoutes ?? true,
|
|
85
|
-
generatePageProps: config.types.generatePageProps ?? pythonTypesConfig?.generatePageProps ?? true,
|
|
86
|
-
generateSchemas: config.types.generateSchemas ?? pythonTypesConfig?.generateSchemas ?? true,
|
|
87
|
-
globalRoute: config.types.globalRoute ?? pythonTypesConfig?.globalRoute ?? false,
|
|
88
|
-
debounce: config.types.debounce ?? DEBOUNCE_MS
|
|
89
|
-
};
|
|
90
|
-
} else if (config.types !== false && pythonTypesConfig?.enabled) {
|
|
91
|
-
const output = pythonTypesConfig.output ?? defaultTypesOutput;
|
|
92
|
-
const defaults = buildTypeDefaults(output);
|
|
93
|
-
typesConfig = {
|
|
94
|
-
enabled: true,
|
|
95
|
-
output,
|
|
96
|
-
openapiPath: pythonTypesConfig.openapiPath ?? defaults.openapiPath,
|
|
97
|
-
routesPath: pythonTypesConfig.routesPath ?? defaults.routesPath,
|
|
98
|
-
pagePropsPath: pythonTypesConfig.pagePropsPath ?? defaults.pagePropsPath,
|
|
99
|
-
schemasTsPath: pythonTypesConfig.schemasTsPath ?? defaults.schemasTsPath,
|
|
100
|
-
generateZod: pythonTypesConfig.generateZod ?? false,
|
|
101
|
-
generateSdk: pythonTypesConfig.generateSdk ?? true,
|
|
102
|
-
generateRoutes: pythonTypesConfig.generateRoutes ?? true,
|
|
103
|
-
generatePageProps: pythonTypesConfig.generatePageProps ?? true,
|
|
104
|
-
generateSchemas: pythonTypesConfig.generateSchemas ?? true,
|
|
105
|
-
globalRoute: pythonTypesConfig.globalRoute ?? false,
|
|
106
|
-
debounce: DEBOUNCE_MS
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
48
|
return {
|
|
110
49
|
apiProxy: config.apiProxy ?? "http://localhost:8000",
|
|
111
50
|
apiPrefix: config.apiPrefix ?? "/api",
|
|
@@ -154,13 +93,14 @@ function createProxyPlugin(config) {
|
|
|
154
93
|
strictPort: true
|
|
155
94
|
} : {},
|
|
156
95
|
// Vite serves HMR on a separate internal port; browsers reach it through
|
|
157
|
-
// Litestar's /static/vite-hmr WebSocket handler.
|
|
158
|
-
hmr
|
|
96
|
+
// Litestar's /static/vite-hmr WebSocket handler. Vite 8.1 moved these network
|
|
97
|
+
// options from server.hmr.* to server.ws.*; hmrServerConfig picks the right key.
|
|
98
|
+
...hmrServerConfig({
|
|
159
99
|
port: hmrPort,
|
|
160
100
|
host: "127.0.0.1",
|
|
161
101
|
...browserHmrPort !== void 0 ? { clientPort: browserHmrPort } : {},
|
|
162
102
|
...config.litestarPort !== void 0 ? { path: hmrPath, protocol: "ws" } : {}
|
|
163
|
-
}
|
|
103
|
+
})
|
|
164
104
|
}
|
|
165
105
|
};
|
|
166
106
|
},
|
|
@@ -25,6 +25,7 @@ export interface BridgeTypesConfig {
|
|
|
25
25
|
generatePageProps: boolean;
|
|
26
26
|
generateSchemas: boolean;
|
|
27
27
|
globalRoute: boolean;
|
|
28
|
+
failOnError?: boolean;
|
|
28
29
|
}
|
|
29
30
|
export interface BridgeSpaConfig {
|
|
30
31
|
/** Use script element instead of data-page attribute for Inertia page data */
|