litestar-vite-plugin 0.15.0-alpha.2 → 0.15.0-alpha.4
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 +91 -20
- package/dist/js/astro.d.ts +85 -23
- package/dist/js/astro.js +300 -9
- package/dist/js/helpers/index.d.ts +2 -2
- package/dist/js/helpers/index.js +2 -2
- package/dist/js/helpers/routes.d.ts +19 -0
- package/dist/js/helpers/routes.js +59 -37
- package/dist/js/index.d.ts +12 -5
- package/dist/js/index.js +40 -27
- package/dist/js/inertia-helpers/{inertia-helpers/index.d.ts → index.d.ts} +12 -1
- package/dist/js/inertia-helpers/index.js +91 -0
- package/dist/js/install-hint.d.ts +9 -0
- package/dist/js/install-hint.js +17 -1
- package/dist/js/nuxt.d.ts +29 -22
- package/dist/js/nuxt.js +269 -45
- package/dist/js/shared/debounce.d.ts +27 -0
- package/dist/js/shared/debounce.js +15 -0
- package/dist/js/sveltekit.d.ts +7 -0
- package/dist/js/sveltekit.js +214 -23
- package/package.json +14 -6
- package/tools/clean.js +1 -1
- package/dist/js/inertia-helpers/helpers/csrf.d.ts +0 -76
- package/dist/js/inertia-helpers/helpers/csrf.js +0 -114
- package/dist/js/inertia-helpers/helpers/index.d.ts +0 -24
- package/dist/js/inertia-helpers/helpers/index.js +0 -26
- package/dist/js/inertia-helpers/helpers/routes.d.ts +0 -140
- package/dist/js/inertia-helpers/helpers/routes.js +0 -280
- package/dist/js/inertia-helpers/inertia-helpers/index.js +0 -47
|
@@ -34,12 +34,26 @@ export interface RoutesMap {
|
|
|
34
34
|
* Convenience alias for route names when using injected metadata.
|
|
35
35
|
*/
|
|
36
36
|
export type RouteName = keyof RoutesMap["routes"];
|
|
37
|
+
/**
|
|
38
|
+
* Litestar helpers namespace for clean global access.
|
|
39
|
+
*/
|
|
40
|
+
export interface LitestarHelpers {
|
|
41
|
+
route: typeof route;
|
|
42
|
+
toRoute: typeof toRoute;
|
|
43
|
+
currentRoute: typeof currentRoute;
|
|
44
|
+
isRoute: typeof isRoute;
|
|
45
|
+
isCurrentRoute: typeof isCurrentRoute;
|
|
46
|
+
getRelativeUrlPath: typeof getRelativeUrlPath;
|
|
47
|
+
routes: Record<string, string>;
|
|
48
|
+
}
|
|
37
49
|
declare global {
|
|
38
50
|
interface Window {
|
|
39
51
|
__LITESTAR_ROUTES__?: RoutesMap;
|
|
52
|
+
__LITESTAR__?: LitestarHelpers;
|
|
40
53
|
routes?: Record<string, string>;
|
|
41
54
|
serverRoutes?: Record<string, string>;
|
|
42
55
|
}
|
|
56
|
+
var __LITESTAR__: LitestarHelpers | undefined;
|
|
43
57
|
var routes: Record<string, string>;
|
|
44
58
|
var serverRoutes: Record<string, string>;
|
|
45
59
|
}
|
|
@@ -137,4 +151,9 @@ export declare function isRoute(url: string, routeName: string): boolean;
|
|
|
137
151
|
* ```
|
|
138
152
|
*/
|
|
139
153
|
export declare function isCurrentRoute(routeName: string): boolean;
|
|
154
|
+
/**
|
|
155
|
+
* Litestar helpers namespace object.
|
|
156
|
+
* Access via window.__LITESTAR__ or import functions directly from this module.
|
|
157
|
+
*/
|
|
158
|
+
export declare const LITESTAR: LitestarHelpers;
|
|
140
159
|
export {};
|
|
@@ -13,6 +13,40 @@
|
|
|
13
13
|
*
|
|
14
14
|
* @module
|
|
15
15
|
*/
|
|
16
|
+
/**
|
|
17
|
+
* Cache for compiled route patterns to avoid repeated regex compilation.
|
|
18
|
+
*/
|
|
19
|
+
const routePatternCache = new Map();
|
|
20
|
+
/**
|
|
21
|
+
* Compile a route pattern to a regex for URL matching.
|
|
22
|
+
* Results are cached for performance.
|
|
23
|
+
*
|
|
24
|
+
* @param routePattern - Route pattern with optional {param:type} placeholders
|
|
25
|
+
* @returns Compiled regex pattern
|
|
26
|
+
*/
|
|
27
|
+
function compileRoutePattern(routePattern) {
|
|
28
|
+
const cached = routePatternCache.get(routePattern);
|
|
29
|
+
if (cached) {
|
|
30
|
+
return cached;
|
|
31
|
+
}
|
|
32
|
+
const regexPattern = routePattern.replace(/\//g, "\\/").replace(/\{([^}]+)\}/g, (_, paramSpec) => {
|
|
33
|
+
// Handle {param:type} syntax
|
|
34
|
+
const paramType = paramSpec.includes(":") ? paramSpec.split(":")[1] : "str";
|
|
35
|
+
switch (paramType) {
|
|
36
|
+
case "uuid":
|
|
37
|
+
return "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
38
|
+
case "path":
|
|
39
|
+
return ".*";
|
|
40
|
+
case "int":
|
|
41
|
+
return "\\d+";
|
|
42
|
+
default:
|
|
43
|
+
return "[^/]+";
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const compiled = new RegExp(`^${regexPattern}$`);
|
|
47
|
+
routePatternCache.set(routePattern, compiled);
|
|
48
|
+
return compiled;
|
|
49
|
+
}
|
|
16
50
|
/**
|
|
17
51
|
* Get the routes object from the page.
|
|
18
52
|
*
|
|
@@ -154,21 +188,7 @@ export function toRoute(url) {
|
|
|
154
188
|
const processedUrl = getRelativeUrlPath(url);
|
|
155
189
|
const normalizedUrl = processedUrl === "/" ? processedUrl : processedUrl.replace(/\/$/, "");
|
|
156
190
|
for (const [routeName, routePattern] of Object.entries(routes)) {
|
|
157
|
-
const
|
|
158
|
-
// Handle {param:type} syntax
|
|
159
|
-
const paramType = paramSpec.includes(":") ? paramSpec.split(":")[1] : "str";
|
|
160
|
-
switch (paramType) {
|
|
161
|
-
case "uuid":
|
|
162
|
-
return "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
163
|
-
case "path":
|
|
164
|
-
return ".*";
|
|
165
|
-
case "int":
|
|
166
|
-
return "\\d+";
|
|
167
|
-
default:
|
|
168
|
-
return "[^/]+";
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
191
|
+
const regex = compileRoutePattern(routePattern);
|
|
172
192
|
if (regex.test(normalizedUrl)) {
|
|
173
193
|
return routeName;
|
|
174
194
|
}
|
|
@@ -214,20 +234,7 @@ export function isRoute(url, routeName) {
|
|
|
214
234
|
const matchingRouteNames = Object.keys(routes).filter((name) => routeNameRegex.test(name));
|
|
215
235
|
for (const name of matchingRouteNames) {
|
|
216
236
|
const routePattern = routes[name];
|
|
217
|
-
const
|
|
218
|
-
const paramType = paramSpec.includes(":") ? paramSpec.split(":")[1] : "str";
|
|
219
|
-
switch (paramType) {
|
|
220
|
-
case "uuid":
|
|
221
|
-
return "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
222
|
-
case "path":
|
|
223
|
-
return "(.*)";
|
|
224
|
-
case "int":
|
|
225
|
-
return "(\\d+)";
|
|
226
|
-
default:
|
|
227
|
-
return "([^/]+)";
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
237
|
+
const regex = compileRoutePattern(routePattern);
|
|
231
238
|
if (regex.test(normalizedUrl)) {
|
|
232
239
|
return true;
|
|
233
240
|
}
|
|
@@ -255,17 +262,27 @@ export function isCurrentRoute(routeName) {
|
|
|
255
262
|
const routeNameRegex = new RegExp(`^${routeName.replace(/\*/g, ".*")}$`);
|
|
256
263
|
return routeNameRegex.test(current);
|
|
257
264
|
}
|
|
258
|
-
|
|
265
|
+
/**
|
|
266
|
+
* Litestar helpers namespace object.
|
|
267
|
+
* Access via window.__LITESTAR__ or import functions directly from this module.
|
|
268
|
+
*/
|
|
269
|
+
export const LITESTAR = {
|
|
270
|
+
route,
|
|
271
|
+
toRoute,
|
|
272
|
+
currentRoute,
|
|
273
|
+
isRoute,
|
|
274
|
+
isCurrentRoute,
|
|
275
|
+
getRelativeUrlPath,
|
|
276
|
+
routes: {},
|
|
277
|
+
};
|
|
278
|
+
// Set up namespaced global access
|
|
259
279
|
if (typeof globalThis !== "undefined") {
|
|
260
|
-
globalThis.
|
|
280
|
+
globalThis.__LITESTAR__ = LITESTAR;
|
|
281
|
+
// Also set up routes for internal use
|
|
282
|
+
globalThis.routes = globalThis.routes || LITESTAR.routes;
|
|
261
283
|
globalThis.serverRoutes = globalThis.serverRoutes || globalThis.routes;
|
|
262
|
-
globalThis.route = route;
|
|
263
|
-
globalThis.toRoute = toRoute;
|
|
264
|
-
globalThis.currentRoute = currentRoute;
|
|
265
|
-
globalThis.isRoute = isRoute;
|
|
266
|
-
globalThis.isCurrentRoute = isCurrentRoute;
|
|
267
284
|
}
|
|
268
|
-
// Keep
|
|
285
|
+
// Keep routes fresh during Vite HMR when the plugin regenerates metadata/types
|
|
269
286
|
if (import.meta.hot) {
|
|
270
287
|
import.meta.hot.on("litestar:types-updated", () => {
|
|
271
288
|
if (typeof window === "undefined") {
|
|
@@ -273,8 +290,13 @@ if (import.meta.hot) {
|
|
|
273
290
|
}
|
|
274
291
|
const updated = getRoutes();
|
|
275
292
|
if (updated) {
|
|
293
|
+
// Update all references
|
|
294
|
+
LITESTAR.routes = updated;
|
|
276
295
|
window.serverRoutes = updated;
|
|
277
296
|
window.routes = updated;
|
|
297
|
+
if (window.__LITESTAR__) {
|
|
298
|
+
window.__LITESTAR__.routes = updated;
|
|
299
|
+
}
|
|
278
300
|
}
|
|
279
301
|
});
|
|
280
302
|
}
|
package/dist/js/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type ConfigEnv, type Plugin, type UserConfig } from "vite";
|
|
2
1
|
import { type Config as FullReloadConfig } from "vite-plugin-full-reload";
|
|
3
2
|
/**
|
|
4
3
|
* Configuration for TypeScript type generation.
|
|
@@ -147,20 +146,28 @@ export interface PluginConfig {
|
|
|
147
146
|
* @default false
|
|
148
147
|
*/
|
|
149
148
|
types?: boolean | TypesConfig;
|
|
149
|
+
/**
|
|
150
|
+
* JavaScript runtime executor for package commands.
|
|
151
|
+
* Used when running tools like @hey-api/openapi-ts.
|
|
152
|
+
*
|
|
153
|
+
* This is typically auto-detected from Python config via LITESTAR_VITE_RUNTIME env var,
|
|
154
|
+
* but can be overridden here for JS-only projects or specific needs.
|
|
155
|
+
*
|
|
156
|
+
* @default undefined (uses LITESTAR_VITE_RUNTIME env or 'node')
|
|
157
|
+
*/
|
|
158
|
+
executor?: "node" | "bun" | "deno" | "yarn" | "pnpm";
|
|
150
159
|
}
|
|
151
160
|
interface RefreshConfig {
|
|
152
161
|
paths: string[];
|
|
153
162
|
config?: FullReloadConfig;
|
|
154
163
|
}
|
|
155
|
-
interface LitestarPlugin extends Plugin {
|
|
156
|
-
config: (config: UserConfig, env: ConfigEnv) => UserConfig;
|
|
157
|
-
}
|
|
158
164
|
type DevServerUrl = `${"http" | "https"}://${string}:${number}`;
|
|
159
165
|
export declare const refreshPaths: string[];
|
|
160
166
|
/**
|
|
161
167
|
* Litestar plugin for Vite.
|
|
162
168
|
*
|
|
163
169
|
* @param config - A config object or relative path(s) of the scripts to be compiled.
|
|
170
|
+
* @returns An array of Vite plugins. Return type is `any[]` to avoid cross-version type conflicts.
|
|
164
171
|
*/
|
|
165
|
-
export default function litestar(config: string | string[] | PluginConfig): [
|
|
172
|
+
export default function litestar(config: string | string[] | PluginConfig): any[];
|
|
166
173
|
export {};
|
package/dist/js/index.js
CHANGED
|
@@ -7,8 +7,9 @@ import { promisify } from "node:util";
|
|
|
7
7
|
import colors from "picocolors";
|
|
8
8
|
import { loadEnv } from "vite";
|
|
9
9
|
import fullReload from "vite-plugin-full-reload";
|
|
10
|
-
import { resolveInstallHint } from "./install-hint.js";
|
|
10
|
+
import { resolveInstallHint, resolvePackageExecutor } from "./install-hint.js";
|
|
11
11
|
import { checkBackendAvailability, loadLitestarMeta } from "./litestar-meta.js";
|
|
12
|
+
import { debounce } from "./shared/debounce.js";
|
|
12
13
|
const execAsync = promisify(exec);
|
|
13
14
|
let exitHandlersBound = false;
|
|
14
15
|
const refreshPaths = ["src/**", "resources/**", "assets/**"].filter((path2) => fs.existsSync(path2.replace(/\*\*$/, "")));
|
|
@@ -16,13 +17,12 @@ function litestar(config) {
|
|
|
16
17
|
const pluginConfig = resolvePluginConfig(config);
|
|
17
18
|
const plugins = [resolveLitestarPlugin(pluginConfig), ...resolveFullReloadConfig(pluginConfig)];
|
|
18
19
|
if (pluginConfig.types !== false && pluginConfig.types.enabled) {
|
|
19
|
-
plugins.push(resolveTypeGenerationPlugin(pluginConfig.types));
|
|
20
|
+
plugins.push(resolveTypeGenerationPlugin(pluginConfig.types, pluginConfig.executor));
|
|
20
21
|
}
|
|
21
22
|
return plugins;
|
|
22
23
|
}
|
|
23
24
|
async function findIndexHtmlPath(server, pluginConfig) {
|
|
24
25
|
if (!pluginConfig.autoDetectIndex) {
|
|
25
|
-
console.log("Auto-detection disabled.");
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
28
|
const root = server.config.root;
|
|
@@ -42,7 +42,7 @@ async function findIndexHtmlPath(server, pluginConfig) {
|
|
|
42
42
|
}
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
45
|
-
function normalizeAppUrl(appUrl,
|
|
45
|
+
function normalizeAppUrl(appUrl, _fallbackPort) {
|
|
46
46
|
if (!appUrl || appUrl === "__litestar_app_url_missing__") {
|
|
47
47
|
return { url: null, note: "APP_URL missing" };
|
|
48
48
|
}
|
|
@@ -59,6 +59,8 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
59
59
|
let resolvedConfig;
|
|
60
60
|
let userConfig;
|
|
61
61
|
let litestarMeta = {};
|
|
62
|
+
const pythonDefaults = loadPythonDefaults();
|
|
63
|
+
const proxyMode = pythonDefaults?.proxyMode ?? "vite_proxy";
|
|
62
64
|
const defaultAliases = {
|
|
63
65
|
"@": `/${pluginConfig.resourceDirectory.replace(/^\/+/, "").replace(/\/+$/, "")}/`
|
|
64
66
|
};
|
|
@@ -109,10 +111,19 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
109
111
|
changeOrigin: true
|
|
110
112
|
}
|
|
111
113
|
} : void 0),
|
|
114
|
+
// Always respect VITE_PORT when set by Python (regardless of VITE_ALLOW_REMOTE)
|
|
115
|
+
...process.env.VITE_PORT ? {
|
|
116
|
+
port: userConfig.server?.port ?? Number.parseInt(process.env.VITE_PORT),
|
|
117
|
+
strictPort: userConfig.server?.strictPort ?? true
|
|
118
|
+
} : void 0,
|
|
119
|
+
// VITE_ALLOW_REMOTE controls host binding (0.0.0.0 for remote access)
|
|
120
|
+
// Also sets port/strictPort for backwards compatibility when VITE_PORT not set
|
|
112
121
|
...process.env.VITE_ALLOW_REMOTE ? {
|
|
113
122
|
host: userConfig.server?.host ?? "0.0.0.0",
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
...process.env.VITE_PORT ? {} : {
|
|
124
|
+
port: userConfig.server?.port ?? 5173,
|
|
125
|
+
strictPort: userConfig.server?.strictPort ?? true
|
|
126
|
+
}
|
|
116
127
|
} : void 0,
|
|
117
128
|
...serverConfig ? {
|
|
118
129
|
host: userConfig.server?.host ?? serverConfig.host,
|
|
@@ -149,7 +160,7 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
149
160
|
const hint = pluginConfig.types !== false ? pluginConfig.types.routesPath : void 0;
|
|
150
161
|
litestarMeta = await loadLitestarMeta(resolvedConfig, hint);
|
|
151
162
|
},
|
|
152
|
-
transform(code,
|
|
163
|
+
transform(code, _id) {
|
|
153
164
|
if (resolvedConfig.command === "serve" && code.includes("__litestar_vite_placeholder__")) {
|
|
154
165
|
const transformedCode = code.replace(/__litestar_vite_placeholder__/g, viteDevServerUrl);
|
|
155
166
|
return pluginConfig.transformOnServe(transformedCode, viteDevServerUrl);
|
|
@@ -171,8 +182,10 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
171
182
|
const isAddressInfo = (x) => typeof x === "object";
|
|
172
183
|
if (isAddressInfo(address)) {
|
|
173
184
|
viteDevServerUrl = userConfig.server?.origin ? userConfig.server.origin : resolveDevServerUrl(address, server.config, userConfig);
|
|
174
|
-
|
|
175
|
-
|
|
185
|
+
if (proxyMode !== "external_proxy") {
|
|
186
|
+
fs.mkdirSync(path.dirname(pluginConfig.hotFile), { recursive: true });
|
|
187
|
+
fs.writeFileSync(pluginConfig.hotFile, viteDevServerUrl);
|
|
188
|
+
}
|
|
176
189
|
setTimeout(async () => {
|
|
177
190
|
const version = litestarMeta.litestarVersion ?? process.env.LITESTAR_VERSION ?? "unknown";
|
|
178
191
|
const backendStatus = await checkBackendAvailability(appUrl);
|
|
@@ -229,7 +242,7 @@ function resolveLitestarPlugin(pluginConfig) {
|
|
|
229
242
|
}, 100);
|
|
230
243
|
}
|
|
231
244
|
});
|
|
232
|
-
if (!exitHandlersBound) {
|
|
245
|
+
if (!exitHandlersBound && proxyMode !== "external_proxy") {
|
|
233
246
|
const clean = () => {
|
|
234
247
|
if (pluginConfig.hotFile && fs.existsSync(pluginConfig.hotFile)) {
|
|
235
248
|
fs.rmSync(pluginConfig.hotFile);
|
|
@@ -291,7 +304,7 @@ function ensureCommandShouldRunInEnvironment(command, env) {
|
|
|
291
304
|
);
|
|
292
305
|
}
|
|
293
306
|
}
|
|
294
|
-
function
|
|
307
|
+
function _pluginVersion() {
|
|
295
308
|
try {
|
|
296
309
|
return JSON.parse(fs.readFileSync(path.join(dirname(), "../package.json")).toString())?.version;
|
|
297
310
|
} catch {
|
|
@@ -362,15 +375,23 @@ function resolvePluginConfig(config) {
|
|
|
362
375
|
debounce: 300
|
|
363
376
|
};
|
|
364
377
|
} else if (typeof resolvedConfig.types === "object" && resolvedConfig.types !== null) {
|
|
378
|
+
const userProvidedOpenapi = Object.hasOwn(resolvedConfig.types, "openapiPath");
|
|
379
|
+
const userProvidedRoutes = Object.hasOwn(resolvedConfig.types, "routesPath");
|
|
365
380
|
typesConfig = {
|
|
366
381
|
enabled: resolvedConfig.types.enabled ?? true,
|
|
367
382
|
output: resolvedConfig.types.output ?? "src/generated/types",
|
|
368
|
-
openapiPath: resolvedConfig.types.openapiPath ?? "src/generated/openapi.json",
|
|
369
|
-
routesPath: resolvedConfig.types.routesPath ?? "src/generated/routes.json",
|
|
383
|
+
openapiPath: resolvedConfig.types.openapiPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "openapi.json") : "src/generated/openapi.json"),
|
|
384
|
+
routesPath: resolvedConfig.types.routesPath ?? (resolvedConfig.types.output ? path.join(resolvedConfig.types.output, "routes.json") : "src/generated/routes.json"),
|
|
370
385
|
generateZod: resolvedConfig.types.generateZod ?? false,
|
|
371
386
|
generateSdk: resolvedConfig.types.generateSdk ?? false,
|
|
372
387
|
debounce: resolvedConfig.types.debounce ?? 300
|
|
373
388
|
};
|
|
389
|
+
if (!userProvidedOpenapi && resolvedConfig.types.output) {
|
|
390
|
+
typesConfig.openapiPath = path.join(typesConfig.output, "openapi.json");
|
|
391
|
+
}
|
|
392
|
+
if (!userProvidedRoutes && resolvedConfig.types.output) {
|
|
393
|
+
typesConfig.routesPath = path.join(typesConfig.output, "routes.json");
|
|
394
|
+
}
|
|
374
395
|
}
|
|
375
396
|
return {
|
|
376
397
|
input: resolvedConfig.input,
|
|
@@ -384,10 +405,11 @@ function resolvePluginConfig(config) {
|
|
|
384
405
|
detectTls: resolvedConfig.detectTls ?? false,
|
|
385
406
|
autoDetectIndex: resolvedConfig.autoDetectIndex ?? true,
|
|
386
407
|
transformOnServe: resolvedConfig.transformOnServe ?? ((code) => code),
|
|
387
|
-
types: typesConfig
|
|
408
|
+
types: typesConfig,
|
|
409
|
+
executor: resolvedConfig.executor ?? pythonDefaults?.executor
|
|
388
410
|
};
|
|
389
411
|
}
|
|
390
|
-
function resolveBase(
|
|
412
|
+
function resolveBase(_config, assetUrl) {
|
|
391
413
|
if (process.env.NODE_ENV === "development") {
|
|
392
414
|
return assetUrl;
|
|
393
415
|
}
|
|
@@ -424,15 +446,6 @@ function resolveFullReloadConfig({ refresh: config }) {
|
|
|
424
446
|
return plugin;
|
|
425
447
|
});
|
|
426
448
|
}
|
|
427
|
-
function debounce(func, wait) {
|
|
428
|
-
let timeout = null;
|
|
429
|
-
return (...args) => {
|
|
430
|
-
if (timeout) {
|
|
431
|
-
clearTimeout(timeout);
|
|
432
|
-
}
|
|
433
|
-
timeout = setTimeout(() => func(...args), wait);
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
449
|
async function emitRouteTypes(routesPath, outputDir) {
|
|
437
450
|
const contents = await fs.promises.readFile(routesPath, "utf-8");
|
|
438
451
|
const json = JSON.parse(contents);
|
|
@@ -558,7 +571,7 @@ export { getCsrfToken, csrfHeaders, csrfFetch } from "litestar-vite-plugin/helpe
|
|
|
558
571
|
`;
|
|
559
572
|
await fs.promises.writeFile(outFile, `${banner}${body}`, "utf-8");
|
|
560
573
|
}
|
|
561
|
-
function resolveTypeGenerationPlugin(typesConfig) {
|
|
574
|
+
function resolveTypeGenerationPlugin(typesConfig, executor) {
|
|
562
575
|
let lastTypesHash = null;
|
|
563
576
|
let lastRoutesHash = null;
|
|
564
577
|
let server = null;
|
|
@@ -580,12 +593,12 @@ function resolveTypeGenerationPlugin(typesConfig) {
|
|
|
580
593
|
}
|
|
581
594
|
const args = ["@hey-api/openapi-ts", "-i", typesConfig.openapiPath, "-o", typesConfig.output];
|
|
582
595
|
if (typesConfig.generateZod) {
|
|
583
|
-
args.push("--plugins", "
|
|
596
|
+
args.push("--plugins", "zod", "@hey-api/typescript");
|
|
584
597
|
}
|
|
585
598
|
if (typesConfig.generateSdk) {
|
|
586
599
|
args.push("--client", "fetch");
|
|
587
600
|
}
|
|
588
|
-
await execAsync(
|
|
601
|
+
await execAsync(resolvePackageExecutor(args.join(" "), executor), {
|
|
589
602
|
cwd: process.cwd()
|
|
590
603
|
});
|
|
591
604
|
generated = true;
|
|
@@ -6,11 +6,22 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
export {
|
|
9
|
+
export { csrfFetch, csrfHeaders, currentRoute, getCsrfToken, getRelativeUrlPath, getRoutes, isCurrentRoute, isRoute, type RouteDefinition, type RoutesMap, route, toRoute, } from "litestar-vite-plugin/helpers";
|
|
10
|
+
/**
|
|
11
|
+
* Unwrap page props that may have content nested under "content" key.
|
|
12
|
+
*
|
|
13
|
+
* Litestar wraps route return values under `content`. This utility
|
|
14
|
+
* spreads the content at the top level for ergonomic prop access.
|
|
15
|
+
*
|
|
16
|
+
* @param props - The raw page props from Inertia
|
|
17
|
+
* @returns Props with content unwrapped if applicable
|
|
18
|
+
*/
|
|
19
|
+
export declare function unwrapPageProps<T extends Record<string, unknown>>(props: T): T;
|
|
10
20
|
/**
|
|
11
21
|
* Resolve a page component from a glob import.
|
|
12
22
|
*
|
|
13
23
|
* Used with Inertia.js to dynamically import page components.
|
|
24
|
+
* Automatically unwraps Litestar's `content` prop for ergonomic access.
|
|
14
25
|
*
|
|
15
26
|
* @param path - Component path or array of paths to try
|
|
16
27
|
* @param pages - Glob import result (e.g., import.meta.glob('./pages/**\/*.vue'))
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inertia.js helpers for Litestar applications.
|
|
3
|
+
*
|
|
4
|
+
* This module re-exports common helpers from litestar-vite-plugin/helpers
|
|
5
|
+
* and adds Inertia-specific utilities.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
// Re-export all helpers from the main helpers module
|
|
10
|
+
// Note: Using package path instead of relative import to ensure proper build output structure
|
|
11
|
+
export { csrfFetch, csrfHeaders, currentRoute,
|
|
12
|
+
// CSRF utilities
|
|
13
|
+
getCsrfToken, getRelativeUrlPath, getRoutes, isCurrentRoute, isRoute,
|
|
14
|
+
// Route utilities
|
|
15
|
+
route, toRoute, } from "litestar-vite-plugin/helpers";
|
|
16
|
+
/**
|
|
17
|
+
* Unwrap page props that may have content nested under "content" key.
|
|
18
|
+
*
|
|
19
|
+
* Litestar wraps route return values under `content`. This utility
|
|
20
|
+
* spreads the content at the top level for ergonomic prop access.
|
|
21
|
+
*
|
|
22
|
+
* @param props - The raw page props from Inertia
|
|
23
|
+
* @returns Props with content unwrapped if applicable
|
|
24
|
+
*/
|
|
25
|
+
export function unwrapPageProps(props) {
|
|
26
|
+
if (props.content !== undefined && props.content !== null && typeof props.content === "object" && !Array.isArray(props.content)) {
|
|
27
|
+
const { content, ...rest } = props;
|
|
28
|
+
return { ...rest, ...content };
|
|
29
|
+
}
|
|
30
|
+
return props;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Wrap a component to automatically unwrap Litestar's content prop.
|
|
34
|
+
*
|
|
35
|
+
* @param component - The original component (function or object with default)
|
|
36
|
+
* @returns Wrapped component that transforms props
|
|
37
|
+
*/
|
|
38
|
+
function wrapComponent(module) {
|
|
39
|
+
// Handle ES module with default export
|
|
40
|
+
const mod = module;
|
|
41
|
+
if (mod.default && typeof mod.default === "function") {
|
|
42
|
+
const Original = mod.default;
|
|
43
|
+
const Wrapped = (props) => Original(unwrapPageProps(props));
|
|
44
|
+
// Copy static properties (displayName, layout, etc.)
|
|
45
|
+
Object.assign(Wrapped, Original);
|
|
46
|
+
return { ...mod, default: Wrapped };
|
|
47
|
+
}
|
|
48
|
+
// Handle direct function export
|
|
49
|
+
if (typeof module === "function") {
|
|
50
|
+
const Original = module;
|
|
51
|
+
const Wrapped = (props) => Original(unwrapPageProps(props));
|
|
52
|
+
Object.assign(Wrapped, Original);
|
|
53
|
+
return Wrapped;
|
|
54
|
+
}
|
|
55
|
+
return module;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a page component from a glob import.
|
|
59
|
+
*
|
|
60
|
+
* Used with Inertia.js to dynamically import page components.
|
|
61
|
+
* Automatically unwraps Litestar's `content` prop for ergonomic access.
|
|
62
|
+
*
|
|
63
|
+
* @param path - Component path or array of paths to try
|
|
64
|
+
* @param pages - Glob import result (e.g., import.meta.glob('./pages/**\/*.vue'))
|
|
65
|
+
* @returns Promise resolving to the component
|
|
66
|
+
* @throws Error if no matching component is found
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import { resolvePageComponent } from 'litestar-vite-plugin/inertia-helpers'
|
|
71
|
+
*
|
|
72
|
+
* createInertiaApp({
|
|
73
|
+
* resolve: (name) => resolvePageComponent(
|
|
74
|
+
* `./pages/${name}.vue`,
|
|
75
|
+
* import.meta.glob('./pages/**\/*.vue')
|
|
76
|
+
* ),
|
|
77
|
+
* // ...
|
|
78
|
+
* })
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export async function resolvePageComponent(path, pages) {
|
|
82
|
+
for (const p of Array.isArray(path) ? path : [path]) {
|
|
83
|
+
const page = pages[p];
|
|
84
|
+
if (typeof page === "undefined") {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const resolved = typeof page === "function" ? await page() : await page;
|
|
88
|
+
return wrapComponent(resolved);
|
|
89
|
+
}
|
|
90
|
+
throw new Error(`Page not found: ${path}`);
|
|
91
|
+
}
|
|
@@ -1 +1,10 @@
|
|
|
1
1
|
export declare function resolveInstallHint(pkg?: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the package executor command based on runtime.
|
|
4
|
+
* Priority: explicit executor > LITESTAR_VITE_RUNTIME env > 'node' default
|
|
5
|
+
*
|
|
6
|
+
* @param pkg - The package command to execute (e.g., "@hey-api/openapi-ts -i schema.json -o src/types")
|
|
7
|
+
* @param executor - Optional explicit executor override
|
|
8
|
+
* @returns The full command string (e.g., "npx @hey-api/openapi-ts ..." or "bunx @hey-api/openapi-ts ...")
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolvePackageExecutor(pkg: string, executor?: string): string;
|
package/dist/js/install-hint.js
CHANGED
|
@@ -16,6 +16,22 @@ function resolveInstallHint(pkg = "@hey-api/openapi-ts") {
|
|
|
16
16
|
}
|
|
17
17
|
return `npm install -D ${pkg}`;
|
|
18
18
|
}
|
|
19
|
+
function resolvePackageExecutor(pkg, executor) {
|
|
20
|
+
const runtime = (executor ?? process.env.LITESTAR_VITE_RUNTIME ?? "").toLowerCase();
|
|
21
|
+
switch (runtime) {
|
|
22
|
+
case "bun":
|
|
23
|
+
return `bunx ${pkg}`;
|
|
24
|
+
case "deno":
|
|
25
|
+
return `deno run -A npm:${pkg}`;
|
|
26
|
+
case "pnpm":
|
|
27
|
+
return `pnpm dlx ${pkg}`;
|
|
28
|
+
case "yarn":
|
|
29
|
+
return `yarn dlx ${pkg}`;
|
|
30
|
+
default:
|
|
31
|
+
return `npx ${pkg}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
19
34
|
export {
|
|
20
|
-
resolveInstallHint
|
|
35
|
+
resolveInstallHint,
|
|
36
|
+
resolvePackageExecutor
|
|
21
37
|
};
|
package/dist/js/nuxt.d.ts
CHANGED
|
@@ -102,6 +102,13 @@ export interface LitestarNuxtConfig {
|
|
|
102
102
|
* @default false
|
|
103
103
|
*/
|
|
104
104
|
verbose?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* JavaScript runtime executor for package commands.
|
|
107
|
+
* Used when running tools like @hey-api/openapi-ts.
|
|
108
|
+
*
|
|
109
|
+
* @default undefined (uses LITESTAR_VITE_RUNTIME env or 'node')
|
|
110
|
+
*/
|
|
111
|
+
executor?: "node" | "bun" | "deno" | "yarn" | "pnpm";
|
|
105
112
|
}
|
|
106
113
|
/**
|
|
107
114
|
* Litestar Vite plugins for Nuxt.
|
|
@@ -133,8 +140,7 @@ export declare function litestarPlugins(userConfig?: LitestarNuxtConfig): Plugin
|
|
|
133
140
|
/**
|
|
134
141
|
* Nuxt module definition for Litestar integration.
|
|
135
142
|
*
|
|
136
|
-
* This is a
|
|
137
|
-
* For full type safety, install @nuxt/kit as a dev dependency.
|
|
143
|
+
* This is a function-based module that works with Nuxt's module system.
|
|
138
144
|
*
|
|
139
145
|
* @example
|
|
140
146
|
* ```typescript
|
|
@@ -164,30 +170,31 @@ export declare function litestarPlugins(userConfig?: LitestarNuxtConfig): Plugin
|
|
|
164
170
|
* }
|
|
165
171
|
* ```
|
|
166
172
|
*/
|
|
167
|
-
|
|
168
|
-
|
|
173
|
+
interface NuxtModuleFunction {
|
|
174
|
+
(userOptions: LitestarNuxtConfig, nuxt: NuxtContext): void | Promise<void>;
|
|
175
|
+
meta?: {
|
|
169
176
|
name: string;
|
|
170
177
|
configKey: string;
|
|
171
|
-
compatibility
|
|
178
|
+
compatibility?: {
|
|
172
179
|
nuxt: string;
|
|
173
180
|
};
|
|
174
181
|
};
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
vite: {
|
|
188
|
-
plugins?: Plugin[];
|
|
189
|
-
};
|
|
182
|
+
getOptions?: () => LitestarNuxtConfig;
|
|
183
|
+
}
|
|
184
|
+
interface NuxtContext {
|
|
185
|
+
options: {
|
|
186
|
+
vite: {
|
|
187
|
+
plugins?: Plugin[];
|
|
188
|
+
};
|
|
189
|
+
runtimeConfig?: {
|
|
190
|
+
public?: Record<string, unknown>;
|
|
191
|
+
};
|
|
192
|
+
nitro?: {
|
|
193
|
+
devProxy?: Record<string, unknown>;
|
|
190
194
|
};
|
|
191
|
-
|
|
192
|
-
};
|
|
195
|
+
litestar?: LitestarNuxtConfig;
|
|
196
|
+
};
|
|
197
|
+
hook?: (name: string, fn: (...args: unknown[]) => void | Promise<void>) => void;
|
|
198
|
+
}
|
|
199
|
+
export declare const litestarModule: NuxtModuleFunction;
|
|
193
200
|
export default litestarModule;
|