@voyant-travel/hono 0.109.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +58 -0
- package/dist/app-workflows.d.ts +31 -0
- package/dist/app-workflows.d.ts.map +1 -0
- package/dist/app-workflows.js +110 -0
- package/dist/app.d.ts +45 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +403 -0
- package/dist/auth/crypto.d.ts +16 -0
- package/dist/auth/crypto.d.ts.map +1 -0
- package/dist/auth/crypto.js +66 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +3 -0
- package/dist/auth/require-user.d.ts +3 -0
- package/dist/auth/require-user.d.ts.map +1 -0
- package/dist/auth/require-user.js +8 -0
- package/dist/auth/session-jwt.d.ts +7 -0
- package/dist/auth/session-jwt.d.ts.map +1 -0
- package/dist/auth/session-jwt.js +23 -0
- package/dist/composition.d.ts +67 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js +46 -0
- package/dist/document-download.d.ts +30 -0
- package/dist/document-download.d.ts.map +1 -0
- package/dist/document-download.js +102 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/lib/db-selector.d.ts +24 -0
- package/dist/lib/db-selector.d.ts.map +1 -0
- package/dist/lib/db-selector.js +28 -0
- package/dist/lib/execution-ctx.d.ts +16 -0
- package/dist/lib/execution-ctx.d.ts.map +1 -0
- package/dist/lib/execution-ctx.js +16 -0
- package/dist/lib/public-paths.d.ts +19 -0
- package/dist/lib/public-paths.d.ts.map +1 -0
- package/dist/lib/public-paths.js +27 -0
- package/dist/lib/request-event-bus.d.ts +21 -0
- package/dist/lib/request-event-bus.d.ts.map +1 -0
- package/dist/lib/request-event-bus.js +43 -0
- package/dist/middleware/auth.d.ts +10 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +280 -0
- package/dist/middleware/body-size.d.ts +7 -0
- package/dist/middleware/body-size.d.ts.map +1 -0
- package/dist/middleware/body-size.js +20 -0
- package/dist/middleware/cors.d.ts +6 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +94 -0
- package/dist/middleware/db.d.ts +43 -0
- package/dist/middleware/db.d.ts.map +1 -0
- package/dist/middleware/db.js +78 -0
- package/dist/middleware/error-boundary.d.ts +5 -0
- package/dist/middleware/error-boundary.d.ts.map +1 -0
- package/dist/middleware/error-boundary.js +76 -0
- package/dist/middleware/idempotency-key.d.ts +97 -0
- package/dist/middleware/idempotency-key.d.ts.map +1 -0
- package/dist/middleware/idempotency-key.js +235 -0
- package/dist/middleware/index.d.ts +14 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +13 -0
- package/dist/middleware/logger.d.ts +5 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +27 -0
- package/dist/middleware/metrics.d.ts +55 -0
- package/dist/middleware/metrics.d.ts.map +1 -0
- package/dist/middleware/metrics.js +94 -0
- package/dist/middleware/public-cache.d.ts +44 -0
- package/dist/middleware/public-cache.d.ts.map +1 -0
- package/dist/middleware/public-cache.js +205 -0
- package/dist/middleware/rate-limit.d.ts +214 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +240 -0
- package/dist/middleware/request-db.d.ts +42 -0
- package/dist/middleware/request-db.d.ts.map +1 -0
- package/dist/middleware/request-db.js +62 -0
- package/dist/middleware/require-actor.d.ts +28 -0
- package/dist/middleware/require-actor.d.ts.map +1 -0
- package/dist/middleware/require-actor.js +89 -0
- package/dist/middleware/require-permission.d.ts +9 -0
- package/dist/middleware/require-permission.d.ts.map +1 -0
- package/dist/middleware/require-permission.js +62 -0
- package/dist/middleware/security-headers.d.ts +10 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +19 -0
- package/dist/module.d.ts +41 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +1 -0
- package/dist/plugin.d.ts +66 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +37 -0
- package/dist/public-capability.d.ts +46 -0
- package/dist/public-capability.d.ts.map +1 -0
- package/dist/public-capability.js +140 -0
- package/dist/public-document-delivery.d.ts +111 -0
- package/dist/public-document-delivery.d.ts.map +1 -0
- package/dist/public-document-delivery.js +234 -0
- package/dist/types.d.ts +318 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/validation.d.ts +36 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +106 -0
- package/package.json +156 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import type { Actor, VoyantVariables as CoreVoyantVariables, EventBus, LinkService, ModuleContainer, QueryGraphContext, QueryRunner, VoyantAuthContext, VoyantPermission } from "@voyant-travel/core";
|
|
2
|
+
import type { SelectApikey } from "@voyant-travel/db/schema/iam";
|
|
3
|
+
import type { KVStore } from "@voyant-travel/utils/cache";
|
|
4
|
+
import type { DriverFactory } from "@voyant-travel/workflows/driver";
|
|
5
|
+
import type { NeonHttpDatabase } from "drizzle-orm/neon-http";
|
|
6
|
+
import type { NeonDatabase as NeonWsDatabase } from "drizzle-orm/neon-serverless";
|
|
7
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
8
|
+
import type { Hono } from "hono";
|
|
9
|
+
import type { HonoExtension, HonoModule } from "./module.js";
|
|
10
|
+
import type { HonoBundle } from "./plugin.js";
|
|
11
|
+
export interface VoyantExecutionContext {
|
|
12
|
+
waitUntil?: (promise: Promise<unknown>) => void;
|
|
13
|
+
passThroughOnException?: () => void;
|
|
14
|
+
}
|
|
15
|
+
export interface VoyantBindings {
|
|
16
|
+
INTERNAL_API_KEY?: string;
|
|
17
|
+
INTERNAL_API_KEY_SCOPES?: string;
|
|
18
|
+
SESSION_CLAIMS_SECRET?: string;
|
|
19
|
+
BETTER_AUTH_SECRET?: string;
|
|
20
|
+
DATABASE_URL: string;
|
|
21
|
+
CORS_ALLOWLIST?: string;
|
|
22
|
+
APP_URL?: string;
|
|
23
|
+
DASH_BASE_URL?: string;
|
|
24
|
+
API_BASE_URL?: string;
|
|
25
|
+
RATE_LIMIT?: KVStore;
|
|
26
|
+
CACHE?: KVStore;
|
|
27
|
+
RATE_LIMITER?: import("./middleware/rate-limit.js").CloudflareRateLimiterBinding;
|
|
28
|
+
/**
|
|
29
|
+
* Workers Analytics Engine dataset receiving per-request metrics
|
|
30
|
+
* (see the `metrics` middleware). Optional — without it the
|
|
31
|
+
* middleware is a no-op.
|
|
32
|
+
*/
|
|
33
|
+
METRICS?: import("./middleware/metrics.js").AnalyticsEngineDatasetLike;
|
|
34
|
+
}
|
|
35
|
+
export type VoyantDb = PostgresJsDatabase | NeonHttpDatabase | NeonWsDatabase;
|
|
36
|
+
export type VoyantQueryRuntime = QueryRunner;
|
|
37
|
+
export type VoyantVariables = CoreVoyantVariables & {
|
|
38
|
+
db: VoyantDb;
|
|
39
|
+
/** Shared app/runtime container for explicit service resolution. */
|
|
40
|
+
container: ModuleContainer;
|
|
41
|
+
eventBus: EventBus;
|
|
42
|
+
/** Shared cross-module link runtime, when the app wires one in. */
|
|
43
|
+
link?: LinkService;
|
|
44
|
+
/** Shared cross-module query runtime, when the app wires one in. */
|
|
45
|
+
query?: VoyantQueryRuntime;
|
|
46
|
+
/** Optional workflow driver surfaced to HTTP routes after lazy app bootstrap. */
|
|
47
|
+
workflowDriver?: import("@voyant-travel/workflows/driver").WorkflowDriver;
|
|
48
|
+
/** Per-request db metrics counter populated by the metrics middleware. */
|
|
49
|
+
__voyantDbMetrics?: import("./middleware/metrics.js").RequestDbMetrics;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Per-request handle returned by a {@link DbFactory} that owns its own
|
|
53
|
+
* Pool / connection: a drizzle client plus a `dispose()` the db
|
|
54
|
+
* middleware schedules via `c.executionCtx.waitUntil` after the
|
|
55
|
+
* response is sent. Used by templates that build a Neon WebSocket
|
|
56
|
+
* Pool per request (see e.g. `dbFromEnvForApp` in template
|
|
57
|
+
* `src/api/lib/db.ts`) — without `dispose()`, the Pool stays open
|
|
58
|
+
* until the Workers isolate is reclaimed.
|
|
59
|
+
*/
|
|
60
|
+
export interface DisposableDb {
|
|
61
|
+
db: VoyantDb;
|
|
62
|
+
dispose: () => Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
export type DbFactory<TBindings extends VoyantBindings = VoyantBindings> = (env: TBindings) => VoyantDb | DisposableDb;
|
|
65
|
+
/**
|
|
66
|
+
* Result of routing a request path to a db factory (see
|
|
67
|
+
* {@link DbFactorySelector}).
|
|
68
|
+
*/
|
|
69
|
+
export interface DbSurfaceSelection<TBindings extends VoyantBindings = VoyantBindings> {
|
|
70
|
+
factory: DbFactory<TBindings>;
|
|
71
|
+
/**
|
|
72
|
+
* Whether this surface must receive an interactive-transaction-capable
|
|
73
|
+
* client. The db middleware asserts the resolved client's capability
|
|
74
|
+
* tag when `true` and skips the assertion when `false` (the default
|
|
75
|
+
* http-backed client is deliberately transaction-incapable).
|
|
76
|
+
*/
|
|
77
|
+
mustSupportTransactions: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Routes a request path to the db factory that should serve it. Built by
|
|
81
|
+
* `createApp` when the deployment supplies both a default (http-backed)
|
|
82
|
+
* and a transactional (WebSocket-backed) factory: surfaces owned by
|
|
83
|
+
* modules that declare `requiresTransactionalDb` get the transactional
|
|
84
|
+
* factory; everything else gets the cheap default. The selector MUST
|
|
85
|
+
* return stable factory references — per-request client sharing
|
|
86
|
+
* (`acquireRequestDb`) keys on factory identity.
|
|
87
|
+
*/
|
|
88
|
+
export interface DbFactorySelector<TBindings extends VoyantBindings = VoyantBindings> {
|
|
89
|
+
select(path: string): DbSurfaceSelection<TBindings>;
|
|
90
|
+
}
|
|
91
|
+
/** Either a single factory for all requests, or a per-path selector. */
|
|
92
|
+
export type DbSource<TBindings extends VoyantBindings = VoyantBindings> = DbFactory<TBindings> | DbFactorySelector<TBindings>;
|
|
93
|
+
export declare function isDbFactorySelector<TBindings extends VoyantBindings>(source: DbSource<TBindings>): source is DbFactorySelector<TBindings>;
|
|
94
|
+
/** Normalize a {@link DbSource} to the factory serving `path`. */
|
|
95
|
+
export declare function selectDbFactory<TBindings extends VoyantBindings>(source: DbSource<TBindings>, path: string): DbFactory<TBindings>;
|
|
96
|
+
export declare function isDisposableDb(value: VoyantDb | DisposableDb): value is DisposableDb;
|
|
97
|
+
/**
|
|
98
|
+
* Normalize a {@link DbFactory} return value to `{ db, dispose? }` so
|
|
99
|
+
* call sites don't repeat the `isDisposableDb` shape check. `dispose`
|
|
100
|
+
* is `undefined` for plain `VoyantDb` factories.
|
|
101
|
+
*/
|
|
102
|
+
export declare function resolveDbFactoryResult(value: VoyantDb | DisposableDb): {
|
|
103
|
+
db: VoyantDb;
|
|
104
|
+
dispose?: () => Promise<void>;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* The shape returned by a custom `auth.resolve` integration. Both `userId`
|
|
108
|
+
* and `actor` are required: `requireActor` is fail-closed, so a resolver
|
|
109
|
+
* that omits `actor` would 401 every protected request. Make the omission a
|
|
110
|
+
* compile-time error instead of a runtime mystery.
|
|
111
|
+
*/
|
|
112
|
+
export type VoyantRequestAuthContext = Omit<VoyantAuthContext, "actor"> & {
|
|
113
|
+
userId: string;
|
|
114
|
+
actor: Actor;
|
|
115
|
+
};
|
|
116
|
+
export interface LogEntry {
|
|
117
|
+
method: string;
|
|
118
|
+
path: string;
|
|
119
|
+
status: number;
|
|
120
|
+
durationMs: number;
|
|
121
|
+
}
|
|
122
|
+
export interface LoggerProvider {
|
|
123
|
+
log(entry: LogEntry): void;
|
|
124
|
+
}
|
|
125
|
+
export interface VoyantAuthResolveArgs<TBindings extends VoyantBindings = VoyantBindings> {
|
|
126
|
+
request: Request;
|
|
127
|
+
env: TBindings;
|
|
128
|
+
db: VoyantDb;
|
|
129
|
+
ctx?: VoyantExecutionContext;
|
|
130
|
+
}
|
|
131
|
+
export interface VoyantAuthPermissionArgs<TBindings extends VoyantBindings = VoyantBindings> extends VoyantAuthResolveArgs<TBindings> {
|
|
132
|
+
permission: VoyantPermission;
|
|
133
|
+
auth: VoyantRequestAuthContext;
|
|
134
|
+
}
|
|
135
|
+
export interface VoyantAuthApiKeyValidationArgs<TBindings extends VoyantBindings = VoyantBindings> extends VoyantAuthResolveArgs<TBindings> {
|
|
136
|
+
apiKey: SelectApikey;
|
|
137
|
+
}
|
|
138
|
+
export interface VoyantAuthIntegration<TBindings extends VoyantBindings = VoyantBindings> {
|
|
139
|
+
handler?: (env: TBindings) => {
|
|
140
|
+
fetch: (req: Request, env: TBindings, ctx?: VoyantExecutionContext) => Response | Promise<Response>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Resolve the request to an auth context, or return `null` for anonymous.
|
|
144
|
+
*
|
|
145
|
+
* The returned object MUST include `actor` — `requireActor` is fail-closed,
|
|
146
|
+
* so omitting it 401s every protected route. For single-tenant admin apps
|
|
147
|
+
* where every authenticated session is staff, return `actor: "staff"`.
|
|
148
|
+
* Customer/partner/supplier sessions should return the corresponding actor
|
|
149
|
+
* so `/v1/public/*` route guards work.
|
|
150
|
+
*/
|
|
151
|
+
resolve?: (args: VoyantAuthResolveArgs<TBindings>) => Promise<VoyantRequestAuthContext | null> | VoyantRequestAuthContext | null;
|
|
152
|
+
hasPermission?: (args: VoyantAuthPermissionArgs<TBindings>) => Promise<boolean> | boolean;
|
|
153
|
+
validateApiKey?: (args: VoyantAuthApiKeyValidationArgs<TBindings>) => Promise<boolean> | boolean;
|
|
154
|
+
}
|
|
155
|
+
export interface VoyantAppConfig<TBindings extends VoyantBindings = VoyantBindings> {
|
|
156
|
+
db: DbFactory<TBindings>;
|
|
157
|
+
/**
|
|
158
|
+
* Optional transaction-capable db factory (e.g. a per-request Neon
|
|
159
|
+
* WebSocket Pool). When provided, `createApp` routes requests by
|
|
160
|
+
* surface: routes of modules declaring `requiresTransactionalDb` (plus
|
|
161
|
+
* any `dbTransactionalPaths`) get this factory; every other request is
|
|
162
|
+
* served by the cheap `db` factory (typically neon-http — zero
|
|
163
|
+
* connection handshake). When omitted, `db` serves everything
|
|
164
|
+
* (previous behavior).
|
|
165
|
+
*/
|
|
166
|
+
dbTransactional?: DbFactory<TBindings>;
|
|
167
|
+
/**
|
|
168
|
+
* Extra path prefixes that must receive the transactional client —
|
|
169
|
+
* for starter-owned routes mounted via `additionalRoutes` that run
|
|
170
|
+
* interactive transactions (e.g. `"/api/checkout"`). Only meaningful
|
|
171
|
+
* together with `dbTransactional`.
|
|
172
|
+
*/
|
|
173
|
+
dbTransactionalPaths?: string[];
|
|
174
|
+
modules?: HonoModule[];
|
|
175
|
+
extensions?: HonoExtension[];
|
|
176
|
+
plugins?: HonoBundle[];
|
|
177
|
+
eventBus?: EventBus;
|
|
178
|
+
link?: LinkService;
|
|
179
|
+
query?: QueryGraphContext | VoyantQueryRuntime;
|
|
180
|
+
auth?: VoyantAuthIntegration<TBindings>;
|
|
181
|
+
publicPaths?: string[];
|
|
182
|
+
logger?: LoggerProvider;
|
|
183
|
+
/**
|
|
184
|
+
* Shared response cache for the public surface (`/v1/public/*` by
|
|
185
|
+
* default). Enabled by default but inert until a route marks its
|
|
186
|
+
* response `Cache-Control: public, s-maxage=…` — personalized routes
|
|
187
|
+
* are never cached. Set `false` to disable, or pass options to tune
|
|
188
|
+
* prefixes/limits. Uses the Cache API where the runtime provides it
|
|
189
|
+
* and falls back to the `env.CACHE` KV binding (Voyant Cloud
|
|
190
|
+
* namespaced workers have no `caches.default`).
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* Transactional outbox (RFC #1687 Phase 2.1). When `true`, request
|
|
194
|
+
* emits persist the envelope to the `event_outbox` table BEFORE any
|
|
195
|
+
* subscriber runs (durable, at-least-once with retry/dead-letter via
|
|
196
|
+
* `drainOutbox` from `@voyant-travel/db/outbox`). Requires the
|
|
197
|
+
* `event_outbox` migration. Deployments should run a periodic drain
|
|
198
|
+
* (cron) for redelivery of failed/interrupted deliveries:
|
|
199
|
+
* `drainOutbox(db, app.eventBus)`. Services needing write atomicity
|
|
200
|
+
* insert rows inside their own transaction via
|
|
201
|
+
* `insertOutboxEvents(tx, ...)`. Default off.
|
|
202
|
+
*/
|
|
203
|
+
outbox?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Per-request metrics to the `env.METRICS` Analytics Engine dataset
|
|
206
|
+
* (method, route pattern, surface, cache status, duration, status,
|
|
207
|
+
* db query count). Enabled by default and inert without the binding;
|
|
208
|
+
* set `false` to disable entirely.
|
|
209
|
+
*/
|
|
210
|
+
metrics?: boolean;
|
|
211
|
+
/**
|
|
212
|
+
* Default request body limit enforced by `Content-Length` before route
|
|
213
|
+
* handlers parse JSON/form data. Enabled by default at 10 MiB. Set
|
|
214
|
+
* `false` to disable or pass `{ maxBytes }` to override.
|
|
215
|
+
*/
|
|
216
|
+
requestBodyLimit?: false | {
|
|
217
|
+
maxBytes: number;
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Default app-wide security headers. Enabled by default. Set `false`
|
|
221
|
+
* to disable, or override CSP/HSTS via the option object.
|
|
222
|
+
*/
|
|
223
|
+
securityHeaders?: false | import("./middleware/security-headers.js").SecurityHeadersOptions;
|
|
224
|
+
/**
|
|
225
|
+
* Default app-wide rate limits. Enabled by default for `/auth/*` POSTs
|
|
226
|
+
* and unauthenticated public writes. Set `false` to disable or tune
|
|
227
|
+
* individual policies.
|
|
228
|
+
*/
|
|
229
|
+
rateLimit?: false | import("./middleware/rate-limit.js").RateLimitConfig;
|
|
230
|
+
publicCache?: false | import("./middleware/public-cache.js").PublicCacheOptions;
|
|
231
|
+
/**
|
|
232
|
+
* Workflow runtime configuration. When set, `createApp()` collects
|
|
233
|
+
* `module.workflows` + `module.eventFilters` (plus the same fields
|
|
234
|
+
* from plugins), invokes `workflows.driver` with framework deps, and
|
|
235
|
+
* — inside the lazy bootstrap path — registers the manifest with the
|
|
236
|
+
* driver and installs an EventBus forwarder that routes emitted
|
|
237
|
+
* events to `driver.ingestEvent(...)`.
|
|
238
|
+
*
|
|
239
|
+
* See `docs/architecture/workflows-runtime-architecture.md` §6, §18.
|
|
240
|
+
*/
|
|
241
|
+
workflows?: VoyantWorkflowsConfig;
|
|
242
|
+
/**
|
|
243
|
+
* Admin API capability metadata, served at `GET /v1/admin/_meta/capabilities`
|
|
244
|
+
* so clients (the admin SDK) can discover what this deployment supports —
|
|
245
|
+
* enabled modules, available operations, contract/deployment version, and the
|
|
246
|
+
* caller's resolved actor + scopes. Provide it from `@voyant-travel/admin-contracts`:
|
|
247
|
+
* `{ contractVersion: ADMIN_CONTRACT_VERSION, operations: operationCapabilities() }`.
|
|
248
|
+
* When omitted, the route is not mounted. Typed structurally so `@voyant-travel/hono`
|
|
249
|
+
* stays decoupled from `@voyant-travel/admin-contracts`.
|
|
250
|
+
*/
|
|
251
|
+
adminMeta?: {
|
|
252
|
+
contractVersion: string;
|
|
253
|
+
deploymentVersion?: string;
|
|
254
|
+
operations: ReadonlyArray<{
|
|
255
|
+
id: string;
|
|
256
|
+
method: string;
|
|
257
|
+
pathTemplate: string;
|
|
258
|
+
classification: string;
|
|
259
|
+
scopes: string[];
|
|
260
|
+
capabilityKey?: string;
|
|
261
|
+
}>;
|
|
262
|
+
};
|
|
263
|
+
additionalRoutes?: (app: Hono<any>) => void;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Workflow runtime configuration block. The driver is resolved at boot
|
|
267
|
+
* time (inside the lazy bootstrap path), after framework deps and —
|
|
268
|
+
* crucially — after runtime bindings are available.
|
|
269
|
+
*
|
|
270
|
+
* `driver` is **always** a function-of-bindings: `(env) => DriverFactory`.
|
|
271
|
+
* This unambiguous shape works for all deployment modes:
|
|
272
|
+
*
|
|
273
|
+
* **Mode 2 / InMemory** — wrap your direct factory:
|
|
274
|
+
*
|
|
275
|
+
* workflows: {
|
|
276
|
+
* driver: () => createNodeStandaloneDriver({ db }),
|
|
277
|
+
* }
|
|
278
|
+
*
|
|
279
|
+
* **Mode 1 (CF edge)** — pull options off `env`:
|
|
280
|
+
*
|
|
281
|
+
* workflows: {
|
|
282
|
+
* driver: (env) => createCloudflareEdgeDriver({
|
|
283
|
+
* orchestratorNamespace: env.WORKFLOW_RUN_DO,
|
|
284
|
+
* manifestKv: env.WORKFLOW_MANIFESTS,
|
|
285
|
+
* tenantScript: "tenant-bundle",
|
|
286
|
+
* }),
|
|
287
|
+
* }
|
|
288
|
+
*
|
|
289
|
+
* The single shape avoids ambiguous "is this a factory or a
|
|
290
|
+
* factory-of-factories?" heuristics. See architecture doc §6.3 +
|
|
291
|
+
* reviewer feedback P2.1.
|
|
292
|
+
*/
|
|
293
|
+
export interface VoyantWorkflowsConfig<TBindings = unknown> {
|
|
294
|
+
/**
|
|
295
|
+
* Function-of-bindings that returns a `DriverFactory`. Resolved
|
|
296
|
+
* lazily with `c.env` once bindings are available, then invoked
|
|
297
|
+
* with `{ services, logger }` to produce the driver.
|
|
298
|
+
*/
|
|
299
|
+
driver: (bindings: TBindings) => DriverFactory;
|
|
300
|
+
/**
|
|
301
|
+
* Environment the manifest registers under. Defaults to `"development"`.
|
|
302
|
+
* Workflow filters are environment-scoped (production manifests don't
|
|
303
|
+
* see preview events and vice versa) per architecture doc §21.10.
|
|
304
|
+
*/
|
|
305
|
+
environment?: "production" | "preview" | "development";
|
|
306
|
+
/**
|
|
307
|
+
* Project / tenant identifier baked into the manifest. Single-tenant
|
|
308
|
+
* runtimes leave this unset (defaults to `"default"`). Multi-tenant
|
|
309
|
+
* deployments override per-app via voyant-cloud's wrapper layer.
|
|
310
|
+
*/
|
|
311
|
+
projectId?: string;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Structural shape of a `DriverFactory` from `@voyant-travel/workflows/driver`.
|
|
315
|
+
* The SDK package's concrete `DriverFactory` satisfies this via TS
|
|
316
|
+
* structural compat (architecture doc §21.19).
|
|
317
|
+
*/
|
|
318
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { dbClientDispose } from "@voyant-travel/db/transaction-capability";
|
|
2
|
+
export function isDbFactorySelector(source) {
|
|
3
|
+
return typeof source !== "function" && typeof source.select === "function";
|
|
4
|
+
}
|
|
5
|
+
/** Normalize a {@link DbSource} to the factory serving `path`. */
|
|
6
|
+
export function selectDbFactory(source, path) {
|
|
7
|
+
return isDbFactorySelector(source) ? source.select(path).factory : source;
|
|
8
|
+
}
|
|
9
|
+
export function isDisposableDb(value) {
|
|
10
|
+
return (typeof value.dispose === "function" &&
|
|
11
|
+
value.db !== undefined);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Normalize a {@link DbFactory} return value to `{ db, dispose? }` so
|
|
15
|
+
* call sites don't repeat the `isDisposableDb` shape check. `dispose`
|
|
16
|
+
* is `undefined` for plain `VoyantDb` factories.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveDbFactoryResult(value) {
|
|
19
|
+
if (isDisposableDb(value)) {
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
const dispose = dbClientDispose(value);
|
|
23
|
+
return dispose ? { db: value, dispose } : { db: value };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Structural shape of a `DriverFactory` from `@voyant-travel/workflows/driver`.
|
|
27
|
+
* The SDK package's concrete `DriverFactory` satisfies this via TS
|
|
28
|
+
* structural compat (architecture doc §21.19).
|
|
29
|
+
*/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import { type ZodType } from "zod";
|
|
3
|
+
export declare class ApiHttpError extends Error {
|
|
4
|
+
readonly status: number;
|
|
5
|
+
readonly code?: string;
|
|
6
|
+
readonly details?: Record<string, unknown>;
|
|
7
|
+
constructor(message: string, options: {
|
|
8
|
+
status: number;
|
|
9
|
+
code?: string;
|
|
10
|
+
details?: Record<string, unknown>;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export declare class RequestValidationError extends ApiHttpError {
|
|
14
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
15
|
+
}
|
|
16
|
+
export declare class UnauthorizedApiError extends ApiHttpError {
|
|
17
|
+
constructor(message?: string);
|
|
18
|
+
}
|
|
19
|
+
export declare class ForbiddenApiError extends ApiHttpError {
|
|
20
|
+
constructor(message?: string);
|
|
21
|
+
}
|
|
22
|
+
export declare function parseJsonBody<T>(c: Context, schema: ZodType<T>, options?: {
|
|
23
|
+
invalidJsonMessage?: string;
|
|
24
|
+
invalidBodyMessage?: string;
|
|
25
|
+
maxBytes?: number;
|
|
26
|
+
}): Promise<T>;
|
|
27
|
+
export declare function parseOptionalJsonBody<T>(c: Context, schema: ZodType<T>, options?: {
|
|
28
|
+
defaultValue?: unknown;
|
|
29
|
+
invalidBodyMessage?: string;
|
|
30
|
+
maxBytes?: number;
|
|
31
|
+
}): Promise<T>;
|
|
32
|
+
export declare function parseQuery<T>(c: Context, schema: ZodType<T>, options?: {
|
|
33
|
+
invalidQueryMessage?: string;
|
|
34
|
+
}): T;
|
|
35
|
+
export declare function normalizeValidationError(error: unknown): ApiHttpError | undefined;
|
|
36
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,KAAK,CAAA;AAI5C,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;gBAGxC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAClC;CAQJ;AAED,qBAAa,sBAAuB,SAAQ,YAAY;gBAC1C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQ/D;AAED,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,OAAO,SAAiB;CAOrC;AAED,qBAAa,iBAAkB,SAAQ,YAAY;gBACrC,OAAO,SAAc;CAOlC;AAqBD,wBAAsB,aAAa,CAAC,CAAC,EACnC,CAAC,EAAE,OAAO,EACV,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAClB,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACxF,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,CAAC,EAAE,OAAO,EACV,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAClB,OAAO,CAAC,EAAE;IACR,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,GACA,OAAO,CAAC,CAAC,CAAC,CAcZ;AAkBD,wBAAgB,UAAU,CAAC,CAAC,EAC1B,CAAC,EAAE,OAAO,EACV,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAClB,OAAO,CAAC,EAAE;IAAE,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,CAAC,CAMH;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAUjF"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ZodError } from "zod";
|
|
2
|
+
import { DEFAULT_REQUEST_BODY_LIMIT_BYTES } from "./middleware/body-size.js";
|
|
3
|
+
export class ApiHttpError extends Error {
|
|
4
|
+
status;
|
|
5
|
+
code;
|
|
6
|
+
details;
|
|
7
|
+
constructor(message, options) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "ApiHttpError";
|
|
10
|
+
this.status = options.status;
|
|
11
|
+
this.code = options.code;
|
|
12
|
+
this.details = options.details;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class RequestValidationError extends ApiHttpError {
|
|
16
|
+
constructor(message, details) {
|
|
17
|
+
super(message, {
|
|
18
|
+
status: 400,
|
|
19
|
+
code: "invalid_request",
|
|
20
|
+
details,
|
|
21
|
+
});
|
|
22
|
+
this.name = "RequestValidationError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class UnauthorizedApiError extends ApiHttpError {
|
|
26
|
+
constructor(message = "Unauthorized") {
|
|
27
|
+
super(message, {
|
|
28
|
+
status: 401,
|
|
29
|
+
code: "unauthorized",
|
|
30
|
+
});
|
|
31
|
+
this.name = "UnauthorizedApiError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class ForbiddenApiError extends ApiHttpError {
|
|
35
|
+
constructor(message = "Forbidden") {
|
|
36
|
+
super(message, {
|
|
37
|
+
status: 403,
|
|
38
|
+
code: "forbidden",
|
|
39
|
+
});
|
|
40
|
+
this.name = "ForbiddenApiError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function toValidationError(error, fallbackMessage = "Invalid request") {
|
|
44
|
+
return new RequestValidationError(error.issues[0]?.message ?? fallbackMessage, {
|
|
45
|
+
issues: error.issues,
|
|
46
|
+
fields: error.flatten(),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function validate(schema, input, fallbackMessage) {
|
|
50
|
+
const parsed = schema.safeParse(input);
|
|
51
|
+
if (!parsed.success) {
|
|
52
|
+
throw toValidationError(parsed.error, fallbackMessage);
|
|
53
|
+
}
|
|
54
|
+
return parsed.data;
|
|
55
|
+
}
|
|
56
|
+
export async function parseJsonBody(c, schema, options) {
|
|
57
|
+
let input;
|
|
58
|
+
const text = await readBoundedRequestText(c, options?.maxBytes);
|
|
59
|
+
try {
|
|
60
|
+
input = JSON.parse(text);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
throw new RequestValidationError(options?.invalidJsonMessage ?? "Invalid JSON body");
|
|
64
|
+
}
|
|
65
|
+
return validate(schema, input, options?.invalidBodyMessage);
|
|
66
|
+
}
|
|
67
|
+
export async function parseOptionalJsonBody(c, schema, options) {
|
|
68
|
+
let input;
|
|
69
|
+
const text = await readBoundedRequestText(c, options?.maxBytes);
|
|
70
|
+
if (text.length === 0) {
|
|
71
|
+
return validate(schema, options?.defaultValue ?? {}, options?.invalidBodyMessage);
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
input = JSON.parse(text);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
input = options?.defaultValue ?? {};
|
|
78
|
+
}
|
|
79
|
+
return validate(schema, input, options?.invalidBodyMessage);
|
|
80
|
+
}
|
|
81
|
+
async function readBoundedRequestText(c, maxBytes = DEFAULT_REQUEST_BODY_LIMIT_BYTES) {
|
|
82
|
+
const contentLength = c.req.header("content-length");
|
|
83
|
+
if (contentLength) {
|
|
84
|
+
const size = Number(contentLength);
|
|
85
|
+
if (Number.isFinite(size) && size > maxBytes) {
|
|
86
|
+
throw new RequestValidationError("Request body too large", { maxBytes });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const text = await c.req.text();
|
|
90
|
+
if (new TextEncoder().encode(text).byteLength > maxBytes) {
|
|
91
|
+
throw new RequestValidationError("Request body too large", { maxBytes });
|
|
92
|
+
}
|
|
93
|
+
return text;
|
|
94
|
+
}
|
|
95
|
+
export function parseQuery(c, schema, options) {
|
|
96
|
+
return validate(schema, Object.fromEntries(new URL(c.req.url).searchParams), options?.invalidQueryMessage ?? "Invalid query parameters");
|
|
97
|
+
}
|
|
98
|
+
export function normalizeValidationError(error) {
|
|
99
|
+
if (error instanceof ApiHttpError) {
|
|
100
|
+
return error;
|
|
101
|
+
}
|
|
102
|
+
if (error instanceof ZodError) {
|
|
103
|
+
return toValidationError(error);
|
|
104
|
+
}
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@voyant-travel/hono",
|
|
3
|
+
"version": "0.109.1",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./app": {
|
|
13
|
+
"types": "./dist/app.d.ts",
|
|
14
|
+
"import": "./dist/app.js",
|
|
15
|
+
"default": "./dist/app.js"
|
|
16
|
+
},
|
|
17
|
+
"./module": {
|
|
18
|
+
"types": "./dist/module.d.ts",
|
|
19
|
+
"import": "./dist/module.js",
|
|
20
|
+
"default": "./dist/module.js"
|
|
21
|
+
},
|
|
22
|
+
"./composition": {
|
|
23
|
+
"types": "./dist/composition.d.ts",
|
|
24
|
+
"import": "./dist/composition.js",
|
|
25
|
+
"default": "./dist/composition.js"
|
|
26
|
+
},
|
|
27
|
+
"./plugin": {
|
|
28
|
+
"types": "./dist/plugin.d.ts",
|
|
29
|
+
"import": "./dist/plugin.js",
|
|
30
|
+
"default": "./dist/plugin.js"
|
|
31
|
+
},
|
|
32
|
+
"./document-download": {
|
|
33
|
+
"types": "./dist/document-download.d.ts",
|
|
34
|
+
"import": "./dist/document-download.js",
|
|
35
|
+
"default": "./dist/document-download.js"
|
|
36
|
+
},
|
|
37
|
+
"./public-document-delivery": {
|
|
38
|
+
"types": "./dist/public-document-delivery.d.ts",
|
|
39
|
+
"import": "./dist/public-document-delivery.js",
|
|
40
|
+
"default": "./dist/public-document-delivery.js"
|
|
41
|
+
},
|
|
42
|
+
"./types": {
|
|
43
|
+
"types": "./dist/types.d.ts",
|
|
44
|
+
"import": "./dist/types.js",
|
|
45
|
+
"default": "./dist/types.js"
|
|
46
|
+
},
|
|
47
|
+
"./middleware": {
|
|
48
|
+
"types": "./dist/middleware/index.d.ts",
|
|
49
|
+
"import": "./dist/middleware/index.js",
|
|
50
|
+
"default": "./dist/middleware/index.js"
|
|
51
|
+
},
|
|
52
|
+
"./middleware/auth": {
|
|
53
|
+
"types": "./dist/middleware/auth.d.ts",
|
|
54
|
+
"import": "./dist/middleware/auth.js",
|
|
55
|
+
"default": "./dist/middleware/auth.js"
|
|
56
|
+
},
|
|
57
|
+
"./middleware/body-size": {
|
|
58
|
+
"types": "./dist/middleware/body-size.d.ts",
|
|
59
|
+
"import": "./dist/middleware/body-size.js",
|
|
60
|
+
"default": "./dist/middleware/body-size.js"
|
|
61
|
+
},
|
|
62
|
+
"./middleware/cors": {
|
|
63
|
+
"types": "./dist/middleware/cors.d.ts",
|
|
64
|
+
"import": "./dist/middleware/cors.js",
|
|
65
|
+
"default": "./dist/middleware/cors.js"
|
|
66
|
+
},
|
|
67
|
+
"./middleware/error-boundary": {
|
|
68
|
+
"types": "./dist/middleware/error-boundary.d.ts",
|
|
69
|
+
"import": "./dist/middleware/error-boundary.js",
|
|
70
|
+
"default": "./dist/middleware/error-boundary.js"
|
|
71
|
+
},
|
|
72
|
+
"./middleware/db": {
|
|
73
|
+
"types": "./dist/middleware/db.d.ts",
|
|
74
|
+
"import": "./dist/middleware/db.js",
|
|
75
|
+
"default": "./dist/middleware/db.js"
|
|
76
|
+
},
|
|
77
|
+
"./middleware/rate-limit": {
|
|
78
|
+
"types": "./dist/middleware/rate-limit.d.ts",
|
|
79
|
+
"import": "./dist/middleware/rate-limit.js",
|
|
80
|
+
"default": "./dist/middleware/rate-limit.js"
|
|
81
|
+
},
|
|
82
|
+
"./middleware/require-actor": {
|
|
83
|
+
"types": "./dist/middleware/require-actor.d.ts",
|
|
84
|
+
"import": "./dist/middleware/require-actor.js",
|
|
85
|
+
"default": "./dist/middleware/require-actor.js"
|
|
86
|
+
},
|
|
87
|
+
"./middleware/require-permission": {
|
|
88
|
+
"types": "./dist/middleware/require-permission.d.ts",
|
|
89
|
+
"import": "./dist/middleware/require-permission.js",
|
|
90
|
+
"default": "./dist/middleware/require-permission.js"
|
|
91
|
+
},
|
|
92
|
+
"./middleware/security-headers": {
|
|
93
|
+
"types": "./dist/middleware/security-headers.d.ts",
|
|
94
|
+
"import": "./dist/middleware/security-headers.js",
|
|
95
|
+
"default": "./dist/middleware/security-headers.js"
|
|
96
|
+
},
|
|
97
|
+
"./middleware/logger": {
|
|
98
|
+
"types": "./dist/middleware/logger.d.ts",
|
|
99
|
+
"import": "./dist/middleware/logger.js",
|
|
100
|
+
"default": "./dist/middleware/logger.js"
|
|
101
|
+
},
|
|
102
|
+
"./auth": {
|
|
103
|
+
"types": "./dist/auth/index.d.ts",
|
|
104
|
+
"import": "./dist/auth/index.js",
|
|
105
|
+
"default": "./dist/auth/index.js"
|
|
106
|
+
},
|
|
107
|
+
"./auth/session-jwt": {
|
|
108
|
+
"types": "./dist/auth/session-jwt.d.ts",
|
|
109
|
+
"import": "./dist/auth/session-jwt.js",
|
|
110
|
+
"default": "./dist/auth/session-jwt.js"
|
|
111
|
+
},
|
|
112
|
+
"./auth/crypto": {
|
|
113
|
+
"types": "./dist/auth/crypto.d.ts",
|
|
114
|
+
"import": "./dist/auth/crypto.js",
|
|
115
|
+
"default": "./dist/auth/crypto.js"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"dependencies": {
|
|
119
|
+
"drizzle-orm": "^0.45.2",
|
|
120
|
+
"hono": "^4.12.10",
|
|
121
|
+
"zod": "^4.3.6",
|
|
122
|
+
"@voyant-travel/core": "^0.109.0",
|
|
123
|
+
"@voyant-travel/db": "^0.108.0",
|
|
124
|
+
"@voyant-travel/storage": "^0.104.1",
|
|
125
|
+
"@voyant-travel/types": "^0.104.5",
|
|
126
|
+
"@voyant-travel/utils": "^0.105.1",
|
|
127
|
+
"@voyant-travel/workflows": "^0.107.10"
|
|
128
|
+
},
|
|
129
|
+
"devDependencies": {
|
|
130
|
+
"@cloudflare/workers-types": "^4.20260426.1",
|
|
131
|
+
"typescript": "^6.0.2",
|
|
132
|
+
"vitest": "^4.1.2",
|
|
133
|
+
"@voyant-travel/voyant-typescript-config": "^0.1.0",
|
|
134
|
+
"@voyant-travel/workflows-orchestrator": "^0.107.10"
|
|
135
|
+
},
|
|
136
|
+
"files": [
|
|
137
|
+
"dist"
|
|
138
|
+
],
|
|
139
|
+
"publishConfig": {
|
|
140
|
+
"access": "public"
|
|
141
|
+
},
|
|
142
|
+
"repository": {
|
|
143
|
+
"type": "git",
|
|
144
|
+
"url": "https://github.com/voyant-travel/voyant.git",
|
|
145
|
+
"directory": "packages/hono"
|
|
146
|
+
},
|
|
147
|
+
"scripts": {
|
|
148
|
+
"typecheck": "tsc --noEmit",
|
|
149
|
+
"lint": "biome check src/",
|
|
150
|
+
"test": "vitest run",
|
|
151
|
+
"build": "tsc -p tsconfig.json",
|
|
152
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo"
|
|
153
|
+
},
|
|
154
|
+
"main": "./dist/index.js",
|
|
155
|
+
"types": "./dist/index.d.ts"
|
|
156
|
+
}
|