@adonisjs/inertia 3.1.1 → 4.0.0-next.1
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 +8 -5
- package/build/bin/test.d.ts +1 -0
- package/build/chunk-4EZ2J6OA.js +7 -0
- package/build/chunk-74S2VAL7.js +761 -0
- package/build/chunk-DISC5OYC.js +46 -0
- package/build/chunk-MLKGABMK.js +9 -0
- package/build/chunk-PDP56GPP.js +75 -0
- package/build/factories/inertia_factory.d.ts +137 -0
- package/build/factories/main.d.ts +1 -0
- package/build/factories/main.js +175 -0
- package/build/index.d.ts +7 -19
- package/build/index.js +21 -307
- package/build/providers/inertia_provider.d.ts +86 -13
- package/build/providers/inertia_provider.js +48 -18
- package/build/src/client/vite.d.ts +63 -0
- package/build/src/{plugins → client}/vite.js +9 -13
- package/build/src/debug.d.ts +22 -0
- package/build/src/define_config.d.ts +29 -0
- package/build/src/headers.d.ts +61 -0
- package/build/src/index_pages.d.ts +5 -0
- package/build/src/inertia.d.ts +253 -0
- package/build/src/inertia_manager.d.ts +46 -0
- package/build/src/inertia_middleware.d.ts +74 -87
- package/build/src/inertia_middleware.js +110 -3
- package/build/src/plugins/edge/plugin.d.ts +30 -6
- package/build/src/plugins/edge/plugin.js +13 -9
- package/build/src/plugins/edge/tags.d.ts +47 -0
- package/build/src/plugins/edge/utils.d.ts +26 -0
- package/build/src/plugins/japa/api_client.d.ts +136 -22
- package/build/src/plugins/japa/api_client.js +36 -48
- package/build/src/props.d.ts +269 -0
- package/build/src/server_renderer.d.ts +54 -0
- package/build/src/symbols.d.ts +25 -0
- package/build/src/types.d.ts +404 -4
- package/build/tests/helpers.d.ts +35 -0
- package/build/tests/index_pages.spec.d.ts +1 -0
- package/build/tests/inertia.spec.d.ts +1 -0
- package/build/tests/inertia_page.spec.d.ts +1 -0
- package/build/tests/middleware.spec.d.ts +1 -0
- package/build/tests/plugins/api_client.spec.d.ts +1 -0
- package/build/tests/plugins/edge.plugin.spec.d.ts +1 -0
- package/build/tests/provider.spec.d.ts +1 -0
- package/build/tests/types/shared_props.spec.d.ts +1 -0
- package/build/tests/types/to_component_props.spec.d.ts +1 -0
- package/build/tests/types/to_page_props.spec.d.ts +1 -0
- package/package.json +88 -71
- package/build/app.css.stub +0 -13
- package/build/chunk-W7TVEB4V.js +0 -412
- package/build/config.stub +0 -33
- package/build/react/app.tsx.stub +0 -38
- package/build/react/errors/not_found.tsx.stub +0 -14
- package/build/react/errors/server_error.tsx.stub +0 -14
- package/build/react/home.tsx.stub +0 -349
- package/build/react/root.edge.stub +0 -76
- package/build/react/ssr.tsx.stub +0 -17
- package/build/react/tsconfig.json.stub +0 -15
- package/build/solid/app.tsx.stub +0 -38
- package/build/solid/errors/not_found.tsx.stub +0 -14
- package/build/solid/errors/server_error.tsx.stub +0 -14
- package/build/solid/home.tsx.stub +0 -358
- package/build/solid/root.edge.stub +0 -73
- package/build/solid/ssr.tsx.stub +0 -19
- package/build/solid/tsconfig.json.stub +0 -16
- package/build/src/helpers.d.ts +0 -12
- package/build/src/helpers.js +0 -14
- package/build/src/plugins/vite.d.ts +0 -26
- package/build/svelte/app.ts.stub +0 -32
- package/build/svelte/errors/not_found.svelte.stub +0 -10
- package/build/svelte/errors/server_error.svelte.stub +0 -14
- package/build/svelte/home.svelte.stub +0 -339
- package/build/svelte/root.edge.stub +0 -75
- package/build/svelte/ssr.ts.stub +0 -19
- package/build/svelte/tsconfig.json.stub +0 -14
- package/build/types-DVqEHBD1.d.ts +0 -240
- package/build/vue/app.ts.stub +0 -41
- package/build/vue/errors/not_found.vue.stub +0 -10
- package/build/vue/errors/server_error.vue.stub +0 -14
- package/build/vue/home.vue.stub +0 -343
- package/build/vue/root.edge.stub +0 -75
- package/build/vue/ssr.ts.stub +0 -22
- package/build/vue/tsconfig.json.stub +0 -16
|
@@ -1,6 +1,113 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "../chunk-
|
|
2
|
+
InertiaManager
|
|
3
|
+
} from "../chunk-74S2VAL7.js";
|
|
4
|
+
import {
|
|
5
|
+
InertiaHeaders
|
|
6
|
+
} from "../chunk-DISC5OYC.js";
|
|
7
|
+
import {
|
|
8
|
+
debug_default
|
|
9
|
+
} from "../chunk-4EZ2J6OA.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(await 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
|
-
|
|
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
|
-
*
|
|
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>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
debug_default
|
|
3
|
+
} from "../../../chunk-4EZ2J6OA.js";
|
|
4
|
+
import "../../../chunk-MLKGABMK.js";
|
|
5
|
+
|
|
1
6
|
// src/plugins/edge/plugin.ts
|
|
2
7
|
import { encode } from "html-entities";
|
|
3
8
|
|
|
4
|
-
// src/debug.ts
|
|
5
|
-
import { debuglog } from "node:util";
|
|
6
|
-
var debug_default = debuglog("adonisjs:inertia");
|
|
7
|
-
|
|
8
9
|
// src/plugins/edge/tags.ts
|
|
9
10
|
import { EdgeError } from "edge-error";
|
|
10
11
|
|
|
@@ -40,10 +41,11 @@ var inertiaTag = {
|
|
|
40
41
|
);
|
|
41
42
|
});
|
|
42
43
|
const attributes = parser.utils.stringify(parsed);
|
|
43
|
-
buffer.
|
|
44
|
-
`
|
|
44
|
+
buffer.outputExpression(
|
|
45
|
+
`state.inertia(state.page, ${attributes})`,
|
|
45
46
|
filename,
|
|
46
|
-
loc.start.line
|
|
47
|
+
loc.start.line,
|
|
48
|
+
false
|
|
47
49
|
);
|
|
48
50
|
}
|
|
49
51
|
};
|
|
@@ -52,7 +54,7 @@ var inertiaHeadTag = {
|
|
|
52
54
|
tagName: "inertiaHead",
|
|
53
55
|
seekable: false,
|
|
54
56
|
compile(_, buffer, { filename, loc }) {
|
|
55
|
-
buffer.
|
|
57
|
+
buffer.outputExpression("state.inertiaHead(state.page)", filename, loc.start.line, false);
|
|
56
58
|
}
|
|
57
59
|
};
|
|
58
60
|
|
|
@@ -63,7 +65,9 @@ var edgePluginInertia = () => {
|
|
|
63
65
|
edge.global(
|
|
64
66
|
"inertia",
|
|
65
67
|
(page = {}, attributes = {}) => {
|
|
66
|
-
if (page.ssrBody)
|
|
68
|
+
if (page.ssrBody) {
|
|
69
|
+
return page.ssrBody;
|
|
70
|
+
}
|
|
67
71
|
const className = attributes?.class ? ` class="${attributes.class}"` : "";
|
|
68
72
|
const id = attributes?.id ? ` id="${attributes.id}"` : ' id="app"';
|
|
69
73
|
const tag = attributes?.as || "div";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type TagContract } from 'edge.js/types';
|
|
2
|
+
/**
|
|
3
|
+
* Edge tag that generates the root element for Inertia.js applications
|
|
4
|
+
*
|
|
5
|
+
* The @inertia tag creates a container element with encoded page data that Inertia.js
|
|
6
|
+
* uses to hydrate the client-side application. Supports customization through attributes.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```edge
|
|
10
|
+
* {{-- Basic usage with default div element and id="app" --}}
|
|
11
|
+
* @inertia()
|
|
12
|
+
*
|
|
13
|
+
* {{-- Custom element and attributes --}}
|
|
14
|
+
* @inertia({ as: 'main', id: 'app-root', class: 'min-h-screen' })
|
|
15
|
+
*
|
|
16
|
+
* {{-- Results in: --}}
|
|
17
|
+
* {{-- <main id="app-root" class="min-h-screen" data-page="{...encoded page data...}"></main> --}}
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Supported attributes:
|
|
21
|
+
* - `as`: HTML tag name for the root element (defaults to 'div')
|
|
22
|
+
* - `id`: Element ID (defaults to 'app')
|
|
23
|
+
* - `class`: CSS class names for the element
|
|
24
|
+
*/
|
|
25
|
+
export declare const inertiaTag: TagContract;
|
|
26
|
+
/**
|
|
27
|
+
* Edge tag that renders server-side rendered head content for Inertia.js
|
|
28
|
+
*
|
|
29
|
+
* The @inertiaHead tag outputs head tags (title, meta, etc.) that were generated
|
|
30
|
+
* during server-side rendering. Only relevant when SSR is enabled.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```edge
|
|
34
|
+
* <!DOCTYPE html>
|
|
35
|
+
* <html>
|
|
36
|
+
* <head>
|
|
37
|
+
* <meta charset="utf-8">
|
|
38
|
+
* <meta name="viewport" content="width=device-width, initial-scale=1">
|
|
39
|
+
* @inertiaHead()
|
|
40
|
+
* </head>
|
|
41
|
+
* <body>
|
|
42
|
+
* @inertia()
|
|
43
|
+
* </body>
|
|
44
|
+
* </html>
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const inertiaHeadTag: TagContract;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates that an AST expression is one of the allowed expression types
|
|
3
|
+
*
|
|
4
|
+
* This utility function is used during Edge template compilation to ensure
|
|
5
|
+
* that only specific expression types are allowed in certain contexts.
|
|
6
|
+
*
|
|
7
|
+
* @param expression - The AST expression to validate
|
|
8
|
+
* @param expressions - Array of allowed expression type names
|
|
9
|
+
* @param errorCallback - Function to call when validation fails
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```js
|
|
13
|
+
* // Ensure expression is either a literal or identifier
|
|
14
|
+
* isSubsetOf(astNode, ['Literal', 'Identifier'], () => {
|
|
15
|
+
* throw new Error('Invalid expression type')
|
|
16
|
+
* })
|
|
17
|
+
*
|
|
18
|
+
* // Allow only object expressions
|
|
19
|
+
* isSubsetOf(astNode, ['ObjectExpression'], () => {
|
|
20
|
+
* throw new EdgeError('Expected object expression')
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function isSubsetOf(expression: {
|
|
25
|
+
type: string;
|
|
26
|
+
}, expressions: string[], errorCallback: () => void): void;
|
|
@@ -1,43 +1,157 @@
|
|
|
1
|
-
import { PluginFn } from '@japa/runner/types';
|
|
2
|
-
import { ApplicationService } from '@adonisjs/core/types';
|
|
3
|
-
import {
|
|
4
|
-
import '@adonisjs/core/http';
|
|
5
|
-
import '@tuyau/utils/types';
|
|
6
|
-
|
|
1
|
+
import type { PluginFn } from '@japa/runner/types';
|
|
2
|
+
import type { ApplicationService } from '@adonisjs/core/types';
|
|
3
|
+
import type { PageProps, InertiaPages } from '../../types.js';
|
|
7
4
|
declare module '@japa/api-client' {
|
|
5
|
+
/**
|
|
6
|
+
* Extended ApiRequest interface with Inertia.js specific methods
|
|
7
|
+
*
|
|
8
|
+
* Adds methods to configure requests for testing Inertia applications,
|
|
9
|
+
* including setting required headers and configuring partial reloads.
|
|
10
|
+
*/
|
|
8
11
|
interface ApiRequest {
|
|
9
12
|
/**
|
|
10
|
-
* Set `X-Inertia` header on the request
|
|
13
|
+
* Set `X-Inertia` header on the request to mark it as an Inertia request
|
|
14
|
+
*
|
|
15
|
+
* This method configures the request to be treated as an Inertia AJAX request
|
|
16
|
+
* by setting the required headers that Inertia.js uses for identification.
|
|
17
|
+
*
|
|
18
|
+
* @returns The ApiRequest instance for method chaining
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```js
|
|
22
|
+
* const response = await client
|
|
23
|
+
* .get('/dashboard')
|
|
24
|
+
* .withInertia()
|
|
25
|
+
* ```
|
|
11
26
|
*/
|
|
12
|
-
withInertia(): this;
|
|
27
|
+
withInertia(this: ApiRequest): this;
|
|
13
28
|
/**
|
|
14
|
-
* Set
|
|
29
|
+
* Set headers for partial data requests (partial reloads)
|
|
30
|
+
*
|
|
31
|
+
* Configures the request to only fetch specific props from a component,
|
|
32
|
+
* simulating Inertia's partial reload functionality in tests.
|
|
33
|
+
*
|
|
34
|
+
* @param component - The component name to partially reload
|
|
35
|
+
* @param props - Array of prop names to include in the partial request
|
|
36
|
+
* @returns The ApiRequest instance for method chaining
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```js
|
|
40
|
+
* const response = await client
|
|
41
|
+
* .get('/users')
|
|
42
|
+
* .withInertiaPartialReload('Users/Index', ['users', 'pagination'])
|
|
43
|
+
* ```
|
|
15
44
|
*/
|
|
16
|
-
withInertiaPartialReload(component:
|
|
45
|
+
withInertiaPartialReload<K extends keyof InertiaPages>(this: ApiRequest, component: K, props: (keyof InertiaPages[K])[]): this;
|
|
17
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Extended ApiResponse interface with Inertia.js specific properties and assertions
|
|
49
|
+
*
|
|
50
|
+
* Provides getters for accessing Inertia response data and assertion methods
|
|
51
|
+
* for validating Inertia responses in tests.
|
|
52
|
+
*/
|
|
18
53
|
interface ApiResponse {
|
|
19
54
|
/**
|
|
20
|
-
* The
|
|
55
|
+
* The name of the Inertia component returned in the response
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```js
|
|
59
|
+
* console.log(response.inertiaComponent) // 'Users/Index'
|
|
60
|
+
* ```
|
|
21
61
|
*/
|
|
22
|
-
inertiaComponent?:
|
|
62
|
+
inertiaComponent?: keyof InertiaPages;
|
|
23
63
|
/**
|
|
24
|
-
* The
|
|
64
|
+
* The props data returned in the Inertia response
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```js
|
|
68
|
+
* console.log(response.inertiaProps.users) // [{ id: 1, name: 'John' }]
|
|
69
|
+
* ```
|
|
25
70
|
*/
|
|
26
71
|
inertiaProps: Record<string, any>;
|
|
27
72
|
/**
|
|
28
|
-
* Assert
|
|
73
|
+
* Assert that the response contains the expected Inertia component
|
|
74
|
+
*
|
|
75
|
+
* @param component - Expected component name
|
|
76
|
+
* @returns The ApiResponse instance for method chaining
|
|
77
|
+
*
|
|
78
|
+
* @throws AssertionError when component names don't match
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```js
|
|
82
|
+
* response.assertInertiaComponent('Users/Index')
|
|
83
|
+
* ```
|
|
29
84
|
*/
|
|
30
|
-
assertInertiaComponent(component: string): this;
|
|
85
|
+
assertInertiaComponent(this: ApiResponse, component: string): this;
|
|
31
86
|
/**
|
|
32
|
-
* Assert
|
|
87
|
+
* Assert that the response props exactly match the provided props
|
|
88
|
+
*
|
|
89
|
+
* @param props - Expected props object to match exactly
|
|
90
|
+
* @returns The ApiResponse instance for method chaining
|
|
91
|
+
*
|
|
92
|
+
* @throws AssertionError when props don't match exactly
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```js
|
|
96
|
+
* response.assertInertiaProps({
|
|
97
|
+
* users: [{ id: 1, name: 'John' }],
|
|
98
|
+
* total: 1
|
|
99
|
+
* })
|
|
100
|
+
* ```
|
|
33
101
|
*/
|
|
34
|
-
assertInertiaProps(props: PageProps): this;
|
|
102
|
+
assertInertiaProps(this: ApiResponse, props: PageProps): this;
|
|
35
103
|
/**
|
|
36
|
-
* Assert
|
|
104
|
+
* Assert that the response props contain a subset of the provided props
|
|
105
|
+
*
|
|
106
|
+
* @param props - Expected subset of props to be present
|
|
107
|
+
* @returns The ApiResponse instance for method chaining
|
|
108
|
+
*
|
|
109
|
+
* @throws AssertionError when expected props are not found
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```js
|
|
113
|
+
* response.assertInertiaPropsContains({
|
|
114
|
+
* user: { name: 'John' }
|
|
115
|
+
* })
|
|
116
|
+
* ```
|
|
37
117
|
*/
|
|
38
|
-
assertInertiaPropsContains(props: PageProps): this;
|
|
118
|
+
assertInertiaPropsContains(this: ApiResponse, props: PageProps): this;
|
|
39
119
|
}
|
|
40
120
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Japa plugin that extends the API client with Inertia.js testing capabilities
|
|
123
|
+
*
|
|
124
|
+
* This plugin adds methods to ApiRequest and ApiResponse classes to support
|
|
125
|
+
* testing Inertia applications, including partial reloads and response assertions.
|
|
126
|
+
*
|
|
127
|
+
* @param app - The AdonisJS application service instance
|
|
128
|
+
* @returns Japa plugin function
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```js
|
|
132
|
+
* // Configure in tests/bootstrap.ts
|
|
133
|
+
* import { inertiaApiClient } from '@adonisjs/inertia/plugins/japa/api_client'
|
|
134
|
+
*
|
|
135
|
+
* export const plugins: Config['plugins'] = [
|
|
136
|
+
* assert(),
|
|
137
|
+
* apiClient(app),
|
|
138
|
+
* inertiaApiClient(app)
|
|
139
|
+
* ]
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```js
|
|
144
|
+
* // Use in tests
|
|
145
|
+
* test('renders dashboard page', async ({ client }) => {
|
|
146
|
+
* const response = await client
|
|
147
|
+
* .get('/dashboard')
|
|
148
|
+
* .withInertia()
|
|
149
|
+
*
|
|
150
|
+
* response.assertInertiaComponent('Dashboard')
|
|
151
|
+
* response.assertInertiaPropsContains({
|
|
152
|
+
* user: { name: 'John' }
|
|
153
|
+
* })
|
|
154
|
+
* })
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export declare function inertiaApiClient(app: ApplicationService): PluginFn;
|
|
@@ -1,37 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InertiaHeaders
|
|
3
|
+
} from "../../../chunk-DISC5OYC.js";
|
|
4
|
+
import "../../../chunk-MLKGABMK.js";
|
|
5
|
+
|
|
1
6
|
// src/plugins/japa/api_client.ts
|
|
2
|
-
import { configProvider } from "@adonisjs/core";
|
|
3
|
-
import { RuntimeException } from "@poppinss/utils";
|
|
4
7
|
import { ApiRequest, ApiResponse } from "@japa/api-client";
|
|
5
8
|
function ensureIsInertiaResponse() {
|
|
6
9
|
if (!this.header("x-inertia")) {
|
|
7
10
|
throw new Error(
|
|
8
|
-
|
|
11
|
+
'Not an Inertia response. Make sure to use "withInertia()" method when making the request'
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function ensureHasAssert(assertLib) {
|
|
16
|
+
if (!assertLib) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
"Response assertions are not available. Make sure to install the @japa/assert plugin"
|
|
9
19
|
);
|
|
10
20
|
}
|
|
11
21
|
}
|
|
12
22
|
function inertiaApiClient(app) {
|
|
13
23
|
return async () => {
|
|
14
|
-
const
|
|
15
|
-
const config = await configProvider.resolve(app, inertiaConfigProvider);
|
|
16
|
-
if (!config) {
|
|
17
|
-
throw new RuntimeException(
|
|
18
|
-
'Invalid "config/inertia.ts" file. Make sure you are using the "defineConfig" method'
|
|
19
|
-
);
|
|
20
|
-
}
|
|
24
|
+
const inertiaConfig = app.config.get("inertia");
|
|
21
25
|
ApiRequest.macro("withInertia", function() {
|
|
22
|
-
this.header(
|
|
23
|
-
this.header(
|
|
26
|
+
this.header(InertiaHeaders.Inertia, "true");
|
|
27
|
+
this.header(InertiaHeaders.Version, String(inertiaConfig.assetsVersion ?? "1"));
|
|
28
|
+
return this;
|
|
29
|
+
});
|
|
30
|
+
ApiRequest.macro("withInertiaPartialReload", function(component, data) {
|
|
31
|
+
this.withInertia();
|
|
32
|
+
this.header(InertiaHeaders.PartialComponent, component);
|
|
33
|
+
this.header(InertiaHeaders.PartialOnly, data.join(","));
|
|
24
34
|
return this;
|
|
25
35
|
});
|
|
26
|
-
ApiRequest.macro(
|
|
27
|
-
"withInertiaPartialReload",
|
|
28
|
-
function(component, data) {
|
|
29
|
-
this.withInertia();
|
|
30
|
-
this.header("X-Inertia-Partial-Data", data.join(","));
|
|
31
|
-
this.header("X-Inertia-Partial-Component", component);
|
|
32
|
-
return this;
|
|
33
|
-
}
|
|
34
|
-
);
|
|
35
36
|
ApiResponse.getter("inertiaComponent", function() {
|
|
36
37
|
ensureIsInertiaResponse.call(this);
|
|
37
38
|
return this.body().component;
|
|
@@ -42,35 +43,22 @@ function inertiaApiClient(app) {
|
|
|
42
43
|
});
|
|
43
44
|
ApiResponse.macro("assertInertiaComponent", function(component) {
|
|
44
45
|
ensureIsInertiaResponse.call(this);
|
|
45
|
-
this.assert
|
|
46
|
+
ensureHasAssert(this.assert);
|
|
47
|
+
this.assert.equal(this.body().component, component);
|
|
48
|
+
return this;
|
|
49
|
+
});
|
|
50
|
+
ApiResponse.macro("assertInertiaProps", function(props) {
|
|
51
|
+
ensureIsInertiaResponse.call(this);
|
|
52
|
+
ensureHasAssert(this.assert);
|
|
53
|
+
this.assert.deepEqual(this.body().props, props);
|
|
54
|
+
return this;
|
|
55
|
+
});
|
|
56
|
+
ApiResponse.macro("assertInertiaPropsContains", function(props) {
|
|
57
|
+
ensureIsInertiaResponse.call(this);
|
|
58
|
+
ensureHasAssert(this.assert);
|
|
59
|
+
this.assert.containSubset(this.body().props, props);
|
|
46
60
|
return this;
|
|
47
61
|
});
|
|
48
|
-
ApiResponse.macro(
|
|
49
|
-
"assertInertiaProps",
|
|
50
|
-
function(props) {
|
|
51
|
-
if (!this.assert) {
|
|
52
|
-
throw new Error(
|
|
53
|
-
"Response assertions are not available. Make sure to install the @japa/assert plugin"
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
ensureIsInertiaResponse.call(this);
|
|
57
|
-
this.assert.deepEqual(this.body().props, props);
|
|
58
|
-
return this;
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
ApiResponse.macro(
|
|
62
|
-
"assertInertiaPropsContains",
|
|
63
|
-
function(props) {
|
|
64
|
-
if (!this.assert) {
|
|
65
|
-
throw new Error(
|
|
66
|
-
"Response assertions are not available. Make sure to install the @japa/assert plugin"
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
ensureIsInertiaResponse.call(this);
|
|
70
|
-
this.assert.containsSubset(this.body().props, props);
|
|
71
|
-
return this;
|
|
72
|
-
}
|
|
73
|
-
);
|
|
74
62
|
};
|
|
75
63
|
}
|
|
76
64
|
export {
|