honertia 0.1.44 → 0.1.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -0
- package/dist/helpers.d.ts +9 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +14 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/test-utils.d.ts.map +1 -1
- package/dist/test-utils.js +5 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,6 +2,142 @@
|
|
|
2
2
|
|
|
3
3
|
Inertia.js adapter for Hono with Effect.ts. Server-driven app with SPA behavior.
|
|
4
4
|
|
|
5
|
+
## Why Honertia
|
|
6
|
+
|
|
7
|
+
Honertia brings the Laravel/Inertia productivity loop to Hono and Cloudflare Workers, with Effect powering the backend control flow instead of ad-hoc promises and unchecked exceptions.
|
|
8
|
+
|
|
9
|
+
- **Server-driven SPA pages on Hono**: Render Inertia-style pages from Hono routes while keeping React/Vite on the client and Worker-friendly request handling on the server.
|
|
10
|
+
- **Effect-native route handlers**: Write actions as typed Effect programs with explicit services, structured failures, redirects, validation errors, and testable dependency layers.
|
|
11
|
+
- **One setup path for real apps**: `setupHonertia()` wires the Inertia middleware, database, auth, shared page props, user loading, and per-request Effect runtime in the right order.
|
|
12
|
+
- **Laravel-style route model binding**: Use paths like `/projects/{project}` or `/users/{user}/posts/{post}` and access resolved models with `yield* bound('project')`, backed by your Drizzle schema.
|
|
13
|
+
- **Safe mutation boundaries**: `validateRequest`, scoped `dbMutation`, and `dbTransaction` make writes explicit and keep unvalidated request data out of database mutations.
|
|
14
|
+
- **Auth built in, not bolted on**: Better Auth helpers cover authenticated routes, guest-only routes, form actions, typed `authorize()`, session loading, and shared auth props.
|
|
15
|
+
- **Effect-aware cache wrapper**: Cache expensive reads with schema-checked serialization, TTLs, stale-while-revalidate, and Worker `waitUntil` background refreshes.
|
|
16
|
+
- **Agent-friendly CLI**: Generate actions, CRUD routes, features, OpenAPI specs, route listings, project checks, and migration previews from a single `honertia` binary.
|
|
17
|
+
- **Production observability hooks**: Structured errors and `EffectErrorObserverService` provide a single integration point for Sentry, PostHog, or any Effect-aware reporting pipeline.
|
|
18
|
+
|
|
19
|
+
Demo Worker: [PatrickOgilvie/honertia-worker-demo](https://github.com/PatrickOgilvie/honertia-worker-demo)
|
|
20
|
+
|
|
21
|
+
One-click demo deploy:
|
|
22
|
+
|
|
23
|
+
[](https://deploy.workers.cloudflare.com/?url=https://github.com/PatrickOgilvie/honertia-worker-demo)
|
|
24
|
+
|
|
25
|
+
## Laravel-Style Helpers
|
|
26
|
+
|
|
27
|
+
Honertia keeps common app code small and expressive. The helpers are Effect-native, but the shape should feel familiar if you like Laravel controllers, form requests, redirects, cache wrappers, and route model binding.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { effectRoutes } from 'honertia/effect'
|
|
31
|
+
import { indexProjects, showProject, updateProject } from './actions/projects'
|
|
32
|
+
|
|
33
|
+
effectRoutes(app)
|
|
34
|
+
.get('/projects', indexProjects, { name: 'projects.index' })
|
|
35
|
+
.get('/projects/{project}', showProject, { name: 'projects.show' })
|
|
36
|
+
.put('/projects/{project}', updateProject, { name: 'projects.update' })
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { Effect } from 'effect'
|
|
41
|
+
import { action, authorize, bound, render } from 'honertia/effect'
|
|
42
|
+
|
|
43
|
+
export const showProject = action(
|
|
44
|
+
Effect.gen(function* () {
|
|
45
|
+
const project = yield* bound('project')
|
|
46
|
+
yield* authorize((auth) => auth.user.id === project.userId)
|
|
47
|
+
|
|
48
|
+
return yield* render('Projects/Show', { project })
|
|
49
|
+
})
|
|
50
|
+
)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { Effect, Schema as S, Duration } from 'effect'
|
|
55
|
+
import { action, authorize, DatabaseService, render } from 'honertia/effect'
|
|
56
|
+
import { cache } from 'honertia/cache'
|
|
57
|
+
import { eq } from 'drizzle-orm'
|
|
58
|
+
import { projects } from '~/db/schema'
|
|
59
|
+
|
|
60
|
+
const ProjectSummary = S.Struct({
|
|
61
|
+
id: S.String,
|
|
62
|
+
name: S.String,
|
|
63
|
+
updatedAt: S.Date,
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
export const indexProjects = action(
|
|
67
|
+
Effect.gen(function* () {
|
|
68
|
+
const auth = yield* authorize()
|
|
69
|
+
const db = yield* DatabaseService
|
|
70
|
+
|
|
71
|
+
const userProjects = yield* cache(
|
|
72
|
+
`users:${auth.user.id}:projects`,
|
|
73
|
+
Effect.tryPromise(() =>
|
|
74
|
+
db.query.projects.findMany({
|
|
75
|
+
columns: { id: true, name: true, updatedAt: true },
|
|
76
|
+
where: eq(projects.userId, auth.user.id),
|
|
77
|
+
orderBy: (project, { desc }) => [desc(project.updatedAt)],
|
|
78
|
+
})
|
|
79
|
+
),
|
|
80
|
+
S.Array(ProjectSummary),
|
|
81
|
+
{ ttl: Duration.minutes(5), swr: Duration.minutes(1), version: true }
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return yield* render('Projects/Index', { projects: userProjects })
|
|
85
|
+
})
|
|
86
|
+
)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { Effect, Schema as S } from 'effect'
|
|
91
|
+
import {
|
|
92
|
+
action,
|
|
93
|
+
authorize,
|
|
94
|
+
bound,
|
|
95
|
+
validateRequest,
|
|
96
|
+
DatabaseService,
|
|
97
|
+
dbMutation,
|
|
98
|
+
redirect,
|
|
99
|
+
requiredString,
|
|
100
|
+
} from 'honertia/effect'
|
|
101
|
+
import { eq } from 'drizzle-orm'
|
|
102
|
+
import { projects } from '~/db/schema'
|
|
103
|
+
|
|
104
|
+
const UpdateProject = S.Struct({
|
|
105
|
+
name: requiredString,
|
|
106
|
+
description: S.optional(S.String),
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
export const updateProject = action(
|
|
110
|
+
Effect.gen(function* () {
|
|
111
|
+
const project = yield* bound('project')
|
|
112
|
+
yield* authorize((auth) => auth.user.id === project.userId)
|
|
113
|
+
|
|
114
|
+
const input = yield* validateRequest(UpdateProject, {
|
|
115
|
+
errorComponent: 'Projects/Edit',
|
|
116
|
+
})
|
|
117
|
+
const db = yield* DatabaseService
|
|
118
|
+
|
|
119
|
+
yield* dbMutation(db, input, async (tx, input) => {
|
|
120
|
+
await tx
|
|
121
|
+
.update(projects)
|
|
122
|
+
.set(input)
|
|
123
|
+
.where(eq(projects.id, project.id))
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
return yield* redirect(`/projects/${project.id}`)
|
|
127
|
+
})
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { render, redirect, notFound, forbidden, jsonOrRender } from 'honertia/effect'
|
|
133
|
+
|
|
134
|
+
return yield* render('Dashboard', { stats })
|
|
135
|
+
return yield* redirect('/login')
|
|
136
|
+
return yield* notFound('Project', projectId)
|
|
137
|
+
return yield* forbidden('You cannot edit this project')
|
|
138
|
+
return yield* jsonOrRender('Projects/Index', { projects })
|
|
139
|
+
```
|
|
140
|
+
|
|
5
141
|
## CLI Commands
|
|
6
142
|
|
|
7
143
|
`honertia` is shipped as a package binary. You can run commands with:
|
|
@@ -372,6 +508,15 @@ registerErrorHandlers(app)
|
|
|
372
508
|
export default app
|
|
373
509
|
```
|
|
374
510
|
|
|
511
|
+
`createTemplate()` emits Inertia's script-element initial page payload:
|
|
512
|
+
|
|
513
|
+
```html
|
|
514
|
+
<script data-page="app" type="application/json">...</script>
|
|
515
|
+
<div id="app"></div>
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
If you provide a custom template renderer, use `serializePage(page)` from `honertia` for the JSON script body so `</script>` sequences inside props cannot close the element early.
|
|
519
|
+
|
|
375
520
|
### 6. src/routes.ts (REQUIRED)
|
|
376
521
|
|
|
377
522
|
Route definitions.
|
package/dist/helpers.d.ts
CHANGED
|
@@ -19,6 +19,15 @@ export interface TemplateOptions {
|
|
|
19
19
|
head?: string;
|
|
20
20
|
rootId?: string;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Serialize an Inertia page object for embedding in a
|
|
24
|
+
* `<script type="application/json">` initial page payload.
|
|
25
|
+
*
|
|
26
|
+
* Escaping `/` prevents a `</script>` sequence inside JSON data from closing
|
|
27
|
+
* the script element early. This mirrors the approach used by @hono/inertia
|
|
28
|
+
* and Inertia's script-element initial page transport.
|
|
29
|
+
*/
|
|
30
|
+
export declare function serializePage(page: PageObject): string;
|
|
22
31
|
/**
|
|
23
32
|
* Creates a template renderer function.
|
|
24
33
|
*
|
package/dist/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAAC,CAAA;AAEvE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,eAAe,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,eAAe,CAAC,GAC7D,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAAC,CAAA;AAEvE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,eAAe,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,eAAe,CAAC,GAC7D,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,MAAM,CA6C7C;AAWD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CA8B7D;AAED;;GAEG;AACH,eAAO,MAAM,IAAI;IACf;;;;;;;;OAQG;4BACmB,MAAM;IAa5B;;;;;;;;;OASG;2CAC2C,MAAM;CAGrD,CAAA"}
|
package/dist/helpers.js
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
* Honertia Helpers
|
|
3
3
|
*/
|
|
4
4
|
import { HonertiaConfigurationError } from './effect/errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Serialize an Inertia page object for embedding in a
|
|
7
|
+
* `<script type="application/json">` initial page payload.
|
|
8
|
+
*
|
|
9
|
+
* Escaping `/` prevents a `</script>` sequence inside JSON data from closing
|
|
10
|
+
* the script element early. This mirrors the approach used by @hono/inertia
|
|
11
|
+
* and Inertia's script-element initial page transport.
|
|
12
|
+
*/
|
|
13
|
+
export function serializePage(page) {
|
|
14
|
+
return JSON.stringify(page).replace(/\//g, '\\/');
|
|
15
|
+
}
|
|
5
16
|
/**
|
|
6
17
|
* Creates a template renderer function.
|
|
7
18
|
*
|
|
@@ -47,11 +58,7 @@ export function createTemplate(options) {
|
|
|
47
58
|
const styleTags = styles
|
|
48
59
|
.map(href => `<link rel="stylesheet" href="${escapeHtml(href)}">`)
|
|
49
60
|
.join('\n ');
|
|
50
|
-
const pageJson =
|
|
51
|
-
.replace(/</g, '\\u003c')
|
|
52
|
-
.replace(/>/g, '\\u003e')
|
|
53
|
-
.replace(/&/g, '\\u0026')
|
|
54
|
-
.replace(/'/g, '\\u0027');
|
|
61
|
+
const pageJson = serializePage(page);
|
|
55
62
|
return `<!DOCTYPE html>
|
|
56
63
|
<html lang="en">
|
|
57
64
|
<head>
|
|
@@ -62,7 +69,8 @@ export function createTemplate(options) {
|
|
|
62
69
|
${head}
|
|
63
70
|
</head>
|
|
64
71
|
<body>
|
|
65
|
-
<
|
|
72
|
+
<script data-page="${escapeHtml(rootId)}" type="application/json">${pageJson}</script>
|
|
73
|
+
<div id="${escapeHtml(rootId)}"></div>
|
|
66
74
|
${scriptTags}
|
|
67
75
|
</body>
|
|
68
76
|
</html>`;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
export { setupHonertia, createErrorHandlers, registerErrorHandlers, type HonertiaSetupConfig, type HonertiaFullConfig, type ErrorHandlerConfig, } from './setup.js';
|
|
10
10
|
export { honertia, HEADERS } from './middleware.js';
|
|
11
11
|
export type { PageObject, HonertiaConfig, HonertiaInstance, RenderOptions, } from './types.js';
|
|
12
|
-
export { createTemplate, createVersion, vite, type PageProps, } from './helpers.js';
|
|
12
|
+
export { createTemplate, createVersion, serializePage, vite, type PageProps, } from './helpers.js';
|
|
13
13
|
export * from './effect/index.js';
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,cAAc,EACd,aAAa,EACb,IAAI,EACJ,KAAK,SAAS,GACf,MAAM,cAAc,CAAA;AAOrB,cAAc,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,cAAc,EACd,aAAa,EACb,aAAa,EACb,IAAI,EACJ,KAAK,SAAS,GACf,MAAM,cAAc,CAAA;AAOrB,cAAc,mBAAmB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ export { setupHonertia, createErrorHandlers, registerErrorHandlers, } from './se
|
|
|
14
14
|
// Core middleware (for manual setup)
|
|
15
15
|
export { honertia, HEADERS } from './middleware.js';
|
|
16
16
|
// Helpers
|
|
17
|
-
export { createTemplate, createVersion, vite, } from './helpers.js';
|
|
17
|
+
export { createTemplate, createVersion, serializePage, vite, } from './helpers.js';
|
|
18
18
|
// =============================================================================
|
|
19
19
|
// Re-exports for convenience (deprecated - use subpath imports instead)
|
|
20
20
|
// =============================================================================
|
package/dist/test-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,YAAY,CAAA;AAM5D,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAA;IACjC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACxD;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;CACvB;AAED,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,cAAmB,8EAkBzD;AAMD;;GAEG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAuB,gCASjC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,qBAA0B,gCAsCpC;AAMD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAG7E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAWjF;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,QAalD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,QAS/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,EAAE,gBAAgB,CAAC,EAAE,MAAM,QAa7E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,QAY/E;AAMD,eAAO,MAAM,SAAS;;;;GAIrB,CAAA;AAED,eAAO,MAAM,YAAY;;;;GAGxB,CAAA;AAED,eAAO,MAAM,UAAU;;;CAGtB,CAAA;AAMD,eAAO,MAAM,eAAe;;;;;;;;;;;CAW3B,CAAA;AAMD;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,SAAI,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,CAOnE;AAMD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7C,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,KAAK,EAAE,MAAM,MAAM,CAAA;CACpB;AAED,wBAAgB,oBAAoB,IAAI,cAAc,CAerD"}
|
package/dist/test-utils.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { Hono } from 'hono';
|
|
8
8
|
import { honertia, HEADERS } from './middleware.js';
|
|
9
|
+
import { serializePage } from './helpers.js';
|
|
9
10
|
// =============================================================================
|
|
10
11
|
// App Factory
|
|
11
12
|
// =============================================================================
|
|
@@ -13,7 +14,7 @@ import { honertia, HEADERS } from './middleware.js';
|
|
|
13
14
|
* Creates a test Hono app with honertia middleware configured
|
|
14
15
|
*/
|
|
15
16
|
export function createTestApp(options = {}) {
|
|
16
|
-
const { version = '1.0.0', render = (page) => `<!DOCTYPE html><html><body><
|
|
17
|
+
const { version = '1.0.0', render = (page) => `<!DOCTYPE html><html><body><script data-page="app" type="application/json">${serializePage(page)}</script><div id="app"></div></body></html>`, } = options;
|
|
17
18
|
const app = new Hono();
|
|
18
19
|
app.use('*', honertia({
|
|
19
20
|
version,
|
|
@@ -77,9 +78,9 @@ export async function parseInertiaResponse(res) {
|
|
|
77
78
|
*/
|
|
78
79
|
export async function parseHtmlResponse(res) {
|
|
79
80
|
const html = await res.text();
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
return JSON.parse(
|
|
81
|
+
const scriptMatch = html.match(/<script\s+data-page="[^"]+"\s+type="application\/json">([\s\S]*?)<\/script>/);
|
|
82
|
+
if (scriptMatch) {
|
|
83
|
+
return JSON.parse(scriptMatch[1]);
|
|
83
84
|
}
|
|
84
85
|
return null;
|
|
85
86
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "honertia",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45",
|
|
4
4
|
"description": "Inertia.js-style server-driven SPA adapter for Hono",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"bin": {
|
|
10
|
-
"honertia": "
|
|
10
|
+
"honertia": "dist/cli/bin.js"
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"license": "MIT",
|
|
65
65
|
"repository": {
|
|
66
66
|
"type": "git",
|
|
67
|
-
"url": "https://github.com/patrickogilvie/honertia"
|
|
67
|
+
"url": "git+https://github.com/patrickogilvie/honertia.git"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"effect": "^3.12.0"
|