@voyant-travel/hono 0.120.0 → 0.121.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 +24 -18
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +31 -5
- package/dist/middleware/require-actor.d.ts.map +1 -1
- package/dist/middleware/require-actor.js +18 -6
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +15 -2
- package/package.json +9 -9
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;AA+BhG,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;AAuBD;;;;;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,
|
|
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;AA+BhG,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;AAuBD;;;;;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,CA4gB5D"}
|
package/dist/app.js
CHANGED
|
@@ -417,6 +417,21 @@ export function mountApp(config) {
|
|
|
417
417
|
// uniform across eager + lazy. Webhook routes are intentionally excluded — the
|
|
418
418
|
// per-module docs cover the admin/storefront surfaces only.
|
|
419
419
|
const moduleMounts = [];
|
|
420
|
+
const deferredLazyRouteMounts = [];
|
|
421
|
+
function deferLazyRoutesAt(moduleName, prefix, load) {
|
|
422
|
+
lazyMounts.push({ prefix, load });
|
|
423
|
+
moduleMounts.push({ moduleName, prefix, load });
|
|
424
|
+
deferredLazyRouteMounts.push(() => {
|
|
425
|
+
mountLazyRoutesAt(app, prefix, load);
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
function deferLazyRoutePaths(moduleName, paths, load) {
|
|
429
|
+
lazyMounts.push({ prefix: "/", load });
|
|
430
|
+
moduleMounts.push({ moduleName, prefix: "/", load });
|
|
431
|
+
deferredLazyRouteMounts.push(() => {
|
|
432
|
+
mountLazyRoutePaths(app, paths, load);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
420
435
|
// Mount module routes
|
|
421
436
|
for (const mod of allModules) {
|
|
422
437
|
const moduleName = mod.module.name;
|
|
@@ -433,19 +448,13 @@ export function mountApp(config) {
|
|
|
433
448
|
moduleMounts.push({ moduleName, prefix: publicPrefix, load: () => publicRoutes });
|
|
434
449
|
}
|
|
435
450
|
if (mod.lazyAdminRoutes) {
|
|
436
|
-
|
|
437
|
-
lazyMounts.push({ prefix: adminPrefix, load: mod.lazyAdminRoutes });
|
|
438
|
-
moduleMounts.push({ moduleName, prefix: adminPrefix, load: mod.lazyAdminRoutes });
|
|
451
|
+
deferLazyRoutesAt(moduleName, adminPrefix, mod.lazyAdminRoutes);
|
|
439
452
|
}
|
|
440
453
|
if (mod.lazyPublicRoutes) {
|
|
441
|
-
|
|
442
|
-
lazyMounts.push({ prefix: publicPrefix, load: mod.lazyPublicRoutes });
|
|
443
|
-
moduleMounts.push({ moduleName, prefix: publicPrefix, load: mod.lazyPublicRoutes });
|
|
454
|
+
deferLazyRoutesAt(moduleName, publicPrefix, mod.lazyPublicRoutes);
|
|
444
455
|
}
|
|
445
456
|
if (mod.lazyRoutes) {
|
|
446
|
-
|
|
447
|
-
lazyMounts.push({ prefix: "/", load: mod.lazyRoutes.load });
|
|
448
|
-
moduleMounts.push({ moduleName, prefix: "/", load: mod.lazyRoutes.load });
|
|
457
|
+
deferLazyRoutePaths(moduleName, mod.lazyRoutes.paths, mod.lazyRoutes.load);
|
|
449
458
|
}
|
|
450
459
|
if (mod.webhookRoutes) {
|
|
451
460
|
app.route(`/v1/${moduleName}`, mod.webhookRoutes);
|
|
@@ -467,24 +476,21 @@ export function mountApp(config) {
|
|
|
467
476
|
moduleMounts.push({ moduleName, prefix: publicPrefix, load: () => publicRoutes });
|
|
468
477
|
}
|
|
469
478
|
if (ext.lazyAdminRoutes) {
|
|
470
|
-
|
|
471
|
-
lazyMounts.push({ prefix: adminPrefix, load: ext.lazyAdminRoutes });
|
|
472
|
-
moduleMounts.push({ moduleName, prefix: adminPrefix, load: ext.lazyAdminRoutes });
|
|
479
|
+
deferLazyRoutesAt(moduleName, adminPrefix, ext.lazyAdminRoutes);
|
|
473
480
|
}
|
|
474
481
|
if (ext.lazyPublicRoutes) {
|
|
475
|
-
|
|
476
|
-
lazyMounts.push({ prefix: publicPrefix, load: ext.lazyPublicRoutes });
|
|
477
|
-
moduleMounts.push({ moduleName, prefix: publicPrefix, load: ext.lazyPublicRoutes });
|
|
482
|
+
deferLazyRoutesAt(moduleName, publicPrefix, ext.lazyPublicRoutes);
|
|
478
483
|
}
|
|
479
484
|
if (ext.lazyRoutes) {
|
|
480
|
-
|
|
481
|
-
lazyMounts.push({ prefix: "/", load: ext.lazyRoutes.load });
|
|
482
|
-
moduleMounts.push({ moduleName, prefix: "/", load: ext.lazyRoutes.load });
|
|
485
|
+
deferLazyRoutePaths(moduleName, ext.lazyRoutes.paths, ext.lazyRoutes.load);
|
|
483
486
|
}
|
|
484
487
|
if (ext.webhookRoutes) {
|
|
485
488
|
app.route(`/v1/${moduleName}`, ext.webhookRoutes);
|
|
486
489
|
}
|
|
487
490
|
}
|
|
491
|
+
for (const mountLazyRoutes of deferredLazyRouteMounts) {
|
|
492
|
+
mountLazyRoutes();
|
|
493
|
+
}
|
|
488
494
|
// Additional routes
|
|
489
495
|
if (config.additionalRoutes) {
|
|
490
496
|
config.additionalRoutes(app);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAM7C,OAAO,EACL,KAAK,QAAQ,EAEb,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAM7C,OAAO,EACL,KAAK,QAAQ,EAEb,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,aAAa,CAAA;AAgIpB,wBAAgB,WAAW,CAAC,SAAS,SAAS,cAAc,EAC1D,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC7B,IAAI,CAAC,EAAE;IACL,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAA;CACxC,GACA,iBAAiB,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,EAAE,eAAe,CAAA;CAC3B,CAAC,CA4LD"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { apikeyTable } from "@voyant-travel/db/schema/iam";
|
|
2
|
-
import { permissionsToStrings } from "@voyant-travel/types/api-keys";
|
|
2
|
+
import { API_KEY_AUDIENCES, permissionsToStrings } from "@voyant-travel/types/api-keys";
|
|
3
3
|
import { and, eq, sql } from "drizzle-orm";
|
|
4
4
|
import { constantTimeEqual, sha256Base64Url, sha256Hex } from "../auth/crypto.js";
|
|
5
5
|
import { extractBearerToken, verifySession } from "../auth/session-jwt.js";
|
|
@@ -91,6 +91,26 @@ async function writeCachedApiKey(kv, keyHash, row) {
|
|
|
91
91
|
// cache writes are best-effort
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
+
const API_KEY_AUDIENCE_SET = new Set(API_KEY_AUDIENCES);
|
|
95
|
+
/**
|
|
96
|
+
* Extract the grant audience from an API key's `metadata` JSON. Malformed or
|
|
97
|
+
* absent metadata falls back to `"staff"` (legacy server-to-server default).
|
|
98
|
+
*/
|
|
99
|
+
function resolveApiKeyAudience(metadata) {
|
|
100
|
+
if (!metadata)
|
|
101
|
+
return "staff";
|
|
102
|
+
try {
|
|
103
|
+
const parsed = JSON.parse(metadata);
|
|
104
|
+
const value = parsed?.audience;
|
|
105
|
+
if (typeof value === "string" && API_KEY_AUDIENCE_SET.has(value)) {
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Ignore malformed metadata — fall back to the staff default.
|
|
111
|
+
}
|
|
112
|
+
return "staff";
|
|
113
|
+
}
|
|
94
114
|
function applyAuthContext(c, auth) {
|
|
95
115
|
if (auth.userId)
|
|
96
116
|
c.set("userId", auth.userId);
|
|
@@ -102,6 +122,8 @@ function applyAuthContext(c, auth) {
|
|
|
102
122
|
c.set("callerType", auth.callerType);
|
|
103
123
|
if (auth.actor)
|
|
104
124
|
c.set("actor", auth.actor);
|
|
125
|
+
if (auth.audience)
|
|
126
|
+
c.set("audience", auth.audience);
|
|
105
127
|
if (auth.scopes !== undefined)
|
|
106
128
|
c.set("scopes", auth.scopes);
|
|
107
129
|
if (auth.isInternalRequest !== undefined)
|
|
@@ -209,16 +231,20 @@ export function requireAuth(dbSource, opts) {
|
|
|
209
231
|
.catch(() => { });
|
|
210
232
|
tryGetExecutionCtx(c)?.waitUntil(counterUpdate);
|
|
211
233
|
const scopes = permissionsToStrings(row.permissions);
|
|
234
|
+
// Audience is a grant attribute carried on the key's `metadata`, not
|
|
235
|
+
// inferred from scopes (D3). Legacy keys with no audience default to
|
|
236
|
+
// `staff`, preserving prior server-to-server behaviour. The actor
|
|
237
|
+
// follows the audience so a non-staff key resolves to its own
|
|
238
|
+
// visibility pool instead of silently gaining operator privileges.
|
|
239
|
+
const audience = resolveApiKeyAudience(row.metadata);
|
|
212
240
|
applyAuthContext(c, {
|
|
213
241
|
organizationId: row.referenceId,
|
|
214
242
|
scopes,
|
|
215
243
|
callerType: "api_key",
|
|
216
244
|
apiTokenId: row.id,
|
|
217
245
|
apiKeyId: row.id,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// `requireActor` doesn't have to default unset callers to "staff".
|
|
221
|
-
actor: "staff",
|
|
246
|
+
actor: audience,
|
|
247
|
+
audience,
|
|
222
248
|
});
|
|
223
249
|
// `await` is load-bearing: with a bare `return next()` the
|
|
224
250
|
// `finally` would run as soon as the downstream promise is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-actor.d.ts","sourceRoot":"","sources":["../../src/middleware/require-actor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAG7C,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"require-actor.d.ts","sourceRoot":"","sources":["../../src/middleware/require-actor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAG7C,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AA0ElE;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAIzD;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,SAAS,SAAS,cAAc,GAAG,cAAc,EAC5E,GAAG,OAAO,EAAE,KAAK,EAAE,GAClB,iBAAiB,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,EAAE,eAAe,CAAA;CAC3B,CAAC,CAAA;AACF,wBAAgB,YAAY,CAAC,SAAS,SAAS,cAAc,GAAG,cAAc,EAC5E,OAAO,EAAE,mBAAmB,EAC5B,GAAG,OAAO,EAAE,KAAK,EAAE,GAClB,iBAAiB,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,EAAE,eAAe,CAAA;CAC3B,CAAC,CAAA"}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { hasApiKeyPermission, permissionStringsToPermissions } from "@voyant-travel/types/api-keys";
|
|
2
2
|
import { normalizePathname } from "../lib/public-paths.js";
|
|
3
|
+
/**
|
|
4
|
+
* Route surfaces exempt from the coarse method+path permission guard because
|
|
5
|
+
* they enforce authorization at a finer grain internally: `_meta` (capability
|
|
6
|
+
* discovery) and `mcp` (the agent tool server, which gates every tool by its own
|
|
7
|
+
* `requiredScopes`). Neither is a real module name.
|
|
8
|
+
*/
|
|
9
|
+
const COARSE_GUARD_EXEMPT_RESOURCES = new Set(["_meta", "mcp"]);
|
|
10
|
+
function isCoarseGuardExempt(resource) {
|
|
11
|
+
return resource !== null && COARSE_GUARD_EXEMPT_RESOURCES.has(resource);
|
|
12
|
+
}
|
|
3
13
|
function apiKeyResourceFromPath(pathname) {
|
|
4
14
|
const surfaceMatch = pathname.match(/^\/v1\/(?:admin|public)\/([^/]+)/);
|
|
5
15
|
if (surfaceMatch?.[1])
|
|
@@ -84,11 +94,13 @@ export function requireActor(...args) {
|
|
|
84
94
|
basePath: options.basePath,
|
|
85
95
|
});
|
|
86
96
|
const resource = apiKeyResourceFromPath(pathname);
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
|
|
97
|
+
// Coarse-guard-exempt surfaces. `_meta` (capability discovery) and `mcp`
|
|
98
|
+
// (the agent tool server) are dispatch surfaces where authorization is
|
|
99
|
+
// enforced at a finer grain than method+path: the MCP server filters and
|
|
100
|
+
// gates each tool by its own `requiredScopes` (voyant#2792, D2). So any
|
|
101
|
+
// authenticated key reaches them; a key with no relevant scopes simply
|
|
102
|
+
// sees an empty tool list. Neither is a real module name.
|
|
103
|
+
if (isCoarseGuardExempt(resource))
|
|
92
104
|
return next();
|
|
93
105
|
const actions = apiKeyPermissionActionsForMethod(c.req.method, pathname);
|
|
94
106
|
if (resource && hasAnyApiKeyPermission(c.get("scopes"), resource, actions)) {
|
|
@@ -119,7 +131,7 @@ export function requireActor(...args) {
|
|
|
119
131
|
basePath: options.basePath,
|
|
120
132
|
});
|
|
121
133
|
const resource = apiKeyResourceFromPath(pathname);
|
|
122
|
-
if (resource && resource
|
|
134
|
+
if (resource && !isCoarseGuardExempt(resource)) {
|
|
123
135
|
const actions = apiKeyPermissionActionsForMethod(c.req.method, pathname);
|
|
124
136
|
if (!hasAnyApiKeyPermission(scopes, resource, actions)) {
|
|
125
137
|
return c.json({ error: "Forbidden: missing required permission" }, 403);
|
package/dist/openapi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
|
package/dist/openapi.js
CHANGED
|
@@ -318,9 +318,22 @@ function deriveSummary(method, path) {
|
|
|
318
318
|
*/
|
|
319
319
|
export function stampModuleMetadata(doc, owner) {
|
|
320
320
|
const paths = {};
|
|
321
|
-
// operationId must be unique across the document; track what we've assigned
|
|
322
|
-
//
|
|
321
|
+
// operationId must be unique across the document; track what we've assigned so
|
|
322
|
+
// a derived id never collides. Pre-seed EVERY route-declared id up front —
|
|
323
|
+
// otherwise a hand-authored id appearing later in iteration order than an
|
|
324
|
+
// earlier op that derived the same string would slip through un-suffixed,
|
|
325
|
+
// leaving duplicate ids in the output (declared ids always win; derived yield).
|
|
323
326
|
const usedOperationIds = new Set();
|
|
327
|
+
for (const item of Object.values(doc.paths ?? {})) {
|
|
328
|
+
if (!item || typeof item !== "object")
|
|
329
|
+
continue;
|
|
330
|
+
for (const method of HTTP_METHODS) {
|
|
331
|
+
const op = item[method];
|
|
332
|
+
const declared = op && typeof op === "object" ? op.operationId : null;
|
|
333
|
+
if (typeof declared === "string" && declared.length > 0)
|
|
334
|
+
usedOperationIds.add(declared);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
324
337
|
for (const [path, item] of Object.entries(doc.paths ?? {})) {
|
|
325
338
|
if (!item || typeof item !== "object") {
|
|
326
339
|
paths[path] = item;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyant-travel/hono",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.121.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -133,21 +133,21 @@
|
|
|
133
133
|
"dependencies": {
|
|
134
134
|
"@hono/zod-openapi": "^1.4.0",
|
|
135
135
|
"drizzle-orm": "^0.45.2",
|
|
136
|
-
"hono": "^4.12.
|
|
136
|
+
"hono": "^4.12.27",
|
|
137
137
|
"zod": "^4.4.3",
|
|
138
|
-
"@voyant-travel/core": "^0.
|
|
139
|
-
"@voyant-travel/db": "^0.109.
|
|
138
|
+
"@voyant-travel/core": "^0.112.0",
|
|
139
|
+
"@voyant-travel/db": "^0.109.5",
|
|
140
140
|
"@voyant-travel/storage": "^0.106.0",
|
|
141
|
-
"@voyant-travel/types": "^0.
|
|
142
|
-
"@voyant-travel/utils": "^0.105.
|
|
143
|
-
"@voyant-travel/workflows": "^0.111.
|
|
141
|
+
"@voyant-travel/types": "^0.107.0",
|
|
142
|
+
"@voyant-travel/utils": "^0.105.6",
|
|
143
|
+
"@voyant-travel/workflows": "^0.111.15"
|
|
144
144
|
},
|
|
145
145
|
"devDependencies": {
|
|
146
|
-
"@cloudflare/workers-types": "^4.
|
|
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.15"
|
|
151
151
|
},
|
|
152
152
|
"files": [
|
|
153
153
|
"dist"
|