litestar-vite-plugin 0.28.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.
@@ -26,6 +26,8 @@
26
26
  * @module
27
27
  */
28
28
  import type { Plugin, ViteDevServer } from "vite";
29
+ import { type LitestarIntegrationConfig } from "./shared/integration-config.js";
30
+ import { type TypesConfigShape } from "./shared/typegen-plugin.js";
29
31
  /**
30
32
  * Astro integration interface.
31
33
  * This is a minimal type definition to avoid requiring astro as a dependency.
@@ -94,130 +96,19 @@ interface AstroIntegrationLogger {
94
96
  error: (message: string) => void;
95
97
  }
96
98
  /**
97
- * Configuration for TypeScript type generation in Astro.
99
+ * Configuration for TypeScript type generation.
100
+ *
101
+ * Alias of the shared {@link TypesConfigShape} so every integration accepts an identical
102
+ * `types` option. Retained as a named export for backwards compatibility.
98
103
  */
99
- export interface AstroTypesConfig {
100
- /**
101
- * Enable type generation.
102
- *
103
- * @default false
104
- */
105
- enabled?: boolean;
106
- /**
107
- * Path to output generated TypeScript types.
108
- * Relative to the Astro project root.
109
- *
110
- * @default 'src/generated'
111
- */
112
- output?: string;
113
- /**
114
- * Path where the OpenAPI schema is exported by Litestar.
115
- *
116
- * @default `${output}/openapi.json`
117
- */
118
- openapiPath?: string;
119
- /**
120
- * Path where route metadata is exported by Litestar.
121
- *
122
- * @default `${output}/routes.json`
123
- */
124
- routesPath?: string;
125
- /**
126
- * Optional path for the generated schemas.ts helper file.
127
- *
128
- * @default `${output}/schemas.ts`
129
- */
130
- schemasTsPath?: string;
131
- /**
132
- * Path where Inertia page props metadata is exported by Litestar.
133
- *
134
- * @default `${output}/inertia-pages.json`
135
- */
136
- pagePropsPath?: string;
137
- /**
138
- * Generate Zod schemas in addition to TypeScript types.
139
- *
140
- * @default false
141
- */
142
- generateZod?: boolean;
143
- /**
144
- * Generate SDK client functions for API calls.
145
- *
146
- * @default true
147
- */
148
- generateSdk?: boolean;
149
- /**
150
- * Generate typed routes.ts from routes.json metadata.
151
- *
152
- * @default true
153
- */
154
- generateRoutes?: boolean;
155
- /**
156
- * Generate Inertia page props types from inertia-pages.json metadata.
157
- *
158
- * @default true
159
- */
160
- generatePageProps?: boolean;
161
- /**
162
- * Generate schemas.ts with ergonomic form/response type helpers.
163
- *
164
- * @default true
165
- */
166
- generateSchemas?: boolean;
167
- /**
168
- * Register route() globally on window object.
169
- *
170
- * @default false
171
- */
172
- globalRoute?: boolean;
173
- /**
174
- * Fail Vite when type generation fails.
175
- *
176
- * Defaults to true during build and false during dev.
177
- */
178
- failOnError?: boolean;
179
- /**
180
- * Debounce time in milliseconds for type regeneration.
181
- *
182
- * @default 300
183
- */
184
- debounce?: number;
185
- }
104
+ export type AstroTypesConfig = TypesConfigShape;
186
105
  /**
187
- * Configuration options for the Litestar Astro integration.
106
+ * Configuration options for the Litestar integration.
107
+ *
108
+ * Alias of the shared {@link LitestarIntegrationConfig}. Retained as a named export for
109
+ * backwards compatibility.
188
110
  */
