@voyant-travel/hono 0.121.2 → 0.122.0
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/app.d.ts.map +1 -1
- package/dist/app.js +224 -60
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/lazy-provider.d.ts +18 -0
- package/dist/lazy-provider.d.ts.map +1 -0
- package/dist/lazy-provider.js +45 -0
- package/dist/lib/db-selector.js +1 -1
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/middleware/public-cache.d.ts +3 -3
- package/dist/middleware/public-cache.d.ts.map +1 -1
- package/dist/middleware/public-cache.js +13 -80
- package/dist/middleware/rate-limit.d.ts +5 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -1
- package/dist/middleware/rate-limit.js +33 -2
- package/dist/plugin.d.ts +51 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +7 -0
- package/dist/types.d.ts +5 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAQhC,OAAO,EAAE,KAAK,gBAAgB,EAA0C,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAQhC,OAAO,EAAE,KAAK,gBAAgB,EAA0C,MAAM,kBAAkB,CAAA;AAqChG,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAY,eAAe,EAAE,MAAM,YAAY,CAAA;AAI5F,4EAA4E;AAC5E,KAAK,QAAQ,CAAC,SAAS,SAAS,cAAc,IAAI;IAChD,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,EAAE,eAAe,CAAA;CAC3B,CAAA;AA0BD;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,gBAAgB,CAAA;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAA;IAEd,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;CAC/D;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB,CAAC,SAAS,GAAG,OAAO;IACtD;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C;;;;;;;;OAQG;IACH,QAAQ,EAAE,OAAO,qBAAqB,EAAE,QAAQ,CAAA;IAChD;;;;;OAKG;IACH,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB;;;;;;OAMG;IACH,YAAY,EAAE,WAAW,EAAE,CAAA;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,SAAS,SAAS,cAAc,EACvD,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,GACjC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAqrB5D"}
|
package/dist/app.js
CHANGED
|
@@ -25,7 +25,7 @@ import { securityHeaders } from "./middleware/security-headers.js";
|
|
|
25
25
|
import { resolveSurfaceMountPath } from "./mount-paths.js";
|
|
26
26
|
import { noopReporter, safeCaptureException } from "./observability/reporter.js";
|
|
27
27
|
import { getRequestId } from "./observability/request-context.js";
|
|
28
|
-
import {
|
|
28
|
+
import { expandHonoBundles, isLazyHonoBundle, } from "./plugin.js";
|
|
29
29
|
const WRITE_METHODS = new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
30
30
|
function resolveConfiguredRateLimitStore(config, env) {
|
|
31
31
|
if (!config?.store)
|
|
@@ -59,8 +59,23 @@ export function mountApp(config) {
|
|
|
59
59
|
const reporter = config.reporter ?? noopReporter;
|
|
60
60
|
const appName = config.appName ?? "voyant";
|
|
61
61
|
app.onError((err, c) => handleApiError(err, c, { reporter, appName }));
|
|
62
|
-
|
|
63
|
-
const
|
|
62
|
+
const pluginInputs = config.plugins ?? [];
|
|
63
|
+
const eagerPlugins = [];
|
|
64
|
+
const lazyPlugins = [];
|
|
65
|
+
const pluginNames = new Set();
|
|
66
|
+
for (const plugin of pluginInputs) {
|
|
67
|
+
if (pluginNames.has(plugin.name)) {
|
|
68
|
+
throw new Error(`Duplicate bundle name: "${plugin.name}"`);
|
|
69
|
+
}
|
|
70
|
+
pluginNames.add(plugin.name);
|
|
71
|
+
if (isLazyHonoBundle(plugin))
|
|
72
|
+
lazyPlugins.push(plugin);
|
|
73
|
+
else
|
|
74
|
+
eagerPlugins.push(plugin);
|
|
75
|
+
}
|
|
76
|
+
// Expand eager plugins into their constituent modules/extensions before
|
|
77
|
+
// mounting. Lazy plugins keep only their static metadata in the eager closure.
|
|
78
|
+
const expanded = eagerPlugins.length > 0 ? expandHonoBundles(eagerPlugins) : null;
|
|
64
79
|
const allModules = [...(config.modules ?? []), ...(expanded?.modules ?? [])];
|
|
65
80
|
const allExtensions = [...(config.extensions ?? []), ...(expanded?.extensions ?? [])];
|
|
66
81
|
// Anonymous-access allow-list (ADR-0008): assembled from module/extension
|
|
@@ -71,6 +86,7 @@ export function mountApp(config) {
|
|
|
71
86
|
const anonymousPaths = assembleAnonymousPaths(allModules, allExtensions, [
|
|
72
87
|
...(config.publicPaths ?? []),
|
|
73
88
|
...(expanded?.anonymousPaths ?? []),
|
|
89
|
+
...lazyPlugins.flatMap((plugin) => plugin.anonymous ?? []),
|
|
74
90
|
]);
|
|
75
91
|
// When the framework owns the bus, route subscriber-dispatch failures
|
|
76
92
|
// (including the workflow forwarder) to the reporter — they're otherwise
|
|
@@ -109,22 +125,25 @@ export function mountApp(config) {
|
|
|
109
125
|
// runtime is fail-closed).
|
|
110
126
|
const collectedWorkflows = [];
|
|
111
127
|
const collectedFilters = [];
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
128
|
+
function collectModuleRuntimeDescriptors(modules) {
|
|
129
|
+
for (const mod of modules) {
|
|
130
|
+
if (mod.module.workflows)
|
|
131
|
+
collectedWorkflows.push(...mod.module.workflows);
|
|
132
|
+
if (mod.module.eventFilters)
|
|
133
|
+
collectedFilters.push(...mod.module.eventFilters);
|
|
134
|
+
}
|
|
117
135
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
136
|
+
function collectPluginRuntimeDescriptors(plugins) {
|
|
137
|
+
for (const plugin of plugins) {
|
|
138
|
+
if (plugin.workflows)
|
|
139
|
+
collectedWorkflows.push(...plugin.workflows);
|
|
140
|
+
if (plugin.eventFilters)
|
|
141
|
+
collectedFilters.push(...plugin.eventFilters);
|
|
142
|
+
}
|
|
123
143
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (config.workflows && collectedWorkflows.length > 0) {
|
|
144
|
+
function assertUniqueWorkflowIds() {
|
|
145
|
+
if (!config.workflows || collectedWorkflows.length === 0)
|
|
146
|
+
return;
|
|
128
147
|
const seen = new Map();
|
|
129
148
|
for (const wf of collectedWorkflows) {
|
|
130
149
|
const existing = seen.get(wf.id);
|
|
@@ -136,6 +155,122 @@ export function mountApp(config) {
|
|
|
136
155
|
seen.set(wf.id, wf);
|
|
137
156
|
}
|
|
138
157
|
}
|
|
158
|
+
collectModuleRuntimeDescriptors(allModules);
|
|
159
|
+
collectPluginRuntimeDescriptors(eagerPlugins);
|
|
160
|
+
assertUniqueWorkflowIds();
|
|
161
|
+
const txModuleNames = new Set();
|
|
162
|
+
const txRequiringModules = [];
|
|
163
|
+
const txPrefixes = [...(config.dbTransactionalPaths ?? [])];
|
|
164
|
+
function addTransactionalModuleName(name) {
|
|
165
|
+
if (txModuleNames.has(name))
|
|
166
|
+
return;
|
|
167
|
+
txModuleNames.add(name);
|
|
168
|
+
txRequiringModules.push(name);
|
|
169
|
+
// `/v1/public/<name>` is added unconditionally (not only when the module
|
|
170
|
+
// mounts publicRoutes): other modules mounted at the public root can serve
|
|
171
|
+
// paths under a flagged module's segment.
|
|
172
|
+
txPrefixes.push(`/v1/admin/${name}`, `/v1/${name}`, `/v1/public/${name}`);
|
|
173
|
+
}
|
|
174
|
+
function addTransactionalSurfaces(modules, extensions) {
|
|
175
|
+
for (const mod of modules) {
|
|
176
|
+
if (mod.module.requiresTransactionalDb)
|
|
177
|
+
addTransactionalModuleName(mod.module.name);
|
|
178
|
+
}
|
|
179
|
+
for (const ext of extensions) {
|
|
180
|
+
if (ext.extension.requiresTransactionalDb)
|
|
181
|
+
addTransactionalModuleName(ext.extension.module);
|
|
182
|
+
}
|
|
183
|
+
for (const mod of modules) {
|
|
184
|
+
if (txModuleNames.has(mod.module.name) && mod.publicRoutes) {
|
|
185
|
+
txPrefixes.push(resolveSurfaceMountPath("/v1/public", mod.publicPath, mod.module.name));
|
|
186
|
+
}
|
|
187
|
+
if (mod.transactionalPaths)
|
|
188
|
+
txPrefixes.push(...mod.transactionalPaths);
|
|
189
|
+
}
|
|
190
|
+
for (const ext of extensions) {
|
|
191
|
+
if (txModuleNames.has(ext.extension.module) && ext.publicRoutes) {
|
|
192
|
+
txPrefixes.push(resolveSurfaceMountPath("/v1/public", ext.publicPath, ext.extension.module));
|
|
193
|
+
}
|
|
194
|
+
if (ext.transactionalPaths)
|
|
195
|
+
txPrefixes.push(...ext.transactionalPaths);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
addTransactionalSurfaces(allModules, allExtensions);
|
|
199
|
+
for (const plugin of lazyPlugins) {
|
|
200
|
+
for (const moduleName of plugin.transactionalModules ?? []) {
|
|
201
|
+
addTransactionalModuleName(moduleName);
|
|
202
|
+
}
|
|
203
|
+
if (plugin.transactionalPaths)
|
|
204
|
+
txPrefixes.push(...plugin.transactionalPaths);
|
|
205
|
+
}
|
|
206
|
+
const loadedLazyBundles = new Map();
|
|
207
|
+
const lazyBundlePromises = new Map();
|
|
208
|
+
let lazyPluginExpansionPromise;
|
|
209
|
+
const expandedLazyBundleNames = new Set();
|
|
210
|
+
function loadLazyBundle(plugin) {
|
|
211
|
+
const cached = loadedLazyBundles.get(plugin.name);
|
|
212
|
+
if (cached)
|
|
213
|
+
return Promise.resolve(cached);
|
|
214
|
+
const pending = lazyBundlePromises.get(plugin.name);
|
|
215
|
+
if (pending)
|
|
216
|
+
return pending;
|
|
217
|
+
const promise = plugin
|
|
218
|
+
.load()
|
|
219
|
+
.then((bundle) => {
|
|
220
|
+
if (bundle.name !== plugin.name) {
|
|
221
|
+
throw new Error(`Lazy bundle "${plugin.name}" loaded bundle "${bundle.name}". ` +
|
|
222
|
+
"The metadata name must match the loaded bundle name.");
|
|
223
|
+
}
|
|
224
|
+
loadedLazyBundles.set(plugin.name, bundle);
|
|
225
|
+
return bundle;
|
|
226
|
+
})
|
|
227
|
+
.catch((error) => {
|
|
228
|
+
lazyBundlePromises.delete(plugin.name);
|
|
229
|
+
throw error;
|
|
230
|
+
});
|
|
231
|
+
lazyBundlePromises.set(plugin.name, promise);
|
|
232
|
+
return promise;
|
|
233
|
+
}
|
|
234
|
+
function applyLazyBundleContributions(bundles) {
|
|
235
|
+
const pending = bundles.filter((bundle) => !expandedLazyBundleNames.has(bundle.name));
|
|
236
|
+
if (pending.length === 0)
|
|
237
|
+
return;
|
|
238
|
+
const lazyExpanded = expandHonoBundles(pending);
|
|
239
|
+
for (const bundle of pending)
|
|
240
|
+
expandedLazyBundleNames.add(bundle.name);
|
|
241
|
+
allModules.push(...lazyExpanded.modules);
|
|
242
|
+
allExtensions.push(...lazyExpanded.extensions);
|
|
243
|
+
anonymousPaths.push(...assembleAnonymousPaths(lazyExpanded.modules, lazyExpanded.extensions, [
|
|
244
|
+
...lazyExpanded.anonymousPaths,
|
|
245
|
+
]));
|
|
246
|
+
for (const mod of lazyExpanded.modules) {
|
|
247
|
+
if (mod.module.service !== undefined) {
|
|
248
|
+
container.register(mod.module.name, mod.module.service);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
for (const sub of lazyExpanded.subscribers) {
|
|
252
|
+
eventBus.subscribe(sub.event, sub.handler, { inline: sub.inline ?? false });
|
|
253
|
+
}
|
|
254
|
+
collectModuleRuntimeDescriptors(lazyExpanded.modules);
|
|
255
|
+
collectPluginRuntimeDescriptors(pending);
|
|
256
|
+
addTransactionalSurfaces(lazyExpanded.modules, lazyExpanded.extensions);
|
|
257
|
+
}
|
|
258
|
+
async function ensureBootstrapLazyPluginsExpanded() {
|
|
259
|
+
const bootstrapLazyPlugins = lazyPlugins.filter((plugin) => plugin.loadOnBootstrap);
|
|
260
|
+
if (bootstrapLazyPlugins.length === 0)
|
|
261
|
+
return;
|
|
262
|
+
if (!lazyPluginExpansionPromise) {
|
|
263
|
+
lazyPluginExpansionPromise = Promise.all(bootstrapLazyPlugins.map(loadLazyBundle))
|
|
264
|
+
.then((bundles) => {
|
|
265
|
+
applyLazyBundleContributions(bundles);
|
|
266
|
+
})
|
|
267
|
+
.catch((error) => {
|
|
268
|
+
lazyPluginExpansionPromise = undefined;
|
|
269
|
+
throw error;
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
await lazyPluginExpansionPromise;
|
|
273
|
+
}
|
|
139
274
|
// Workflow driver construction is **deferred** to the lazy bootstrap
|
|
140
275
|
// path so callers whose driver options come from `env.*` bindings can
|
|
141
276
|
// pass a function-of-bindings shape. Node / InMemory users usually
|
|
@@ -146,6 +281,8 @@ export function mountApp(config) {
|
|
|
146
281
|
if (!bootstrapPromise) {
|
|
147
282
|
bootstrapPromise = (async () => {
|
|
148
283
|
const ctx = { bindings, container, eventBus };
|
|
284
|
+
await ensureBootstrapLazyPluginsExpanded();
|
|
285
|
+
assertUniqueWorkflowIds();
|
|
149
286
|
// ---- Workflow runtime FIRST — fail-closed manifest registration
|
|
150
287
|
// and EventBus forwarder must be in place before any module
|
|
151
288
|
// bootstrap can emit. Otherwise a `module.bootstrap` that
|
|
@@ -196,7 +333,12 @@ export function mountApp(config) {
|
|
|
196
333
|
});
|
|
197
334
|
}
|
|
198
335
|
};
|
|
199
|
-
for (const plugin of
|
|
336
|
+
for (const plugin of [
|
|
337
|
+
...eagerPlugins,
|
|
338
|
+
...lazyPlugins
|
|
339
|
+
.filter((p) => p.loadOnBootstrap)
|
|
340
|
+
.map((p) => loadedLazyBundles.get(p.name)),
|
|
341
|
+
]) {
|
|
200
342
|
await runIsolated(`plugin:${plugin.name}`, plugin.bootstrap);
|
|
201
343
|
}
|
|
202
344
|
for (const mod of allModules) {
|
|
@@ -322,48 +464,6 @@ export function mountApp(config) {
|
|
|
322
464
|
if (authHandler) {
|
|
323
465
|
mountAuthForwarding(app, authHandler, { reporter, appName });
|
|
324
466
|
}
|
|
325
|
-
// Transactional surface map: a request must be served by a
|
|
326
|
-
// transaction-capable db client when its path belongs to (a) a module
|
|
327
|
-
// declaring `requiresTransactionalDb`, (b) a module targeted by an
|
|
328
|
-
// extension that declares it (extensions mount under the target
|
|
329
|
-
// module's prefix — e.g. catalog-authoring's compose routes live under
|
|
330
|
-
// /v1/admin/products), or (c) a template-supplied extra path
|
|
331
|
-
// (`dbTransactionalPaths` — for additionalRoutes / adapter-wired flows
|
|
332
|
-
// like the catalog booking engine whose transactionality depends on
|
|
333
|
-
// starter wiring).
|
|
334
|
-
const txModuleNames = new Set(allModules.filter((m) => m.module.requiresTransactionalDb).map((m) => m.module.name));
|
|
335
|
-
for (const ext of allExtensions) {
|
|
336
|
-
if (ext.extension.requiresTransactionalDb)
|
|
337
|
-
txModuleNames.add(ext.extension.module);
|
|
338
|
-
}
|
|
339
|
-
const txRequiringModules = [...txModuleNames];
|
|
340
|
-
const txPrefixes = [...(config.dbTransactionalPaths ?? [])];
|
|
341
|
-
for (const name of txModuleNames) {
|
|
342
|
-
// `/v1/public/<name>` is added unconditionally (not only when the
|
|
343
|
-
// module mounts publicRoutes): other modules mounted at the public
|
|
344
|
-
// root can serve paths under a flagged module's segment — e.g.
|
|
345
|
-
// storefront (publicPath "/") handles
|
|
346
|
-
// /v1/public/bookings/sessions/bootstrap, which reaches
|
|
347
|
-
// bookings' transactional reserve flow.
|
|
348
|
-
txPrefixes.push(`/v1/admin/${name}`, `/v1/${name}`, `/v1/public/${name}`);
|
|
349
|
-
}
|
|
350
|
-
for (const mod of allModules) {
|
|
351
|
-
if (txModuleNames.has(mod.module.name) && mod.publicRoutes) {
|
|
352
|
-
txPrefixes.push(resolveSurfaceMountPath("/v1/public", mod.publicPath, mod.module.name));
|
|
353
|
-
}
|
|
354
|
-
// Absolute transactional prefixes for routes mounted outside the name-based
|
|
355
|
-
// surface (e.g. a lazy family at `/v1/admin/catalog/quote`), so the
|
|
356
|
-
// deployment doesn't hand-maintain them in `dbTransactionalPaths` (ADR-0008).
|
|
357
|
-
if (mod.transactionalPaths)
|
|
358
|
-
txPrefixes.push(...mod.transactionalPaths);
|
|
359
|
-
}
|
|
360
|
-
for (const ext of allExtensions) {
|
|
361
|
-
if (txModuleNames.has(ext.extension.module) && ext.publicRoutes) {
|
|
362
|
-
txPrefixes.push(resolveSurfaceMountPath("/v1/public", ext.publicPath, ext.extension.module));
|
|
363
|
-
}
|
|
364
|
-
if (ext.transactionalPaths)
|
|
365
|
-
txPrefixes.push(...ext.transactionalPaths);
|
|
366
|
-
}
|
|
367
467
|
// With a `dbTransactional` factory, requests are routed per surface:
|
|
368
468
|
// transactional prefixes get it, everything else gets the cheap
|
|
369
469
|
// default (typically neon-http — no per-request connection handshake).
|
|
@@ -432,6 +532,61 @@ export function mountApp(config) {
|
|
|
432
532
|
mountLazyRoutePaths(app, paths, load);
|
|
433
533
|
});
|
|
434
534
|
}
|
|
535
|
+
function mountModuleRoutesInto(target, mod) {
|
|
536
|
+
const moduleName = mod.module.name;
|
|
537
|
+
const adminPrefix = `/v1/admin/${moduleName}`;
|
|
538
|
+
const publicPrefix = resolveSurfaceMountPath("/v1/public", mod.publicPath, moduleName);
|
|
539
|
+
if (mod.adminRoutes) {
|
|
540
|
+
target.route(adminPrefix, mod.adminRoutes);
|
|
541
|
+
}
|
|
542
|
+
if (mod.publicRoutes) {
|
|
543
|
+
target.route(publicPrefix, mod.publicRoutes);
|
|
544
|
+
}
|
|
545
|
+
if (mod.lazyAdminRoutes) {
|
|
546
|
+
mountLazyRoutesAt(target, adminPrefix, mod.lazyAdminRoutes);
|
|
547
|
+
}
|
|
548
|
+
if (mod.lazyPublicRoutes) {
|
|
549
|
+
mountLazyRoutesAt(target, publicPrefix, mod.lazyPublicRoutes);
|
|
550
|
+
}
|
|
551
|
+
if (mod.lazyRoutes) {
|
|
552
|
+
mountLazyRoutePaths(target, mod.lazyRoutes.paths, mod.lazyRoutes.load);
|
|
553
|
+
}
|
|
554
|
+
if (mod.webhookRoutes) {
|
|
555
|
+
target.route(`/v1/${moduleName}`, mod.webhookRoutes);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
function mountExtensionRoutesInto(target, ext) {
|
|
559
|
+
const moduleName = ext.extension.module;
|
|
560
|
+
const adminPrefix = `/v1/admin/${moduleName}`;
|
|
561
|
+
const publicPrefix = resolveSurfaceMountPath("/v1/public", ext.publicPath, moduleName);
|
|
562
|
+
if (ext.adminRoutes) {
|
|
563
|
+
target.route(adminPrefix, ext.adminRoutes);
|
|
564
|
+
}
|
|
565
|
+
if (ext.publicRoutes) {
|
|
566
|
+
target.route(publicPrefix, ext.publicRoutes);
|
|
567
|
+
}
|
|
568
|
+
if (ext.lazyAdminRoutes) {
|
|
569
|
+
mountLazyRoutesAt(target, adminPrefix, ext.lazyAdminRoutes);
|
|
570
|
+
}
|
|
571
|
+
if (ext.lazyPublicRoutes) {
|
|
572
|
+
mountLazyRoutesAt(target, publicPrefix, ext.lazyPublicRoutes);
|
|
573
|
+
}
|
|
574
|
+
if (ext.lazyRoutes) {
|
|
575
|
+
mountLazyRoutePaths(target, ext.lazyRoutes.paths, ext.lazyRoutes.load);
|
|
576
|
+
}
|
|
577
|
+
if (ext.webhookRoutes) {
|
|
578
|
+
target.route(`/v1/${moduleName}`, ext.webhookRoutes);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
function buildBundleRouteApp(bundle) {
|
|
582
|
+
const pluginRoutes = new OpenAPIHono();
|
|
583
|
+
const bundleExpanded = expandHonoBundles([bundle]);
|
|
584
|
+
for (const mod of bundleExpanded.modules)
|
|
585
|
+
mountModuleRoutesInto(pluginRoutes, mod);
|
|
586
|
+
for (const ext of bundleExpanded.extensions)
|
|
587
|
+
mountExtensionRoutesInto(pluginRoutes, ext);
|
|
588
|
+
return pluginRoutes;
|
|
589
|
+
}
|
|
435
590
|
// Mount module routes
|
|
436
591
|
for (const mod of allModules) {
|
|
437
592
|
const moduleName = mod.module.name;
|
|
@@ -488,6 +643,15 @@ export function mountApp(config) {
|
|
|
488
643
|
app.route(`/v1/${moduleName}`, ext.webhookRoutes);
|
|
489
644
|
}
|
|
490
645
|
}
|
|
646
|
+
for (const plugin of lazyPlugins) {
|
|
647
|
+
if (!plugin.routes || plugin.routes.length === 0)
|
|
648
|
+
continue;
|
|
649
|
+
deferLazyRoutePaths(`plugin:${plugin.name}`, plugin.routes, async () => {
|
|
650
|
+
const bundle = await loadLazyBundle(plugin);
|
|
651
|
+
applyLazyBundleContributions([bundle]);
|
|
652
|
+
return buildBundleRouteApp(bundle);
|
|
653
|
+
});
|
|
654
|
+
}
|
|
491
655
|
for (const mountLazyRoutes of deferredLazyRouteMounts) {
|
|
492
656
|
mountLazyRoutes();
|
|
493
657
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,15 +6,17 @@ export { constantTimeEqual, extractBearerToken, generateNumericCode, randomBytes
|
|
|
6
6
|
export { type CreateAppConfig, createApp } from "./create-app.js";
|
|
7
7
|
export type { AuthenticatedR2DocumentDownloadResolver, AuthenticatedR2DocumentDownloadResolverOptions, DocumentDownloadEnvelope, DocumentDownloadResolution, DocumentDownloadResolver, DocumentDownloadResolverResult, StoredDocumentReference, } from "./document-download.js";
|
|
8
8
|
export { createAuthenticatedR2DocumentDownloadResolver, encodeStorageKeyPath, resolveStoredDocumentDownload, } from "./document-download.js";
|
|
9
|
+
export { type AsyncMethodProvider, lazyProvider } from "./lazy-provider.js";
|
|
9
10
|
export { createLazyRouteHandler, type LazyHonoRoutes, type LazyRoutesLoader, mountLazyRoutePaths, mountLazyRoutesAt, } from "./lazy-routes.js";
|
|
10
11
|
export { createPathDbSelector, type PathDbSelectorOptions } from "./lib/db-selector.js";
|
|
11
|
-
export
|
|
12
|
+
export type { RateLimitStore } from "./middleware/index.js";
|
|
13
|
+
export { clientIpKey, consoleLoggerProvider, cors, createMemoryRateLimitStore, createRedisRateLimitStore, DEFAULT_IDEMPOTENCY_TTL_MS, db, enforceRateLimit, errorBoundary, handleApiError, type IdempotencyKeyOptions, idempotencyKey, isStaffRbacEnforced, LIVE_LIMITS, logger, purgeExpiredIdempotencyKeys, rateLimit, requestId, requireActor, requireAuth, requirePermission, } from "./middleware/index.js";
|
|
12
14
|
export type { HonoExtension, HonoModule } from "./module.js";
|
|
13
15
|
export type { ErrorEvent, Reporter } from "./observability/index.js";
|
|
14
16
|
export { consoleReporter, getRequestId, noopReporter, runWithRequestId, safeCaptureException, } from "./observability/index.js";
|
|
15
17
|
export { openApiValidationHook } from "./openapi-validation.js";
|
|
16
|
-
export type { ExpandedHonoBundles, ExpandedHonoPlugins, HonoBundle, HonoPlugin, } from "./plugin.js";
|
|
17
|
-
export { defineHonoBundle, defineHonoPlugin, expandHonoBundles, expandHonoPlugins, } from "./plugin.js";
|
|
18
|
+
export type { ExpandedHonoBundles, ExpandedHonoPlugins, HonoBundle, HonoBundleInput, HonoPlugin, LazyHonoBundle, } from "./plugin.js";
|
|
19
|
+
export { defineHonoBundle, defineHonoPlugin, defineLazyHonoBundle, expandHonoBundles, expandHonoPlugins, isLazyHonoBundle, } from "./plugin.js";
|
|
18
20
|
export type { CreatePublicCapabilityOptions, PublicCapabilityCookieOptions, PublicCapabilityPayload, VerifyPublicCapabilityOptions, } from "./public-capability.js";
|
|
19
21
|
export { createPublicCapabilityToken, extractPublicCapabilityToken, serializePublicCapabilityCookie, verifyPublicCapabilityToken, } from "./public-capability.js";
|
|
20
22
|
export { type CreatePublicDocumentDeliveryInput, createDrizzlePublicDocumentDeliveryGrantStore, createPublicDocumentDeliveryGrant, createPublicDocumentDeliveryHonoModule, createPublicDocumentDeliveryRoutes, type PublicDocumentDeliveryAccessContext, type PublicDocumentDeliveryEnvelope, type PublicDocumentDeliveryGrant, type PublicDocumentDeliveryGrantStore, type PublicDocumentDeliveryResolution, type PublicDocumentDeliveryRouteOptions, type PublicDocumentDeliverySource, type RevokePublicDocumentDeliveryGrantInput, resolvePublicDocumentDeliveryGrant, revokePublicDocumentDeliveryGrant, } from "./public-document-delivery.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,eAAe,EACf,SAAS,EACT,YAAY,EACZ,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACjE,YAAY,EACV,uCAAuC,EACvC,8CAA8C,EAC9C,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,6CAA6C,EAC7C,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AACvF,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,IAAI,EACJ,0BAA0B,EAC1B,EAAE,EACF,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,KAAK,qBAAqB,EAC1B,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,MAAM,EACN,2BAA2B,EAC3B,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC5D,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EACL,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,13 @@ export { mountApp } from "./app.js";
|
|
|
3
3
|
export { constantTimeEqual, extractBearerToken, generateNumericCode, randomBytesHex, requireUserId, sha256Base64Url, sha256Hex, unsignCookie, verifySession, } from "./auth/index.js";
|
|
4
4
|
export { createApp } from "./create-app.js";
|
|
5
5
|
export { createAuthenticatedR2DocumentDownloadResolver, encodeStorageKeyPath, resolveStoredDocumentDownload, } from "./document-download.js";
|
|
6
|
+
export { lazyProvider } from "./lazy-provider.js";
|
|
6
7
|
export { createLazyRouteHandler, mountLazyRoutePaths, mountLazyRoutesAt, } from "./lazy-routes.js";
|
|
7
8
|
export { createPathDbSelector } from "./lib/db-selector.js";
|
|
8
|
-
export { clientIpKey, consoleLoggerProvider, cors, DEFAULT_IDEMPOTENCY_TTL_MS, db, enforceRateLimit, errorBoundary, handleApiError, idempotencyKey, isStaffRbacEnforced, LIVE_LIMITS, logger, purgeExpiredIdempotencyKeys, rateLimit, requestId, requireActor, requireAuth, requirePermission, } from "./middleware/index.js";
|
|
9
|
+
export { clientIpKey, consoleLoggerProvider, cors, createMemoryRateLimitStore, createRedisRateLimitStore, DEFAULT_IDEMPOTENCY_TTL_MS, db, enforceRateLimit, errorBoundary, handleApiError, idempotencyKey, isStaffRbacEnforced, LIVE_LIMITS, logger, purgeExpiredIdempotencyKeys, rateLimit, requestId, requireActor, requireAuth, requirePermission, } from "./middleware/index.js";
|
|
9
10
|
export { consoleReporter, getRequestId, noopReporter, runWithRequestId, safeCaptureException, } from "./observability/index.js";
|
|
10
11
|
export { openApiValidationHook } from "./openapi-validation.js";
|
|
11
|
-
export { defineHonoBundle, defineHonoPlugin, expandHonoBundles, expandHonoPlugins, } from "./plugin.js";
|
|
12
|
+
export { defineHonoBundle, defineHonoPlugin, defineLazyHonoBundle, expandHonoBundles, expandHonoPlugins, isLazyHonoBundle, } from "./plugin.js";
|
|
12
13
|
export { createPublicCapabilityToken, extractPublicCapabilityToken, serializePublicCapabilityCookie, verifyPublicCapabilityToken, } from "./public-capability.js";
|
|
13
14
|
export { createDrizzlePublicDocumentDeliveryGrantStore, createPublicDocumentDeliveryGrant, createPublicDocumentDeliveryHonoModule, createPublicDocumentDeliveryRoutes, resolvePublicDocumentDeliveryGrant, revokePublicDocumentDeliveryGrant, } from "./public-document-delivery.js";
|
|
14
15
|
export { ApiHttpError, ForbiddenApiError, normalizeValidationError, parseJsonBody, parseOptionalJsonBody, parseQuery, RequestValidationError, UnauthorizedApiError, } from "./validation.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type AnyAsyncFunction = (...args: any[]) => Promise<unknown>;
|
|
2
|
+
export type AsyncMethodProvider<T extends object> = {
|
|
3
|
+
[K in keyof T]: T[K] extends (...args: infer Args) => infer Result ? (...args: Args) => Promise<Awaited<Result>> : never;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Build a memoized proxy for a provider/service value that is expensive to
|
|
7
|
+
* import eagerly. Method calls and direct function calls resolve the target on
|
|
8
|
+
* first use, cache it for the isolate/process, and retry after a failed load.
|
|
9
|
+
*
|
|
10
|
+
* This helper is only for async provider seams. Object providers must expose
|
|
11
|
+
* async methods only; plain properties and sync-returning methods are outside
|
|
12
|
+
* the contract because a proxy cannot distinguish `service.flag` from
|
|
13
|
+
* `service.method` until call time.
|
|
14
|
+
*/
|
|
15
|
+
export declare function lazyProvider<T extends AnyAsyncFunction>(load: () => Promise<T>): T;
|
|
16
|
+
export declare function lazyProvider<T extends object>(load: () => Promise<AsyncMethodProvider<T>>): AsyncMethodProvider<T>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=lazy-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-provider.d.ts","sourceRoot":"","sources":["../src/lazy-provider.ts"],"names":[],"mappings":"AACA,KAAK,gBAAgB,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE5D,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,IAAI;KACjD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,IAAI,KAAK,MAAM,MAAM,GAC9D,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAC3C,KAAK;CACV,CAAA;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,gBAAgB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AACnF,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,IAAI,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAC1C,mBAAmB,CAAC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function lazyProvider(load) {
|
|
2
|
+
let targetPromise;
|
|
3
|
+
function resolveTarget() {
|
|
4
|
+
if (!targetPromise) {
|
|
5
|
+
targetPromise = load().catch((error) => {
|
|
6
|
+
targetPromise = undefined;
|
|
7
|
+
throw error;
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
return targetPromise;
|
|
11
|
+
}
|
|
12
|
+
const callable = async (...args) => {
|
|
13
|
+
const target = await resolveTarget();
|
|
14
|
+
if (typeof target !== "function") {
|
|
15
|
+
throw new TypeError("Lazy provider target is not callable");
|
|
16
|
+
}
|
|
17
|
+
return target(...args);
|
|
18
|
+
};
|
|
19
|
+
return new Proxy(callable, {
|
|
20
|
+
apply: (_target, thisArg, args) => resolveTarget().then((target) => {
|
|
21
|
+
if (typeof target !== "function") {
|
|
22
|
+
throw new TypeError("Lazy provider target is not callable");
|
|
23
|
+
}
|
|
24
|
+
return Reflect.apply(target, thisArg, args);
|
|
25
|
+
}),
|
|
26
|
+
get: (_target, prop) => {
|
|
27
|
+
if (prop === "then")
|
|
28
|
+
return undefined;
|
|
29
|
+
if (prop === "toString")
|
|
30
|
+
return () => "[lazy provider]";
|
|
31
|
+
if (prop === Symbol.toStringTag)
|
|
32
|
+
return "LazyProvider";
|
|
33
|
+
return async (...args) => {
|
|
34
|
+
const target = await resolveTarget();
|
|
35
|
+
const value = Reflect.get(target, prop, target);
|
|
36
|
+
if (typeof value !== "function") {
|
|
37
|
+
if (args.length === 0)
|
|
38
|
+
return value;
|
|
39
|
+
throw new TypeError(`Lazy provider property "${String(prop)}" is not callable`);
|
|
40
|
+
}
|
|
41
|
+
return Reflect.apply(value, target, args);
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
package/dist/lib/db-selector.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* (`acquireRequestDb`) works across middlewares.
|
|
8
8
|
*/
|
|
9
9
|
export function createPathDbSelector(options) {
|
|
10
|
-
const prefixes = [...new Set(options.transactionalPrefixes)];
|
|
11
10
|
const transactional = {
|
|
12
11
|
factory: options.transactionalFactory,
|
|
13
12
|
mustSupportTransactions: true,
|
|
@@ -18,6 +17,7 @@ export function createPathDbSelector(options) {
|
|
|
18
17
|
};
|
|
19
18
|
return {
|
|
20
19
|
select(path) {
|
|
20
|
+
const prefixes = [...new Set(options.transactionalPrefixes)];
|
|
21
21
|
for (const prefix of prefixes) {
|
|
22
22
|
if (path === prefix || path.startsWith(`${prefix}/`))
|
|
23
23
|
return transactional;
|
|
@@ -7,7 +7,7 @@ export { DEFAULT_IDEMPOTENCY_TTL_MS, type IdempotencyKeyOptions, idempotencyKey,
|
|
|
7
7
|
export { consoleLoggerProvider, logger } from "./logger.js";
|
|
8
8
|
export { type AnalyticsEngineDatasetLike, DB_METRICS_CONTEXT_KEY, type MetricsMiddlewareOptions, metrics, type RequestDbMetrics, withQueryCounting, } from "./metrics.js";
|
|
9
9
|
export { type PublicCacheOptions, publicResponseCache, resetPublicCacheStateForTests, } from "./public-cache.js";
|
|
10
|
-
export { type CloudflareRateLimiterBinding, clientIpKey, createCloudflareRateLimitStore, createKvRateLimitStore, createMemoryRateLimitStore, enforceRateLimit, LIVE_LIMITS, type RateLimitConfig, type RateLimitPolicy, type RateLimitRequestContext, type RateLimitResult, type RateLimitRule, type RateLimitStore, rateLimit, resolveRateLimitStore, } from "./rate-limit.js";
|
|
10
|
+
export { type CloudflareRateLimiterBinding, clientIpKey, createCloudflareRateLimitStore, createKvRateLimitStore, createMemoryRateLimitStore, createRedisRateLimitStore, enforceRateLimit, LIVE_LIMITS, type RateLimitConfig, type RateLimitPolicy, type RateLimitRequestContext, type RateLimitResult, type RateLimitRule, type RateLimitStore, type RedisRateLimitStoreOptions, rateLimit, resolveRateLimitStore, } from "./rate-limit.js";
|
|
11
11
|
export { isStaffRbacEnforced, requireActor } from "./require-actor.js";
|
|
12
12
|
export { requirePermission } from "./require-permission.js";
|
|
13
13
|
export { type SecurityHeadersOptions, securityHeaders } from "./security-headers.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EACL,gCAAgC,EAChC,KAAK,uBAAuB,EAC5B,gBAAgB,GACjB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,EAC1B,cAAc,EACd,SAAS,GACV,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,cAAc,EACd,2BAA2B,GAC5B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EACL,KAAK,0BAA0B,EAC/B,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,OAAO,EACP,KAAK,gBAAgB,EACrB,iBAAiB,GAClB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,KAAK,4BAA4B,EACjC,WAAW,EACX,8BAA8B,EAC9B,sBAAsB,EACtB,0BAA0B,EAC1B,gBAAgB,EAChB,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,SAAS,EACT,qBAAqB,GACtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EACL,gCAAgC,EAChC,KAAK,uBAAuB,EAC5B,gBAAgB,GACjB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,EAC1B,cAAc,EACd,SAAS,GACV,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,cAAc,EACd,2BAA2B,GAC5B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EACL,KAAK,0BAA0B,EAC/B,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,OAAO,EACP,KAAK,gBAAgB,EACrB,iBAAiB,GAClB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,KAAK,4BAA4B,EACjC,WAAW,EACX,8BAA8B,EAC9B,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,EAChB,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,0BAA0B,EAC/B,SAAS,EACT,qBAAqB,GACtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,KAAK,sBAAsB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA"}
|
package/dist/middleware/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export { DEFAULT_IDEMPOTENCY_TTL_MS, idempotencyKey, purgeExpiredIdempotencyKeys
|
|
|
7
7
|
export { consoleLoggerProvider, logger } from "./logger.js";
|
|
8
8
|
export { DB_METRICS_CONTEXT_KEY, metrics, withQueryCounting, } from "./metrics.js";
|
|
9
9
|
export { publicResponseCache, resetPublicCacheStateForTests, } from "./public-cache.js";
|
|
10
|
-
export { clientIpKey, createCloudflareRateLimitStore, createKvRateLimitStore, createMemoryRateLimitStore, enforceRateLimit, LIVE_LIMITS, rateLimit, resolveRateLimitStore, } from "./rate-limit.js";
|
|
10
|
+
export { clientIpKey, createCloudflareRateLimitStore, createKvRateLimitStore, createMemoryRateLimitStore, createRedisRateLimitStore, enforceRateLimit, LIVE_LIMITS, rateLimit, resolveRateLimitStore, } from "./rate-limit.js";
|
|
11
11
|
export { isStaffRbacEnforced, requireActor } from "./require-actor.js";
|
|
12
12
|
export { requirePermission } from "./require-permission.js";
|
|
13
13
|
export { securityHeaders } from "./security-headers.js";
|
|
@@ -34,9 +34,9 @@ export declare function resetPublicCacheStateForTests(): void;
|
|
|
34
34
|
* and no module-graph instantiation, which is the entire point under
|
|
35
35
|
* storefront load (#1686).
|
|
36
36
|
*
|
|
37
|
-
* Backend selection:
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* Backend selection: the injected `env.CACHE` {@link KVStore}. Node
|
|
38
|
+
* composition decides whether that is memory, Postgres, Redis, or a tiered
|
|
39
|
+
* store; this middleware never probes a global runtime cache.
|
|
40
40
|
*/
|
|
41
41
|
export declare function publicResponseCache<TBindings extends VoyantBindings>(options?: PublicCacheOptions): MiddlewareHandler<{
|
|
42
42
|
Bindings: TBindings;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-cache.d.ts","sourceRoot":"","sources":["../../src/middleware/public-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAG7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;
|
|
1
|
+
{"version":3,"file":"public-cache.d.ts","sourceRoot":"","sources":["../../src/middleware/public-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAG7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAwCD,6DAA6D;AAC7D,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD;AAiDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,SAAS,cAAc,EAClE,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAAC;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,CAAC,CA4C5C"}
|
|
@@ -33,45 +33,9 @@ function parseCacheControl(value) {
|
|
|
33
33
|
}
|
|
34
34
|
return { isPublic, sMaxage };
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
37
|
-
* `caches.default` is available on regular Cloudflare Workers but
|
|
38
|
-
* DISABLED inside Workers-for-Platforms namespaced scripts (access or
|
|
39
|
-
* use throws). Probe once, and demote to "unavailable" on any runtime
|
|
40
|
-
* failure so namespaced deployments settle on the KV fallback after a
|
|
41
|
-
* single failed attempt.
|
|
42
|
-
*/
|
|
43
|
-
let cacheApiState = "unknown";
|
|
44
|
-
function getCacheApi() {
|
|
45
|
-
if (cacheApiState === "unavailable")
|
|
46
|
-
return undefined;
|
|
47
|
-
try {
|
|
48
|
-
const candidate = globalThis.caches?.default;
|
|
49
|
-
if (candidate && typeof candidate.match === "function") {
|
|
50
|
-
cacheApiState = "available";
|
|
51
|
-
return candidate;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
// fall through to unavailable
|
|
56
|
-
}
|
|
57
|
-
cacheApiState = "unavailable";
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
|
60
|
-
function markCacheApiUnavailable() {
|
|
61
|
-
cacheApiState = "unavailable";
|
|
62
|
-
}
|
|
63
36
|
/** Test hook — resets the memoized Cache API probe state. */
|
|
64
37
|
export function resetPublicCacheStateForTests() {
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
function sanitizedResponseCopy(res) {
|
|
68
|
-
const headers = new Headers();
|
|
69
|
-
res.headers.forEach((value, name) => {
|
|
70
|
-
if (!isUncacheableHeader(name))
|
|
71
|
-
headers.set(name, value);
|
|
72
|
-
});
|
|
73
|
-
headers.set("x-voyant-cache", "hit");
|
|
74
|
-
return new Response(res.body, { status: res.status, headers });
|
|
38
|
+
// Retained for test/import compatibility after removing the global Cache API path.
|
|
75
39
|
}
|
|
76
40
|
function kvKeyFor(url) {
|
|
77
41
|
return `${KV_KEY_PREFIX}${url}`;
|
|
@@ -123,9 +87,9 @@ async function kvStore(kv, url, res, ttlSeconds, maxBodyBytes) {
|
|
|
123
87
|
* and no module-graph instantiation, which is the entire point under
|
|
124
88
|
* storefront load (#1686).
|
|
125
89
|
*
|
|
126
|
-
* Backend selection:
|
|
127
|
-
*
|
|
128
|
-
*
|
|
90
|
+
* Backend selection: the injected `env.CACHE` {@link KVStore}. Node
|
|
91
|
+
* composition decides whether that is memory, Postgres, Redis, or a tiered
|
|
92
|
+
* store; this middleware never probes a global runtime cache.
|
|
129
93
|
*/
|
|
130
94
|
export function publicResponseCache(options = {}) {
|
|
131
95
|
const prefixes = options.pathPrefixes ?? DEFAULT_PREFIXES;
|
|
@@ -141,58 +105,27 @@ export function publicResponseCache(options = {}) {
|
|
|
141
105
|
const requestDirective = c.req.header("cache-control")?.toLowerCase() ?? "";
|
|
142
106
|
const bypass = requestDirective.includes("no-cache") || requestDirective.includes("no-store");
|
|
143
107
|
const url = c.req.url;
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
const hit = await cacheApi.match(url);
|
|
150
|
-
if (hit)
|
|
151
|
-
return sanitizedResponseCopy(hit);
|
|
152
|
-
}
|
|
153
|
-
catch {
|
|
154
|
-
markCacheApiUnavailable();
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else if (kv) {
|
|
158
|
-
const hit = await kvMatch(kv, url);
|
|
159
|
-
if (hit)
|
|
160
|
-
return hit;
|
|
161
|
-
}
|
|
108
|
+
const kv = c.env.CACHE;
|
|
109
|
+
if (!bypass && kv) {
|
|
110
|
+
const hit = await kvMatch(kv, url);
|
|
111
|
+
if (hit)
|
|
112
|
+
return hit;
|
|
162
113
|
}
|
|
163
114
|
await next();
|
|
164
115
|
const res = c.res;
|
|
165
|
-
if (
|
|
116
|
+
if (res?.status !== 200)
|
|
166
117
|
return;
|
|
167
118
|
if (res.headers.has("set-cookie"))
|
|
168
119
|
return;
|
|
169
120
|
const { isPublic, sMaxage } = parseCacheControl(res.headers.get("cache-control"));
|
|
170
121
|
if (!isPublic || !sMaxage)
|
|
171
122
|
return;
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
if (!backendCacheApi && !backendKv)
|
|
123
|
+
const backendKv = c.env.CACHE;
|
|
124
|
+
if (!backendKv)
|
|
175
125
|
return;
|
|
176
126
|
const copy = res.clone();
|
|
177
127
|
const store = (async () => {
|
|
178
|
-
|
|
179
|
-
try {
|
|
180
|
-
const headers = new Headers();
|
|
181
|
-
copy.headers.forEach((value, name) => {
|
|
182
|
-
if (!isUncacheableHeader(name))
|
|
183
|
-
headers.set(name, value);
|
|
184
|
-
});
|
|
185
|
-
await backendCacheApi.put(url, new Response(copy.body, { status: copy.status, headers }));
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
markCacheApiUnavailable();
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
const fallbackKv = backendKv ?? c.env.CACHE;
|
|
193
|
-
if (fallbackKv) {
|
|
194
|
-
await kvStore(fallbackKv, url, copy, sMaxage, maxKvBodyBytes);
|
|
195
|
-
}
|
|
128
|
+
await kvStore(backendKv, url, copy, sMaxage, maxKvBodyBytes);
|
|
196
129
|
})();
|
|
197
130
|
const executionCtx = tryGetExecutionCtx(c);
|
|
198
131
|
if (executionCtx) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KVStore } from "@voyant-travel/utils/cache";
|
|
2
|
+
import { type LazyRedisClient } from "@voyant-travel/utils/redis-client";
|
|
2
3
|
import type { MiddlewareHandler } from "hono";
|
|
3
4
|
/**
|
|
4
5
|
* Distributed-capable rate limiting (security finding C2).
|
|
@@ -165,6 +166,10 @@ export declare function createKvRateLimitStore(kv: KVStore): RateLimitStore;
|
|
|
165
166
|
* not expose it).
|
|
166
167
|
*/
|
|
167
168
|
export declare function createCloudflareRateLimitStore(binding: CloudflareRateLimiterBinding): RateLimitStore;
|
|
169
|
+
export interface RedisRateLimitStoreOptions {
|
|
170
|
+
client?: LazyRedisClient;
|
|
171
|
+
}
|
|
172
|
+
export declare function createRedisRateLimitStore(redisUrl: string, options?: RedisRateLimitStoreOptions): RateLimitStore;
|
|
168
173
|
/** Test-only: re-arm the once-per-isolate missing-store warning. */
|
|
169
174
|
export declare function resetRateLimitWarningsForTests(): void;
|
|
170
175
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wEAAwE;IACxE,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;CAC3F;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAA;IACX,gCAAgC;IAChC,aAAa,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,uEAAuE;IACvE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,uBAAuB,KAAK,MAAM,CAAA;CACnD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,cAAc,GAAG,SAAS,CAAC,CAAA;IACvE,oEAAoE;IACpE,IAAI,CAAC,EAAE,KAAK,GAAG,aAAa,CAAA;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,aAAa,CAAA;CACpC;AAED,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAC5D;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IAC9E,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE;IAAE,GAAG,EAAE;QAAE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAM5F;AAID;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAyC5F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,OAAO,GAAG,cAAc,CAmBlE;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,4BAA4B,GACpC,cAAc,CAShB;
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createLazyRedisClient } from "@voyant-travel/utils/redis-client";
|
|
1
2
|
/**
|
|
2
3
|
* Derive the client dimension for rate-limit keys: `cf-connecting-ip`
|
|
3
4
|
* (set by Cloudflare, not spoofable through the edge), else the first
|
|
@@ -115,8 +116,29 @@ export function createCloudflareRateLimitStore(binding) {
|
|
|
115
116
|
},
|
|
116
117
|
};
|
|
117
118
|
}
|
|
119
|
+
export function createRedisRateLimitStore(redisUrl, options = {}) {
|
|
120
|
+
const lazyClient = options.client ?? createLazyRedisClient(redisUrl);
|
|
121
|
+
return {
|
|
122
|
+
async limit(key, { max, windowSeconds }) {
|
|
123
|
+
const client = await lazyClient.get();
|
|
124
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
125
|
+
const windowKey = Math.floor(nowSeconds / windowSeconds);
|
|
126
|
+
const storageKey = `${key}:${windowKey}`;
|
|
127
|
+
const count = await client.incr(storageKey);
|
|
128
|
+
if (count === 1) {
|
|
129
|
+
await client.expire(storageKey, Math.max(1, windowSeconds * 2));
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
allowed: count <= max,
|
|
133
|
+
remaining: Math.max(0, max - count),
|
|
134
|
+
retryAfterSeconds: Math.max(1, windowSeconds - (nowSeconds % windowSeconds)),
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
118
139
|
// ---- Store resolution ----
|
|
119
140
|
const bindingStoreCache = new WeakMap();
|
|
141
|
+
const explicitStoreCache = new WeakMap();
|
|
120
142
|
const kvStoreCache = new WeakMap();
|
|
121
143
|
const sharedMemoryStore = createMemoryRateLimitStore();
|
|
122
144
|
let warnedNoDistributedStore = false;
|
|
@@ -148,6 +170,15 @@ export function resolveRateLimitStore(c, memoryFallback = sharedMemoryStore) {
|
|
|
148
170
|
}
|
|
149
171
|
return store;
|
|
150
172
|
}
|
|
173
|
+
const explicit = env.RATE_LIMIT_STORE;
|
|
174
|
+
if (explicit && typeof explicit.limit === "function") {
|
|
175
|
+
let store = explicitStoreCache.get(explicit);
|
|
176
|
+
if (!store) {
|
|
177
|
+
store = explicit;
|
|
178
|
+
explicitStoreCache.set(explicit, store);
|
|
179
|
+
}
|
|
180
|
+
return store;
|
|
181
|
+
}
|
|
151
182
|
const kv = env.RATE_LIMIT;
|
|
152
183
|
if (kv && typeof kv.get === "function" && typeof kv.put === "function") {
|
|
153
184
|
let store = kvStoreCache.get(kv);
|
|
@@ -159,8 +190,8 @@ export function resolveRateLimitStore(c, memoryFallback = sharedMemoryStore) {
|
|
|
159
190
|
}
|
|
160
191
|
if (!warnedNoDistributedStore && !isDevLikeEnv()) {
|
|
161
192
|
warnedNoDistributedStore = true;
|
|
162
|
-
console.warn("[voyant] rate-limit: no distributed store available (
|
|
163
|
-
"
|
|
193
|
+
console.warn("[voyant] rate-limit: no distributed store available (inject RATE_LIMIT_STORE " +
|
|
194
|
+
"or a KV-compatible RATE_LIMIT fallback). " +
|
|
164
195
|
"Falling back to a per-isolate in-memory limiter — limits apply " +
|
|
165
196
|
"per instance, not fleet-wide.");
|
|
166
197
|
}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -52,10 +52,60 @@ export interface HonoBundle {
|
|
|
52
52
|
}
|
|
53
53
|
/** @deprecated Prefer {@link HonoBundle}. */
|
|
54
54
|
export type HonoPlugin = HonoBundle;
|
|
55
|
+
declare const LAZY_HONO_BUNDLE: unique symbol;
|
|
56
|
+
/**
|
|
57
|
+
* Lazy bundle declaration. The bundle's heavy runtime graph is imported only
|
|
58
|
+
* when a declared route matcher is hit, unless `loadOnBootstrap` asks the app
|
|
59
|
+
* to load it during request/headless bootstrap. `name` and `anonymous` remain
|
|
60
|
+
* eager metadata so duplicate checks and auth allow-lists stay fail-closed.
|
|
61
|
+
*/
|
|
62
|
+
export interface LazyHonoBundle {
|
|
63
|
+
readonly [LAZY_HONO_BUNDLE]: true;
|
|
64
|
+
/** Unique bundle identifier matching the loaded bundle's `name`. */
|
|
65
|
+
name: string;
|
|
66
|
+
/** Optional version tag for diagnostics. */
|
|
67
|
+
version?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Absolute unauthenticated paths contributed by the eventual bundle. Declare
|
|
70
|
+
* webhook/callback paths here so the first matching request can pass auth
|
|
71
|
+
* before the bundle has been imported.
|
|
72
|
+
*/
|
|
73
|
+
anonymous?: string[];
|
|
74
|
+
/**
|
|
75
|
+
* Absolute route matchers the eventual bundle may serve. Required for lazy
|
|
76
|
+
* bundles that contribute HTTP routes because Hono routes must be registered
|
|
77
|
+
* before the first request builds the matcher.
|
|
78
|
+
*/
|
|
79
|
+
routes?: readonly string[];
|
|
80
|
+
/**
|
|
81
|
+
* Module names whose lazy-loaded routes must receive a transaction-capable DB
|
|
82
|
+
* client. This is eager metadata so the first matching request is routed to
|
|
83
|
+
* `dbTransactional` before the bundle implementation is imported.
|
|
84
|
+
*/
|
|
85
|
+
transactionalModules?: readonly string[];
|
|
86
|
+
/**
|
|
87
|
+
* Absolute API path prefixes whose lazy-loaded routes must receive the
|
|
88
|
+
* transaction-capable DB client. Use this when only a subset of the lazy
|
|
89
|
+
* bundle's explicit `routes` require transactions.
|
|
90
|
+
*/
|
|
91
|
+
transactionalPaths?: readonly string[];
|
|
92
|
+
/**
|
|
93
|
+
* Load this bundle during app bootstrap instead of waiting for a declared
|
|
94
|
+
* route matcher. Set this for lazy bundles that contribute subscribers,
|
|
95
|
+
* workflow metadata, container services, or bootstraps needed before a
|
|
96
|
+
* bundle-owned route is hit.
|
|
97
|
+
*/
|
|
98
|
+
loadOnBootstrap?: boolean;
|
|
99
|
+
/** Loads and constructs the real bundle. Memoized by `mountApp`. */
|
|
100
|
+
load: () => Promise<HonoBundle>;
|
|
101
|
+
}
|
|
102
|
+
export type HonoBundleInput = HonoBundle | LazyHonoBundle;
|
|
55
103
|
/**
|
|
56
104
|
* Identity helper — returns the bundle unchanged, purely for IDE inference.
|
|
57
105
|
*/
|
|
58
106
|
export declare function defineHonoBundle<P extends HonoBundle>(bundle: P): P;
|
|
107
|
+
export declare function defineLazyHonoBundle<P extends Omit<LazyHonoBundle, typeof LAZY_HONO_BUNDLE>>(bundle: P): P & LazyHonoBundle;
|
|
108
|
+
export declare function isLazyHonoBundle(bundle: HonoBundleInput): bundle is LazyHonoBundle;
|
|
59
109
|
/** @deprecated Prefer {@link defineHonoBundle}. */
|
|
60
110
|
export declare const defineHonoPlugin: typeof defineHonoBundle;
|
|
61
111
|
export interface ExpandedHonoBundles {
|
|
@@ -76,4 +126,5 @@ export type ExpandedHonoPlugins = ExpandedHonoBundles;
|
|
|
76
126
|
export declare function expandHonoBundles(bundles: ReadonlyArray<HonoBundle>): ExpandedHonoBundles;
|
|
77
127
|
/** @deprecated Prefer {@link expandHonoBundles}. */
|
|
78
128
|
export declare const expandHonoPlugins: typeof expandHonoBundles;
|
|
129
|
+
export {};
|
|
79
130
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,UAAU,EACV,kBAAkB,EACnB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE5D;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qEAAqE;IACrE,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,gEAAgE;IAChE,OAAO,CAAC,EAAE,UAAU,EAAE,CAAA;IACtB,sEAAsE;IACtE,UAAU,CAAC,EAAE,aAAa,EAAE,CAAA;IAC5B,wEAAwE;IACxE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;IAC1B,kDAAkD;IAClD,KAAK,CAAC,EAAE,cAAc,EAAE,CAAA;IACxB;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACzC;;;OAGG;IACH,YAAY,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAChD;AAED,6CAA6C;AAC7C,MAAM,MAAM,UAAU,GAAG,UAAU,CAAA;AAEnC;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEnE;AAED,mDAAmD;AACnD,eAAO,MAAM,gBAAgB,yBAAmB,CAAA;AAEhD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,sEAAsE;IACtE,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB;AAED,sDAAsD;AACtD,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAA;AAErD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,mBAAmB,CAsBzF;AAED,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,0BAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
const LAZY_HONO_BUNDLE = Symbol.for("voyant.hono.lazyBundle");
|
|
1
2
|
/**
|
|
2
3
|
* Identity helper — returns the bundle unchanged, purely for IDE inference.
|
|
3
4
|
*/
|
|
4
5
|
export function defineHonoBundle(bundle) {
|
|
5
6
|
return bundle;
|
|
6
7
|
}
|
|
8
|
+
export function defineLazyHonoBundle(bundle) {
|
|
9
|
+
return { ...bundle, [LAZY_HONO_BUNDLE]: true };
|
|
10
|
+
}
|
|
11
|
+
export function isLazyHonoBundle(bundle) {
|
|
12
|
+
return bundle[LAZY_HONO_BUNDLE] === true;
|
|
13
|
+
}
|
|
7
14
|
/** @deprecated Prefer {@link defineHonoBundle}. */
|
|
8
15
|
export const defineHonoPlugin = defineHonoBundle;
|
|
9
16
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
|
8
8
|
import type { Hono } from "hono";
|
|
9
9
|
import type { HonoExtension, HonoModule } from "./module.js";
|
|
10
10
|
import type { Reporter } from "./observability/reporter.js";
|
|
11
|
-
import type {
|
|
11
|
+
import type { HonoBundleInput } from "./plugin.js";
|
|
12
12
|
export interface VoyantExecutionContext {
|
|
13
13
|
waitUntil?: (promise: Promise<unknown>) => void;
|
|
14
14
|
passThroughOnException?: () => void;
|
|
@@ -24,6 +24,7 @@ export interface VoyantBindings {
|
|
|
24
24
|
DASH_BASE_URL?: string;
|
|
25
25
|
API_BASE_URL?: string;
|
|
26
26
|
RATE_LIMIT?: KVStore;
|
|
27
|
+
RATE_LIMIT_STORE?: import("./middleware/rate-limit.js").RateLimitStore;
|
|
27
28
|
CACHE?: KVStore;
|
|
28
29
|
RATE_LIMITER?: import("./middleware/rate-limit.js").CloudflareRateLimiterBinding;
|
|
29
30
|
/**
|
|
@@ -182,7 +183,7 @@ export interface VoyantAppConfig<TBindings extends VoyantBindings = VoyantBindin
|
|
|
182
183
|
dbTransactionalPaths?: string[];
|
|
183
184
|
modules?: HonoModule[];
|
|
184
185
|
extensions?: HonoExtension[];
|
|
185
|
-
plugins?:
|
|
186
|
+
plugins?: HonoBundleInput[];
|
|
186
187
|
eventBus?: EventBus;
|
|
187
188
|
link?: LinkService;
|
|
188
189
|
query?: QueryGraphContext | VoyantQueryRuntime;
|
|
@@ -217,9 +218,8 @@ export interface VoyantAppConfig<TBindings extends VoyantBindings = VoyantBindin
|
|
|
217
218
|
* default). Enabled by default but inert until a route marks its
|
|
218
219
|
* response `Cache-Control: public, s-maxage=…` — personalized routes
|
|
219
220
|
* are never cached. Set `false` to disable, or pass options to tune
|
|
220
|
-
* prefixes/limits. Uses the
|
|
221
|
-
*
|
|
222
|
-
* namespaced workers have no `caches.default`).
|
|
221
|
+
* prefixes/limits. Uses the injected `env.CACHE` KVStore when one is
|
|
222
|
+
* available.
|
|
223
223
|
*/
|
|
224
224
|
publicCache?: false | import("./middleware/public-cache.js").PublicCacheOptions;
|
|
225
225
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,eAAe,IAAI,mBAAmB,EACtC,QAAQ,EACR,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAEhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,KAAK,EAAE,YAAY,IAAI,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyant-travel/hono",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.122.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -135,19 +135,19 @@
|
|
|
135
135
|
"drizzle-orm": "^0.45.2",
|
|
136
136
|
"hono": "^4.12.27",
|
|
137
137
|
"zod": "^4.4.3",
|
|
138
|
-
"@voyant-travel/core": "^0.112.
|
|
139
|
-
"@voyant-travel/db": "^0.
|
|
138
|
+
"@voyant-travel/core": "^0.112.3",
|
|
139
|
+
"@voyant-travel/db": "^0.110.0",
|
|
140
140
|
"@voyant-travel/storage": "^0.106.0",
|
|
141
|
-
"@voyant-travel/types": "^0.107.
|
|
142
|
-
"@voyant-travel/utils": "^0.
|
|
143
|
-
"@voyant-travel/workflows": "^0.111.
|
|
141
|
+
"@voyant-travel/types": "^0.107.1",
|
|
142
|
+
"@voyant-travel/utils": "^0.106.0",
|
|
143
|
+
"@voyant-travel/workflows": "^0.111.18"
|
|
144
144
|
},
|
|
145
145
|
"devDependencies": {
|
|
146
146
|
"@cloudflare/workers-types": "^4.20260702.1",
|
|
147
147
|
"typescript": "^6.0.3",
|
|
148
148
|
"vitest": "^4.1.9",
|
|
149
149
|
"@voyant-travel/voyant-typescript-config": "^0.1.0",
|
|
150
|
-
"@voyant-travel/workflows-orchestrator": "^0.111.
|
|
150
|
+
"@voyant-travel/workflows-orchestrator": "^0.111.18"
|
|
151
151
|
},
|
|
152
152
|
"files": [
|
|
153
153
|
"dist"
|