@stratal/inertia 0.0.21 → 0.0.23
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/build-seo-tags-DBsHKxX9.mjs +123 -0
- package/dist/build-seo-tags-DBsHKxX9.mjs.map +1 -0
- package/dist/decorate-B7nr7eBl.mjs +9 -0
- package/dist/generator/type-generator.worker.mjs +1 -1
- package/dist/generator/type-generator.worker.mjs.map +1 -1
- package/dist/index.d.mts +177 -105
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +215 -389
- package/dist/index.mjs.map +1 -1
- package/dist/quarry.d.mts +45 -0
- package/dist/quarry.d.mts.map +1 -0
- package/dist/quarry.mjs +392 -0
- package/dist/quarry.mjs.map +1 -0
- package/dist/react.d.mts +12 -31
- package/dist/react.d.mts.map +1 -1
- package/dist/react.mjs +29 -48
- package/dist/react.mjs.map +1 -1
- package/dist/seo-runtime.d.mts +1 -0
- package/dist/seo-runtime.mjs +56 -0
- package/dist/seo-runtime.mjs.map +1 -0
- package/dist/testing.d.mts +1 -1
- package/dist/testing.mjs.map +1 -1
- package/dist/{type-generator-o_PxETTs.mjs → type-generator-DFpha_Fp.mjs} +237 -35
- package/dist/type-generator-DFpha_Fp.mjs.map +1 -0
- package/dist/types--_iJ04lT.d.mts +148 -0
- package/dist/types--_iJ04lT.d.mts.map +1 -0
- package/dist/vite.d.mts +19 -0
- package/dist/vite.d.mts.map +1 -1
- package/dist/vite.mjs +67 -8
- package/dist/vite.mjs.map +1 -1
- package/package.json +28 -25
- package/dist/type-generator-o_PxETTs.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { t as __decorate } from "./decorate-B7nr7eBl.mjs";
|
|
2
|
+
import { n as buildSeoTags, r as descriptorToHtml, t as DATA_SEO_ATTR } from "./build-seo-tags-DBsHKxX9.mjs";
|
|
3
3
|
import { ApplicationError } from "stratal/errors";
|
|
4
|
-
import { I18N_TOKENS } from "stratal/i18n";
|
|
5
4
|
import { Module } from "stratal/module";
|
|
6
|
-
import { Delete, Get, Patch, Post, Put, ROUTER_TOKENS, Route, RouterContext, SchemaValidationError } from "stratal/router";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { dirname, join, relative } from "node:path";
|
|
10
|
-
import { Command } from "stratal/quarry";
|
|
11
|
-
import { watch } from "node:fs/promises";
|
|
5
|
+
import { Delete, Get, Patch, Post, Put, ROUTER_TOKENS, Route, RouterContext, SchemaValidationError, applyTrailingSlash } from "stratal/router";
|
|
6
|
+
import { CONTAINER_TOKEN, DI_TOKENS, Request, Singleton, Transient, inject } from "stratal/di";
|
|
7
|
+
import { I18N_TOKENS } from "stratal/i18n";
|
|
12
8
|
import { LOGGER_TOKENS } from "stratal/logger";
|
|
13
9
|
import { deleteCookie, getSignedCookie, setSignedCookie } from "hono/cookie";
|
|
14
10
|
import { z } from "stratal/validation";
|
|
@@ -44,359 +40,35 @@ function augmentRouterContext(resolveService) {
|
|
|
44
40
|
const flashOut = this.c.get("inertiaFlashOut");
|
|
45
41
|
if (flashOut) flashOut[key] = value;
|
|
46
42
|
});
|
|
43
|
+
RouterContext.macro("share", function(key, value) {
|
|
44
|
+
resolveService(this).share(key, value);
|
|
45
|
+
});
|
|
46
|
+
RouterContext.macro("seo", function(data) {
|
|
47
|
+
resolveService(this).seo(data);
|
|
48
|
+
});
|
|
47
49
|
RouterContext.macro("withoutSsr", function() {
|
|
48
50
|
this.c.set("withoutSsr", true);
|
|
49
51
|
});
|
|
50
52
|
}
|
|
51
53
|
//#endregion
|
|
52
|
-
//#region src/vite/create-vite-config.ts
|
|
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;
|
|
89
|
-
}
|
|
90
|
-
//#endregion
|
|
91
|
-
//#region src/commands/inertia-build.command.ts
|
|
92
|
-
var InertiaBuildCommand = class extends Command {
|
|
93
|
-
static command = "inertia:build {--outDir=dist : Output directory} {--ssr : Also build SSR bundle}";
|
|
94
|
-
static description = "Build Inertia.js frontend for production";
|
|
95
|
-
async handle() {
|
|
96
|
-
const outDir = this.string("outDir") || "dist";
|
|
97
|
-
const shouldBuildSsr = this.boolean("ssr");
|
|
98
|
-
const cwd = process.cwd();
|
|
99
|
-
if (!existsSync(join(cwd, "src/inertia/app.tsx"))) {
|
|
100
|
-
this.fail("src/inertia/app.tsx not found. Run `quarry inertia:install` first.");
|
|
101
|
-
return 1;
|
|
102
|
-
}
|
|
103
|
-
const configPath = writeTempViteConfig({
|
|
104
|
-
cwd,
|
|
105
|
-
outDir
|
|
106
|
-
});
|
|
107
|
-
this.info("Building Inertia.js frontend for production...");
|
|
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;
|
|
120
|
-
}
|
|
121
|
-
this.success("SSR build complete!");
|
|
122
|
-
}
|
|
123
|
-
this.success(`Output in ${outDir}/`);
|
|
124
|
-
this.info("Deploy with: npx wrangler deploy");
|
|
125
|
-
return 0;
|
|
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
|
-
}
|
|
148
|
-
};
|
|
149
|
-
//#endregion
|
|
150
|
-
//#region src/commands/inertia-dev.command.ts
|
|
151
|
-
var InertiaDevCommand = class extends Command {
|
|
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.}";
|
|
153
|
-
static description = "Start Inertia.js Vite development server";
|
|
154
|
-
async handle() {
|
|
155
|
-
const port = this.number("port");
|
|
156
|
-
const host = this.boolean("host");
|
|
157
|
-
const persistTo = this.string("persist-to");
|
|
158
|
-
const cwd = process.cwd();
|
|
159
|
-
if (!existsSync(join(cwd, "src/inertia/app.tsx"))) {
|
|
160
|
-
this.fail("src/inertia/app.tsx not found. Run `quarry inertia:install` first.");
|
|
161
|
-
return 1;
|
|
162
|
-
}
|
|
163
|
-
const configPath = writeTempViteConfig({
|
|
164
|
-
cwd,
|
|
165
|
-
server: {
|
|
166
|
-
port,
|
|
167
|
-
host
|
|
168
|
-
},
|
|
169
|
-
persistTo
|
|
170
|
-
});
|
|
171
|
-
this.info("Starting Vite dev server...");
|
|
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, {
|
|
181
|
-
cwd,
|
|
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
|
-
});
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
//#endregion
|
|
196
|
-
//#region src/commands/inertia-install.command.ts
|
|
197
|
-
const ROOT_HTML = `<!DOCTYPE html>
|
|
198
|
-
<html lang="en">
|
|
199
|
-
<head>
|
|
200
|
-
<meta charset="utf-8" />
|
|
201
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
202
|
-
@viteHead
|
|
203
|
-
@inertiaHead
|
|
204
|
-
</head>
|
|
205
|
-
<body>
|
|
206
|
-
@inertia
|
|
207
|
-
@viteScripts
|
|
208
|
-
</body>
|
|
209
|
-
</html>`;
|
|
210
|
-
const APP_TSX = `import { createInertiaApp } from '@inertiajs/react'
|
|
211
|
-
|
|
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
|
-
})`;
|
|
220
|
-
const HOME_TSX = `export default function Home({ message }: { message: string }) {
|
|
221
|
-
return (
|
|
222
|
-
<div>
|
|
223
|
-
<h1>{message}</h1>
|
|
224
|
-
<p>This page is rendered with Inertia.js and Stratal.</p>
|
|
225
|
-
</div>
|
|
226
|
-
)
|
|
227
|
-
}`;
|
|
228
|
-
var InertiaInstallCommand = class extends Command {
|
|
229
|
-
static command = "inertia:install {--skip-deps : Skip installing npm dependencies}";
|
|
230
|
-
static description = "Scaffold Inertia.js files for a Stratal project";
|
|
231
|
-
async handle() {
|
|
232
|
-
const skipDeps = this.boolean("skip-deps");
|
|
233
|
-
const cwd = process.cwd();
|
|
234
|
-
const inertiaDir = join(cwd, "src", "inertia");
|
|
235
|
-
const pagesDir = join(inertiaDir, "pages");
|
|
236
|
-
this.info("Creating src/inertia/ directory...");
|
|
237
|
-
mkdirSync(pagesDir, { recursive: true });
|
|
238
|
-
const publicDir = join(inertiaDir, "public");
|
|
239
|
-
mkdirSync(publicDir, { recursive: true });
|
|
240
|
-
const gitkeepPath = join(publicDir, ".gitkeep");
|
|
241
|
-
if (!existsSync(gitkeepPath)) writeFileSync(gitkeepPath, "", "utf-8");
|
|
242
|
-
this.success("Created src/inertia/public/");
|
|
243
|
-
const files = [
|
|
244
|
-
{
|
|
245
|
-
path: join(inertiaDir, "root.html"),
|
|
246
|
-
content: ROOT_HTML,
|
|
247
|
-
name: "root.html"
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
path: join(inertiaDir, "app.tsx"),
|
|
251
|
-
content: APP_TSX,
|
|
252
|
-
name: "app.tsx"
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
path: join(pagesDir, "Home.tsx"),
|
|
256
|
-
content: HOME_TSX,
|
|
257
|
-
name: "pages/Home.tsx"
|
|
258
|
-
}
|
|
259
|
-
];
|
|
260
|
-
for (const file of files) if (existsSync(file.path)) this.warn(`Skipping ${file.name} (already exists)`);
|
|
261
|
-
else {
|
|
262
|
-
writeFileSync(file.path, file.content, "utf-8");
|
|
263
|
-
this.success(`Created src/inertia/${file.name}`);
|
|
264
|
-
}
|
|
265
|
-
const appModulePath = join(cwd, "src", "app.module.ts");
|
|
266
|
-
if (existsSync(appModulePath)) {
|
|
267
|
-
this.info("Updating src/app.module.ts...");
|
|
268
|
-
try {
|
|
269
|
-
if (await this.updateAppModule(appModulePath)) this.success("Updated src/app.module.ts with InertiaModule");
|
|
270
|
-
else this.info("InertiaModule already configured in app.module.ts");
|
|
271
|
-
} catch (err) {
|
|
272
|
-
this.warn(`Could not auto-update app.module.ts: ${err.message}`);
|
|
273
|
-
this.info("Please manually add InertiaModule.forRoot() to your module imports");
|
|
274
|
-
}
|
|
275
|
-
} else this.info("No src/app.module.ts found — please manually configure InertiaModule");
|
|
276
|
-
try {
|
|
277
|
-
const { outputPath, pageCount } = await runTypeGeneration(cwd);
|
|
278
|
-
const relPath = relative(cwd, outputPath);
|
|
279
|
-
this.success(`Generated ${relPath} (${pageCount} page${pageCount !== 1 ? "s" : ""})`);
|
|
280
|
-
} catch {
|
|
281
|
-
this.warn("Could not generate initial type definitions. Run `quarry inertia:types` manually.");
|
|
282
|
-
}
|
|
283
|
-
if (!skipDeps) {
|
|
284
|
-
this.newLine();
|
|
285
|
-
this.info("Install the following dependencies:");
|
|
286
|
-
this.line(" npm install @stratal/inertia @inertiajs/react @inertiajs/vite react react-dom");
|
|
287
|
-
this.line(" npm install -D @types/react @types/react-dom vite @cloudflare/vite-plugin");
|
|
288
|
-
}
|
|
289
|
-
this.newLine();
|
|
290
|
-
this.success("Inertia.js scaffolding complete!");
|
|
291
|
-
this.info("Run `quarry inertia:dev` to start the dev server");
|
|
292
|
-
return 0;
|
|
293
|
-
}
|
|
294
|
-
async updateAppModule(modulePath) {
|
|
295
|
-
const { Project, SyntaxKind } = await import("ts-morph");
|
|
296
|
-
const sourceFile = new Project({ useInMemoryFileSystem: false }).addSourceFileAtPath(modulePath);
|
|
297
|
-
if (sourceFile.getImportDeclaration((decl) => decl.getModuleSpecifierValue() === "@stratal/inertia")) return false;
|
|
298
|
-
sourceFile.addImportDeclaration({
|
|
299
|
-
defaultImport: "rootView",
|
|
300
|
-
moduleSpecifier: "./inertia/root.html?raw"
|
|
301
|
-
});
|
|
302
|
-
sourceFile.addImportDeclaration({
|
|
303
|
-
namedImports: ["InertiaModule"],
|
|
304
|
-
moduleSpecifier: "@stratal/inertia"
|
|
305
|
-
});
|
|
306
|
-
const classes = sourceFile.getClasses();
|
|
307
|
-
for (const cls of classes) {
|
|
308
|
-
const moduleDecorator = cls.getDecorator("Module");
|
|
309
|
-
if (!moduleDecorator) continue;
|
|
310
|
-
const args = moduleDecorator.getArguments();
|
|
311
|
-
if (args.length === 0) continue;
|
|
312
|
-
const objLiteral = args[0].asKind(SyntaxKind.ObjectLiteralExpression);
|
|
313
|
-
if (!objLiteral) continue;
|
|
314
|
-
const importsProp = objLiteral.getProperty("imports");
|
|
315
|
-
if (importsProp) {
|
|
316
|
-
const arrayLiteral = (importsProp.asKind(SyntaxKind.PropertyAssignment)?.getInitializer())?.asKind(SyntaxKind.ArrayLiteralExpression);
|
|
317
|
-
if (arrayLiteral) arrayLiteral.addElement(`InertiaModule.forRoot({\n rootView,\n })`);
|
|
318
|
-
} else objLiteral.addPropertyAssignment({
|
|
319
|
-
name: "imports",
|
|
320
|
-
initializer: `[\n InertiaModule.forRoot({\n rootView,\n }),\n ]`
|
|
321
|
-
});
|
|
322
|
-
break;
|
|
323
|
-
}
|
|
324
|
-
await sourceFile.save();
|
|
325
|
-
return true;
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
//#endregion
|
|
329
|
-
//#region src/commands/inertia-types.command.ts
|
|
330
|
-
var InertiaTypesCommand = class extends Command {
|
|
331
|
-
static command = "inertia:types {--watch : Watch for changes and regenerate}";
|
|
332
|
-
static description = "Generate Inertia.js page type definitions";
|
|
333
|
-
async handle() {
|
|
334
|
-
const cwd = process.cwd();
|
|
335
|
-
if (!existsSync(findPagesDir(cwd))) {
|
|
336
|
-
this.fail("src/inertia/pages/ not found. Run `quarry inertia:install` first.");
|
|
337
|
-
return 1;
|
|
338
|
-
}
|
|
339
|
-
if (!await this.generate(cwd)) return 1;
|
|
340
|
-
if (this.boolean("watch")) {
|
|
341
|
-
this.info("Watching for changes...");
|
|
342
|
-
await this.watchForChanges(cwd);
|
|
343
|
-
}
|
|
344
|
-
return 0;
|
|
345
|
-
}
|
|
346
|
-
async generate(cwd) {
|
|
347
|
-
try {
|
|
348
|
-
const { outputPath, pageCount } = await runTypeGeneration(cwd);
|
|
349
|
-
const relPath = relative(cwd, outputPath);
|
|
350
|
-
this.success(`Generated ${relPath} (${pageCount} page${pageCount !== 1 ? "s" : ""})`);
|
|
351
|
-
return true;
|
|
352
|
-
} catch (err) {
|
|
353
|
-
this.fail(`Type generation failed: ${err.message}`);
|
|
354
|
-
return false;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
async watchForChanges(cwd) {
|
|
358
|
-
const srcDir = join(cwd, "src");
|
|
359
|
-
try {
|
|
360
|
-
const watcher = watch(srcDir, { recursive: true });
|
|
361
|
-
for await (const event of watcher) if (event.filename && /\.(tsx|ts)$/.test(event.filename)) {
|
|
362
|
-
this.info(`Change detected: ${event.filename}`);
|
|
363
|
-
await this.generate(cwd);
|
|
364
|
-
}
|
|
365
|
-
} catch (err) {
|
|
366
|
-
this.fail(`Watch failed: ${err.message}`);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
//#endregion
|
|
371
54
|
//#region src/inertia.tokens.ts
|
|
372
55
|
const INERTIA_TOKENS = {
|
|
373
56
|
Options: Symbol.for("stratal:inertia:options"),
|
|
374
57
|
InertiaService: Symbol.for("stratal:inertia:service"),
|
|
375
58
|
TemplateService: Symbol.for("stratal:inertia:template"),
|
|
376
59
|
ManifestService: Symbol.for("stratal:inertia:manifest"),
|
|
377
|
-
SsrRenderer: Symbol.for("stratal:inertia:ssr-renderer")
|
|
60
|
+
SsrRenderer: Symbol.for("stratal:inertia:ssr-renderer"),
|
|
61
|
+
HreflangService: Symbol.for("stratal:inertia:hreflang"),
|
|
62
|
+
SeoService: Symbol.for("stratal:inertia:seo")
|
|
378
63
|
};
|
|
379
64
|
//#endregion
|
|
380
|
-
//#region \0@oxc-project+runtime@0.
|
|
381
|
-
function __decorateMetadata(k, v) {
|
|
382
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
383
|
-
}
|
|
384
|
-
//#endregion
|
|
385
|
-
//#region \0@oxc-project+runtime@0.129.0/helpers/decorateParam.js
|
|
65
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/decorateParam.js
|
|
386
66
|
function __decorateParam(paramIndex, decorator) {
|
|
387
67
|
return function(target, key) {
|
|
388
68
|
decorator(target, key, paramIndex);
|
|
389
69
|
};
|
|
390
70
|
}
|
|
391
71
|
//#endregion
|
|
392
|
-
//#region \0@oxc-project+runtime@0.129.0/helpers/decorate.js
|
|
393
|
-
function __decorate(decorators, target, key, desc) {
|
|
394
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
395
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
396
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
397
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
398
|
-
}
|
|
399
|
-
//#endregion
|
|
400
72
|
//#region src/middleware/inertia.middleware.ts
|
|
401
73
|
let InertiaMiddleware = class InertiaMiddleware {
|
|
402
74
|
options;
|
|
@@ -440,11 +112,61 @@ let InertiaMiddleware = class InertiaMiddleware {
|
|
|
440
112
|
}
|
|
441
113
|
}
|
|
442
114
|
};
|
|
443
|
-
InertiaMiddleware = __decorate([
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
115
|
+
InertiaMiddleware = __decorate([Transient(), __decorateParam(0, inject(INERTIA_TOKENS.Options))], InertiaMiddleware);
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/services/hreflang.service.ts
|
|
118
|
+
let HreflangService = class HreflangService {
|
|
119
|
+
container;
|
|
120
|
+
constructor(container) {
|
|
121
|
+
this.container = container;
|
|
122
|
+
}
|
|
123
|
+
buildLinks(currentUrl) {
|
|
124
|
+
const i18n = this.container.tryResolve(I18N_TOKENS.Options);
|
|
125
|
+
if (!i18n) return [];
|
|
126
|
+
const locales = i18n.locales ?? ["en"];
|
|
127
|
+
if (locales.length < 2) return [];
|
|
128
|
+
const defaultLocale = i18n.defaultLocale ?? "en";
|
|
129
|
+
const trailingSlash = this.container.resolve(DI_TOKENS.Application).config.trailingSlash ?? "ignore";
|
|
130
|
+
const localeUrl = this.container.resolve(ROUTER_TOKENS.LocaleUrlService);
|
|
131
|
+
if (localeUrl.pathEnabled) return this.buildPathLinks(currentUrl, locales, defaultLocale, localeUrl, trailingSlash);
|
|
132
|
+
if ((i18n.detection && "strategy" in i18n.detection ? i18n.detection.strategy : void 0) === "querystring") return this.buildQuerystringLinks(currentUrl, locales, defaultLocale, trailingSlash);
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
buildPathLinks(url, locales, defaultLocale, localeUrl, trailingSlash) {
|
|
136
|
+
const basePath = localeUrl.stripPrefix(url.pathname);
|
|
137
|
+
const links = locales.map((locale) => this.linkTag(locale, this.compose(url, localeUrl.applyPrefix(basePath, locale), url.search, trailingSlash)));
|
|
138
|
+
links.push(this.linkTag("x-default", this.compose(url, localeUrl.applyPrefix(basePath, defaultLocale), url.search, trailingSlash)));
|
|
139
|
+
return links;
|
|
140
|
+
}
|
|
141
|
+
buildQuerystringLinks(url, locales, defaultLocale, trailingSlash) {
|
|
142
|
+
const params = new URLSearchParams(url.search);
|
|
143
|
+
params.delete("locale");
|
|
144
|
+
const baseQs = params.toString();
|
|
145
|
+
const links = locales.map((locale) => {
|
|
146
|
+
const qs = this.composeQuery(baseQs, locale === defaultLocale ? null : ["locale", locale]);
|
|
147
|
+
return this.linkTag(locale, this.compose(url, url.pathname, qs, trailingSlash));
|
|
148
|
+
});
|
|
149
|
+
const xDefaultQs = baseQs ? `?${baseQs}` : "";
|
|
150
|
+
links.push(this.linkTag("x-default", this.compose(url, url.pathname, xDefaultQs, trailingSlash)));
|
|
151
|
+
return links;
|
|
152
|
+
}
|
|
153
|
+
compose(url, pathname, search, mode) {
|
|
154
|
+
return applyTrailingSlash(url.origin + pathname + search, mode);
|
|
155
|
+
}
|
|
156
|
+
composeQuery(baseQs, extra) {
|
|
157
|
+
if (!extra) return baseQs ? `?${baseQs}` : "";
|
|
158
|
+
const tail = `${extra[0]}=${encodeURIComponent(extra[1])}`;
|
|
159
|
+
return baseQs ? `?${baseQs}&${tail}` : `?${tail}`;
|
|
160
|
+
}
|
|
161
|
+
linkTag(hreflang, href) {
|
|
162
|
+
return {
|
|
163
|
+
rel: "alternate",
|
|
164
|
+
hreflang,
|
|
165
|
+
href
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
HreflangService = __decorate([Singleton(), __decorateParam(0, inject(CONTAINER_TOKEN))], HreflangService);
|
|
448
170
|
//#endregion
|
|
449
171
|
//#region src/types.ts
|
|
450
172
|
const INERTIA_PROP_OPTIONAL = Symbol.for("stratal:inertia:prop:optional");
|
|
@@ -458,15 +180,20 @@ let InertiaService = class InertiaService {
|
|
|
458
180
|
options;
|
|
459
181
|
template;
|
|
460
182
|
ssr;
|
|
183
|
+
seoService;
|
|
461
184
|
sharedData = {};
|
|
462
|
-
constructor(options, template, ssr) {
|
|
185
|
+
constructor(options, template, ssr, seoService) {
|
|
463
186
|
this.options = options;
|
|
464
187
|
this.template = template;
|
|
465
188
|
this.ssr = ssr;
|
|
189
|
+
this.seoService = seoService;
|
|
466
190
|
}
|
|
467
191
|
share(key, value) {
|
|
468
192
|
this.sharedData[key] = value;
|
|
469
193
|
}
|
|
194
|
+
seo(data) {
|
|
195
|
+
this.seoService.set(data);
|
|
196
|
+
}
|
|
470
197
|
location(url) {
|
|
471
198
|
return new Response("", {
|
|
472
199
|
status: 409,
|
|
@@ -513,12 +240,18 @@ let InertiaService = class InertiaService {
|
|
|
513
240
|
const url = reqUrl.search ? `${reqUrl.pathname}${reqUrl.search}` : reqUrl.pathname;
|
|
514
241
|
const isInertia = ctx.c.get("inertia");
|
|
515
242
|
const { shared: resolvedShared, sharedKeys } = await this.resolveSharedData(ctx);
|
|
243
|
+
const resolvedSeo = await this.seoService.resolve(ctx);
|
|
516
244
|
const allProps = {
|
|
517
245
|
...resolvedShared,
|
|
518
246
|
...this.sharedData,
|
|
247
|
+
seo: this.always(() => resolvedSeo),
|
|
519
248
|
...props
|
|
520
249
|
};
|
|
521
|
-
const allSharedKeys = [
|
|
250
|
+
const allSharedKeys = [
|
|
251
|
+
...sharedKeys,
|
|
252
|
+
...Object.keys(this.sharedData),
|
|
253
|
+
"seo"
|
|
254
|
+
];
|
|
522
255
|
const result = await this.processProps(allProps, ctx, component, isInertia);
|
|
523
256
|
const { errors: flashErrors, ...flash } = ctx.c.get("inertiaFlash") ?? {};
|
|
524
257
|
const errors = flashErrors && typeof flashErrors === "object" && !Array.isArray(flashErrors) ? flashErrors : {};
|
|
@@ -545,8 +278,9 @@ let InertiaService = class InertiaService {
|
|
|
545
278
|
...renderOptions.clearHistory ? { clearHistory: true } : {},
|
|
546
279
|
...renderOptions.preserveFragment ? { preserveFragment: true } : {}
|
|
547
280
|
};
|
|
281
|
+
const status = renderOptions.status ?? 200;
|
|
548
282
|
if (isInertia) return new Response(JSON.stringify(page), {
|
|
549
|
-
status
|
|
283
|
+
status,
|
|
550
284
|
headers: {
|
|
551
285
|
"Content-Type": "application/json",
|
|
552
286
|
"X-Inertia": "true",
|
|
@@ -557,9 +291,10 @@ let InertiaService = class InertiaService {
|
|
|
557
291
|
head: [],
|
|
558
292
|
body: ""
|
|
559
293
|
} : await this.ssr.render(page);
|
|
560
|
-
const
|
|
294
|
+
const seoTags = this.seoService.tagsFor(resolvedSeo);
|
|
295
|
+
const html = this.template.render(page, [...ssrResult.head, ...seoTags], ssrResult.body);
|
|
561
296
|
return new Response(html, {
|
|
562
|
-
status
|
|
297
|
+
status,
|
|
563
298
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
564
299
|
});
|
|
565
300
|
}
|
|
@@ -588,6 +323,7 @@ let InertiaService = class InertiaService {
|
|
|
588
323
|
const uri = container.resolve(ROUTER_TOKENS.Uri);
|
|
589
324
|
const name = registry.findNameByRoute(ctx.c.req.method, ctx.c.req.routePath) ?? null;
|
|
590
325
|
const params = { ...ctx.param() };
|
|
326
|
+
const localePathService = container.resolve(ROUTER_TOKENS.LocalePathService);
|
|
591
327
|
shared.routes = this.serializeRoutes(registry.named());
|
|
592
328
|
shared.trailingSlash = application.config.trailingSlash ?? "ignore";
|
|
593
329
|
shared.route = {
|
|
@@ -595,6 +331,10 @@ let InertiaService = class InertiaService {
|
|
|
595
331
|
params,
|
|
596
332
|
defaults: uri.getDefaults()
|
|
597
333
|
};
|
|
334
|
+
shared.localeConfig = {
|
|
335
|
+
defaultLocale: localePathService.localePathConfig?.defaultLocale ?? null,
|
|
336
|
+
prefixDefaultLocale: localePathService.prefixDefaultLocale
|
|
337
|
+
};
|
|
598
338
|
}
|
|
599
339
|
return {
|
|
600
340
|
shared,
|
|
@@ -619,6 +359,7 @@ let InertiaService = class InertiaService {
|
|
|
619
359
|
const partialDataHeader = ctx.header("x-inertia-partial-data");
|
|
620
360
|
const partialExceptHeader = ctx.header("x-inertia-partial-except");
|
|
621
361
|
const resetHeader = ctx.header("x-inertia-reset");
|
|
362
|
+
const shouldResolveDeferred = ctx.header("x-inertia-resolve-deferred") === "true";
|
|
622
363
|
const isPartialReload = isInertia && partialComponent === component && partialDataHeader;
|
|
623
364
|
const requestedProps = partialDataHeader?.split(",").map((s) => s.trim()) ?? [];
|
|
624
365
|
const exceptProps = partialExceptHeader?.split(",").map((s) => s.trim()) ?? [];
|
|
@@ -641,7 +382,8 @@ let InertiaService = class InertiaService {
|
|
|
641
382
|
}
|
|
642
383
|
if (this.isDeferredProp(value)) {
|
|
643
384
|
if (isPartialReload && this.isRequested(key, requestedProps)) resolvedProps[key] = await value.callback();
|
|
644
|
-
else if (!isPartialReload)
|
|
385
|
+
else if (!isPartialReload) if (shouldResolveDeferred) resolvedProps[key] = await value.callback();
|
|
386
|
+
else {
|
|
645
387
|
deferredProps[value.group] ??= [];
|
|
646
388
|
deferredProps[value.group].push(key);
|
|
647
389
|
}
|
|
@@ -728,15 +470,11 @@ let InertiaService = class InertiaService {
|
|
|
728
470
|
}
|
|
729
471
|
};
|
|
730
472
|
InertiaService = __decorate([
|
|
731
|
-
|
|
473
|
+
Request(INERTIA_TOKENS.InertiaService),
|
|
732
474
|
__decorateParam(0, inject(INERTIA_TOKENS.Options)),
|
|
733
475
|
__decorateParam(1, inject(INERTIA_TOKENS.TemplateService)),
|
|
734
476
|
__decorateParam(2, inject(INERTIA_TOKENS.SsrRenderer)),
|
|
735
|
-
|
|
736
|
-
Object,
|
|
737
|
-
Object,
|
|
738
|
-
Object
|
|
739
|
-
])
|
|
477
|
+
__decorateParam(3, inject(INERTIA_TOKENS.SeoService))
|
|
740
478
|
], InertiaService);
|
|
741
479
|
//#endregion
|
|
742
480
|
//#region src/services/manifest.service.ts
|
|
@@ -744,12 +482,11 @@ const DEFAULT_ENTRY_CLIENT_PATH = "src/inertia/app.tsx";
|
|
|
744
482
|
let ManifestService = class ManifestService {
|
|
745
483
|
manifest;
|
|
746
484
|
entryClientPath;
|
|
485
|
+
isDev = Boolean(import.meta.env.DEV);
|
|
747
486
|
constructor(options) {
|
|
748
|
-
this.manifest =
|
|
487
|
+
this.manifest = globalThis.__STRATAL_INERTIA_MANIFEST__ ?? null;
|
|
749
488
|
this.entryClientPath = (options.entryClientPath ?? DEFAULT_ENTRY_CLIENT_PATH).replace(/^\/+/, "");
|
|
750
|
-
|
|
751
|
-
get isDev() {
|
|
752
|
-
return this.manifest === null;
|
|
489
|
+
if (!this.isDev && !this.manifest) throw new Error("@stratal/inertia: production build is missing the Vite client manifest. This is wired by stratalInertia() in vite.config.ts — confirm it is in your plugin list and that the client environment built successfully before the worker environment.");
|
|
753
490
|
}
|
|
754
491
|
getHeadTags() {
|
|
755
492
|
if (this.isDev) return "<link rel=\"stylesheet\" href=\"/__inertia/ssr-css\" data-ssr-css />";
|
|
@@ -779,11 +516,71 @@ hot.on("vite:afterUpdate", () => {
|
|
|
779
516
|
return tags.join("\n");
|
|
780
517
|
}
|
|
781
518
|
};
|
|
782
|
-
ManifestService = __decorate([
|
|
783
|
-
|
|
519
|
+
ManifestService = __decorate([Transient(), __decorateParam(0, inject(INERTIA_TOKENS.Options))], ManifestService);
|
|
520
|
+
//#endregion
|
|
521
|
+
//#region src/services/seo.service.ts
|
|
522
|
+
let SeoService = class SeoService {
|
|
523
|
+
options;
|
|
524
|
+
hreflang;
|
|
525
|
+
accumulated = {};
|
|
526
|
+
constructor(options, hreflang) {
|
|
527
|
+
this.options = options;
|
|
528
|
+
this.hreflang = hreflang;
|
|
529
|
+
}
|
|
530
|
+
/** Merges the given metadata into the request's accumulated SEO data. */
|
|
531
|
+
set(data) {
|
|
532
|
+
this.accumulated = mergeSeo(this.accumulated, data);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Resolves the final SEO data: module defaults (base) merged with the
|
|
536
|
+
* request's accumulated data, then the title template applied. Resolver
|
|
537
|
+
* functions for `defaults`/`titleTemplate` are awaited with the request `ctx`.
|
|
538
|
+
* Locale-aware `hreflang` alternates are appended last so they ride the same
|
|
539
|
+
* head injection and SPA reconciliation as the rest of the SEO tags.
|
|
540
|
+
*
|
|
541
|
+
* The resolved `title` is ALWAYS a string (falling back to `''`). This makes
|
|
542
|
+
* the `<title>` descriptor deterministic: every navigation — including to a
|
|
543
|
+
* page with no SEO — produces a title, so the client head-sync sets
|
|
544
|
+
* `document.title` rather than leaving the previous page's title stale.
|
|
545
|
+
*/
|
|
546
|
+
async resolve(ctx) {
|
|
547
|
+
const seo = this.options.seo;
|
|
548
|
+
const resolved = mergeSeo(typeof seo?.defaults === "function" ? await seo.defaults(ctx) : seo?.defaults ?? {}, this.accumulated);
|
|
549
|
+
const template = seo?.titleTemplate;
|
|
550
|
+
if (typeof template === "function") resolved.title = await template(resolved.title, ctx);
|
|
551
|
+
else if (typeof template === "string" && this.accumulated.title != null) resolved.title = template.split("%s").join(this.accumulated.title);
|
|
552
|
+
resolved.title ??= "";
|
|
553
|
+
const hreflang = this.hreflang.buildLinks(new URL(ctx.c.req.url));
|
|
554
|
+
if (hreflang.length > 0) resolved.link = [...resolved.link ?? [], ...hreflang];
|
|
555
|
+
return resolved;
|
|
556
|
+
}
|
|
557
|
+
/** Renders resolved SEO data into a list of head-tag HTML strings. */
|
|
558
|
+
tagsFor(resolved) {
|
|
559
|
+
return buildSeoTags(resolved).map(descriptorToHtml);
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
SeoService = __decorate([
|
|
563
|
+
Request(INERTIA_TOKENS.SeoService),
|
|
784
564
|
__decorateParam(0, inject(INERTIA_TOKENS.Options)),
|
|
785
|
-
|
|
786
|
-
],
|
|
565
|
+
__decorateParam(1, inject(INERTIA_TOKENS.HreflangService))
|
|
566
|
+
], SeoService);
|
|
567
|
+
/** Merges `b` over `a`: `openGraph`/`twitter` shallow-merge, `meta`/`link` concat, scalars overwrite. */
|
|
568
|
+
function mergeSeo(a, b) {
|
|
569
|
+
return {
|
|
570
|
+
...a,
|
|
571
|
+
...b,
|
|
572
|
+
...a.openGraph || b.openGraph ? { openGraph: {
|
|
573
|
+
...a.openGraph,
|
|
574
|
+
...b.openGraph
|
|
575
|
+
} } : {},
|
|
576
|
+
...a.twitter || b.twitter ? { twitter: {
|
|
577
|
+
...a.twitter,
|
|
578
|
+
...b.twitter
|
|
579
|
+
} } : {},
|
|
580
|
+
...a.meta || b.meta ? { meta: [...a.meta ?? [], ...b.meta ?? []] } : {},
|
|
581
|
+
...a.link || b.link ? { link: [...a.link ?? [], ...b.link ?? []] } : {}
|
|
582
|
+
};
|
|
583
|
+
}
|
|
787
584
|
//#endregion
|
|
788
585
|
//#region src/services/ssr-renderer.service.ts
|
|
789
586
|
let SsrRendererService = class SsrRendererService {
|
|
@@ -827,10 +624,9 @@ let SsrRendererService = class SsrRendererService {
|
|
|
827
624
|
}
|
|
828
625
|
};
|
|
829
626
|
SsrRendererService = __decorate([
|
|
830
|
-
|
|
627
|
+
Singleton(),
|
|
831
628
|
__decorateParam(0, inject(INERTIA_TOKENS.Options)),
|
|
832
|
-
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService))
|
|
833
|
-
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
629
|
+
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService))
|
|
834
630
|
], SsrRendererService);
|
|
835
631
|
//#endregion
|
|
836
632
|
//#region src/services/template.service.ts
|
|
@@ -847,10 +643,10 @@ let TemplateService = class TemplateService {
|
|
|
847
643
|
const viteHead = this.manifest.getHeadTags();
|
|
848
644
|
const viteScripts = this.manifest.getScriptTags();
|
|
849
645
|
let html = this.options.rootView;
|
|
850
|
-
html = html.replace("@inertiaHead", headTags);
|
|
851
|
-
html = html.replace("@inertia", appHtml);
|
|
852
|
-
html = html.replace("@viteHead", viteHead);
|
|
853
|
-
html = html.replace("@viteScripts", viteScripts);
|
|
646
|
+
html = html.replace("@inertiaHead", () => headTags);
|
|
647
|
+
html = html.replace("@inertia", () => appHtml);
|
|
648
|
+
html = html.replace("@viteHead", () => viteHead);
|
|
649
|
+
html = html.replace("@viteScripts", () => viteScripts);
|
|
854
650
|
return html;
|
|
855
651
|
}
|
|
856
652
|
buildClientOnlyBody(page) {
|
|
@@ -860,8 +656,7 @@ let TemplateService = class TemplateService {
|
|
|
860
656
|
TemplateService = __decorate([
|
|
861
657
|
Transient(),
|
|
862
658
|
__decorateParam(0, inject(INERTIA_TOKENS.Options)),
|
|
863
|
-
__decorateParam(1, inject(INERTIA_TOKENS.ManifestService))
|
|
864
|
-
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
659
|
+
__decorateParam(1, inject(INERTIA_TOKENS.ManifestService))
|
|
865
660
|
], TemplateService);
|
|
866
661
|
//#endregion
|
|
867
662
|
//#region src/inertia.module.ts
|
|
@@ -894,7 +689,8 @@ let InertiaModule = _InertiaModule = class InertiaModule {
|
|
|
894
689
|
if (context.type !== "http") return void 0;
|
|
895
690
|
if (this.isPrecognitionRequest(context)) return this.handlePrecognitionValidationError(error, context);
|
|
896
691
|
if (!this.isInertiaRequest(context)) return void 0;
|
|
897
|
-
|
|
692
|
+
if (this.isReadRequest(context)) return void 0;
|
|
693
|
+
const issues = error.issues ?? [];
|
|
898
694
|
const errors = {};
|
|
899
695
|
for (const issue of issues) errors[issue.path] = issue.message;
|
|
900
696
|
context.ctx.flash("errors", errors);
|
|
@@ -902,12 +698,23 @@ let InertiaModule = _InertiaModule = class InertiaModule {
|
|
|
902
698
|
});
|
|
903
699
|
handler.renderable(ApplicationError, (error, context) => {
|
|
904
700
|
if (context.type !== "http") return void 0;
|
|
905
|
-
const message =
|
|
701
|
+
const message = error.message;
|
|
906
702
|
if (this.isPrecognitionRequest(context)) return this.createPrecognitionErrorResponse({ _form: message });
|
|
907
703
|
if (!this.isInertiaRequest(context)) return void 0;
|
|
704
|
+
if (this.isReadRequest(context)) return void 0;
|
|
908
705
|
context.ctx.flash("errors", { _form: message });
|
|
909
706
|
return this.redirectBack(context);
|
|
910
707
|
});
|
|
708
|
+
handler.errorPage(async (errorResponse, status, context) => {
|
|
709
|
+
try {
|
|
710
|
+
return await context.ctx.getContainer().resolve(INERTIA_TOKENS.InertiaService).render(context.ctx, `Errors/${status}`, {
|
|
711
|
+
status,
|
|
712
|
+
message: errorResponse.message
|
|
713
|
+
}, { status });
|
|
714
|
+
} catch {
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
});
|
|
911
718
|
}
|
|
912
719
|
onInitialize() {
|
|
913
720
|
augmentRouterContext((ctx) => {
|
|
@@ -917,11 +724,28 @@ let InertiaModule = _InertiaModule = class InertiaModule {
|
|
|
917
724
|
isInertiaRequest(context) {
|
|
918
725
|
return context.ctx.header("x-inertia") === "true";
|
|
919
726
|
}
|
|
727
|
+
/**
|
|
728
|
+
* GET/HEAD requests are idempotent navigations — including Inertia deferred
|
|
729
|
+
* partial reloads, which fetch deferred props over a follow-up XHR that still
|
|
730
|
+
* carries `X-Inertia: true`.
|
|
731
|
+
*
|
|
732
|
+
* Such requests must NOT use the flash-errors + redirect-back convention: the
|
|
733
|
+
* redirect points back at the very URL that just threw, so an error raised
|
|
734
|
+
* while resolving a deferred prop would redirect → re-request → throw again
|
|
735
|
+
* in an infinite loop (`ERR_TOO_MANY_REDIRECTS`). For these we fall through to
|
|
736
|
+
* the errorPage pipeline, which renders `Errors/${status}` in place as an
|
|
737
|
+
* Inertia response. Redirect-back stays for mutations (POST/PUT/PATCH/DELETE),
|
|
738
|
+
* where it drives the post-submit form-error flow.
|
|
739
|
+
*/
|
|
740
|
+
isReadRequest(context) {
|
|
741
|
+
const method = context.ctx.c.req.method.toUpperCase();
|
|
742
|
+
return method === "GET" || method === "HEAD";
|
|
743
|
+
}
|
|
920
744
|
isPrecognitionRequest(context) {
|
|
921
745
|
return context.ctx.header("precognition") === "true";
|
|
922
746
|
}
|
|
923
747
|
handlePrecognitionValidationError(error, context) {
|
|
924
|
-
const issues = error.
|
|
748
|
+
const issues = error.issues ?? [];
|
|
925
749
|
let errors = {};
|
|
926
750
|
for (const issue of issues) errors[issue.path] = issue.message;
|
|
927
751
|
const validateOnly = context.ctx.header("precognition-validate-only");
|
|
@@ -964,8 +788,7 @@ let InertiaModule = _InertiaModule = class InertiaModule {
|
|
|
964
788
|
InertiaModule = _InertiaModule = __decorate([Module({ providers: [
|
|
965
789
|
{
|
|
966
790
|
provide: INERTIA_TOKENS.InertiaService,
|
|
967
|
-
useClass: InertiaService
|
|
968
|
-
scope: Scope.Request
|
|
791
|
+
useClass: InertiaService
|
|
969
792
|
},
|
|
970
793
|
{
|
|
971
794
|
provide: INERTIA_TOKENS.TemplateService,
|
|
@@ -977,13 +800,16 @@ InertiaModule = _InertiaModule = __decorate([Module({ providers: [
|
|
|
977
800
|
},
|
|
978
801
|
{
|
|
979
802
|
provide: INERTIA_TOKENS.SsrRenderer,
|
|
980
|
-
useClass: SsrRendererService
|
|
981
|
-
|
|
803
|
+
useClass: SsrRendererService
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
provide: INERTIA_TOKENS.HreflangService,
|
|
807
|
+
useClass: HreflangService
|
|
982
808
|
},
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
809
|
+
{
|
|
810
|
+
provide: INERTIA_TOKENS.SeoService,
|
|
811
|
+
useClass: SeoService
|
|
812
|
+
}
|
|
987
813
|
] })], InertiaModule);
|
|
988
814
|
//#endregion
|
|
989
815
|
//#region src/flash/cookie-flash-store.ts
|
|
@@ -1175,6 +1001,6 @@ let HandlePrecognitiveRequests = class HandlePrecognitiveRequests {
|
|
|
1175
1001
|
};
|
|
1176
1002
|
HandlePrecognitiveRequests = __decorate([Transient()], HandlePrecognitiveRequests);
|
|
1177
1003
|
//#endregion
|
|
1178
|
-
export { CookieFlashStore, HandlePrecognitiveRequests, INERTIA_TOKENS,
|
|
1004
|
+
export { CookieFlashStore, DATA_SEO_ATTR, HandlePrecognitiveRequests, INERTIA_TOKENS, InertiaDelete, InertiaGet, InertiaMiddleware, InertiaModule, InertiaPatch, InertiaPost, InertiaPut, InertiaRoute, InertiaService, ManifestService, SeoService, SsrRendererService, TemplateService, buildSeoTags, descriptorToHtml };
|
|
1179
1005
|
|
|
1180
1006
|
//# sourceMappingURL=index.mjs.map
|