@adonisjs/inertia 4.0.0-next.0 → 4.0.0-next.10

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.
Files changed (89) hide show
  1. package/README.md +8 -5
  2. package/build/bin/test.d.ts +1 -0
  3. package/build/chunk-4EZ2J6OA.js +7 -0
  4. package/build/chunk-5QRJHXXQ.js +91 -0
  5. package/build/chunk-DISC5OYC.js +46 -0
  6. package/build/chunk-MLKGABMK.js +9 -0
  7. package/build/chunk-YQ72YL64.js +813 -0
  8. package/build/factories/inertia_factory.d.ts +137 -0
  9. package/build/factories/main.d.ts +1 -0
  10. package/build/factories/main.js +175 -0
  11. package/build/index.d.ts +7 -19
  12. package/build/index.js +21 -307
  13. package/build/providers/inertia_provider.d.ts +86 -13
  14. package/build/providers/inertia_provider.js +48 -18
  15. package/build/src/client/helpers.d.ts +27 -0
  16. package/build/src/client/helpers.js +30 -0
  17. package/build/src/client/react/context.d.ts +24 -0
  18. package/build/src/client/react/index.d.ts +3 -0
  19. package/build/src/client/react/index.js +72 -0
  20. package/build/src/client/react/link.d.ts +64 -0
  21. package/build/src/client/react/router.d.ts +33 -0
  22. package/build/src/client/vite.d.ts +65 -0
  23. package/build/src/{plugins → client}/vite.js +6 -2
  24. package/build/src/debug.d.ts +22 -0
  25. package/build/src/define_config.d.ts +30 -0
  26. package/build/src/headers.d.ts +61 -0
  27. package/build/src/index_pages.d.ts +32 -0
  28. package/build/src/inertia.d.ts +261 -0
  29. package/build/src/inertia_manager.d.ts +47 -0
  30. package/build/src/inertia_middleware.d.ts +76 -86
  31. package/build/src/inertia_middleware.js +110 -3
  32. package/build/src/plugins/edge/plugin.d.ts +30 -6
  33. package/build/src/plugins/edge/plugin.js +13 -9
  34. package/build/src/plugins/edge/tags.d.ts +47 -0
  35. package/build/src/plugins/edge/utils.d.ts +26 -0
  36. package/build/src/plugins/japa/api_client.d.ts +136 -22
  37. package/build/src/plugins/japa/api_client.js +36 -48
  38. package/build/src/props.d.ts +276 -0
  39. package/build/src/server_renderer.d.ts +54 -0
  40. package/build/src/symbols.d.ts +25 -0
  41. package/build/src/types.d.ts +400 -4
  42. package/build/tests/helpers.d.ts +35 -0
  43. package/build/tests/index_pages.spec.d.ts +1 -0
  44. package/build/tests/inertia.spec.d.ts +1 -0
  45. package/build/tests/inertia_page.spec.d.ts +1 -0
  46. package/build/tests/middleware.spec.d.ts +1 -0
  47. package/build/tests/plugins/api_client.spec.d.ts +1 -0
  48. package/build/tests/plugins/edge.plugin.spec.d.ts +1 -0
  49. package/build/tests/provider.spec.d.ts +1 -0
  50. package/build/tests/types/react.spec.d.ts +65 -0
  51. package/build/tests/types/shared_props.spec.d.ts +1 -0
  52. package/build/tests/types/to_component_props.spec.d.ts +1 -0
  53. package/build/tests/types/to_page_props.spec.d.ts +1 -0
  54. package/package.json +99 -71
  55. package/build/app.css.stub +0 -13
  56. package/build/chunk-AWCR2NAY.js +0 -412
  57. package/build/config.stub +0 -33
  58. package/build/react/app.tsx.stub +0 -38
  59. package/build/react/errors/not_found.tsx.stub +0 -14
  60. package/build/react/errors/server_error.tsx.stub +0 -14
  61. package/build/react/home.tsx.stub +0 -349
  62. package/build/react/root.edge.stub +0 -76
  63. package/build/react/ssr.tsx.stub +0 -17
  64. package/build/react/tsconfig.json.stub +0 -15
  65. package/build/solid/app.tsx.stub +0 -38
  66. package/build/solid/errors/not_found.tsx.stub +0 -14
  67. package/build/solid/errors/server_error.tsx.stub +0 -14
  68. package/build/solid/home.tsx.stub +0 -358
  69. package/build/solid/root.edge.stub +0 -73
  70. package/build/solid/ssr.tsx.stub +0 -19
  71. package/build/solid/tsconfig.json.stub +0 -16
  72. package/build/src/helpers.d.ts +0 -12
  73. package/build/src/helpers.js +0 -14
  74. package/build/src/plugins/vite.d.ts +0 -26
  75. package/build/svelte/app.ts.stub +0 -32
  76. package/build/svelte/errors/not_found.svelte.stub +0 -10
  77. package/build/svelte/errors/server_error.svelte.stub +0 -14
  78. package/build/svelte/home.svelte.stub +0 -339
  79. package/build/svelte/root.edge.stub +0 -75
  80. package/build/svelte/ssr.ts.stub +0 -19
  81. package/build/svelte/tsconfig.json.stub +0 -14
  82. package/build/types-DVqEHBD1.d.ts +0 -240
  83. package/build/vue/app.ts.stub +0 -41
  84. package/build/vue/errors/not_found.vue.stub +0 -10
  85. package/build/vue/errors/server_error.vue.stub +0 -14
  86. package/build/vue/home.vue.stub +0 -343
  87. package/build/vue/root.edge.stub +0 -75
  88. package/build/vue/ssr.ts.stub +0 -22
  89. package/build/vue/tsconfig.json.stub +0 -16
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Creates an AdonisJS assembler hook to automatically generate TypeScript definitions
3
+ * for Inertia.js pages based on the specified framework.
4
+ *
5
+ * This function scans page components in the 'inertia/pages' directory and generates
6
+ * type definitions that map page names to their component props.
7
+ *
8
+ * @param config - Configuration object specifying the frontend framework
9
+ * @param config.framework - The frontend framework ('vue3' or 'react')
10
+ * @returns Assembler hook object with run method for generating page types
11
+ *
12
+ * @example
13
+ * ```js
14
+ * // In your adonisrc.ts file
15
+ * export default defineConfig({
16
+ * assembler: {
17
+ * onBuildStarting: [indexPages({ framework: 'vue3' })]
18
+ * }
19
+ * })
20
+ * ```
21
+ */
22
+ export declare const indexPages: (config: {
23
+ framework: "vue3" | "react";
24
+ }) => {
25
+ /**
26
+ * Executes the page indexing process to generate TypeScript definitions.
27
+ *
28
+ * @param _ - Unused first parameter (assembler context)
29
+ * @param indexGenerator - The index generator instance used to register the pages type generation
30
+ */
31
+ run(_: import("@adonisjs/assembler").DevServer | import("@adonisjs/assembler").TestRunner | import("@adonisjs/assembler").Bundler, indexGenerator: import("@adonisjs/assembler/index_generator").IndexGenerator): void;
32
+ };
@@ -0,0 +1,261 @@
1
+ import { type Vite } from '@adonisjs/vite';
2
+ import type { HttpContext } from '@adonisjs/core/http';
3
+ import { type ServerRenderer } from './server_renderer.js';
4
+ import type { PageProps, PageObject, AsPageProps, RequestInfo, InertiaConfig, ComponentProps, SharedProps } from './types.js';
5
+ import { defer, merge, always, optional, deepMerge } from './props.ts';
6
+ import { type AsyncOrSync } from '@poppinss/utils/types';
7
+ /**
8
+ * Main class used to interact with Inertia
9
+ *
10
+ * Provides a complete interface for handling Inertia.js requests, rendering pages,
11
+ * managing props, and controlling page navigation behavior.
12
+ *
13
+ * @example
14
+ * ```js
15
+ * const inertia = new Inertia(ctx, config, vite, serverRenderer)
16
+ *
17
+ * // Render a page
18
+ * const result = await inertia.render('Home', { user: { name: 'John' } })
19
+ *
20
+ * // Clear browser history
21
+ * inertia.clearHistory()
22
+ *
23
+ * // Redirect to a different location
24
+ * inertia.location('/dashboard')
25
+ * ```
26
+ */
27
+ export declare class Inertia<Pages> {
28
+ #private;
29
+ protected ctx: HttpContext;
30
+ protected config: InertiaConfig;
31
+ /**
32
+ * Defer prop evaluation until client-side rendering
33
+ *
34
+ * @example
35
+ * ```js
36
+ * {
37
+ * expensiveData: inertia.defer(() => computeExpensiveData())
38
+ * }
39
+ * ```
40
+ */
41
+ defer: typeof defer;
42
+ /**
43
+ * Always include prop in both server and client renders
44
+ *
45
+ * @example
46
+ * ```js
47
+ * {
48
+ * currentUser: inertia.always(() => getCurrentUser())
49
+ * }
50
+ * ```
51
+ */
52
+ always: typeof always;
53
+ /**
54
+ * Merge prop with existing client-side data
55
+ *
56
+ * @example
57
+ * ```js
58
+ * {
59
+ * posts: inertia.merge(() => getPosts())
60
+ * }
61
+ * ```
62
+ */
63
+ merge: typeof merge;
64
+ /**
65
+ * Include prop only when specifically requested
66
+ *
67
+ * @example
68
+ * ```js
69
+ * {
70
+ * optionalData: inertia.optional(() => getOptionalData())
71
+ * }
72
+ * ```
73
+ */
74
+ optional: typeof optional;
75
+ /**
76
+ * Deep merge prop with existing client-side data
77
+ *
78
+ * @example
79
+ * ```js
80
+ * {
81
+ * settings: inertia.deepMerge(() => getSettings())
82
+ * }
83
+ * ```
84
+ */
85
+ deepMerge: typeof deepMerge;
86
+ /**
87
+ * Creates a new Inertia instance
88
+ *
89
+ * @param ctx - HTTP context for the current request
90
+ * @param config - Inertia configuration object
91
+ * @param vite - Vite instance for asset management
92
+ * @param serverRenderer - Optional server renderer for SSR
93
+ *
94
+ * @example
95
+ * ```js
96
+ * const inertia = new Inertia(ctx, {
97
+ * rootView: 'app',
98
+ * ssr: { enabled: true }
99
+ * }, vite, serverRenderer)
100
+ * ```
101
+ */
102
+ constructor(ctx: HttpContext, config: InertiaConfig, vite?: Vite, serverRenderer?: ServerRenderer);
103
+ /**
104
+ * Extract Inertia-specific information from request headers
105
+ *
106
+ * Parses various Inertia headers to determine request type and props filtering.
107
+ *
108
+ * @param reCompute - Whether to recompute the request info instead of using cached version
109
+ * @returns The request information object containing Inertia-specific data
110
+ *
111
+ * @example
112
+ * ```js
113
+ * const info = inertia.requestInfo()
114
+ * if (info.isInertiaRequest) {
115
+ * // Handle as Inertia request
116
+ * }
117
+ * ```
118
+ */
119
+ requestInfo(reCompute?: boolean): RequestInfo;
120
+ /**
121
+ * Compute and cache the assets version
122
+ *
123
+ * Uses Vite manifest hash when available, otherwise defaults to '1'.
124
+ *
125
+ * @returns The computed version string for asset versioning
126
+ */
127
+ getVersion(): string;
128
+ /**
129
+ * Determine if server-side rendering is enabled for a specific component
130
+ *
131
+ * Checks global SSR settings and component-specific configuration.
132
+ *
133
+ * @param component - The component name to check
134
+ * @returns Promise resolving to true if SSR is enabled for the component
135
+ *
136
+ * @example
137
+ * ```js
138
+ * const shouldSSR = await inertia.ssrEnabled('UserProfile')
139
+ * if (shouldSSR) {
140
+ * // Render on server
141
+ * }
142
+ * ```
143
+ */
144
+ ssrEnabled<Page extends keyof Pages & string>(component: Page): Promise<boolean>;
145
+ /**
146
+ * Share props across all pages
147
+ *
148
+ * Merges the provided props with existing shared state, making them available
149
+ * to all pages rendered by this Inertia instance. Shared props are included
150
+ * in every page render alongside page-specific props.
151
+ *
152
+ * @param sharedState - Props to share across all pages
153
+ * @returns The Inertia instance for method chaining
154
+ *
155
+ * @example
156
+ * ```js
157
+ * // Share user data across all pages
158
+ * inertia.share({
159
+ * user: getCurrentUser(),
160
+ * flash: getFlashMessages()
161
+ * })
162
+ *
163
+ * // Chain multiple shares
164
+ * inertia
165
+ * .share({ currentUser: user })
166
+ * .share({ permissions: userPermissions })
167
+ * ```
168
+ */
169
+ share(sharedState: PageProps | (() => AsyncOrSync<PageProps>)): this;
170
+ /**
171
+ * Build a page object with processed props and metadata
172
+ *
173
+ * Creates the complete page object that will be sent to the client or used for SSR.
174
+ *
175
+ * @param page - The page component name
176
+ * @param pageProps - Props to pass to the page component
177
+ * @returns Promise resolving to the complete page object
178
+ *
179
+ * @example
180
+ * ```js
181
+ * const pageObject = await inertia.page('Dashboard', {
182
+ * user: { name: 'John' },
183
+ * posts: defer(() => getPosts())
184
+ * })
185
+ * ```
186
+ */
187
+ page<Page extends keyof Pages & string>(page: Page, pageProps: Pages[Page] extends ComponentProps ? AsPageProps<Omit<Pages[Page], keyof SharedProps>> : never): Promise<PageObject<Pages[Page]>>;
188
+ /**
189
+ * Render a page using Inertia
190
+ *
191
+ * This method handles three distinct rendering scenarios:
192
+ * 1. Inertia requests - Returns JSON page object for client-side navigation
193
+ * 2. Initial page loads with SSR - Returns HTML with server-rendered content
194
+ * 3. Initial page loads without SSR - Returns HTML for client-side hydration
195
+ *
196
+ * @param page - The page component name to render
197
+ * @param pageProps - Props to pass to the page component
198
+ * @param viewProps - Additional props to pass to the root view template
199
+ * @returns Promise resolving to PageObject for Inertia requests, HTML string for initial page loads
200
+ *
201
+ * @example
202
+ * ```js
203
+ * // For Inertia requests, returns PageObject
204
+ * const result = await inertia.render('Profile', {
205
+ * user: getCurrentUser(),
206
+ * posts: defer(() => getUserPosts())
207
+ * })
208
+ *
209
+ * // For initial page loads, returns HTML string
210
+ * const html = await inertia.render('Home', { welcome: 'Hello World' })
211
+ * ```
212
+ */
213
+ render<Page extends keyof Pages & string>(page: Page, pageProps: Pages[Page] extends ComponentProps ? AsPageProps<Omit<Pages[Page], keyof SharedProps>> : never, viewProps?: Record<string, any>): Promise<string | PageObject<Pages[Page]>>;
214
+ /**
215
+ * Clear the browser history on the next navigation
216
+ *
217
+ * Instructs the client to clear the browser history stack when navigating.
218
+ *
219
+ * @example
220
+ * ```js
221
+ * inertia.clearHistory()
222
+ * return inertia.render('Dashboard', props)
223
+ * ```
224
+ */
225
+ clearHistory(): void;
226
+ /**
227
+ * Control whether browser history should be encrypted
228
+ *
229
+ * Enables or disables encryption of sensitive data in browser history.
230
+ *
231
+ * @param encrypt - Whether to encrypt history (defaults to true)
232
+ *
233
+ * @example
234
+ * ```js
235
+ * // Enable encryption for sensitive pages
236
+ * inertia.encryptHistory(true)
237
+ *
238
+ * // Disable encryption for public pages
239
+ * inertia.encryptHistory(false)
240
+ * ```
241
+ */
242
+ encryptHistory(encrypt?: boolean): void;
243
+ /**
244
+ * Redirect to a different location
245
+ *
246
+ * Sets the appropriate headers to redirect the client to a new URL.
247
+ * Uses a 409 status code which Inertia.js interprets as a redirect instruction.
248
+ *
249
+ * @param url - The URL to redirect to
250
+ *
251
+ * @example
252
+ * ```js
253
+ * // Redirect after login
254
+ * inertia.location('/dashboard')
255
+ *
256
+ * // Redirect with full URL
257
+ * inertia.location('https://example.com/external')
258
+ * ```
259
+ */
260
+ location(url: string): void;
261
+ }
@@ -0,0 +1,47 @@
1
+ import { type Vite } from '@adonisjs/vite';
2
+ import { type HttpContext } from '@adonisjs/core/http';
3
+ import { Inertia } from './inertia.ts';
4
+ import { type ComponentProps, type InertiaConfig } from './types.ts';
5
+ /**
6
+ * Manager class for managing Inertia instances
7
+ *
8
+ * Acts as a factory for creating Inertia instances with shared configuration
9
+ * and Vite integration.
10
+ *
11
+ * @example
12
+ * ```js
13
+ * const manager = new InertiaManager(config, vite)
14
+ * const inertia = manager.createForRequest(ctx)
15
+ * ```
16
+ */
17
+ export declare class InertiaManager {
18
+ #private;
19
+ /**
20
+ * Creates a new InertiaManager instance
21
+ *
22
+ * @param config - Inertia configuration object
23
+ * @param vite - Optional Vite instance for development mode and SSR
24
+ *
25
+ * @example
26
+ * ```js
27
+ * const manager = new InertiaManager({
28
+ * rootView: 'app',
29
+ * ssr: { enabled: true }
30
+ * }, vite)
31
+ * ```
32
+ */
33
+ constructor(config: InertiaConfig, vite?: Vite);
34
+ /**
35
+ * Creates a new Inertia instance for a specific HTTP request
36
+ *
37
+ * @param ctx - HTTP context for the current request
38
+ * @returns A new Inertia instance configured for the given request
39
+ *
40
+ * @example
41
+ * ```js
42
+ * const inertia = manager.createForRequest(ctx)
43
+ * await inertia.render('Home', { user: ctx.auth.user })
44
+ * ```
45
+ */
46
+ createForRequest<Pages extends Record<string, ComponentProps>>(ctx: HttpContext): Inertia<Pages>;
47
+ }
@@ -1,108 +1,98 @@
1
- import { Vite } from '@adonisjs/vite';
2
- import { HttpContext } from '@adonisjs/core/http';
3
- import { NextFn } from '@adonisjs/core/types/http';
4
- import { R as ResolvedConfig, D as Data, P as PageObject, M as MaybePromise, O as OptionalProp, a as MergeProp, A as AlwaysProp, b as DeferProp } from '../types-DVqEHBD1.js';
5
- import '@adonisjs/core/types';
6
- import '@tuyau/utils/types';
7
-
1
+ import type { HttpContext } from '@adonisjs/core/http';
2
+ import { type Inertia } from './inertia.js';
3
+ import type { InertiaPages, PageProps } from './types.js';
4
+ declare module '@adonisjs/core/http' {
5
+ interface HttpContext {
6
+ inertia: Inertia<InertiaPages>;
7
+ }
8
+ }
8
9
  /**
9
- * Main class used to interact with Inertia
10
+ * Base middleware class for handling Inertia.js requests
11
+ *
12
+ * This middleware handles the initialization of the Inertia instance,
13
+ * manages request headers, handles redirects for mutation methods,
14
+ * and implements asset versioning.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * export default class InertiaMiddleware extends BaseInertiaMiddleware {
19
+ * async share() {
20
+ * return {
21
+ * user: ctx.auth?.user
22
+ * }
23
+ * }
24
+ * }
25
+ * ```
10
26
  */