189
- export interface LitestarAstroConfig {
190
- /**
191
- * URL of the Litestar API backend for proxying requests during development.
192
- *
193
- * @example 'http://127.0.0.1:8000'
194
- * @default 'http://localhost:8000'
195
- */
196
- apiProxy?: string;
197
- /**
198
- * API route prefix to proxy to the Litestar backend.
199
- * Requests matching this prefix will be forwarded to the apiProxy URL.
200
- *
201
- * @example '/api'
202
- * @default '/api'
203
- */
204
- apiPrefix?: string;
205
- /**
206
- * Enable and configure TypeScript type generation.
207
- *
208
- * When set to `true`, enables type generation with default settings.
209
- * When set to an AstroTypesConfig object, enables type generation with custom settings.
210
- *
211
- * @default false
212
- */
213
- types?: boolean | AstroTypesConfig;
214
- /**
215
- * Enable verbose logging for debugging.
216
- *
217
- * @default false
218
- */
219
- verbose?: boolean;
220
- }
111
+ export type LitestarAstroConfig = LitestarIntegrationConfig;
221
112
  /**
222
113
  * Litestar integration for Astro.
223
114
  *
package/dist/js/astro.js CHANGED
@@ -1,63 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { readBridgeConfig } from "./shared/bridge-schema.js";
3
+ import { resolveIntegrationConfig } from "./shared/integration-config.js";
4
4
  import { installManagedShutdown } from "./shared/managed-shutdown.js";
5
- import { normalizeHost, resolveHotFilePath, resolveLitestarPort } from "./shared/network.js";
6
- import { createLitestarTypeGenPlugin, resolveTypesConfig } from "./shared/typegen-plugin.js";
5
+ import { normalizeHost } from "./shared/network.js";
6
+ import { createLitestarTypeGenPlugin } from "./shared/typegen-plugin.js";
7
7
  import { hmrServerConfig } from "./shared/vite-compat.js";
8
8
  function resolveConfig(config = {}) {
9
- let hotFile;
10
- let proxyMode = "vite";
11
- let port;
12
- let pythonTypesConfig;
13
- let pythonExecutor;
14
- let hasPythonConfig = false;
15
- const envPort = process.env.VITE_PORT;
16
- if (envPort) {
17
- port = Number.parseInt(envPort, 10);
18
- if (Number.isNaN(port)) {
19
- port = void 0;
20
- }
21
- }
22
- const runtime = readBridgeConfig();
23
- let assetUrl;
24
- let litestarPort;
25
- if (runtime) {
26
- hasPythonConfig = true;
27
- const hot = runtime.hotFile;
28
- hotFile = resolveHotFilePath(runtime.bundleDir, hot);
29
- proxyMode = runtime.proxyMode;
30
- port = 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: "src/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
- port,
56
- litestarPort,
57
- assetUrl,
58
- executor: pythonExecutor,
59
- hasPythonConfig
60
- };
9
+ return resolveIntegrationConfig(config, "src/generated");
61
10
  }
62
11
  function createProxyPlugin(config) {
63
12
  return {
@@ -12,9 +12,11 @@
12
12
  declare global {
13
13
  interface Window {
14
14
  __LITESTAR_CSRF__?: string;
15
+ __LITESTAR_CSRF_HEADER_NAME__?: string;
16
+ __LITESTAR_CSRF_COOKIE_NAME__?: string;
15
17
  }
16
18
  }
17
- export declare const DEFAULT_CSRF_HEADER_NAME = "X-CSRFToken";
19
+ export declare function getCsrfHeaderName(): string;
18
20
  /**
19
21
  * Get the CSRF token from the page.
20
22
  *
@@ -10,7 +10,13 @@
10
10
  * @module
11
11
  */
12
12
  let csrfTokenCache = null;
