@adonisjs/inertia 4.0.0-next.1 → 4.0.0-next.11
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/build/debug-CBMTuPUm.js +3 -0
- package/build/factories/main.js +59 -172
- package/build/headers-DafWEpBh.js +11 -0
- package/build/index.js +5 -24
- package/build/inertia-D5A2KtfR.js +57 -0
- package/build/inertia_manager-Di3J3hSG.js +403 -0
- package/build/providers/inertia_provider.d.ts +2 -2
- package/build/providers/inertia_provider.js +25 -79
- package/build/src/client/helpers.d.ts +27 -0
- package/build/src/client/helpers.js +13 -0
- package/build/src/client/react/context.d.ts +24 -0
- package/build/src/client/react/index.d.ts +3 -0
- package/build/src/client/react/index.js +29 -0
- package/build/src/client/react/link.d.ts +64 -0
- package/build/src/client/react/router.d.ts +33 -0
- package/build/src/client/vite.d.ts +3 -1
- package/build/src/client/vite.js +16 -29
- package/build/src/define_config.d.ts +1 -0
- package/build/src/index_pages.d.ts +27 -0
- package/build/src/inertia.d.ts +15 -7
- package/build/src/inertia_manager.d.ts +1 -0
- package/build/src/inertia_middleware.d.ts +6 -3
- package/build/src/inertia_middleware.js +45 -111
- package/build/src/plugins/edge/plugin.js +49 -81
- package/build/src/plugins/japa/api_client.js +44 -59
- package/build/src/props.d.ts +16 -9
- package/build/src/server_renderer.d.ts +2 -2
- package/build/src/types.d.ts +17 -28
- package/build/src/types.js +1 -0
- package/build/tests/types/react.spec.d.ts +65 -0
- package/package.json +47 -25
- package/build/chunk-4EZ2J6OA.js +0 -7
- package/build/chunk-74S2VAL7.js +0 -761
- package/build/chunk-DISC5OYC.js +0 -46
- package/build/chunk-MLKGABMK.js +0 -9
- package/build/chunk-PDP56GPP.js +0 -75
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { t as InertiaHeaders } from "./headers-DafWEpBh.js";
|
|
2
|
+
import { t as debug_default } from "./debug-CBMTuPUm.js";
|
|
3
|
+
import "node:module";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { serialize } from "@adonisjs/core/transformers";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __export = (all, symbols) => {
|
|
9
|
+
let target = {};
|
|
10
|
+
for (var name in all) __defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
if (symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
+
return target;
|
|
16
|
+
};
|
|
17
|
+
var symbols_exports = /* @__PURE__ */ __export({
|
|
18
|
+
ALWAYS_PROP: () => ALWAYS_PROP,
|
|
19
|
+
DEEP_MERGE: () => DEEP_MERGE,
|
|
20
|
+
DEFERRED_PROP: () => DEFERRED_PROP,
|
|
21
|
+
OPTIONAL_PROP: () => OPTIONAL_PROP,
|
|
22
|
+
TO_BE_MERGED: () => TO_BE_MERGED
|
|
23
|
+
});
|
|
24
|
+
const ALWAYS_PROP = Symbol.for("ALWAYS_PROP");
|
|
25
|
+
const OPTIONAL_PROP = Symbol.for("OPTIONAL_PROP");
|
|
26
|
+
const TO_BE_MERGED = Symbol.for("TO_BE_MERGED");
|
|
27
|
+
const DEFERRED_PROP = Symbol.for("DEFERRED_PROP");
|
|
28
|
+
const DEEP_MERGE = Symbol.for("DEEP_MERGE");
|
|
29
|
+
function isObject(value) {
|
|
30
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
31
|
+
}
|
|
32
|
+
function defer(fn, group = "default") {
|
|
33
|
+
return {
|
|
34
|
+
group,
|
|
35
|
+
compute: fn,
|
|
36
|
+
merge() {
|
|
37
|
+
return merge(this);
|
|
38
|
+
},
|
|
39
|
+
[DEFERRED_PROP]: true
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function optional(fn) {
|
|
43
|
+
return {
|
|
44
|
+
compute: fn,
|
|
45
|
+
[OPTIONAL_PROP]: true
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function always(value) {
|
|
49
|
+
return {
|
|
50
|
+
value,
|
|
51
|
+
[ALWAYS_PROP]: true
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function merge(value) {
|
|
55
|
+
return {
|
|
56
|
+
value,
|
|
57
|
+
[TO_BE_MERGED]: true,
|
|
58
|
+
[DEEP_MERGE]: false
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function deepMerge(value) {
|
|
62
|
+
return {
|
|
63
|
+
value,
|
|
64
|
+
[TO_BE_MERGED]: true,
|
|
65
|
+
[DEEP_MERGE]: true
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function isDeferredProp(propValue) {
|
|
69
|
+
return DEFERRED_PROP in propValue;
|
|
70
|
+
}
|
|
71
|
+
function isMergeableProp(propValue) {
|
|
72
|
+
return TO_BE_MERGED in propValue;
|
|
73
|
+
}
|
|
74
|
+
function isAlwaysProp(propValue) {
|
|
75
|
+
return ALWAYS_PROP in propValue;
|
|
76
|
+
}
|
|
77
|
+
function isOptionalProp(propValue) {
|
|
78
|
+
return OPTIONAL_PROP in propValue;
|
|
79
|
+
}
|
|
80
|
+
async function unpackPropValue(value, containerResolver) {
|
|
81
|
+
return serialize(value, containerResolver);
|
|
82
|
+
}
|
|
83
|
+
async function buildStandardVisitProps(pageProps, containerResolver) {
|
|
84
|
+
const mergeProps = [];
|
|
85
|
+
const deepMergeProps = [];
|
|
86
|
+
const newProps = {};
|
|
87
|
+
const deferredProps = {};
|
|
88
|
+
const unpackedValues = [];
|
|
89
|
+
for (const [key, value] of Object.entries(pageProps)) if (isObject(value)) {
|
|
90
|
+
if (isDeferredProp(value)) {
|
|
91
|
+
deferredProps[value.group] = deferredProps[value.group] ?? [];
|
|
92
|
+
deferredProps[value.group].push(key);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (isOptionalProp(value)) continue;
|
|
96
|
+
if (isAlwaysProp(value)) {
|
|
97
|
+
unpackedValues.push({
|
|
98
|
+
key,
|
|
99
|
+
value: value.value
|
|
100
|
+
});
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (isMergeableProp(value)) {
|
|
104
|
+
if (value[DEEP_MERGE]) deepMergeProps.push(key);
|
|
105
|
+
else mergeProps.push(key);
|
|
106
|
+
if (isObject(value.value) && isDeferredProp(value.value)) {
|
|
107
|
+
deferredProps[value.value.group] = deferredProps[value.value.group] ?? [];
|
|
108
|
+
deferredProps[value.value.group].push(key);
|
|
109
|
+
unpackedValues.push({
|
|
110
|
+
key,
|
|
111
|
+
value: value.value.compute
|
|
112
|
+
});
|
|
113
|
+
} else unpackedValues.push({
|
|
114
|
+
key,
|
|
115
|
+
value: value.value
|
|
116
|
+
});
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
unpackedValues.push({
|
|
120
|
+
key,
|
|
121
|
+
value
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
if (typeof value === "function") {
|
|
125
|
+
unpackedValues.push({
|
|
126
|
+
key,
|
|
127
|
+
value
|
|
128
|
+
});
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
newProps[key] = value;
|
|
132
|
+
}
|
|
133
|
+
await Promise.all(unpackedValues.map(async ({ key, value }) => {
|
|
134
|
+
if (typeof value === "function") return Promise.resolve(value()).then((r) => unpackPropValue(r, containerResolver)).then((jsonValue) => {
|
|
135
|
+
newProps[key] = jsonValue;
|
|
136
|
+
});
|
|
137
|
+
else return unpackPropValue(value, containerResolver).then((jsonValue) => {
|
|
138
|
+
newProps[key] = jsonValue;
|
|
139
|
+
});
|
|
140
|
+
}));
|
|
141
|
+
return {
|
|
142
|
+
props: newProps,
|
|
143
|
+
mergeProps,
|
|
144
|
+
deepMergeProps,
|
|
145
|
+
deferredProps
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async function buildPartialRequestProps(pageProps, cherryPickProps, containerResolver) {
|
|
149
|
+
const mergeProps = [];
|
|
150
|
+
const deepMergeProps = [];
|
|
151
|
+
const newProps = {};
|
|
152
|
+
const unpackedValues = [];
|
|
153
|
+
for (const [key, value] of Object.entries(pageProps)) if (isObject(value)) {
|
|
154
|
+
if (isAlwaysProp(value)) {
|
|
155
|
+
unpackedValues.push({
|
|
156
|
+
key,
|
|
157
|
+
value: value.value
|
|
158
|
+
});
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (!cherryPickProps.includes(key)) continue;
|
|
162
|
+
if (isDeferredProp(value)) {
|
|
163
|
+
unpackedValues.push({
|
|
164
|
+
key,
|
|
165
|
+
value: value.compute
|
|
166
|
+
});
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (isOptionalProp(value)) {
|
|
170
|
+
unpackedValues.push({
|
|
171
|
+
key,
|
|
172
|
+
value: value.compute
|
|
173
|
+
});
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (isMergeableProp(value)) {
|
|
177
|
+
if (value[DEEP_MERGE]) deepMergeProps.push(key);
|
|
178
|
+
else mergeProps.push(key);
|
|
179
|
+
if (isObject(value.value) && isDeferredProp(value.value)) unpackedValues.push({
|
|
180
|
+
key,
|
|
181
|
+
value: value.value.compute
|
|
182
|
+
});
|
|
183
|
+
else unpackedValues.push({
|
|
184
|
+
key,
|
|
185
|
+
value: value.value
|
|
186
|
+
});
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
unpackedValues.push({
|
|
190
|
+
key,
|
|
191
|
+
value
|
|
192
|
+
});
|
|
193
|
+
} else {
|
|
194
|
+
if (!cherryPickProps.includes(key)) continue;
|
|
195
|
+
if (typeof value === "function") {
|
|
196
|
+
unpackedValues.push({
|
|
197
|
+
key,
|
|
198
|
+
value
|
|
199
|
+
});
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
newProps[key] = value;
|
|
203
|
+
}
|
|
204
|
+
await Promise.all(unpackedValues.map(async ({ key, value }) => {
|
|
205
|
+
if (typeof value === "function") return Promise.resolve(value()).then((r) => unpackPropValue(r, containerResolver)).then((jsonValue) => {
|
|
206
|
+
newProps[key] = jsonValue;
|
|
207
|
+
});
|
|
208
|
+
else return unpackPropValue(value, containerResolver).then((jsonValue) => {
|
|
209
|
+
newProps[key] = jsonValue;
|
|
210
|
+
});
|
|
211
|
+
}));
|
|
212
|
+
return {
|
|
213
|
+
props: newProps,
|
|
214
|
+
mergeProps,
|
|
215
|
+
deepMergeProps,
|
|
216
|
+
deferredProps: {}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
var Inertia = class {
|
|
220
|
+
#sharedStateProviders;
|
|
221
|
+
#cachedRequestInfo;
|
|
222
|
+
#serverRenderer;
|
|
223
|
+
#vite;
|
|
224
|
+
#shouldClearHistory;
|
|
225
|
+
#shouldEncryptHistory;
|
|
226
|
+
#cachedVersion;
|
|
227
|
+
defer = defer;
|
|
228
|
+
always = always;
|
|
229
|
+
merge = merge;
|
|
230
|
+
optional = optional;
|
|
231
|
+
deepMerge = deepMerge;
|
|
232
|
+
constructor(ctx, config, vite, serverRenderer) {
|
|
233
|
+
this.ctx = ctx;
|
|
234
|
+
this.config = config;
|
|
235
|
+
if (debug_default.enabled) debug_default("instantiating inertia instance for request \"%s\" using config %O", ctx.request.url(), this.config);
|
|
236
|
+
this.#shouldClearHistory = false;
|
|
237
|
+
this.#vite = vite;
|
|
238
|
+
this.#serverRenderer = serverRenderer;
|
|
239
|
+
this.#shouldEncryptHistory = config.encryptHistory ?? false;
|
|
240
|
+
this.#cachedVersion = this.config.assetsVersion ? String(this.config.assetsVersion) : void 0;
|
|
241
|
+
}
|
|
242
|
+
#resolveRootView() {
|
|
243
|
+
return typeof this.config.rootView === "function" ? this.config.rootView(this.ctx) : this.config.rootView;
|
|
244
|
+
}
|
|
245
|
+
async #buildPageProps(component, requestInfo, pageProps) {
|
|
246
|
+
let finalProps;
|
|
247
|
+
if (this.#sharedStateProviders) finalProps = {
|
|
248
|
+
...await Promise.all(this.#sharedStateProviders.map((provider) => {
|
|
249
|
+
return typeof provider === "function" ? provider() : provider;
|
|
250
|
+
})).then((resolvedSharedState) => {
|
|
251
|
+
return resolvedSharedState.reduce((result, state) => {
|
|
252
|
+
return {
|
|
253
|
+
...result,
|
|
254
|
+
...state
|
|
255
|
+
};
|
|
256
|
+
}, {});
|
|
257
|
+
}),
|
|
258
|
+
...pageProps
|
|
259
|
+
};
|
|
260
|
+
else finalProps = { ...pageProps };
|
|
261
|
+
if (requestInfo.partialComponent === component) {
|
|
262
|
+
const only = requestInfo.onlyProps;
|
|
263
|
+
const except = requestInfo.exceptProps ?? [];
|
|
264
|
+
const cherryPickProps = Object.keys(finalProps).filter((propName) => {
|
|
265
|
+
if (only) return only.includes(propName) && !except.includes(propName);
|
|
266
|
+
return !except.includes(propName);
|
|
267
|
+
});
|
|
268
|
+
debug_default("building props for a partial reload %O", requestInfo);
|
|
269
|
+
debug_default("cherry picking props %s", cherryPickProps);
|
|
270
|
+
return buildPartialRequestProps(finalProps, cherryPickProps, this.ctx.containerResolver);
|
|
271
|
+
}
|
|
272
|
+
debug_default("building props for a standard visit %O", requestInfo);
|
|
273
|
+
return buildStandardVisitProps(finalProps, this.ctx.containerResolver);
|
|
274
|
+
}
|
|
275
|
+
#handleInertiaRequest(pageObject) {
|
|
276
|
+
this.ctx.response.header(InertiaHeaders.Inertia, "true");
|
|
277
|
+
return pageObject;
|
|
278
|
+
}
|
|
279
|
+
async #renderWithSSR(pageObject, viewProps) {
|
|
280
|
+
if (!this.#serverRenderer) throw new Error("Cannot server render pages without a server renderer");
|
|
281
|
+
debug_default("server-side rendering %O", pageObject);
|
|
282
|
+
const { head, body } = await this.#serverRenderer.render(pageObject);
|
|
283
|
+
return this.ctx.view.render(this.#resolveRootView(), {
|
|
284
|
+
page: {
|
|
285
|
+
ssrHead: head,
|
|
286
|
+
ssrBody: body,
|
|
287
|
+
...pageObject
|
|
288
|
+
},
|
|
289
|
+
...viewProps
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
async #renderClientSide(pageObject, viewProps) {
|
|
293
|
+
debug_default("rendering shell for SPA %O", pageObject);
|
|
294
|
+
return this.ctx.view.render(this.#resolveRootView(), {
|
|
295
|
+
page: pageObject,
|
|
296
|
+
...viewProps
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
requestInfo(reCompute) {
|
|
300
|
+
if (reCompute) this.#cachedRequestInfo = void 0;
|
|
301
|
+
this.#cachedRequestInfo = this.#cachedRequestInfo ?? {
|
|
302
|
+
version: this.ctx.request.header(InertiaHeaders.Version),
|
|
303
|
+
isInertiaRequest: !!this.ctx.request.header(InertiaHeaders.Inertia),
|
|
304
|
+
isPartialRequest: !!this.ctx.request.header(InertiaHeaders.PartialComponent),
|
|
305
|
+
partialComponent: this.ctx.request.header(InertiaHeaders.PartialComponent),
|
|
306
|
+
onlyProps: this.ctx.request.header(InertiaHeaders.PartialOnly)?.split(","),
|
|
307
|
+
exceptProps: this.ctx.request.header(InertiaHeaders.PartialExcept)?.split(","),
|
|
308
|
+
resetProps: this.ctx.request.header(InertiaHeaders.Reset)?.split(","),
|
|
309
|
+
errorBag: this.ctx.request.header(InertiaHeaders.ErrorBag)
|
|
310
|
+
};
|
|
311
|
+
return this.#cachedRequestInfo;
|
|
312
|
+
}
|
|
313
|
+
getVersion() {
|
|
314
|
+
if (this.#cachedVersion) return this.#cachedVersion;
|
|
315
|
+
if (this.#vite?.hasManifestFile) this.#cachedVersion = createHash("md5").update(JSON.stringify(this.#vite.manifest())).digest("hex");
|
|
316
|
+
else this.#cachedVersion = "1";
|
|
317
|
+
return this.#cachedVersion;
|
|
318
|
+
}
|
|
319
|
+
async ssrEnabled(component) {
|
|
320
|
+
if (!this.config.ssr.enabled) return false;
|
|
321
|
+
if (typeof this.config.ssr.pages === "function") return this.config.ssr.pages(this.ctx, component);
|
|
322
|
+
if (this.config.ssr.pages) return this.config.ssr.pages?.includes(component);
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
share(sharedState) {
|
|
326
|
+
if (!this.#sharedStateProviders) this.#sharedStateProviders = [];
|
|
327
|
+
this.#sharedStateProviders.push(sharedState);
|
|
328
|
+
return this;
|
|
329
|
+
}
|
|
330
|
+
async page(page, pageProps) {
|
|
331
|
+
const requestInfo = this.requestInfo();
|
|
332
|
+
const { props, mergeProps, deferredProps, deepMergeProps } = await this.#buildPageProps(page, requestInfo, pageProps);
|
|
333
|
+
return {
|
|
334
|
+
component: page,
|
|
335
|
+
url: this.ctx.request.url(true),
|
|
336
|
+
version: this.getVersion(),
|
|
337
|
+
clearHistory: this.#shouldClearHistory,
|
|
338
|
+
encryptHistory: this.#shouldEncryptHistory,
|
|
339
|
+
props,
|
|
340
|
+
deferredProps,
|
|
341
|
+
mergeProps,
|
|
342
|
+
deepMergeProps
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
async render(page, pageProps, viewProps) {
|
|
346
|
+
const requestInfo = this.requestInfo();
|
|
347
|
+
const pageObject = await this.page(page, pageProps);
|
|
348
|
+
if (requestInfo.isInertiaRequest) return this.#handleInertiaRequest(pageObject);
|
|
349
|
+
if (await this.ssrEnabled(page)) return this.#renderWithSSR(pageObject, viewProps);
|
|
350
|
+
return this.#renderClientSide(pageObject, viewProps);
|
|
351
|
+
}
|
|
352
|
+
clearHistory() {
|
|
353
|
+
this.#shouldClearHistory = true;
|
|
354
|
+
}
|
|
355
|
+
encryptHistory(encrypt = true) {
|
|
356
|
+
this.#shouldEncryptHistory = encrypt;
|
|
357
|
+
}
|
|
358
|
+
location(url) {
|
|
359
|
+
this.ctx.response.header(InertiaHeaders.Location, url);
|
|
360
|
+
this.ctx.response.status(409);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
var ServerRenderer = class {
|
|
364
|
+
#runtime;
|
|
365
|
+
#config;
|
|
366
|
+
#vite;
|
|
367
|
+
constructor(config, vite) {
|
|
368
|
+
this.#config = config;
|
|
369
|
+
this.#vite = vite;
|
|
370
|
+
}
|
|
371
|
+
async render(pageObject) {
|
|
372
|
+
let render;
|
|
373
|
+
if (this.#vite.getDevServer()) {
|
|
374
|
+
debug_default("creating SSR bundle using dev-server");
|
|
375
|
+
this.#runtime ??= await this.#vite.createModuleRunner();
|
|
376
|
+
this.#runtime.clearCache();
|
|
377
|
+
render = await this.#runtime.import(this.#config.ssr.entrypoint);
|
|
378
|
+
} else {
|
|
379
|
+
debug_default("creating SSR bundle using production build");
|
|
380
|
+
render = await import(pathToFileURL(this.#config.ssr.bundle).href);
|
|
381
|
+
}
|
|
382
|
+
const result = await render.default(pageObject);
|
|
383
|
+
debug_default("SSR bundle %o", result);
|
|
384
|
+
return {
|
|
385
|
+
head: result.head,
|
|
386
|
+
body: result.body
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
var InertiaManager = class {
|
|
391
|
+
#vite;
|
|
392
|
+
#config;
|
|
393
|
+
#serverRenderer;
|
|
394
|
+
constructor(config, vite) {
|
|
395
|
+
this.#config = config;
|
|
396
|
+
this.#vite = vite;
|
|
397
|
+
this.#serverRenderer = this.#vite ? new ServerRenderer(this.#config, this.#vite) : void 0;
|
|
398
|
+
}
|
|
399
|
+
createForRequest(ctx) {
|
|
400
|
+
return new Inertia(ctx, this.#config, this.#vite, this.#serverRenderer);
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
export { symbols_exports as i, ServerRenderer as n, Inertia as r, InertiaManager as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Route } from '@adonisjs/core/http';
|
|
2
2
|
import type { ApplicationService } from '@adonisjs/core/types';
|
|
3
|
-
import type { AsPageProps, InertiaPages } from '../src/types.js';
|
|
3
|
+
import type { AsPageProps, ComponentProps, InertiaPages, SharedProps } from '../src/types.js';
|
|
4
4
|
declare module '@adonisjs/core/http' {
|
|
5
5
|
interface BriskRoute {
|
|
6
6
|
/**
|
|
@@ -29,7 +29,7 @@ declare module '@adonisjs/core/http' {
|
|
|
29
29
|
* })
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
renderInertia<Page extends keyof InertiaPages>(component: Page, props: AsPageProps<InertiaPages[Page]
|
|
32
|
+
renderInertia<Page extends keyof InertiaPages>(component: Page, props: InertiaPages[Page] extends ComponentProps ? AsPageProps<Omit<InertiaPages[Page], keyof SharedProps>> : never, viewProps?: Record<string, any>): Route;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
@@ -1,82 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import "../chunk-DISC5OYC.js";
|
|
5
|
-
import "../chunk-4EZ2J6OA.js";
|
|
6
|
-
import "../chunk-MLKGABMK.js";
|
|
7
|
-
|
|
8
|
-
// providers/inertia_provider.ts
|
|
1
|
+
import { t as InertiaManager } from "../inertia_manager-Di3J3hSG.js";
|
|
2
|
+
import "../headers-DafWEpBh.js";
|
|
3
|
+
import "../debug-CBMTuPUm.js";
|
|
9
4
|
import { BriskRoute } from "@adonisjs/core/http";
|
|
10
5
|
var InertiaProvider = class {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
async registerEdgePlugin() {
|
|
33
|
-
const edgeExports = await import("edge.js");
|
|
34
|
-
const { edgePluginInertia } = await import("../src/plugins/edge/plugin.js");
|
|
35
|
-
edgeExports.default.use(edgePluginInertia());
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Registers the InertiaManager as a singleton in the IoC container
|
|
39
|
-
*
|
|
40
|
-
* This method sets up the core Inertia manager with the application's
|
|
41
|
-
* configuration and Vite integration. The manager handles page rendering,
|
|
42
|
-
* asset management, and SSR functionality.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```js
|
|
46
|
-
* // The manager is automatically available for injection:
|
|
47
|
-
* const inertiaManager = await app.container.make(InertiaManager)
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
async register() {
|
|
51
|
-
this.app.container.singleton(InertiaManager, async (resolver) => {
|
|
52
|
-
const config = this.app.config.get("inertia", {});
|
|
53
|
-
const vite = await resolver.make("vite");
|
|
54
|
-
return new InertiaManager(config, vite);
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Boot the provider by registering Edge plugin and route macros
|
|
59
|
-
*
|
|
60
|
-
* This method completes the Inertia setup by registering the Edge plugin
|
|
61
|
-
* and adding the renderInertia macro to BriskRoute for convenient route definitions.
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```js
|
|
65
|
-
* // Routes can now use the renderInertia macro
|
|
66
|
-
* router.get('/dashboard', []).renderInertia('Dashboard', {
|
|
67
|
-
* user: getCurrentUser()
|
|
68
|
-
* })
|
|
69
|
-
* ```
|
|
70
|
-
*/
|
|
71
|
-
async boot() {
|
|
72
|
-
await this.registerEdgePlugin();
|
|
73
|
-
BriskRoute.macro("renderInertia", function(template, props, viewProps) {
|
|
74
|
-
return this.setHandler(({ inertia }) => {
|
|
75
|
-
return inertia.render(template, props, viewProps);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
export {
|
|
81
|
-
InertiaProvider as default
|
|
6
|
+
constructor(app) {
|
|
7
|
+
this.app = app;
|
|
8
|
+
}
|
|
9
|
+
async registerEdgePlugin() {
|
|
10
|
+
const edgeExports = await import("edge.js");
|
|
11
|
+
const { edgePluginInertia } = await import("../src/plugins/edge/plugin.js");
|
|
12
|
+
edgeExports.default.use(edgePluginInertia());
|
|
13
|
+
}
|
|
14
|
+
async register() {
|
|
15
|
+
this.app.container.singleton(InertiaManager, async (resolver) => {
|
|
16
|
+
return new InertiaManager(this.app.config.get("inertia", {}), await resolver.make("vite"));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async boot() {
|
|
20
|
+
await this.registerEdgePlugin();
|
|
21
|
+
BriskRoute.macro("renderInertia", function(template, props, viewProps) {
|
|
22
|
+
return this.setHandler(({ inertia }) => {
|
|
23
|
+
return inertia.render(template, props, viewProps);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
82
27
|
};
|
|
28
|
+
export { InertiaProvider as default };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a page component from a given path or array of paths by looking up
|
|
3
|
+
* the component in the provided pages registry. Supports both direct promises
|
|
4
|
+
* and lazy-loaded functions that return promises.
|
|
5
|
+
*
|
|
6
|
+
* @param path - The page path(s) to resolve. Can be a single string or array of strings
|
|
7
|
+
* @param pages - Registry of page components where keys are paths and values are either promises or functions returning promises
|
|
8
|
+
* @param layout - Optional layout component to assign to the resolved page
|
|
9
|
+
* @returns Promise resolving to the page component
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```js
|
|
13
|
+
* // Single path resolution
|
|
14
|
+
* const component = await resolvePageComponent('Home', {
|
|
15
|
+
* 'Home': () => import('./pages/Home.vue'),
|
|
16
|
+
* 'About': () => import('./pages/About.vue')
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* // Multiple path resolution (fallback)
|
|
20
|
+
* const component = await resolvePageComponent(['Dashboard/Admin', 'Dashboard'], {
|
|
21
|
+
* 'Dashboard': () => import('./pages/Dashboard.vue')
|
|
22
|
+
* })
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @throws Error When none of the provided paths can be resolved in the pages registry
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolvePageComponent<T>(path: string | string[], pages: Record<string, Promise<T> | (() => Promise<T>) | T>, layout?: any): Promise<T>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
async function resolvePageComponent(path, pages, layout) {
|
|
2
|
+
for (const p of Array.isArray(path) ? path : [path]) {
|
|
3
|
+
const page = pages[p];
|
|
4
|
+
if (typeof page === "undefined") continue;
|
|
5
|
+
const resolvedPage = await (typeof page === "function" ? page() : page);
|
|
6
|
+
if (!resolvedPage) throw new Error(`Invalid page exported from "${path}". Make sure to default export a function`);
|
|
7
|
+
if ("default" in resolvedPage === false) throw new Error(`Invalid page exported from "${path}". Make sure to default export a function`);
|
|
8
|
+
if (layout && !resolvedPage.default.layout) resolvedPage.default.layout = layout;
|
|
9
|
+
return resolvedPage;
|
|
10
|
+
}
|
|
11
|
+
throw new Error(`Page not found: "${path}"`);
|
|
12
|
+
}
|
|
13
|
+
export { resolvePageComponent };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Tuyau } from '@tuyau/core/client';
|
|
3
|
+
import type { AdonisRegistry } from '@tuyau/core/types';
|
|
4
|
+
/**
|
|
5
|
+
* Provider component that makes the Tuyau client available to child components.
|
|
6
|
+
*
|
|
7
|
+
* This component should wrap your entire application or the part of your
|
|
8
|
+
* application that needs access to type-safe routing functionality.
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
export declare function TuyauProvider<R extends AdonisRegistry>(props: {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
client: Tuyau<R>;
|
|
14
|
+
}): React.JSX.Element;
|
|
15
|
+
/**
|
|
16
|
+
* Hook to access the Tuyau client from any component within a TuyauProvider.
|
|
17
|
+
*
|
|
18
|
+
* Provides type-safe access to route generation and navigation utilities.
|
|
19
|
+
* Must be used within a component tree wrapped by TuyauProvider.
|
|
20
|
+
*
|
|
21
|
+
* @returns The Tuyau client instance with full type safety
|
|
22
|
+
* @throws Error if used outside of a TuyauProvider
|
|
23
|
+
*/
|
|
24
|
+
export declare function useTuyau(): Tuyau<any>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Link as Link$1, router } from "@inertiajs/react";
|
|
3
|
+
const TuyauContext = React.createContext(null);
|
|
4
|
+
function TuyauProvider(props) {
|
|
5
|
+
return <TuyauContext.Provider value={props.client}>{props.children}</TuyauContext.Provider>;
|
|
6
|
+
}
|
|
7
|
+
function useTuyau() {
|
|
8
|
+
const context = React.useContext(TuyauContext);
|
|
9
|
+
if (!context) throw new Error("You must wrap your app in a TuyauProvider");
|
|
10
|
+
return context;
|
|
11
|
+
}
|
|
12
|
+
function useRouter() {
|
|
13
|
+
const tuyau = useTuyau();
|
|
14
|
+
return { visit: (props, options) => {
|
|
15
|
+
const routeInfo = tuyau.getRoute(props.route, { params: props.params });
|
|
16
|
+
const url = routeInfo.url;
|
|
17
|
+
return router.visit(url, {
|
|
18
|
+
...options,
|
|
19
|
+
method: routeInfo.methods[0].toLowerCase()
|
|
20
|
+
});
|
|
21
|
+
} };
|
|
22
|
+
}
|
|
23
|
+
function LinkInner(props, ref) {
|
|
24
|
+
const { route, params, ...linkProps } = props;
|
|
25
|
+
const routeInfo = useTuyau().getRoute(props.route, { params });
|
|
26
|
+
return <Link$1 {...linkProps} href={routeInfo.url} method={routeInfo.methods[0].toLowerCase()} ref={ref} />;
|
|
27
|
+
}
|
|
28
|
+
const Link = React.forwardRef(LinkInner);
|
|
29
|
+
export { Link, TuyauProvider, useRouter, useTuyau };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { UserRegistry } from '@tuyau/core/types';
|
|
3
|
+
import { AreAllOptional } from '@poppinss/utils/types';
|
|
4
|
+
import { Link as InertiaLink } from '@inertiajs/react';
|
|
5
|
+
/**
|
|
6
|
+
* Get parameter tuple type for a route
|
|
7
|
+
*/
|
|
8
|
+
type ExtractParamsTuple<Route extends keyof UserRegistry> = UserRegistry[Route]['types']['paramsTuple'];
|
|
9
|
+
/**
|
|
10
|
+
* Get parameter object type for a route
|
|
11
|
+
*/
|
|
12
|
+
type ExtractParamsObject<Route extends keyof UserRegistry> = UserRegistry[Route]['types']['params'];
|
|
13
|
+
/**
|
|
14
|
+
* Get params format for a route
|
|
15
|
+
*/
|
|
16
|
+
type RouteParamsFormats<Route extends keyof UserRegistry> = ExtractParamsObject<Route> extends Record<string, never> ? never : ExtractParamsTuple<Route> | ExtractParamsObject<Route>;
|
|
17
|
+
/**
|
|
18
|
+
* Parameters required for route navigation with proper type safety.
|
|
19
|
+
*/
|
|
20
|
+
export type LinkParams<Route extends keyof UserRegistry> = {
|
|
21
|
+
route: Route;
|
|
22
|
+
} & (RouteParamsFormats<Route> extends never ? {
|
|
23
|
+
params?: never;
|
|
24
|
+
} : AreAllOptional<ExtractParamsObject<Route>> extends true ? {
|
|
25
|
+
params?: RouteParamsFormats<Route>;
|
|
26
|
+
} : {
|
|
27
|
+
params: RouteParamsFormats<Route>;
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Props for the Link component extending InertiaLink props
|
|
31
|
+
* with route-specific type safety and parameter validation.
|
|
32
|
+
*/
|
|
33
|
+
type LinkProps<Route extends keyof UserRegistry> = Omit<React.ComponentPropsWithoutRef<typeof InertiaLink>, 'href' | 'method'> & LinkParams<Route>;
|
|
34
|
+
/**
|
|
35
|
+
* Internal Link component implementation with forward ref support.
|
|
36
|
+
* Resolves route parameters and generates the appropriate URL and HTTP method
|
|
37
|
+
* for Inertia navigation.
|
|
38
|
+
*
|
|
39
|
+
* @param props - Link properties including route and parameters
|
|
40
|
+
* @param ref - Forward ref for the underlying InertiaLink component
|
|
41
|
+
*/
|
|
42
|
+
declare function LinkInner<Route extends keyof UserRegistry>(props: LinkProps<Route>, ref?: React.ForwardedRef<React.ElementRef<typeof InertiaLink>>): React.JSX.Element;
|
|
43
|
+
/**
|
|
44
|
+
* Type-safe Link component for Inertia.js navigation.
|
|
45
|
+
*
|
|
46
|
+
* Provides compile-time route validation and automatic parameter type checking
|
|
47
|
+
* based on your application's route definitions. Automatically resolves the
|
|
48
|
+
* correct URL and HTTP method for each route.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* // Link to a route without parameters
|
|
53
|
+
* <Link route="home">Home</Link>
|
|
54
|
+
*
|
|
55
|
+
* // Link to a route with required parameters
|
|
56
|
+
* <Link route="user.show" params={{ id: 1 }}>
|
|
57
|
+
* View User
|
|
58
|
+
* </Link>
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare const Link: <Route extends keyof UserRegistry>(props: LinkProps<Route> & {
|
|
62
|
+
ref?: React.Ref<React.ElementRef<typeof InertiaLink>>;
|
|
63
|
+
}) => ReturnType<typeof LinkInner>;
|
|
64
|
+
export {};
|