11
- declare class Inertia {
12
- #private;
13
- protected ctx: HttpContext;
14
- protected config: ResolvedConfig;
15
- protected vite?: Vite | undefined;
16
- constructor(ctx: HttpContext, config: ResolvedConfig, vite?: Vite | undefined);
17
- /**
18
- * Share data for the current request.
19
- * This data will override any shared data defined in the config.
20
- */
21
- share(data: Record<string, Data>): void;
22
- /**
23
- * Render a page using Inertia
24
- */
25
- render<TPageProps extends Record<string, any> = {}, TViewProps extends Record<string, any> = {}>(component: string, pageProps?: TPageProps, viewProps?: TViewProps): Promise<string | PageObject<TPageProps>>;
27
+ export default abstract class BaseInertiaMiddleware {
26
28
  /**
27
- * Clear history state.
29
+ * Extract validation errors from the session and format them for Inertia
28
30
  *
29
- * See https://v2.inertiajs.com/history-encryption#clearing-history
30
- */
31
- clearHistory(): void;
32
- /**
33
- * Encrypt history
31
+ * Retrieves validation errors from the session flash messages and formats
32
+ * them according to Inertia's error bag conventions. Supports both simple
33
+ * error objects and error bags for multi-form scenarios.
34
+ *
35
+ * @param ctx - The HTTP context containing session data
36
+ * @returns Formatted validation errors, either as a simple object or error bags
34
37
  *
35
- * See https://v2.inertiajs.com/history-encryption
38
+ * @example
39
+ * ```js
40
+ * const errors = middleware.getValidationErrors(ctx)
41
+ * // Returns: { email: 'Email is required', password: 'Password too short' }
42
+ * // Or with error bags: { login: { email: 'Email is required' } }
43
+ * ```
36
44
  */
37
- encryptHistory(encrypt?: boolean): void;
45
+ getValidationErrors(ctx: HttpContext): Record<string, string> | {
46
+ [errorBag: string]: Record<string, string>;
47
+ };
38
48
  /**
39
- * Create a lazy prop
49
+ * Share data with all Inertia pages
40
50
  *
41
- * Lazy props are never resolved on first visit, but only when the client
42
- * request a partial reload explicitely with this value.
51
+ * This method should return an object containing data that will be
52
+ * available to all Inertia pages as props.
43
53
  *
44
- * See https://inertiajs.com/partial-reloads#lazy-data-evaluation
54
+ * @param ctx - The HTTP context object
55
+ * @returns Props to share across all pages
45
56
  *
46
- * @deprecated use `optional` instead
57
+ * @example
58
+ * ```js
59
+ * async share() {
60
+ * return {
61
+ * user: ctx.auth?.user,
62
+ * flash: ctx.session?.flashMessages.all()
63
+ * }
64
+ * }
65
+ * ```
47
66
  */
48
- lazy<T>(callback: () => MaybePromise<T>): OptionalProp<() => MaybePromise<T>>;
67
+ abstract share?(ctx: HttpContext): PageProps | Promise<PageProps>;
49
68
  /**
50
- * Create an optional prop
69
+ * Initialize the Inertia instance for the current request
51
70
  *
52
- * See https://inertiajs.com/partial-reloads#lazy-data-evaluation
53
- */
54
- optional<T>(callback: () => MaybePromise<T>): OptionalProp<() => MaybePromise<T>>;
55
- /**
56
- * Create a mergeable prop
71
+ * This method creates an Inertia instance and attaches it to the
72
+ * HTTP context, making it available throughout the request lifecycle.
57
73
  *
58
- * See https://v2.inertiajs.com/merging-props
59
- */
60
- merge<T>(callback: () => MaybePromise<T>): MergeProp<() => MaybePromise<T>>;
61
- /**
62
- * Create an always prop
63
- *
64
- * Always props are resolved on every request, no matter if it's a partial
65
- * request or not.
74
+ * @param ctx - The HTTP context object
66
75
  *
67
- * See https://inertiajs.com/partial-reloads#lazy-data-evaluation
76
+ * @example
77
+ * ```ts
78
+ * await middleware.init(ctx)
79
+ * ```
68
80
  */
69
- always<T>(callback: () => MaybePromise<T>): AlwaysProp<() => MaybePromise<T>>;
81
+ init(ctx: HttpContext): Promise<void>;
70
82
  /**
71
- * Create a deferred prop
83
+ * Clean up and finalize the Inertia response
72
84
  *
73
- * Deferred props feature allows you to defer the loading of certain
74
- * page data until after the initial page render.
85
+ * This method handles the final processing of Inertia requests including:
86
+ * - Setting appropriate response headers
87
+ * - Handling redirects for mutation methods (PUT/PATCH/DELETE)
88
+ * - Managing asset versioning conflicts
75
89
  *
76
- * See https://v2.inertiajs.com/deferred-props
77
- */
78
- defer<T>(callback: () => MaybePromise<T>, group?: string): DeferProp<() => MaybePromise<T>>;
79
- /**
80
- * This method can be used to redirect the user to an external website
81
- * or even a non-inertia route of your application.
90
+ * @param ctx - The HTTP context object
82
91
  *
83
- * See https://inertiajs.com/redirects#external-redirects
92
+ * @example
93
+ * ```ts
94
+ * await middleware.dispose(ctx)
95
+ * ```
84
96
  */
85
- location(url: string): Promise<void>;
86
- }
87
-
88
- /**
89
- * HttpContext augmentations
90
- */
91
- declare module '@adonisjs/core/http' {
92
- interface HttpContext {
93
- inertia: Inertia;
94
- }
95
- }
96
- /**
97
- * Inertia middleware to handle the Inertia requests and
98
- * set appropriate headers/status
99
- */
100
- declare class InertiaMiddleware {
101
- #private;
102
- protected config: ResolvedConfig;
103
- protected vite?: Vite | undefined;
104
- constructor(config: ResolvedConfig, vite?: Vite | undefined);
105
- handle(ctx: HttpContext, next: NextFn): Promise<void>;
97
+ dispose(ctx: HttpContext): void;
106
98
  }
107
-
108
- export { InertiaMiddleware as default };
@@ -1,6 +1,113 @@
1
1
  import {
2
- InertiaMiddleware
3
- } from "../chunk-AWCR2NAY.js";
2
+ InertiaManager
3
+ } from "../chunk-YQ72YL64.js";
4
+ import {
5
+ debug_default
6
+ } from "../chunk-4EZ2J6OA.js";
7
+ import {
8
+ InertiaHeaders
9
+ } from "../chunk-DISC5OYC.js";
10
+ import "../chunk-MLKGABMK.js";
11
+
12
+ // src/inertia_middleware.ts
13
+ var MUTATION_METHODS = ["PUT", "PATCH", "DELETE"];
14
+ var BaseInertiaMiddleware = class {
15
+ /**
16
+ * Extract validation errors from the session and format them for Inertia
17
+ *
18
+ * Retrieves validation errors from the session flash messages and formats
19
+ * them according to Inertia's error bag conventions. Supports both simple
20
+ * error objects and error bags for multi-form scenarios.
21
+ *
22
+ * @param ctx - The HTTP context containing session data
23
+ * @returns Formatted validation errors, either as a simple object or error bags
24
+ *
25
+ * @example
26
+ * ```js
27
+ * const errors = middleware.getValidationErrors(ctx)
28
+ * // Returns: { email: 'Email is required', password: 'Password too short' }
29
+ * // Or with error bags: { login: { email: 'Email is required' } }
30
+ * ```
31
+ */
32
+ getValidationErrors(ctx) {
33
+ if (!ctx.session) {
34
+ return {};
35
+ }
36
+ const inputErrors = ctx.session.flashMessages.get("inputErrorsBag", {});
37
+ const errors = Object.entries(inputErrors).reduce(
38
+ (result, [field, messages]) => {
39
+ result[field] = Array.isArray(messages) ? messages[0] : messages;
40
+ return result;
41
+ },
42
+ {}
43
+ );
44
+ const errorBag = ctx.request.header(InertiaHeaders.ErrorBag);
45
+ if (errorBag) {
46
+ return { [errorBag]: errors };
47
+ }
48
+ return errors;
49
+ }
50
+ /**
51
+ * Initialize the Inertia instance for the current request
52
+ *
53
+ * This method creates an Inertia instance and attaches it to the
54
+ * HTTP context, making it available throughout the request lifecycle.
55
+ *
56
+ * @param ctx - The HTTP context object
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * await middleware.init(ctx)
61
+ * ```
62
+ */
63
+ async init(ctx) {
64
+ debug_default("initiating inertia");
65
+ const inertiaContainer = await ctx.containerResolver.make(InertiaManager);
66
+ ctx.inertia = inertiaContainer.createForRequest(ctx);
67
+ if (this.share) {
68
+ ctx.inertia.share(() => this.share(ctx));
69
+ }
70
+ }
71
+ /**
72
+ * Clean up and finalize the Inertia response
73
+ *
74
+ * This method handles the final processing of Inertia requests including:
75
+ * - Setting appropriate response headers
76
+ * - Handling redirects for mutation methods (PUT/PATCH/DELETE)
77
+ * - Managing asset versioning conflicts
78
+ *
79
+ * @param ctx - The HTTP context object
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * await middleware.dispose(ctx)
84
+ * ```
85
+ */
86
+ dispose(ctx) {
87
+ const requestInfo = ctx.inertia.requestInfo();
88
+ if (!requestInfo.isInertiaRequest) {
89
+ return;
90
+ }
91
+ debug_default("disposing as inertia request");
92
+ ctx.response.header("Vary", InertiaHeaders.Inertia);
93
+ const method = ctx.request.method();
94
+ if (ctx.response.getStatus() === 302 && MUTATION_METHODS.includes(method)) {
95
+ debug_default("upgrading response status from 302 to 303");
96
+ ctx.response.status(303);
97
+ }
98
+ const version = ctx.inertia.getVersion();
99
+ const clientVersion = requestInfo.version ?? "";
100
+ if (method === "GET" && clientVersion !== version) {
101
+ debug_default("version mis-match. Reloading page");
102
+ if (ctx.session) {
103
+ ctx.session.reflash();
104
+ }
105
+ ctx.response.removeHeader(InertiaHeaders.Inertia);
106
+ ctx.response.header(InertiaHeaders.Location, ctx.request.url(true));
107
+ ctx.response.status(409);
108
+ }
109
+ }
110
+ };
4
111
  export {
5
- InertiaMiddleware as default
112
+ BaseInertiaMiddleware as default
6
113
  };