13
- export const DEFAULT_CSRF_HEADER_NAME = "X-CSRFToken";
13
+ const DEFAULT_CSRF_HEADER_NAME = "X-CSRFToken";
14
+ export function getCsrfHeaderName() {
15
+ if (typeof window !== "undefined" && typeof window.__LITESTAR_CSRF_HEADER_NAME__ === "string" && window.__LITESTAR_CSRF_HEADER_NAME__.length > 0) {
16
+ return window.__LITESTAR_CSRF_HEADER_NAME__;
17
+ }
18
+ return DEFAULT_CSRF_HEADER_NAME;
19
+ }
14
20
  function getWindowToken() {
15
21
  if (typeof window !== "undefined") {
16
22
  return window.__LITESTAR_CSRF__;
@@ -63,6 +69,12 @@ function getCookie(name) {
63
69
  return undefined;
64
70
  }
65
71
  function getCookieToken() {
72
+ if (typeof window !== "undefined" && typeof window.__LITESTAR_CSRF_COOKIE_NAME__ === "string" && window.__LITESTAR_CSRF_COOKIE_NAME__.length > 0) {
73
+ const configured = getCookie(window.__LITESTAR_CSRF_COOKIE_NAME__);
74
+ if (configured !== undefined) {
75
+ return configured;
76
+ }
77
+ }
66
78
  return getCookie("csrftoken") ?? getCookie("XSRF-TOKEN");
67
79
  }
68
80
  /**
@@ -122,17 +134,17 @@ export function getCsrfToken() {
122
134
  };
123
135
  return token;
124
136
  }
125
- function hasCsrfHeader(headers) {
137
+ function hasCsrfHeader(headers, headerName) {
126
138
  if (headers == null) {
127
139
  return false;
128
140
  }
129
141
  if (headers instanceof Headers) {
130
- return headers.has(DEFAULT_CSRF_HEADER_NAME);
142
+ return headers.has(headerName);
131
143
  }
132
144
  if (Array.isArray(headers)) {
133
- return headers.some((entry) => Array.isArray(entry) && entry.length >= 2 && typeof entry[0] === "string" && entry[0].toLowerCase() === DEFAULT_CSRF_HEADER_NAME.toLowerCase());
145
+ return headers.some((entry) => Array.isArray(entry) && entry.length >= 2 && typeof entry[0] === "string" && entry[0].toLowerCase() === headerName.toLowerCase());
134
146
  }
135
- return Object.keys(headers).some((key) => key.toLowerCase() === DEFAULT_CSRF_HEADER_NAME.toLowerCase());
147
+ return Object.keys(headers).some((key) => key.toLowerCase() === headerName.toLowerCase());
136
148
  }
137
149
  /**
138
150
  * Create headers object with CSRF token included.
@@ -156,13 +168,14 @@ export function csrfHeaders(additionalHeaders = {}) {
156
168
  if (!token) {
157
169
  return additionalHeaders;
158
170
  }
159
- const existingTokenHeader = Object.keys(additionalHeaders).find((key) => key.toLowerCase() === DEFAULT_CSRF_HEADER_NAME.toLowerCase());
171
+ const headerName = getCsrfHeaderName();
172
+ const existingTokenHeader = Object.keys(additionalHeaders).find((key) => key.toLowerCase() === headerName.toLowerCase());
160
173
  if (existingTokenHeader !== undefined) {
161
174
  return additionalHeaders;
162
175
  }
163
176
  return {
164
177
  ...additionalHeaders,
165
- [DEFAULT_CSRF_HEADER_NAME]: token,
178
+ [headerName]: token,
166
179
  };
167
180
  }
168
181
  /**
@@ -188,31 +201,32 @@ export function csrfFetch(input, init) {
188
201
  if (!token) {
189
202
  return fetch(input, init);
190
203
  }
191
- if (!hasCsrfHeader(init?.headers)) {
204
+ const headerName = getCsrfHeaderName();
205
+ if (!hasCsrfHeader(init?.headers, headerName)) {
192
206
  if (!init || typeof init.headers === "undefined") {
193
207
  return fetch(input, {
194
208
  ...init,
195
- headers: { [DEFAULT_CSRF_HEADER_NAME]: token },
209
+ headers: { [headerName]: token },
196
210
  });
197
211
  }
198
212
  if (typeof init.headers === "object" && init.headers !== null && !(init.headers instanceof Headers)) {
199
213
  if (Array.isArray(init.headers)) {
200
214
  return fetch(input, {
201
215
  ...init,
202
- headers: [...init.headers, [DEFAULT_CSRF_HEADER_NAME, token]],
216
+ headers: [...init.headers, [headerName, token]],
203
217
  });
204
218
  }
205
219
  return fetch(input, {
206
220
  ...init,
207
221
  headers: {
208
222
  ...init.headers,
209
- [DEFAULT_CSRF_HEADER_NAME]: token,
223
+ [headerName]: token,
210
224
  },
211
225
  });
212
226
  }
213
227
  if (init.headers instanceof Headers) {
214
228
  const headers = new Headers(init.headers);
215
- headers.set(DEFAULT_CSRF_HEADER_NAME, token);
229
+ headers.set(headerName, token);
216
230
  return fetch(input, {
217
231
  ...init,
218
232
  headers,
@@ -0,0 +1,3 @@
1
+ type ExpressionContext = Record<string, unknown>;
2
+ export declare function compileExpression(source: string): ((context: ExpressionContext) => unknown) | null;
3
+ export {};