litestar-vite-plugin 0.27.0 → 0.29.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 +37 -18
- package/dist/js/astro.d.ts +12 -121
- package/dist/js/astro.js +8 -55
- package/dist/js/helpers/channels.d.ts +31 -0
- package/dist/js/helpers/channels.js +37 -0
- package/dist/js/helpers/csrf.d.ts +3 -1
- package/dist/js/helpers/csrf.js +26 -12
- package/dist/js/helpers/expression.d.ts +3 -0
- package/dist/js/helpers/expression.js +524 -0
- package/dist/js/helpers/htmx.d.ts +1 -1
- package/dist/js/helpers/htmx.js +33 -140
- package/dist/js/helpers/index.d.ts +5 -1
- package/dist/js/helpers/index.js +9 -1
- package/dist/js/helpers/queues.d.ts +61 -0
- package/dist/js/helpers/queues.js +117 -0
- package/dist/js/helpers/stream-element.d.ts +79 -0
- package/dist/js/helpers/stream-element.js +229 -0
- package/dist/js/helpers/stream.d.ts +76 -0
- package/dist/js/helpers/stream.js +242 -0
- package/dist/js/index.d.ts +4 -106
- package/dist/js/index.js +4 -0
- package/dist/js/install-hint.js +8 -15
- package/dist/js/nuxt.d.ts +12 -128
- package/dist/js/nuxt.js +17 -74
- package/dist/js/react/index.d.ts +28 -0
- package/dist/js/react/index.js +54 -0
- package/dist/js/shared/bridge-schema.d.ts +10 -7
- package/dist/js/shared/bridge-schema.js +6 -0
- package/dist/js/shared/emit-page-props-types.js +22 -6
- package/dist/js/shared/emit-static-props-types.js +6 -2
- package/dist/js/shared/integration-config.d.ts +75 -0
- package/dist/js/shared/integration-config.js +59 -0
- package/dist/js/shared/logger.d.ts +0 -4
- package/dist/js/shared/logger.js +1 -2
- package/dist/js/shared/managed-shutdown.d.ts +8 -0
- package/dist/js/shared/managed-shutdown.js +26 -0
- package/dist/js/shared/network.d.ts +4 -3
- package/dist/js/shared/typegen-core.d.ts +2 -9
- package/dist/js/shared/typegen-core.js +0 -1
- package/dist/js/shared/typegen-plugin.d.ts +84 -0
- package/dist/js/shared/vite-compat.d.ts +0 -4
- package/dist/js/shared/vite-compat.js +1 -3
- package/dist/js/svelte/index.d.ts +27 -0
- package/dist/js/svelte/index.js +51 -0
- package/dist/js/sveltekit.d.ts +12 -128
- package/dist/js/sveltekit.js +6 -55
- package/dist/js/vue/index.d.ts +29 -0
- package/dist/js/vue/index.js +57 -0
- package/package.json +47 -4
package/dist/js/install-hint.js
CHANGED
|
@@ -51,19 +51,7 @@ function resolveInstallHint(pkg = "@hey-api/openapi-ts") {
|
|
|
51
51
|
return `npm install -D ${packageArgs}`;
|
|
52
52
|
}
|
|
53
53
|
function resolvePackageExecutor(pkg, executor) {
|
|
54
|
-
|
|
55
|
-
switch (runtime) {
|
|
56
|
-
case "bun":
|
|
57
|
-
return `bunx ${pkg}`;
|
|
58
|
-
case "deno":
|
|
59
|
-
return `deno run -A npm:${pkg}`;
|
|
60
|
-
case "pnpm":
|
|
61
|
-
return `pnpm dlx ${pkg}`;
|
|
62
|
-
case "yarn":
|
|
63
|
-
return `yarn dlx ${pkg}`;
|
|
64
|
-
default:
|
|
65
|
-
return `npx ${pkg}`;
|
|
66
|
-
}
|
|
54
|
+
return resolvePackageExecutorArgv(pkg.split(" "), executor).join(" ");
|
|
67
55
|
}
|
|
68
56
|
function getPackageNameFromSpec(packageSpec) {
|
|
69
57
|
if (packageSpec.startsWith("@")) {
|
|
@@ -88,9 +76,14 @@ function resolvePackageExecutorArgv(args, executor, options = {}) {
|
|
|
88
76
|
case "bun":
|
|
89
77
|
if (requiresMultiplePackages) return [];
|
|
90
78
|
return ["bunx", ...packageSpec ? [packageSpec, ...args] : args];
|
|
91
|
-
case "deno":
|
|
79
|
+
case "deno": {
|
|
92
80
|
if (requiresMultiplePackages) return [];
|
|
93
|
-
|
|
81
|
+
if (packageSpec) {
|
|
82
|
+
return ["deno", "run", "-A", `npm:${resolveDenoPackageSpec(packageSpec, binName)}`, ...args];
|
|
83
|
+
}
|
|
84
|
+
const [firstArg, ...restArgs] = args;
|
|
85
|
+
return firstArg ? ["deno", "run", "-A", `npm:${firstArg}`, ...restArgs] : ["deno", "run", "-A"];
|
|
86
|
+
}
|
|
94
87
|
case "pnpm":
|
|
95
88
|
if (requiresMultiplePackages && binName) {
|
|
96
89
|
return ["pnpm", "dlx", ...packageSpecs.map((spec) => `--package=${spec}`), binName, ...args];
|
package/dist/js/nuxt.d.ts
CHANGED
|
@@ -23,138 +23,22 @@
|
|
|
23
23
|
* @module
|
|
24
24
|
*/
|
|
25
25
|
import type { Plugin } from "vite";
|
|
26
|
+
import { type LitestarIntegrationConfig } from "./shared/integration-config.js";
|
|
27
|
+
import { type TypesConfigShape } from "./shared/typegen-plugin.js";
|
|
26
28
|
/**
|
|
27
|
-
* Configuration for TypeScript type generation
|
|
29
|
+
* Configuration for TypeScript type generation.
|
|
30
|
+
*
|
|
31
|
+
* Alias of the shared {@link TypesConfigShape} so every integration accepts an identical
|
|
32
|
+
* `types` option. Retained as a named export for backwards compatibility.
|
|
28
33
|
*/
|
|
29
|
-
export
|
|
30
|
-
/**
|
|
31
|
-
* Enable type generation.
|
|
32
|
-
*
|
|
33
|
-
* @default false
|
|
34
|
-
*/
|
|
35
|
-
enabled?: boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Path to output generated TypeScript types.
|
|
38
|
-
* Relative to the Nuxt project root.
|
|
39
|
-
*
|
|
40
|
-
* @default 'generated'
|
|
41
|
-
*/
|
|
42
|
-
output?: string;
|
|
43
|
-
/**
|
|
44
|
-
* Path where the OpenAPI schema is exported by Litestar.
|
|
45
|
-
*
|
|
46
|
-
* @default `${output}/openapi.json`
|
|
47
|
-
*/
|
|
48
|
-
openapiPath?: string;
|
|
49
|
-
/**
|
|
50
|
-
* Path where route metadata is exported by Litestar.
|
|
51
|
-
*
|
|
52
|
-
* @default `${output}/routes.json`
|
|
53
|
-
*/
|
|
54
|
-
routesPath?: string;
|
|
55
|
-
/**
|
|
56
|
-
* Optional path for the generated schemas.ts helper file.
|
|
57
|
-
*
|
|
58
|
-
* @default `${output}/schemas.ts`
|
|
59
|
-
*/
|
|
60
|
-
schemasTsPath?: string;
|
|
61
|
-
/**
|
|
62
|
-
* Path where Inertia page props metadata is exported by Litestar.
|
|
63
|
-
*
|
|
64
|
-
* @default `${output}/inertia-pages.json`
|
|
65
|
-
*/
|
|
66
|
-
pagePropsPath?: string;
|
|
67
|
-
/**
|
|
68
|
-
* Generate Zod schemas in addition to TypeScript types.
|
|
69
|
-
*
|
|
70
|
-
* @default false
|
|
71
|
-
*/
|
|
72
|
-
generateZod?: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Generate SDK client functions for API calls.
|
|
75
|
-
*
|
|
76
|
-
* @default true
|
|
77
|
-
*/
|
|
78
|
-
generateSdk?: boolean;
|
|
79
|
-
/**
|
|
80
|
-
* Generate typed routes.ts from routes.json metadata.
|
|
81
|
-
*
|
|
82
|
-
* @default true
|
|
83
|
-
*/
|
|
84
|
-
generateRoutes?: boolean;
|
|
85
|
-
/**
|
|
86
|
-
* Generate Inertia page props types from inertia-pages.json metadata.
|
|
87
|
-
*
|
|
88
|
-
* @default true
|
|
89
|
-
*/
|
|
90
|
-
generatePageProps?: boolean;
|
|
91
|
-
/**
|
|
92
|
-
* Generate schemas.ts with ergonomic form/response type helpers.
|
|
93
|
-
*
|
|
94
|
-
* @default true
|
|
95
|
-
*/
|
|
96
|
-
generateSchemas?: boolean;
|
|
97
|
-
/**
|
|
98
|
-
* Register route() globally on window object.
|
|
99
|
-
*
|
|
100
|
-
* @default false
|
|
101
|
-
*/
|
|
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;
|
|
109
|
-
/**
|
|
110
|
-
* Debounce time in milliseconds for type regeneration.
|
|
111
|
-
*
|
|
112
|
-
* @default 300
|
|
113
|
-
*/
|
|
114
|
-
debounce?: number;
|
|
115
|
-
}
|
|
34
|
+
export type NuxtTypesConfig = TypesConfigShape;
|
|
116
35
|
/**
|
|
117
|
-
* Configuration options for the Litestar
|
|
36
|
+
* Configuration options for the Litestar integration.
|
|
37
|
+
*
|
|
38
|
+
* Alias of the shared {@link LitestarIntegrationConfig}. Retained as a named export for
|
|
39
|
+
* backwards compatibility.
|
|
118
40
|
*/
|
|
119
|
-
export
|
|
120
|
-
/**
|
|
121
|
-
* URL of the Litestar API backend for proxying requests during development.
|
|
122
|
-
*
|
|
123
|
-
* @example 'http://127.0.0.1:8000'
|
|
124
|
-
* @default 'http://localhost:8000'
|
|
125
|
-
*/
|
|
126
|
-
apiProxy?: string;
|
|
127
|
-
/**
|
|
128
|
-
* API route prefix to proxy to the Litestar backend.
|
|
129
|
-
* Requests matching this prefix will be forwarded to the apiProxy URL.
|
|
130
|
-
*
|
|
131
|
-
* @example '/api'
|
|
132
|
-
* @default '/api'
|
|
133
|
-
*/
|
|
134
|
-
apiPrefix?: string;
|
|
135
|
-
/**
|
|
136
|
-
* Enable and configure TypeScript type generation.
|
|
137
|
-
*
|
|
138
|
-
* When set to `true`, enables type generation with default settings.
|
|
139
|
-
* When set to a NuxtTypesConfig object, enables type generation with custom settings.
|
|
140
|
-
*
|
|
141
|
-
* @default false
|
|
142
|
-
*/
|
|
143
|
-
types?: boolean | NuxtTypesConfig;
|
|
144
|
-
/**
|
|
145
|
-
* Enable verbose logging for debugging.
|
|
146
|
-
*
|
|
147
|
-
* @default false
|
|
148
|
-
*/
|
|
149
|
-
verbose?: boolean;
|
|
150
|
-
/**
|
|
151
|
-
* JavaScript runtime executor for package commands.
|
|
152
|
-
* Used when running tools like @hey-api/openapi-ts.
|
|
153
|
-
*
|
|
154
|
-
* @default undefined (uses LITESTAR_VITE_RUNTIME env or 'node')
|
|
155
|
-
*/
|
|
156
|
-
executor?: "node" | "bun" | "deno" | "yarn" | "pnpm";
|
|
157
|
-
}
|
|
41
|
+
export type LitestarNuxtConfig = LitestarIntegrationConfig;
|
|
158
42
|
/**
|
|
159
43
|
* Nuxt module definition for Litestar integration.
|
|
160
44
|
*
|
package/dist/js/nuxt.js
CHANGED
|
@@ -1,63 +1,13 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import colors from "picocolors";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { resolveIntegrationConfig } from "./shared/integration-config.js";
|
|
5
|
+
import { installManagedShutdown } from "./shared/managed-shutdown.js";
|
|
6
|
+
import { normalizeHost } from "./shared/network.js";
|
|
7
|
+
import { createLitestarTypeGenPlugin } from "./shared/typegen-plugin.js";
|
|
7
8
|
import { hmrServerConfig } from "./shared/vite-compat.js";
|
|
8
9
|
function resolveConfig(config = {}) {
|
|
9
|
-
|
|
10
|
-
let proxyMode = "vite";
|
|
11
|
-
let devPort;
|
|
12
|
-
let pythonTypesConfig;
|
|
13
|
-
let hasPythonConfig = false;
|
|
14
|
-
const envPort = process.env.VITE_PORT;
|
|
15
|
-
if (envPort) {
|
|
16
|
-
devPort = Number.parseInt(envPort, 10);
|
|
17
|
-
if (Number.isNaN(devPort)) {
|
|
18
|
-
devPort = void 0;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
let pythonExecutor;
|
|
22
|
-
let assetUrl;
|
|
23
|
-
let litestarPort;
|
|
24
|
-
const runtime = readBridgeConfig();
|
|
25
|
-
if (runtime) {
|
|
26
|
-
hasPythonConfig = true;
|
|
27
|
-
const hot = runtime.hotFile;
|
|
28
|
-
hotFile = resolveHotFilePath(runtime.bundleDir, hot);
|
|
29
|
-
proxyMode = runtime.proxyMode;
|
|
30
|
-
devPort = runtime.port;
|
|
31
|
-
pythonExecutor = runtime.executor;
|
|
32
|
-
assetUrl = runtime.assetUrl;
|
|
33
|
-
if (runtime.types) {
|
|
34
|
-
pythonTypesConfig = runtime.types;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const resolvedLitestarPort = resolveLitestarPort(runtime?.litestarPort, runtime?.appUrl);
|
|
38
|
-
if (resolvedLitestarPort !== null) {
|
|
39
|
-
litestarPort = resolvedLitestarPort;
|
|
40
|
-
}
|
|
41
|
-
const typesConfig = resolveTypesConfig({
|
|
42
|
-
requested: config.types,
|
|
43
|
-
pythonConfig: pythonTypesConfig ?? void 0,
|
|
44
|
-
defaultOutput: "generated",
|
|
45
|
-
mergePythonWhenTrue: true,
|
|
46
|
-
mergePythonForObject: true
|
|
47
|
-
});
|
|
48
|
-
return {
|
|
49
|
-
apiProxy: config.apiProxy ?? "http://localhost:8000",
|
|
50
|
-
apiPrefix: config.apiPrefix ?? "/api",
|
|
51
|
-
types: typesConfig,
|
|
52
|
-
verbose: config.verbose ?? false,
|
|
53
|
-
hotFile,
|
|
54
|
-
proxyMode,
|
|
55
|
-
devPort,
|
|
56
|
-
litestarPort,
|
|
57
|
-
assetUrl,
|
|
58
|
-
executor: config.executor ?? pythonExecutor,
|
|
59
|
-
hasPythonConfig
|
|
60
|
-
};
|
|
10
|
+
return resolveIntegrationConfig(config, "generated");
|
|
61
11
|
}
|
|
62
12
|
async function getPort() {
|
|
63
13
|
return new Promise((resolve, reject) => {
|
|
@@ -80,7 +30,7 @@ function createProxyPlugin(config) {
|
|
|
80
30
|
async config() {
|
|
81
31
|
hmrPort = await getPort();
|
|
82
32
|
const hmrPath = `${(config.assetUrl ?? "/static").replace(/\/$/, "")}/vite-hmr`;
|
|
83
|
-
const browserHmrPort = config.litestarPort ?? config.
|
|
33
|
+
const browserHmrPort = config.litestarPort ?? config.port;
|
|
84
34
|
return {
|
|
85
35
|
server: {
|
|
86
36
|
// Force IPv4 binding for consistency with Python proxy configuration
|
|
@@ -88,8 +38,8 @@ function createProxyPlugin(config) {
|
|
|
88
38
|
host: "127.0.0.1",
|
|
89
39
|
// Set the port from Python config/env to ensure Nuxt uses the expected port
|
|
90
40
|
// strictPort: true prevents auto-incrementing to a different port
|
|
91
|
-
...config.
|
|
92
|
-
port: config.
|
|
41
|
+
...config.port !== void 0 ? {
|
|
42
|
+
port: config.port,
|
|
93
43
|
strictPort: true
|
|
94
44
|
} : {},
|
|
95
45
|
// Vite serves HMR on a separate internal port; browsers reach it through
|
|
@@ -105,6 +55,7 @@ function createProxyPlugin(config) {
|
|
|
105
55
|
};
|
|
106
56
|
},
|
|
107
57
|
configureServer(server) {
|
|
58
|
+
installManagedShutdown(server);
|
|
108
59
|
if (config.verbose) {
|
|
109
60
|
server.middlewares.use((req, _res, next) => {
|
|
110
61
|
if (req.url?.startsWith(config.apiPrefix)) {
|
|
@@ -186,26 +137,18 @@ function litestarNuxtModule(userOptions, nuxt) {
|
|
|
186
137
|
console.log(colors.cyan("[litestar-nuxt]"), "Nitro devProxy configured:");
|
|
187
138
|
console.log(JSON.stringify(nuxt.options.nitro.devProxy, null, 2));
|
|
188
139
|
}
|
|
189
|
-
if (config.hotFile && config.devPort) {
|
|
190
|
-
const rawHost = process.env.NUXT_HOST || process.env.HOST || "127.0.0.1";
|
|
191
|
-
const host = normalizeHost(rawHost);
|
|
192
|
-
const url = `http://${host}:${config.devPort}`;
|
|
193
|
-
fs.mkdirSync(path.dirname(config.hotFile), { recursive: true });
|
|
194
|
-
fs.writeFileSync(config.hotFile, url);
|
|
195
|
-
if (config.verbose) {
|
|
196
|
-
console.log(colors.cyan("[litestar-nuxt]"), colors.dim(`Hotfile written: ${config.hotFile} -> ${url}`));
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
140
|
if (nuxt.hook && config.hotFile) {
|
|
141
|
+
const hotFile = config.hotFile;
|
|
200
142
|
nuxt.hook("listen", (_server, listener) => {
|
|
201
143
|
const info = listener;
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
fs.
|
|
144
|
+
const port = info?.address?.port ?? info?.port;
|
|
145
|
+
if (typeof port === "number") {
|
|
146
|
+
const host = normalizeHost(info.address?.address || info.host || "127.0.0.1");
|
|
147
|
+
const url = `http://${host}:${port}`;
|
|
148
|
+
fs.mkdirSync(path.dirname(hotFile), { recursive: true });
|
|
149
|
+
fs.writeFileSync(hotFile, url);
|
|
207
150
|
if (config.verbose) {
|
|
208
|
-
console.log(colors.cyan("[litestar-nuxt]"), colors.dim(`Hotfile
|
|
151
|
+
console.log(colors.cyan("[litestar-nuxt]"), colors.dim(`Hotfile written after listen: ${hotFile} -> ${url}`));
|
|
209
152
|
}
|
|
210
153
|
}
|
|
211
154
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React bindings for generic and Litestar Queues event streams.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { type EventStreamOptions, type QueueEventStreamOptions, type StreamGap } from "litestar-vite-plugin/helpers";
|
|
7
|
+
export interface EventStreamState<TFrame> {
|
|
8
|
+
healthy: boolean;
|
|
9
|
+
lastEvent: TFrame | null;
|
|
10
|
+
lastGap: StreamGap | null;
|
|
11
|
+
events: TFrame[];
|
|
12
|
+
}
|
|
13
|
+
export type ReactEventStreamOptions<TFrame> = EventStreamOptions<TFrame> & {
|
|
14
|
+
key: string;
|
|
15
|
+
bufferSize?: number;
|
|
16
|
+
};
|
|
17
|
+
export type ReactQueueEventStreamOptions<TFrame> = QueueEventStreamOptions<TFrame> & {
|
|
18
|
+
key: string;
|
|
19
|
+
bufferSize?: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Subscribe a React component to a generic event stream.
|
|
23
|
+
*/
|
|
24
|
+
export declare function useEventStream<TFrame = unknown>(options: ReactEventStreamOptions<TFrame>): EventStreamState<TFrame>;
|
|
25
|
+
/**
|
|
26
|
+
* Subscribe a React component to a Litestar Queues event stream.
|
|
27
|
+
*/
|
|
28
|
+
export declare function useQueueEventStream<TFrame = unknown>(options: ReactQueueEventStreamOptions<TFrame>): EventStreamState<TFrame>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React bindings for generic and Litestar Queues event streams.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { createEventStream, createQueueEventStream } from "litestar-vite-plugin/helpers";
|
|
7
|
+
import { useEffect, useRef, useState } from "react";
|
|
8
|
+
function initialState() {
|
|
9
|
+
return { events: [], healthy: false, lastEvent: null, lastGap: null };
|
|
10
|
+
}
|
|
11
|
+
function useStream(factory, options) {
|
|
12
|
+
const optionsRef = useRef(options);
|
|
13
|
+
optionsRef.current = options;
|
|
14
|
+
const [state, setState] = useState(initialState);
|
|
15
|
+
const transport = options.transport ?? "websocket";
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setState(initialState);
|
|
18
|
+
const { bufferSize: _bufferSize, key: _key, ...streamOptions } = optionsRef.current;
|
|
19
|
+
const stream = factory({
|
|
20
|
+
...streamOptions,
|
|
21
|
+
onEvent: (frame) => {
|
|
22
|
+
optionsRef.current.onEvent(frame);
|
|
23
|
+
setState((current) => {
|
|
24
|
+
const bufferSize = Math.max(0, optionsRef.current.bufferSize ?? 100);
|
|
25
|
+
const events = bufferSize === 0 ? [] : [...current.events, frame].slice(-bufferSize);
|
|
26
|
+
return { ...current, events, lastEvent: frame };
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
onGap: (gap) => {
|
|
30
|
+
optionsRef.current.onGap?.(gap);
|
|
31
|
+
setState((current) => ({ ...current, lastGap: gap }));
|
|
32
|
+
},
|
|
33
|
+
onHealthChange: (healthy) => {
|
|
34
|
+
optionsRef.current.onHealthChange?.(healthy);
|
|
35
|
+
setState((current) => ({ ...current, healthy }));
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
stream.connect();
|
|
39
|
+
return () => stream.dispose();
|
|
40
|
+
}, [factory, options.key, transport]);
|
|
41
|
+
return state;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Subscribe a React component to a generic event stream.
|
|
45
|
+
*/
|
|
46
|
+
export function useEventStream(options) {
|
|
47
|
+
return useStream(createEventStream, options);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Subscribe a React component to a Litestar Queues event stream.
|
|
51
|
+
*/
|
|
52
|
+
export function useQueueEventStream(options) {
|
|
53
|
+
return useStream(createQueueEventStream, options);
|
|
54
|
+
}
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
type BridgeMode = "spa" | "template" | "hybrid" | "framework" | "external";
|
|
12
|
+
type BridgeProxyMode = "vite" | "direct" | "proxy" | null;
|
|
13
|
+
type BridgeExecutor = "node" | "bun" | "deno" | "yarn" | "pnpm";
|
|
14
14
|
export interface BridgeTypesConfig {
|
|
15
15
|
enabled: boolean;
|
|
16
16
|
output: string;
|
|
@@ -27,7 +27,7 @@ export interface BridgeTypesConfig {
|
|
|
27
27
|
globalRoute: boolean;
|
|
28
28
|
failOnError?: boolean;
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
interface BridgeSpaConfig {
|
|
31
31
|
/** Use script element instead of data-page attribute for Inertia page data */
|
|
32
32
|
useScriptElement: boolean;
|
|
33
33
|
}
|
|
@@ -35,11 +35,13 @@ export interface BridgeSchema {
|
|
|
35
35
|
assetUrl: string;
|
|
36
36
|
deployAssetUrl: string | null;
|
|
37
37
|
appUrl: string | null;
|
|
38
|
+
csrfCookieName: string | null;
|
|
39
|
+
csrfHeaderName: string | null;
|
|
38
40
|
/**
|
|
39
41
|
* Litestar dev server port. Used by framework integrations to set
|
|
40
|
-
* `vite.server.
|
|
41
|
-
*
|
|
42
|
-
* contract.
|
|
42
|
+
* `vite.server.ws.clientPort` on Vite 8.1+ (`vite.server.hmr.clientPort` on
|
|
43
|
+
* Vite 7 / 8.0), ensuring the browser connects to Litestar (not the framework
|
|
44
|
+
* dev server) for HMR — preserving the single-port contract.
|
|
43
45
|
*/
|
|
44
46
|
litestarPort: number | null;
|
|
45
47
|
bundleDir: string;
|
|
@@ -71,3 +73,4 @@ export interface BridgeSchema {
|
|
|
71
73
|
}
|
|
72
74
|
export declare function parseBridgeSchema(value: unknown): BridgeSchema;
|
|
73
75
|
export declare function readBridgeConfig(explicitPath?: string): BridgeSchema | null;
|
|
76
|
+
export {};
|
|
@@ -4,6 +4,8 @@ const allowedTopLevelKeys = /* @__PURE__ */ new Set([
|
|
|
4
4
|
"assetUrl",
|
|
5
5
|
"deployAssetUrl",
|
|
6
6
|
"appUrl",
|
|
7
|
+
"csrfCookieName",
|
|
8
|
+
"csrfHeaderName",
|
|
7
9
|
"litestarPort",
|
|
8
10
|
"bundleDir",
|
|
9
11
|
"resourceDir",
|
|
@@ -174,6 +176,8 @@ function parseBridgeSchema(value) {
|
|
|
174
176
|
const assetUrl = assertString(obj, "assetUrl");
|
|
175
177
|
const deployAssetUrl = assertNullableString(obj, "deployAssetUrl");
|
|
176
178
|
const appUrl = assertOptionalNullableString(obj, "appUrl");
|
|
179
|
+
const csrfCookieName = assertOptionalNullableString(obj, "csrfCookieName");
|
|
180
|
+
const csrfHeaderName = assertOptionalNullableString(obj, "csrfHeaderName");
|
|
177
181
|
const litestarPort = assertOptionalNullableInteger(obj, "litestarPort");
|
|
178
182
|
const bundleDir = assertString(obj, "bundleDir");
|
|
179
183
|
const resourceDir = assertString(obj, "resourceDir");
|
|
@@ -195,6 +199,8 @@ function parseBridgeSchema(value) {
|
|
|
195
199
|
assetUrl,
|
|
196
200
|
deployAssetUrl,
|
|
197
201
|
appUrl,
|
|
202
|
+
csrfCookieName,
|
|
203
|
+
csrfHeaderName,
|
|
198
204
|
litestarPort,
|
|
199
205
|
bundleDir,
|
|
200
206
|
resourceDir,
|
|
@@ -104,12 +104,8 @@ export interface FlashMessages {}
|
|
|
104
104
|
`;
|
|
105
105
|
}
|
|
106
106
|
const defaultGeneratedSharedProps = {
|
|
107
|
-
errors: { type: "Record<string, string[]>", optional: true },
|
|
108
107
|
csrf_token: { type: "string", optional: true },
|
|
109
|
-
...includeDefaultAuth
|
|
110
|
-
auth: { type: "AuthData", optional: true },
|
|
111
|
-
flash: { type: "FlashMessages", optional: true }
|
|
112
|
-
} : {}
|
|
108
|
+
...includeDefaultAuth ? { auth: { type: "AuthData", optional: true } } : {}
|
|
113
109
|
};
|
|
114
110
|
const generatedSharedProps = Object.keys(json.sharedProps ?? {}).length > 0 ? json.sharedProps : defaultGeneratedSharedProps;
|
|
115
111
|
const generatedSharedPropLines = Object.entries(generatedSharedProps).toSorted(([a], [b]) => a.localeCompare(b)).map(([key, def]) => {
|
|
@@ -246,7 +242,8 @@ export interface FlashMessages {}
|
|
|
246
242
|
const propsType = rawType.includes("|") ? `(${rawType})` : rawType;
|
|
247
243
|
pageEntries.push(` "${component}": ${propsType} & FullSharedProps`);
|
|
248
244
|
}
|
|
249
|
-
const
|
|
245
|
+
const flashReference = includeDefaultFlash ? '/// <reference path="./inertia.d.ts" />\n' : "";
|
|
246
|
+
const body = `${flashReference}// AUTO-GENERATED by litestar-vite. Do not edit.
|
|
250
247
|
/* eslint-disable */
|
|
251
248
|
|
|
252
249
|
// Import user-defined type extensions (edit page-props.user.ts to customize)
|
|
@@ -285,6 +282,25 @@ export type InertiaPageProps<C extends ComponentName> = PageProps[C]
|
|
|
285
282
|
export type PagePropsFor<C extends ComponentName> = PageProps[C]
|
|
286
283
|
`;
|
|
287
284
|
const result = await writeIfChanged(outFile, body, { encoding: "utf-8" });
|
|
285
|
+
const declarationFile = path.join(outDir, "inertia.d.ts");
|
|
286
|
+
if (includeDefaultFlash) {
|
|
287
|
+
const declaration = `// AUTO-GENERATED by litestar-vite. Do not edit.
|
|
288
|
+
/* eslint-disable */
|
|
289
|
+
import "@inertiajs/core"
|
|
290
|
+
import type { FlashMessages } from "./page-props"
|
|
291
|
+
|
|
292
|
+
declare module "@inertiajs/core" {
|
|
293
|
+
interface InertiaConfig {
|
|
294
|
+
flashDataType: FlashMessages
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export {}
|
|
299
|
+
`;
|
|
300
|
+
await writeIfChanged(declarationFile, declaration, { encoding: "utf-8" });
|
|
301
|
+
} else if (fs.existsSync(declarationFile)) {
|
|
302
|
+
await fs.promises.rm(declarationFile);
|
|
303
|
+
}
|
|
288
304
|
const userStubFile = path.join(outDir, "page-props.user.ts");
|
|
289
305
|
if (!fs.existsSync(userStubFile)) {
|
|
290
306
|
const userStub = `/**
|
|
@@ -64,8 +64,12 @@ async function emitStaticPropsTypes(outputDir, projectRoot = process.cwd()) {
|
|
|
64
64
|
/* eslint-disable */
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
67
|
+
* Build-time constants from Python ViteConfig.static_props, inlined into the bundle.
|
|
68
|
+
*
|
|
69
|
+
* No static props are configured, so this file is empty. This is not an error.
|
|
70
|
+
*
|
|
71
|
+
* Looking for values sent on every Inertia response? Those come from
|
|
72
|
+
* InertiaConfig.extra_static_page_props and are typed in page-props.ts, not here.
|
|
69
73
|
*
|
|
70
74
|
* @example
|
|
71
75
|
* config = ViteConfig(
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type RequiredTypeGenConfig, type TypesConfigShape } from "./typegen-plugin.js";
|
|
2
|
+
/** JavaScript runtime used to invoke package commands. */
|
|
3
|
+
type IntegrationExecutor = "node" | "bun" | "deno" | "yarn" | "pnpm";
|
|
4
|
+
/** Proxy strategy reported by the Python side in `.litestar.json`. */
|
|
5
|
+
type IntegrationProxyMode = "vite" | "direct" | "proxy" | null;
|
|
6
|
+
/**
|
|
7
|
+
* User-facing options accepted by every framework integration.
|
|
8
|
+
*/
|
|
9
|
+
export interface LitestarIntegrationConfig {
|
|
10
|
+
/**
|
|
11
|
+
* Litestar backend URL that API requests are proxied to.
|
|
12
|
+
*
|
|
13
|
+
* @default 'http://localhost:8000'
|
|
14
|
+
*/
|
|
15
|
+
apiProxy?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Path prefix treated as backend API routes.
|
|
18
|
+
*
|
|
19
|
+
* @default '/api'
|
|
20
|
+
*/
|
|
21
|
+
apiPrefix?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Type generation. `true` enables with defaults, `false` disables, or pass an object
|
|
24
|
+
* to override individual fields.
|
|
25
|
+
*
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
types?: boolean | "auto" | TypesConfigShape;
|
|
29
|
+
/**
|
|
30
|
+
* Log integration activity.
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
verbose?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* JavaScript runtime executor for package commands. Overrides the executor reported by
|
|
37
|
+
* Python in `.litestar.json`.
|
|
38
|
+
*/
|
|
39
|
+
executor?: IntegrationExecutor;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Integration configuration with defaults applied and bridge-file values merged in.
|
|
43
|
+
*/
|
|
44
|
+
export interface ResolvedIntegrationConfig {
|
|
45
|
+
apiProxy: string;
|
|
46
|
+
apiPrefix: string;
|
|
47
|
+
types: RequiredTypeGenConfig | false;
|
|
48
|
+
verbose: boolean;
|
|
49
|
+
hotFile?: string;
|
|
50
|
+
proxyMode: IntegrationProxyMode;
|
|
51
|
+
/** Preferred dev server port (provided by Python via `VITE_PORT` or the bridge file). */
|
|
52
|
+
port?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Litestar dev server port. Used to set `vite.server.ws.clientPort` on Vite
|
|
55
|
+
* 8.1+ (`vite.server.hmr.clientPort` on Vite 7 / 8.0) so the browser opens HMR
|
|
56
|
+
* WebSockets against Litestar (single-port contract).
|
|
57
|
+
*/
|
|
58
|
+
litestarPort?: number;
|
|
59
|
+
/** Asset URL prefix (e.g. `/static`); used to build the HMR path. */
|
|
60
|
+
assetUrl?: string;
|
|
61
|
+
/** JavaScript runtime executor for package commands. */
|
|
62
|
+
executor?: IntegrationExecutor;
|
|
63
|
+
/** Whether `.litestar.json` was found. */
|
|
64
|
+
hasPythonConfig: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Apply defaults and merge `.litestar.json` values into a framework integration's options.
|
|
68
|
+
*
|
|
69
|
+
* @param config - User-supplied integration options.
|
|
70
|
+
* @param defaultOutput - Framework-conventional directory for generated types, used when the
|
|
71
|
+
* user and Python side both leave `types.output` unset.
|
|
72
|
+
* @returns The resolved configuration.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveIntegrationConfig(config: LitestarIntegrationConfig, defaultOutput: string): ResolvedIntegrationConfig;
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { readBridgeConfig } from "./bridge-schema.js";
|
|
2
|
+
import { resolveHotFilePath, resolveLitestarPort } from "./network.js";
|
|
3
|
+
import { resolveTypesConfig } from "./typegen-plugin.js";
|
|
4
|
+
function resolvePortFromEnv() {
|
|
5
|
+
const envPort = process.env.VITE_PORT;
|
|
6
|
+
if (!envPort) {
|
|
7
|
+
return void 0;
|
|
8
|
+
}
|
|
9
|
+
const parsed = Number.parseInt(envPort, 10);
|
|
10
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
11
|
+
}
|
|
12
|
+
function resolveIntegrationConfig(config, defaultOutput) {
|
|
13
|
+
let hotFile;
|
|
14
|
+
let proxyMode = "vite";
|
|
15
|
+
let port = resolvePortFromEnv();
|
|
16
|
+
let pythonTypesConfig;
|
|
17
|
+
let pythonExecutor;
|
|
18
|
+
let assetUrl;
|
|
19
|
+
let litestarPort;
|
|
20
|
+
let hasPythonConfig = false;
|
|
21
|
+
const runtime = readBridgeConfig();
|
|
22
|
+
if (runtime) {
|
|
23
|
+
hasPythonConfig = true;
|
|
24
|
+
hotFile = resolveHotFilePath(runtime.bundleDir, runtime.hotFile);
|
|
25
|
+
proxyMode = runtime.proxyMode;
|
|
26
|
+
port = runtime.port;
|
|
27
|
+
pythonExecutor = runtime.executor;
|
|
28
|
+
assetUrl = runtime.assetUrl;
|
|
29
|
+
if (runtime.types) {
|
|
30
|
+
pythonTypesConfig = runtime.types;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const resolvedLitestarPort = resolveLitestarPort(runtime?.litestarPort, runtime?.appUrl);
|
|
34
|
+
if (resolvedLitestarPort !== null) {
|
|
35
|
+
litestarPort = resolvedLitestarPort;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
apiProxy: config.apiProxy ?? "http://localhost:8000",
|
|
39
|
+
apiPrefix: config.apiPrefix ?? "/api",
|
|
40
|
+
types: resolveTypesConfig({
|
|
41
|
+
requested: config.types,
|
|
42
|
+
pythonConfig: pythonTypesConfig ?? void 0,
|
|
43
|
+
defaultOutput,
|
|
44
|
+
mergePythonWhenTrue: true,
|
|
45
|
+
mergePythonForObject: true
|
|
46
|
+
}),
|
|
47
|
+
verbose: config.verbose ?? false,
|
|
48
|
+
hotFile,
|
|
49
|
+
proxyMode,
|
|
50
|
+
port,
|
|
51
|
+
litestarPort,
|
|
52
|
+
assetUrl,
|
|
53
|
+
executor: config.executor ?? pythonExecutor,
|
|
54
|
+
hasPythonConfig
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
resolveIntegrationConfig
|
|
59
|
+
};
|