@@ -1,8 +1,32 @@
1
- import { PluginFn } from 'edge.js/types';
2
-
1
+ import type { PluginFn } from 'edge.js/types';
3
2
  /**
4
- * Register the Inertia tags and globals within Edge
3
+ * Edge.js plugin that registers Inertia.js tags and global functions
4
+ *
5
+ * This plugin adds the @inertia and @inertiaHead tags to Edge templates,
6
+ * along with global helper functions for rendering Inertia pages.
7
+ *
8
+ * @returns Edge plugin function that registers Inertia functionality
9
+ *
10
+ * @example
11
+ * ```js
12
+ * // Configure in config/edge.ts
13
+ * import { edgePluginInertia } from '@adonisjs/inertia/plugins/edge'
14
+ *
15
+ * edge.use(edgePluginInertia())
16
+ * ```
17
+ *
18
+ * @example
19
+ * ```edge
20
+ * {{-- Use in Edge templates --}}
21
+ * <!DOCTYPE html>
22
+ * <html>
23
+ * <head>
24
+ * @inertiaHead()
25
+ * </head>
26
+ * <body>
27
+ * @inertia({ id: 'app', class: 'min-h-screen' })
28
+ * </body>
29
+ * </html>
30
+ * ```
5
31
  */
6
- declare const edgePluginInertia: () => PluginFn<undefined>;
7
-
8
- export { edgePluginInertia };
32
+ export declare const edgePluginInertia: () => PluginFn<undefined>;