@stratal/inertia 0.0.1 → 0.0.19
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/dist/index.d.mts +265 -52
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +551 -177
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +83 -0
- package/dist/react.d.mts.map +1 -0
- package/dist/react.mjs +158 -0
- package/dist/react.mjs.map +1 -0
- package/dist/testing.d.mts +36 -0
- package/dist/testing.d.mts.map +1 -0
- package/dist/testing.mjs +78 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/type-generator-C5JljyzK.mjs +391 -0
- package/dist/type-generator-C5JljyzK.mjs.map +1 -0
- package/dist/vite.d.mts +8 -1
- package/dist/vite.d.mts.map +1 -1
- package/dist/vite.mjs +152 -4
- package/dist/vite.mjs.map +1 -0
- package/package.json +47 -19
- package/dist/inertia-dev-css-plugin-BYromyO_.mjs +0 -70
- package/dist/inertia-dev-css-plugin-BYromyO_.mjs.map +0 -1
- package/dist/inertia-types-plugin-NO_uxhxQ.mjs +0 -39
- package/dist/inertia-types-plugin-NO_uxhxQ.mjs.map +0 -1
- package/dist/rolldown-runtime-wcPFST8Q.mjs +0 -13
- package/dist/type-generator-DlXIc6e2.mjs +0 -193
- package/dist/type-generator-DlXIc6e2.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,96 +1,91 @@
|
|
|
1
|
-
import { n as runTypeGeneration, t as findPagesDir } from "./type-generator-
|
|
1
|
+
import { n as runTypeGeneration, t as findPagesDir } from "./type-generator-C5JljyzK.mjs";
|
|
2
|
+
import { Scope, Transient, inject } from "stratal/di";
|
|
3
|
+
import { ApplicationError } from "stratal/errors";
|
|
4
|
+
import { I18N_TOKENS } from "stratal/i18n";
|
|
2
5
|
import { Module } from "stratal/module";
|
|
3
|
-
import { Route, RouterContext } from "stratal/router";
|
|
6
|
+
import { Delete, Get, Patch, Post, Put, ROUTER_TOKENS, Route, RouterContext, SchemaValidationError } from "stratal/router";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
4
8
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { join, relative } from "node:path";
|
|
9
|
+
import { dirname, join, relative } from "node:path";
|
|
6
10
|
import { Command } from "stratal/quarry";
|
|
7
11
|
import { watch } from "node:fs/promises";
|
|
8
|
-
import {
|
|
12
|
+
import { LOGGER_TOKENS } from "stratal/logger";
|
|
13
|
+
import { deleteCookie, getSignedCookie, setSignedCookie } from "hono/cookie";
|
|
9
14
|
import { z } from "stratal/validation";
|
|
10
15
|
//#region src/augment/router-context.ts
|
|
11
16
|
function augmentRouterContext(resolveService) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
proto.redirect = function(url, status) {
|
|
17
|
+
const originalRedirect = RouterContext.prototype.redirect;
|
|
18
|
+
RouterContext.macro("redirect", function(url, status) {
|
|
15
19
|
if (!status || status === 302) {
|
|
16
20
|
const method = this.c.req.method;
|
|
17
21
|
if (method !== "GET" && method !== "HEAD") return originalRedirect.call(this, url, 303);
|
|
18
22
|
}
|
|
19
23
|
return originalRedirect.call(this, url, status);
|
|
20
|
-
};
|
|
21
|
-
|
|
24
|
+
});
|
|
25
|
+
RouterContext.macro("inertia", function(component, props, options) {
|
|
22
26
|
return resolveService(this).render(this, component, props, options);
|
|
23
|
-
};
|
|
24
|
-
|
|
27
|
+
});
|
|
28
|
+
RouterContext.macro("defer", function(callback, group) {
|
|
25
29
|
return resolveService(this).defer(callback, group);
|
|
26
|
-
};
|
|
27
|
-
|
|
30
|
+
});
|
|
31
|
+
RouterContext.macro("optional", function(callback) {
|
|
28
32
|
return resolveService(this).optional(callback);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
return resolveService(this).merge(callback);
|
|
32
|
-
};
|
|
33
|
-
|
|
33
|
+
});
|
|
34
|
+
RouterContext.macro("merge", function(callback, options) {
|
|
35
|
+
return resolveService(this).merge(callback, options);
|
|
36
|
+
});
|
|
37
|
+
RouterContext.macro("once", function(callback, options) {
|
|
38
|
+
return resolveService(this).once(callback, options);
|
|
39
|
+
});
|
|
40
|
+
RouterContext.macro("always", function(callback) {
|
|
41
|
+
return resolveService(this).always(callback);
|
|
42
|
+
});
|
|
43
|
+
RouterContext.macro("flash", function(key, value) {
|
|
44
|
+
const flashOut = this.c.get("inertiaFlashOut");
|
|
45
|
+
if (flashOut) flashOut[key] = value;
|
|
46
|
+
});
|
|
47
|
+
RouterContext.macro("withoutSsr", function() {
|
|
34
48
|
this.c.set("withoutSsr", true);
|
|
35
|
-
};
|
|
49
|
+
});
|
|
36
50
|
}
|
|
37
51
|
//#endregion
|
|
38
52
|
//#region src/vite/create-vite-config.ts
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
configEnvironment(_name, env) {
|
|
76
|
-
const existing = env.optimizeDeps?.exclude ?? [];
|
|
77
|
-
env.optimizeDeps = {
|
|
78
|
-
...env.optimizeDeps,
|
|
79
|
-
exclude: [...existing, ...optimizeDepsExclude]
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
],
|
|
84
|
-
publicDir: join(options.cwd, "src", "inertia", "public"),
|
|
85
|
-
build: {
|
|
86
|
-
...options.outDir ? { outDir: options.outDir } : {},
|
|
87
|
-
rolldownOptions: { input: options.entryPath }
|
|
88
|
-
},
|
|
89
|
-
...options.server ? { server: {
|
|
90
|
-
port: options.server.port,
|
|
91
|
-
host: options.server.host ?? void 0
|
|
92
|
-
} } : {}
|
|
93
|
-
}, userConfig);
|
|
53
|
+
function writeTempViteConfig(options) {
|
|
54
|
+
const configPath = join(join(options.cwd, "node_modules", ".stratal"), "vite.config.mjs");
|
|
55
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
56
|
+
const hasUserConfig = existsSync(join(options.cwd, "vite.config.ts"));
|
|
57
|
+
const serverConfig = options.server ? `server: { port: ${options.server.port}, host: ${options.server.host ? "true" : "undefined"} },` : "";
|
|
58
|
+
const outDirConfig = options.outDir ? `outDir: '${options.outDir}',` : "";
|
|
59
|
+
writeFileSync(configPath, `
|
|
60
|
+
import { mergeConfig } from 'vite'
|
|
61
|
+
import { cloudflare } from '@cloudflare/vite-plugin'
|
|
62
|
+
import { stratalInertia } from '@stratal/inertia/vite'
|
|
63
|
+
|
|
64
|
+
let inertiaPlugin = null
|
|
65
|
+
try {
|
|
66
|
+
const mod = await import('@inertiajs/vite')
|
|
67
|
+
const inertia = mod.default ?? mod
|
|
68
|
+
inertiaPlugin = inertia()
|
|
69
|
+
} catch {}
|
|
70
|
+
|
|
71
|
+
const baseConfig = {
|
|
72
|
+
plugins: [
|
|
73
|
+
cloudflare(${options.persistTo ? `{ persistState: { path: ${JSON.stringify(options.persistTo)} } }` : ""}),
|
|
74
|
+
...(inertiaPlugin ? [inertiaPlugin] : []),
|
|
75
|
+
...stratalInertia(),
|
|
76
|
+
],
|
|
77
|
+
publicDir: '${join(options.cwd, "src", "inertia", "public").replace(/\\/g, "/")}',
|
|
78
|
+
build: {
|
|
79
|
+
${outDirConfig}
|
|
80
|
+
},
|
|
81
|
+
${serverConfig}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
${hasUserConfig ? `const userModule = await import('${join(options.cwd, "vite.config.ts").replace(/\\/g, "/")}')
|
|
85
|
+
const userConfig = userModule.default ?? userModule
|
|
86
|
+
export default mergeConfig(baseConfig, userConfig)` : "export default baseConfig"}
|
|
87
|
+
`, "utf-8");
|
|
88
|
+
return configPath;
|
|
94
89
|
}
|
|
95
90
|
//#endregion
|
|
96
91
|
//#region src/commands/inertia-build.command.ts
|
|
@@ -101,72 +96,100 @@ var InertiaBuildCommand = class extends Command {
|
|
|
101
96
|
const outDir = this.string("outDir") || "dist";
|
|
102
97
|
const shouldBuildSsr = this.boolean("ssr");
|
|
103
98
|
const cwd = process.cwd();
|
|
104
|
-
|
|
105
|
-
if (!existsSync(join(cwd, entryPath))) {
|
|
99
|
+
if (!existsSync(join(cwd, "src/inertia/app.tsx"))) {
|
|
106
100
|
this.fail("src/inertia/app.tsx not found. Run `quarry inertia:install` first.");
|
|
107
101
|
return 1;
|
|
108
102
|
}
|
|
103
|
+
const configPath = writeTempViteConfig({
|
|
104
|
+
cwd,
|
|
105
|
+
outDir
|
|
106
|
+
});
|
|
109
107
|
this.info("Building Inertia.js frontend for production...");
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.
|
|
119
|
-
if (
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
...config,
|
|
123
|
-
build: {
|
|
124
|
-
...config.build,
|
|
125
|
-
ssr: true
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
this.success("SSR build complete!");
|
|
108
|
+
const clientCode = await this.spawnVite(cwd, configPath, ["build"]);
|
|
109
|
+
if (clientCode !== 0) {
|
|
110
|
+
this.fail("Client build failed.");
|
|
111
|
+
return clientCode;
|
|
112
|
+
}
|
|
113
|
+
this.success("Client build complete!");
|
|
114
|
+
if (shouldBuildSsr) {
|
|
115
|
+
this.info("Building SSR bundle...");
|
|
116
|
+
const ssrCode = await this.spawnVite(cwd, configPath, ["build", "--ssr"]);
|
|
117
|
+
if (ssrCode !== 0) {
|
|
118
|
+
this.fail("SSR build failed.");
|
|
119
|
+
return ssrCode;
|
|
129
120
|
}
|
|
130
|
-
this.success(
|
|
131
|
-
} catch (err) {
|
|
132
|
-
this.fail(`Build failed: ${err.message}`);
|
|
133
|
-
return 1;
|
|
121
|
+
this.success("SSR build complete!");
|
|
134
122
|
}
|
|
123
|
+
this.success(`Output in ${outDir}/`);
|
|
124
|
+
this.info("Deploy with: npx wrangler deploy");
|
|
135
125
|
return 0;
|
|
136
126
|
}
|
|
127
|
+
spawnVite(cwd, configPath, args) {
|
|
128
|
+
return new Promise((resolve) => {
|
|
129
|
+
const child = spawn("npx", [
|
|
130
|
+
"vite",
|
|
131
|
+
"--config",
|
|
132
|
+
configPath,
|
|
133
|
+
...args
|
|
134
|
+
], {
|
|
135
|
+
cwd,
|
|
136
|
+
stdio: "inherit",
|
|
137
|
+
shell: true
|
|
138
|
+
});
|
|
139
|
+
child.on("error", (err) => {
|
|
140
|
+
this.fail(`Vite process error: ${err.message}`);
|
|
141
|
+
resolve(1);
|
|
142
|
+
});
|
|
143
|
+
child.on("close", (code) => {
|
|
144
|
+
resolve(code ?? 0);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
137
148
|
};
|
|
138
149
|
//#endregion
|
|
139
150
|
//#region src/commands/inertia-dev.command.ts
|
|
140
151
|
var InertiaDevCommand = class extends Command {
|
|
141
|
-
static command = "inertia:dev {--port=
|
|
152
|
+
static command = "inertia:dev {--port= : Dev server port} {--host : Expose to network} {--persist-to= : Shared persist directory for @cloudflare/vite-plugin (relative to cwd; the plugin appends /v3). Use to share R2/KV/cache emulator state across multiple workers in dev.}";
|
|
142
153
|
static description = "Start Inertia.js Vite development server";
|
|
143
154
|
async handle() {
|
|
144
|
-
const port = this.number("port")
|
|
155
|
+
const port = this.number("port");
|
|
145
156
|
const host = this.boolean("host");
|
|
157
|
+
const persistTo = this.string("persist-to");
|
|
146
158
|
const cwd = process.cwd();
|
|
147
|
-
|
|
148
|
-
if (!existsSync(join(cwd, entryPath))) {
|
|
159
|
+
if (!existsSync(join(cwd, "src/inertia/app.tsx"))) {
|
|
149
160
|
this.fail("src/inertia/app.tsx not found. Run `quarry inertia:install` first.");
|
|
150
161
|
return 1;
|
|
151
162
|
}
|
|
163
|
+
const configPath = writeTempViteConfig({
|
|
164
|
+
cwd,
|
|
165
|
+
server: {
|
|
166
|
+
port,
|
|
167
|
+
host
|
|
168
|
+
},
|
|
169
|
+
persistTo
|
|
170
|
+
});
|
|
152
171
|
this.info("Starting Vite dev server...");
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
172
|
+
const args = [
|
|
173
|
+
"vite",
|
|
174
|
+
"dev",
|
|
175
|
+
"--config",
|
|
176
|
+
configPath
|
|
177
|
+
];
|
|
178
|
+
if (host) args.push("--host");
|
|
179
|
+
return new Promise((resolve) => {
|
|
180
|
+
const child = spawn("npx", args, {
|
|
156
181
|
cwd,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
return 0;
|
|
182
|
+
stdio: "inherit",
|
|
183
|
+
shell: true
|
|
184
|
+
});
|
|
185
|
+
child.on("error", (err) => {
|
|
186
|
+
this.fail(`Failed to start dev server: ${err.message}`);
|
|
187
|
+
resolve(1);
|
|
188
|
+
});
|
|
189
|
+
child.on("close", (code) => {
|
|
190
|
+
resolve(code ?? 0);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
170
193
|
}
|
|
171
194
|
};
|
|
172
195
|
//#endregion
|
|
@@ -186,7 +209,14 @@ const ROOT_HTML = `<!DOCTYPE html>
|
|
|
186
209
|
</html>`;
|
|
187
210
|
const APP_TSX = `import { createInertiaApp } from '@inertiajs/react'
|
|
188
211
|
|
|
189
|
-
createInertiaApp(
|
|
212
|
+
createInertiaApp({
|
|
213
|
+
resolve: async (name) => {
|
|
214
|
+
const pages = import.meta.glob('./pages/**/*.tsx')
|
|
215
|
+
const page = await pages[\`./pages/\${name}.tsx\`]?.()
|
|
216
|
+
if (!page) throw new Error(\`Page not found: \${name}\`)
|
|
217
|
+
return page
|
|
218
|
+
},
|
|
219
|
+
})`;
|
|
190
220
|
const HOME_TSX = `export default function Home({ message }: { message: string }) {
|
|
191
221
|
return (
|
|
192
222
|
<div>
|
|
@@ -302,15 +332,14 @@ var InertiaTypesCommand = class extends Command {
|
|
|
302
332
|
static description = "Generate Inertia.js page type definitions";
|
|
303
333
|
async handle() {
|
|
304
334
|
const cwd = process.cwd();
|
|
305
|
-
|
|
306
|
-
if (!existsSync(pagesDir)) {
|
|
335
|
+
if (!existsSync(findPagesDir(cwd))) {
|
|
307
336
|
this.fail("src/inertia/pages/ not found. Run `quarry inertia:install` first.");
|
|
308
337
|
return 1;
|
|
309
338
|
}
|
|
310
339
|
if (!await this.generate(cwd)) return 1;
|
|
311
340
|
if (this.boolean("watch")) {
|
|
312
341
|
this.info("Watching for changes...");
|
|
313
|
-
await this.watchForChanges(cwd
|
|
342
|
+
await this.watchForChanges(cwd);
|
|
314
343
|
}
|
|
315
344
|
return 0;
|
|
316
345
|
}
|
|
@@ -325,9 +354,10 @@ var InertiaTypesCommand = class extends Command {
|
|
|
325
354
|
return false;
|
|
326
355
|
}
|
|
327
356
|
}
|
|
328
|
-
async watchForChanges(cwd
|
|
357
|
+
async watchForChanges(cwd) {
|
|
358
|
+
const srcDir = join(cwd, "src");
|
|
329
359
|
try {
|
|
330
|
-
const watcher = watch(
|
|
360
|
+
const watcher = watch(srcDir, { recursive: true });
|
|
331
361
|
for await (const event of watcher) if (event.filename && /\.(tsx|ts)$/.test(event.filename)) {
|
|
332
362
|
this.info(`Change detected: ${event.filename}`);
|
|
333
363
|
await this.generate(cwd);
|
|
@@ -347,19 +377,19 @@ const INERTIA_TOKENS = {
|
|
|
347
377
|
SsrRenderer: Symbol.for("stratal:inertia:ssr-renderer")
|
|
348
378
|
};
|
|
349
379
|
//#endregion
|
|
350
|
-
//#region \0@oxc-project+runtime@0.
|
|
380
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorateMetadata.js
|
|
351
381
|
function __decorateMetadata(k, v) {
|
|
352
382
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
353
383
|
}
|
|
354
384
|
//#endregion
|
|
355
|
-
//#region \0@oxc-project+runtime@0.
|
|
385
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorateParam.js
|
|
356
386
|
function __decorateParam(paramIndex, decorator) {
|
|
357
387
|
return function(target, key) {
|
|
358
388
|
decorator(target, key, paramIndex);
|
|
359
389
|
};
|
|
360
390
|
}
|
|
361
391
|
//#endregion
|
|
362
|
-
//#region \0@oxc-project+runtime@0.
|
|
392
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
|
|
363
393
|
function __decorate(decorators, target, key, desc) {
|
|
364
394
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
365
395
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -378,6 +408,13 @@ let InertiaMiddleware = class InertiaMiddleware {
|
|
|
378
408
|
ctx.c.set("inertia", isInertia);
|
|
379
409
|
ctx.c.set("inertiaPrefetch", isPrefetch);
|
|
380
410
|
ctx.c.set("withoutSsr", false);
|
|
411
|
+
ctx.c.set("inertiaFlashOut", {});
|
|
412
|
+
let hadFlash = false;
|
|
413
|
+
if (this.options.flash) {
|
|
414
|
+
const flashData = await this.options.flash.store.read(ctx);
|
|
415
|
+
hadFlash = Object.keys(flashData).length > 0;
|
|
416
|
+
ctx.c.set("inertiaFlash", flashData);
|
|
417
|
+
} else ctx.c.set("inertiaFlash", {});
|
|
381
418
|
if (isInertia && ctx.c.req.method === "GET") {
|
|
382
419
|
const clientVersion = ctx.header("x-inertia-version");
|
|
383
420
|
const serverVersion = this.options.version ?? "";
|
|
@@ -388,6 +425,11 @@ let InertiaMiddleware = class InertiaMiddleware {
|
|
|
388
425
|
}
|
|
389
426
|
}
|
|
390
427
|
await next();
|
|
428
|
+
if (this.options.flash) {
|
|
429
|
+
const flashOut = ctx.c.get("inertiaFlashOut");
|
|
430
|
+
if (Object.keys(flashOut).length > 0) await this.options.flash.store.write(ctx, flashOut);
|
|
431
|
+
else if (hadFlash) await this.options.flash.store.clear(ctx);
|
|
432
|
+
}
|
|
391
433
|
ctx.c.header("Vary", "X-Inertia");
|
|
392
434
|
if (isInertia) {
|
|
393
435
|
const method = ctx.c.req.method;
|
|
@@ -405,6 +447,8 @@ InertiaMiddleware = __decorate([
|
|
|
405
447
|
const INERTIA_PROP_OPTIONAL = Symbol.for("stratal:inertia:prop:optional");
|
|
406
448
|
const INERTIA_PROP_DEFERRED = Symbol.for("stratal:inertia:prop:deferred");
|
|
407
449
|
const INERTIA_PROP_MERGE = Symbol.for("stratal:inertia:prop:merge");
|
|
450
|
+
const INERTIA_PROP_ONCE = Symbol.for("stratal:inertia:prop:once");
|
|
451
|
+
const INERTIA_PROP_ALWAYS = Symbol.for("stratal:inertia:prop:always");
|
|
408
452
|
//#endregion
|
|
409
453
|
//#region src/services/inertia.service.ts
|
|
410
454
|
let InertiaService = class InertiaService {
|
|
@@ -436,30 +480,63 @@ let InertiaService = class InertiaService {
|
|
|
436
480
|
group
|
|
437
481
|
};
|
|
438
482
|
}
|
|
439
|
-
merge(callback) {
|
|
483
|
+
merge(callback, options) {
|
|
440
484
|
return {
|
|
441
485
|
[INERTIA_PROP_MERGE]: true,
|
|
486
|
+
callback,
|
|
487
|
+
strategy: options?.strategy ?? "append",
|
|
488
|
+
matchOn: options?.matchOn
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
once(callback, options) {
|
|
492
|
+
return {
|
|
493
|
+
[INERTIA_PROP_ONCE]: true,
|
|
494
|
+
callback,
|
|
495
|
+
expiresAt: options?.expiresAt ?? null,
|
|
496
|
+
key: options?.key
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
always(callback) {
|
|
500
|
+
return {
|
|
501
|
+
[INERTIA_PROP_ALWAYS]: true,
|
|
442
502
|
callback
|
|
443
503
|
};
|
|
444
504
|
}
|
|
445
505
|
async render(ctx, component, props = {}, renderOptions = {}) {
|
|
446
|
-
const
|
|
506
|
+
const reqUrl = new URL(ctx.c.req.url);
|
|
507
|
+
const url = reqUrl.search ? `${reqUrl.pathname}${reqUrl.search}` : reqUrl.pathname;
|
|
447
508
|
const isInertia = ctx.c.get("inertia");
|
|
509
|
+
const { shared: resolvedShared, sharedKeys } = await this.resolveSharedData(ctx);
|
|
448
510
|
const allProps = {
|
|
449
|
-
...
|
|
511
|
+
...resolvedShared,
|
|
450
512
|
...this.sharedData,
|
|
451
513
|
...props
|
|
452
514
|
};
|
|
453
|
-
const
|
|
515
|
+
const allSharedKeys = [...sharedKeys, ...Object.keys(this.sharedData)];
|
|
516
|
+
const result = await this.processProps(allProps, ctx, component, isInertia);
|
|
517
|
+
const { errors: flashErrors, ...flash } = ctx.c.get("inertiaFlash") ?? {};
|
|
518
|
+
const errors = flashErrors && typeof flashErrors === "object" && !Array.isArray(flashErrors) ? flashErrors : {};
|
|
454
519
|
const page = {
|
|
455
520
|
component,
|
|
456
|
-
props:
|
|
521
|
+
props: {
|
|
522
|
+
...result.resolvedProps,
|
|
523
|
+
errors
|
|
524
|
+
},
|
|
457
525
|
url,
|
|
458
|
-
version: this.options.version ??
|
|
459
|
-
|
|
460
|
-
|
|
526
|
+
version: this.options.version ?? null,
|
|
527
|
+
flash,
|
|
528
|
+
rememberedState: {},
|
|
529
|
+
...result.mergeProps.length > 0 ? { mergeProps: result.mergeProps } : {},
|
|
530
|
+
...result.prependProps.length > 0 ? { prependProps: result.prependProps } : {},
|
|
531
|
+
...result.deepMergeProps.length > 0 ? { deepMergeProps: result.deepMergeProps } : {},
|
|
532
|
+
...result.matchPropsOn.length > 0 ? { matchPropsOn: result.matchPropsOn } : {},
|
|
533
|
+
...Object.keys(result.deferredProps).length > 0 ? { deferredProps: result.deferredProps } : {},
|
|
534
|
+
...Object.keys(result.deferredProps).length > 0 && !this.isPartialReload(ctx, component) ? { initialDeferredProps: result.deferredProps } : {},
|
|
535
|
+
...Object.keys(result.onceProps).length > 0 ? { onceProps: result.onceProps } : {},
|
|
536
|
+
...allSharedKeys.length > 0 ? { sharedProps: allSharedKeys } : {},
|
|
461
537
|
...renderOptions.encryptHistory ? { encryptHistory: true } : {},
|
|
462
|
-
...renderOptions.clearHistory ? { clearHistory: true } : {}
|
|
538
|
+
...renderOptions.clearHistory ? { clearHistory: true } : {},
|
|
539
|
+
...renderOptions.preserveFragment ? { preserveFragment: true } : {}
|
|
463
540
|
};
|
|
464
541
|
if (isInertia) return new Response(JSON.stringify(page), {
|
|
465
542
|
status: 200,
|
|
@@ -479,23 +556,71 @@ let InertiaService = class InertiaService {
|
|
|
479
556
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
480
557
|
});
|
|
481
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* Resolve shared data from module options and i18n configuration.
|
|
561
|
+
*
|
|
562
|
+
* Processes static values and resolver functions from `sharedData` config.
|
|
563
|
+
* When `i18n` option is set, auto-injects `locale` and `translations` props
|
|
564
|
+
* using the core {@link MessageLoaderService} resolved from the request container.
|
|
565
|
+
*/
|
|
482
566
|
async resolveSharedData(ctx) {
|
|
483
567
|
const shared = {};
|
|
484
568
|
const configShared = this.options.sharedData;
|
|
485
|
-
if (
|
|
486
|
-
for (const [key, value] of Object.entries(configShared)) if (typeof value === "function") shared[key] = await value(ctx);
|
|
569
|
+
if (configShared) for (const [key, value] of Object.entries(configShared)) if (typeof value === "function") shared[key] = await value(ctx);
|
|
487
570
|
else shared[key] = value;
|
|
488
|
-
|
|
571
|
+
if (this.options.i18n) {
|
|
572
|
+
const loader = ctx.getContainer().resolve(I18N_TOKENS.MessageLoader);
|
|
573
|
+
const locale = ctx.getLocale();
|
|
574
|
+
shared.locale = locale;
|
|
575
|
+
shared.translations = loader.getFilteredMessages(locale, { only: this.options.i18n.only });
|
|
576
|
+
}
|
|
577
|
+
if (this.options.routes) {
|
|
578
|
+
const registry = ctx.getContainer().resolve(ROUTER_TOKENS.RouteRegistry);
|
|
579
|
+
shared.routes = this.serializeRoutes(registry.named());
|
|
580
|
+
}
|
|
581
|
+
return {
|
|
582
|
+
shared,
|
|
583
|
+
sharedKeys: Object.keys(shared)
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
isPartialReload(ctx, component) {
|
|
587
|
+
const isInertia = ctx.c.get("inertia");
|
|
588
|
+
const partialComponent = ctx.header("x-inertia-partial-component");
|
|
589
|
+
const partialDataHeader = ctx.header("x-inertia-partial-data");
|
|
590
|
+
return !!(isInertia && partialComponent === component && partialDataHeader);
|
|
489
591
|
}
|
|
490
592
|
async processProps(allProps, ctx, component, isInertia) {
|
|
491
593
|
const resolvedProps = {};
|
|
492
594
|
const mergeProps = [];
|
|
595
|
+
const prependProps = [];
|
|
596
|
+
const deepMergeProps = [];
|
|
597
|
+
const matchPropsOn = [];
|
|
493
598
|
const deferredProps = {};
|
|
599
|
+
const onceProps = {};
|
|
494
600
|
const partialComponent = ctx.header("x-inertia-partial-component");
|
|
495
601
|
const partialDataHeader = ctx.header("x-inertia-partial-data");
|
|
602
|
+
const partialExceptHeader = ctx.header("x-inertia-partial-except");
|
|
603
|
+
const resetHeader = ctx.header("x-inertia-reset");
|
|
496
604
|
const isPartialReload = isInertia && partialComponent === component && partialDataHeader;
|
|
497
605
|
const requestedProps = partialDataHeader?.split(",").map((s) => s.trim()) ?? [];
|
|
606
|
+
const exceptProps = partialExceptHeader?.split(",").map((s) => s.trim()) ?? [];
|
|
607
|
+
resetHeader?.split(",").map((s) => s.trim());
|
|
498
608
|
for (const [key, value] of Object.entries(allProps)) {
|
|
609
|
+
if (this.isAlwaysProp(value)) {
|
|
610
|
+
resolvedProps[key] = await value.callback();
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
if (this.isOnceProp(value)) {
|
|
614
|
+
if (isPartialReload && this.isRequested(key, requestedProps)) resolvedProps[key] = await value.callback();
|
|
615
|
+
else if (!isPartialReload) {
|
|
616
|
+
resolvedProps[key] = await value.callback();
|
|
617
|
+
onceProps[key] = {
|
|
618
|
+
prop: value.key ?? key,
|
|
619
|
+
...value.expiresAt != null ? { expiresAt: value.expiresAt } : {}
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
499
624
|
if (this.isDeferredProp(value)) {
|
|
500
625
|
if (isPartialReload && this.isRequested(key, requestedProps)) resolvedProps[key] = await value.callback();
|
|
501
626
|
else if (!isPartialReload) {
|
|
@@ -506,7 +631,18 @@ let InertiaService = class InertiaService {
|
|
|
506
631
|
}
|
|
507
632
|
if (this.isMergeProp(value)) {
|
|
508
633
|
if (isPartialReload && !this.isRequested(key, requestedProps)) continue;
|
|
509
|
-
|
|
634
|
+
switch (value.strategy) {
|
|
635
|
+
case "prepend":
|
|
636
|
+
prependProps.push(key);
|
|
637
|
+
break;
|
|
638
|
+
case "deep":
|
|
639
|
+
deepMergeProps.push(key);
|
|
640
|
+
break;
|
|
641
|
+
default:
|
|
642
|
+
mergeProps.push(key);
|
|
643
|
+
break;
|
|
644
|
+
}
|
|
645
|
+
if (value.matchOn) matchPropsOn.push(`${key}:${value.matchOn}`);
|
|
510
646
|
resolvedProps[key] = await value.callback();
|
|
511
647
|
continue;
|
|
512
648
|
}
|
|
@@ -515,13 +651,17 @@ let InertiaService = class InertiaService {
|
|
|
515
651
|
continue;
|
|
516
652
|
}
|
|
517
653
|
if (isPartialReload) {
|
|
518
|
-
if (this.isRequested(key, requestedProps)) resolvedProps[key] = value;
|
|
654
|
+
if (this.isRequested(key, requestedProps) && !this.isExcepted(key, exceptProps)) resolvedProps[key] = value;
|
|
519
655
|
} else resolvedProps[key] = value;
|
|
520
656
|
}
|
|
521
657
|
return {
|
|
522
658
|
resolvedProps,
|
|
523
659
|
mergeProps,
|
|
524
|
-
|
|
660
|
+
prependProps,
|
|
661
|
+
deepMergeProps,
|
|
662
|
+
matchPropsOn,
|
|
663
|
+
deferredProps,
|
|
664
|
+
onceProps
|
|
525
665
|
};
|
|
526
666
|
}
|
|
527
667
|
/**
|
|
@@ -531,6 +671,9 @@ let InertiaService = class InertiaService {
|
|
|
531
671
|
isRequested(key, requestedProps) {
|
|
532
672
|
return requestedProps.some((prop) => prop === key || prop.startsWith(`${key}.`));
|
|
533
673
|
}
|
|
674
|
+
isExcepted(key, exceptProps) {
|
|
675
|
+
return exceptProps.some((prop) => prop === key || prop.startsWith(`${key}.`));
|
|
676
|
+
}
|
|
534
677
|
isOptionalProp(value) {
|
|
535
678
|
return typeof value === "object" && value !== null && INERTIA_PROP_OPTIONAL in value;
|
|
536
679
|
}
|
|
@@ -540,6 +683,23 @@ let InertiaService = class InertiaService {
|
|
|
540
683
|
isMergeProp(value) {
|
|
541
684
|
return typeof value === "object" && value !== null && INERTIA_PROP_MERGE in value;
|
|
542
685
|
}
|
|
686
|
+
isOnceProp(value) {
|
|
687
|
+
return typeof value === "object" && value !== null && INERTIA_PROP_ONCE in value;
|
|
688
|
+
}
|
|
689
|
+
isAlwaysProp(value) {
|
|
690
|
+
return typeof value === "object" && value !== null && INERTIA_PROP_ALWAYS in value;
|
|
691
|
+
}
|
|
692
|
+
serializeRoutes(routes) {
|
|
693
|
+
const serialized = {};
|
|
694
|
+
for (const route of routes) if (route.name) serialized[route.name] = {
|
|
695
|
+
path: route.path,
|
|
696
|
+
paramNames: route.paramNames,
|
|
697
|
+
domainParamNames: route.domainParamNames,
|
|
698
|
+
...route.domain ? { domain: route.domain } : {},
|
|
699
|
+
...route.localePaths?.length ? { localePaths: route.localePaths } : {}
|
|
700
|
+
};
|
|
701
|
+
return serialized;
|
|
702
|
+
}
|
|
543
703
|
isSsrDisabled(pathname) {
|
|
544
704
|
const patterns = this.options.ssr?.disabled;
|
|
545
705
|
if (!patterns || patterns.length === 0) return false;
|
|
@@ -550,7 +710,7 @@ let InertiaService = class InertiaService {
|
|
|
550
710
|
}
|
|
551
711
|
};
|
|
552
712
|
InertiaService = __decorate([
|
|
553
|
-
Transient(),
|
|
713
|
+
Transient(INERTIA_TOKENS.InertiaService),
|
|
554
714
|
__decorateParam(0, inject(INERTIA_TOKENS.Options)),
|
|
555
715
|
__decorateParam(1, inject(INERTIA_TOKENS.TemplateService)),
|
|
556
716
|
__decorateParam(2, inject(INERTIA_TOKENS.SsrRenderer)),
|
|
@@ -611,8 +771,9 @@ ManifestService = __decorate([
|
|
|
611
771
|
let SsrRendererService = class SsrRendererService {
|
|
612
772
|
bundle = null;
|
|
613
773
|
loadPromise = null;
|
|
614
|
-
constructor(options) {
|
|
774
|
+
constructor(options, logger) {
|
|
615
775
|
this.options = options;
|
|
776
|
+
this.logger = logger;
|
|
616
777
|
}
|
|
617
778
|
async render(page) {
|
|
618
779
|
if (!this.options.ssr) return {
|
|
@@ -637,8 +798,10 @@ let SsrRendererService = class SsrRendererService {
|
|
|
637
798
|
if (!this.options.ssr) return;
|
|
638
799
|
try {
|
|
639
800
|
const mod = await this.options.ssr.bundle();
|
|
640
|
-
|
|
641
|
-
|
|
801
|
+
const resolved = "default" in mod ? mod.default : mod;
|
|
802
|
+
this.bundle = resolved;
|
|
803
|
+
} catch (error) {
|
|
804
|
+
this.logger.warn("[stratal:inertia] Failed to load SSR bundle. Falling back to client-side rendering.", { error });
|
|
642
805
|
this.loadPromise = null;
|
|
643
806
|
}
|
|
644
807
|
}
|
|
@@ -646,7 +809,8 @@ let SsrRendererService = class SsrRendererService {
|
|
|
646
809
|
SsrRendererService = __decorate([
|
|
647
810
|
Transient(),
|
|
648
811
|
__decorateParam(0, inject(INERTIA_TOKENS.Options)),
|
|
649
|
-
|
|
812
|
+
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService)),
|
|
813
|
+
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
650
814
|
], SsrRendererService);
|
|
651
815
|
//#endregion
|
|
652
816
|
//#region src/services/template.service.ts
|
|
@@ -700,19 +864,86 @@ let InertiaModule = _InertiaModule = class InertiaModule {
|
|
|
700
864
|
}]
|
|
701
865
|
};
|
|
702
866
|
}
|
|
703
|
-
|
|
704
|
-
|
|
867
|
+
configureRoutes(router) {
|
|
868
|
+
router.use(InertiaMiddleware);
|
|
869
|
+
}
|
|
870
|
+
onException(handler) {
|
|
871
|
+
handler.renderable(SchemaValidationError, (error, context) => {
|
|
872
|
+
if (context.type !== "http") return void 0;
|
|
873
|
+
if (this.isPrecognitionRequest(context)) return this.handlePrecognitionValidationError(error, context);
|
|
874
|
+
if (!this.isInertiaRequest(context)) return void 0;
|
|
875
|
+
const issues = error.metadata?.issues ?? [];
|
|
876
|
+
const errors = {};
|
|
877
|
+
for (const issue of issues) errors[issue.path] = issue.message;
|
|
878
|
+
context.ctx.flash("errors", errors);
|
|
879
|
+
return this.redirectBack(context);
|
|
880
|
+
});
|
|
881
|
+
handler.renderable(ApplicationError, (error, context) => {
|
|
882
|
+
if (context.type !== "http") return void 0;
|
|
883
|
+
const message = context.ctx.getContainer().resolve(I18N_TOKENS.I18nService).t(error.message, error.metadata);
|
|
884
|
+
if (this.isPrecognitionRequest(context)) return this.createPrecognitionErrorResponse({ _form: message });
|
|
885
|
+
if (!this.isInertiaRequest(context)) return void 0;
|
|
886
|
+
context.ctx.flash("errors", { _form: message });
|
|
887
|
+
return this.redirectBack(context);
|
|
888
|
+
});
|
|
705
889
|
}
|
|
706
890
|
onInitialize() {
|
|
707
891
|
augmentRouterContext((ctx) => {
|
|
708
892
|
return ctx.getContainer().resolve(INERTIA_TOKENS.InertiaService);
|
|
709
893
|
});
|
|
710
894
|
}
|
|
895
|
+
isInertiaRequest(context) {
|
|
896
|
+
return context.ctx.header("x-inertia") === "true";
|
|
897
|
+
}
|
|
898
|
+
isPrecognitionRequest(context) {
|
|
899
|
+
return context.ctx.header("precognition") === "true";
|
|
900
|
+
}
|
|
901
|
+
handlePrecognitionValidationError(error, context) {
|
|
902
|
+
const issues = error.metadata?.issues ?? [];
|
|
903
|
+
let errors = {};
|
|
904
|
+
for (const issue of issues) errors[issue.path] = issue.message;
|
|
905
|
+
const validateOnly = context.ctx.header("precognition-validate-only");
|
|
906
|
+
if (validateOnly) {
|
|
907
|
+
const fields = validateOnly.split(",").map((f) => f.trim());
|
|
908
|
+
const filtered = {};
|
|
909
|
+
for (const field of fields) if (errors[field]) filtered[field] = errors[field];
|
|
910
|
+
errors = filtered;
|
|
911
|
+
}
|
|
912
|
+
if (Object.keys(errors).length === 0) return new Response(null, {
|
|
913
|
+
status: 204,
|
|
914
|
+
headers: {
|
|
915
|
+
"Precognition": "true",
|
|
916
|
+
"Precognition-Success": "true",
|
|
917
|
+
"Vary": "Precognition"
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
return this.createPrecognitionErrorResponse(errors);
|
|
921
|
+
}
|
|
922
|
+
createPrecognitionErrorResponse(errors) {
|
|
923
|
+
return new Response(JSON.stringify({ errors }), {
|
|
924
|
+
status: 422,
|
|
925
|
+
headers: {
|
|
926
|
+
"Content-Type": "application/json",
|
|
927
|
+
"Precognition": "true",
|
|
928
|
+
"Vary": "Precognition"
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
redirectBack(context) {
|
|
933
|
+
const referer = context.ctx.header("referer");
|
|
934
|
+
if (referer) {
|
|
935
|
+
const parsed = new URL(referer);
|
|
936
|
+
const url = parsed.search ? `${parsed.pathname}${parsed.search}` : parsed.pathname;
|
|
937
|
+
return context.ctx.redirect(url, 303);
|
|
938
|
+
}
|
|
939
|
+
return context.ctx.redirect("/", 303);
|
|
940
|
+
}
|
|
711
941
|
};
|
|
712
942
|
InertiaModule = _InertiaModule = __decorate([Module({ providers: [
|
|
713
943
|
{
|
|
714
944
|
provide: INERTIA_TOKENS.InertiaService,
|
|
715
|
-
useClass: InertiaService
|
|
945
|
+
useClass: InertiaService,
|
|
946
|
+
scope: Scope.Request
|
|
716
947
|
},
|
|
717
948
|
{
|
|
718
949
|
provide: INERTIA_TOKENS.TemplateService,
|
|
@@ -724,7 +955,8 @@ InertiaModule = _InertiaModule = __decorate([Module({ providers: [
|
|
|
724
955
|
},
|
|
725
956
|
{
|
|
726
957
|
provide: INERTIA_TOKENS.SsrRenderer,
|
|
727
|
-
useClass: SsrRendererService
|
|
958
|
+
useClass: SsrRendererService,
|
|
959
|
+
scope: Scope.Singleton
|
|
728
960
|
},
|
|
729
961
|
InertiaInstallCommand,
|
|
730
962
|
InertiaTypesCommand,
|
|
@@ -732,28 +964,85 @@ InertiaModule = _InertiaModule = __decorate([Module({ providers: [
|
|
|
732
964
|
InertiaBuildCommand
|
|
733
965
|
] })], InertiaModule);
|
|
734
966
|
//#endregion
|
|
735
|
-
//#region src/
|
|
967
|
+
//#region src/flash/cookie-flash-store.ts
|
|
968
|
+
var CookieFlashStore = class {
|
|
969
|
+
cookieName;
|
|
970
|
+
secret;
|
|
971
|
+
cookieOptions;
|
|
972
|
+
constructor(options) {
|
|
973
|
+
this.secret = options.secret;
|
|
974
|
+
this.cookieName = options.cookie ?? "stratal_flash";
|
|
975
|
+
this.cookieOptions = {
|
|
976
|
+
path: "/",
|
|
977
|
+
httpOnly: true,
|
|
978
|
+
sameSite: "Lax",
|
|
979
|
+
...options.cookieOptions
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
async read(ctx) {
|
|
983
|
+
const value = await getSignedCookie(ctx.c, this.secret, this.cookieName);
|
|
984
|
+
if (!value) return {};
|
|
985
|
+
try {
|
|
986
|
+
return JSON.parse(atob(value));
|
|
987
|
+
} catch {
|
|
988
|
+
return {};
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
async write(ctx, data) {
|
|
992
|
+
const encoded = btoa(JSON.stringify(data));
|
|
993
|
+
await setSignedCookie(ctx.c, this.cookieName, encoded, this.secret, this.cookieOptions);
|
|
994
|
+
}
|
|
995
|
+
clear(ctx) {
|
|
996
|
+
deleteCookie(ctx.c, this.cookieName, { path: this.cookieOptions.path });
|
|
997
|
+
return Promise.resolve();
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
const inertiaResponse = {
|
|
1001
|
+
schema: z.object({
|
|
1002
|
+
component: z.string(),
|
|
1003
|
+
props: z.record(z.string(), z.unknown()),
|
|
1004
|
+
url: z.string(),
|
|
1005
|
+
version: z.string().nullable(),
|
|
1006
|
+
flash: z.record(z.string(), z.unknown()),
|
|
1007
|
+
rememberedState: z.record(z.string(), z.unknown()),
|
|
1008
|
+
mergeProps: z.array(z.string()).optional(),
|
|
1009
|
+
prependProps: z.array(z.string()).optional(),
|
|
1010
|
+
deepMergeProps: z.array(z.string()).optional(),
|
|
1011
|
+
matchPropsOn: z.array(z.string()).optional(),
|
|
1012
|
+
deferredProps: z.record(z.string(), z.array(z.string())).optional(),
|
|
1013
|
+
initialDeferredProps: z.record(z.string(), z.array(z.string())).optional(),
|
|
1014
|
+
onceProps: z.record(z.string(), z.object({
|
|
1015
|
+
prop: z.string(),
|
|
1016
|
+
expiresAt: z.number().nullable().optional()
|
|
1017
|
+
})).optional(),
|
|
1018
|
+
sharedProps: z.array(z.string()).optional(),
|
|
1019
|
+
encryptHistory: z.boolean().optional(),
|
|
1020
|
+
clearHistory: z.boolean().optional(),
|
|
1021
|
+
preserveFragment: z.boolean().optional()
|
|
1022
|
+
}),
|
|
1023
|
+
description: "Inertia page response",
|
|
1024
|
+
contentType: "text/html"
|
|
1025
|
+
};
|
|
736
1026
|
/**
|
|
737
|
-
*
|
|
1027
|
+
* Builds a full RouteConfig from InertiaRouteConfig by applying inertia defaults.
|
|
738
1028
|
*/
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
clearHistory: z.boolean()
|
|
748
|
-
});
|
|
1029
|
+
function buildInertiaConfig(config) {
|
|
1030
|
+
const { hideFromDocs = true, ...rest } = config;
|
|
1031
|
+
return {
|
|
1032
|
+
...rest,
|
|
1033
|
+
response: inertiaResponse,
|
|
1034
|
+
hideFromDocs
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
749
1037
|
/**
|
|
750
|
-
* Decorator for Inertia page routes.
|
|
1038
|
+
* Decorator for Inertia page routes using convention-based routing.
|
|
751
1039
|
*
|
|
752
1040
|
* Wraps `@Route()` with:
|
|
753
1041
|
* - Auto-applied Inertia page response schema
|
|
754
1042
|
* - `hideFromDocs: true` by default (overridable)
|
|
755
1043
|
*
|
|
756
|
-
*
|
|
1044
|
+
* **Cannot be mixed with HTTP method decorators** (`@Get`, `@Post`, `@InertiaGet`, etc.)
|
|
1045
|
+
* in the same controller.
|
|
757
1046
|
*
|
|
758
1047
|
* @example
|
|
759
1048
|
* ```typescript
|
|
@@ -767,18 +1056,103 @@ const inertiaPageSchema = z.object({
|
|
|
767
1056
|
* ```
|
|
768
1057
|
*/
|
|
769
1058
|
function InertiaRoute(config = {}) {
|
|
770
|
-
|
|
771
|
-
return Route({
|
|
772
|
-
...rest,
|
|
773
|
-
response: {
|
|
774
|
-
schema: inertiaPageSchema,
|
|
775
|
-
description: "Inertia page response",
|
|
776
|
-
contentType: "text/html"
|
|
777
|
-
},
|
|
778
|
-
hideFromDocs
|
|
779
|
-
});
|
|
1059
|
+
return Route(buildInertiaConfig(config));
|
|
780
1060
|
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Registers a GET route for an Inertia page.
|
|
1063
|
+
*
|
|
1064
|
+
* Wraps `@Get()` with auto-applied Inertia page response schema
|
|
1065
|
+
* and `hideFromDocs: true` by default.
|
|
1066
|
+
*
|
|
1067
|
+
* @param path - Route path relative to the controller base path
|
|
1068
|
+
* @param config - Optional route configuration (query, params, tags, etc.)
|
|
1069
|
+
*
|
|
1070
|
+
* @example
|
|
1071
|
+
* ```typescript
|
|
1072
|
+
* @Controller('/notes')
|
|
1073
|
+
* export class NotesController {
|
|
1074
|
+
* @InertiaGet('/')
|
|
1075
|
+
* async index(ctx: RouterContext) {
|
|
1076
|
+
* return ctx.inertia('notes/Index', { notes: [] })
|
|
1077
|
+
* }
|
|
1078
|
+
*
|
|
1079
|
+
* @InertiaGet('/:id', { params: z.object({ id: z.string() }) })
|
|
1080
|
+
* async show(ctx: RouterContext) {
|
|
1081
|
+
* return ctx.inertia('notes/Show', { note })
|
|
1082
|
+
* }
|
|
1083
|
+
* }
|
|
1084
|
+
* ```
|
|
1085
|
+
*/
|
|
1086
|
+
function InertiaGet(path, config = {}) {
|
|
1087
|
+
return Get(path, buildInertiaConfig(config));
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Registers a POST route for an Inertia form submission.
|
|
1091
|
+
*
|
|
1092
|
+
* Wraps `@Post()` with auto-applied Inertia page response schema
|
|
1093
|
+
* and `hideFromDocs: true` by default.
|
|
1094
|
+
*
|
|
1095
|
+
* @param path - Route path relative to the controller base path
|
|
1096
|
+
* @param config - Optional route configuration (body, params, tags, etc.)
|
|
1097
|
+
*/
|
|
1098
|
+
function InertiaPost(path, config = {}) {
|
|
1099
|
+
return Post(path, buildInertiaConfig(config));
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* Registers a PUT route for an Inertia form submission.
|
|
1103
|
+
*
|
|
1104
|
+
* Wraps `@Put()` with auto-applied Inertia page response schema
|
|
1105
|
+
* and `hideFromDocs: true` by default.
|
|
1106
|
+
*
|
|
1107
|
+
* @param path - Route path relative to the controller base path
|
|
1108
|
+
* @param config - Optional route configuration (body, params, tags, etc.)
|
|
1109
|
+
*/
|
|
1110
|
+
function InertiaPut(path, config = {}) {
|
|
1111
|
+
return Put(path, buildInertiaConfig(config));
|
|
1112
|
+
}
|
|
1113
|
+
/**
|
|
1114
|
+
* Registers a PATCH route for an Inertia form submission.
|
|
1115
|
+
*
|
|
1116
|
+
* Wraps `@Patch()` with auto-applied Inertia page response schema
|
|
1117
|
+
* and `hideFromDocs: true` by default.
|
|
1118
|
+
*
|
|
1119
|
+
* @param path - Route path relative to the controller base path
|
|
1120
|
+
* @param config - Optional route configuration (body, params, tags, etc.)
|
|
1121
|
+
*/
|
|
1122
|
+
function InertiaPatch(path, config = {}) {
|
|
1123
|
+
return Patch(path, buildInertiaConfig(config));
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Registers a DELETE route for an Inertia form submission.
|
|
1127
|
+
*
|
|
1128
|
+
* Wraps `@Delete()` with auto-applied Inertia page response schema
|
|
1129
|
+
* and `hideFromDocs: true` by default.
|
|
1130
|
+
*
|
|
1131
|
+
* @param path - Route path relative to the controller base path
|
|
1132
|
+
* @param config - Optional route configuration (params, tags, etc.)
|
|
1133
|
+
*/
|
|
1134
|
+
function InertiaDelete(path, config = {}) {
|
|
1135
|
+
return Delete(path, buildInertiaConfig(config));
|
|
1136
|
+
}
|
|
1137
|
+
//#endregion
|
|
1138
|
+
//#region src/middleware/handle-precognitive-requests.middleware.ts
|
|
1139
|
+
let HandlePrecognitiveRequests = class HandlePrecognitiveRequests {
|
|
1140
|
+
async handle(ctx, next) {
|
|
1141
|
+
const isPrecognition = ctx.header("precognition") === "true";
|
|
1142
|
+
ctx.c.set("precognition", isPrecognition);
|
|
1143
|
+
if (isPrecognition) ctx.c.set("validationSuccessResponse", new Response(null, {
|
|
1144
|
+
status: 204,
|
|
1145
|
+
headers: {
|
|
1146
|
+
"Precognition": "true",
|
|
1147
|
+
"Precognition-Success": "true",
|
|
1148
|
+
"Vary": "Precognition"
|
|
1149
|
+
}
|
|
1150
|
+
}));
|
|
1151
|
+
await next();
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
HandlePrecognitiveRequests = __decorate([Transient()], HandlePrecognitiveRequests);
|
|
781
1155
|
//#endregion
|
|
782
|
-
export { INERTIA_TOKENS, InertiaBuildCommand, InertiaDevCommand, InertiaInstallCommand, InertiaMiddleware, InertiaModule, InertiaRoute, InertiaService, InertiaTypesCommand, ManifestService, SsrRendererService, TemplateService, runTypeGeneration };
|
|
1156
|
+
export { CookieFlashStore, HandlePrecognitiveRequests, INERTIA_TOKENS, InertiaBuildCommand, InertiaDelete, InertiaDevCommand, InertiaGet, InertiaInstallCommand, InertiaMiddleware, InertiaModule, InertiaPatch, InertiaPost, InertiaPut, InertiaRoute, InertiaService, InertiaTypesCommand, ManifestService, SsrRendererService, TemplateService, runTypeGeneration };
|
|
783
1157
|
|
|
784
1158
|
//# sourceMappingURL=index.mjs.map
|