@voyant-travel/apps 0.9.1 → 0.10.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.
@@ -89,6 +89,7 @@ export declare const authorizeAppOAuthRoute: {
89
89
  release_id: z.ZodString;
90
90
  redirect_uri: z.ZodString;
91
91
  state: z.ZodString;
92
+ nonce: z.ZodOptional<z.ZodString>;
92
93
  code_challenge: z.ZodString;
93
94
  code_challenge_method: z.ZodLiteral<"S256">;
94
95
  actor_id: z.ZodOptional<z.ZodString>;
@@ -382,6 +383,106 @@ export declare const installAppRoute: {
382
383
  } & {
383
384
  getRoutingPath(): "/install";
384
385
  };
386
+ export declare const resolveMarketplaceInstallIntentRoute: {
387
+ method: "post";
388
+ path: "/marketplace/install-intents/resolve";
389
+ request: {
390
+ body: {
391
+ required: boolean;
392
+ content: {
393
+ "application/json": {
394
+ schema: z.ZodObject<{
395
+ intent: z.ZodString;
396
+ }, z.core.$strict>;
397
+ };
398
+ };
399
+ };
400
+ };
401
+ responses: {
402
+ 201: {
403
+ description: string;
404
+ content: {
405
+ "application/json": {
406
+ schema: z.ZodObject<{
407
+ data: z.ZodObject<{
408
+ appId: z.ZodString;
409
+ releaseId: z.ZodString;
410
+ acquisitionId: z.ZodString;
411
+ created: z.ZodBoolean;
412
+ }, z.core.$strict>;
413
+ }, z.core.$strip>;
414
+ };
415
+ };
416
+ };
417
+ 404: {
418
+ description: string;
419
+ content: {
420
+ "application/json": {
421
+ schema: z.ZodObject<{
422
+ error: z.ZodString;
423
+ }, z.core.$strip>;
424
+ };
425
+ };
426
+ };
427
+ 501: {
428
+ description: string;
429
+ content: {
430
+ "application/json": {
431
+ schema: z.ZodObject<{
432
+ error: z.ZodString;
433
+ }, z.core.$strip>;
434
+ };
435
+ };
436
+ };
437
+ };
438
+ } & {
439
+ getRoutingPath(): "/marketplace/install-intents/resolve";
440
+ };
441
+ export declare const createMarketplaceSetupHandoffRoute: {
442
+ method: "post";
443
+ path: "/installations/{installationId}/setup-handoff";
444
+ request: {
445
+ params: z.ZodObject<{
446
+ installationId: z.ZodString;
447
+ }, z.core.$strip>;
448
+ };
449
+ responses: {
450
+ 201: {
451
+ description: string;
452
+ content: {
453
+ "application/json": {
454
+ schema: z.ZodObject<{
455
+ data: z.ZodObject<{
456
+ redirectUrl: z.ZodString;
457
+ }, z.core.$strict>;
458
+ }, z.core.$strip>;
459
+ };
460
+ };
461
+ };
462
+ 404: {
463
+ description: string;
464
+ content: {
465
+ "application/json": {
466
+ schema: z.ZodObject<{
467
+ error: z.ZodString;
468
+ }, z.core.$strip>;
469
+ };
470
+ };
471
+ };
472
+ 501: {
473
+ description: string;
474
+ content: {
475
+ "application/json": {
476
+ schema: z.ZodObject<{
477
+ error: z.ZodString;
478
+ }, z.core.$strip>;
479
+ };
480
+ };
481
+ };
482
+ };
483
+ } & {
484
+ getRoutingPath(): "/installations/:installationId/setup-handoff";
485
+ };
385
486
  export declare const listAppInstallationsRoute: {
386
487
  method: "get";
387
488
  path: "/installations";
@@ -1,5 +1,6 @@
1
1
  import { createRoute, z } from "@hono/zod-openapi";
2
2
  import { activateInstallationBodySchema, appCredentialRevocationSchema, appInstallationAuditQuerySchema, appInstallationListQuerySchema, appListQuerySchema, appOAuthAuthorizeQuerySchema, appOAuthTokenSchema, appSessionTokenExchangeSchema, appSessionTokenIssueSchema, appWebhookReplaySchema, createCustomAppRegistrationSchema, installAppSchema, lifecycleActionBodySchema, releaseManifestFetchSchema, releaseManifestUploadSchema, } from "./contracts.js";
3
+ import { marketplaceInstallIntentResultSchema, marketplaceSetupHandoffResultSchema, resolveMarketplaceInstallIntentSchema, } from "./marketplace-acquisition.js";
3
4
  const appIdParamSchema = z.object({ appId: z.string().min(1) });
4
5
  const installationIdParamSchema = z.object({ installationId: z.string().min(1) });
5
6
  const errorSchema = z.object({ error: z.string() });
@@ -100,6 +101,26 @@ export const installAppRoute = createRoute({
100
101
  request: { body: requiredJsonBody(installAppSchema) },
101
102
  responses: { 201: jsonContent(dataEnvelopeSchema, "Installed app") },
102
103
  });
104
+ export const resolveMarketplaceInstallIntentRoute = createRoute({
105
+ method: "post",
106
+ path: "/marketplace/install-intents/resolve",
107
+ request: { body: requiredJsonBody(resolveMarketplaceInstallIntentSchema) },
108
+ responses: {
109
+ 201: jsonContent(marketplaceInstallIntentResultSchema, "Admitted Marketplace install intent"),
110
+ 404: jsonContent(errorSchema, "Install intent unavailable"),
111
+ 501: jsonContent(errorSchema, "Managed Marketplace is not configured"),
112
+ },
113
+ });
114
+ export const createMarketplaceSetupHandoffRoute = createRoute({
115
+ method: "post",
116
+ path: "/installations/{installationId}/setup-handoff",
117
+ request: { params: installationIdParamSchema },
118
+ responses: {
119
+ 201: jsonContent(marketplaceSetupHandoffResultSchema, "Created one-time app setup handoff"),
120
+ 404: jsonContent(errorSchema, "Marketplace installation unavailable"),
121
+ 501: jsonContent(errorSchema, "Managed Marketplace is not configured"),
122
+ },
123
+ });
103
124
  export const listAppInstallationsRoute = createRoute({
104
125
  method: "get",
105
126
  path: "/installations",
package/dist/routes.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { EventBus } from "@voyant-travel/core/events";
3
3
  import type { createCustomFieldsService } from "@voyant-travel/custom-fields";
4
4
  import { type AccessCatalog } from "@voyant-travel/types/api-keys";
5
5
  import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
6
- import type { ManagedAppInstallationAuthority } from "./runtime-port.js";
6
+ import type { ManagedAppInstallationAuthority, ManagedMarketplaceAcquisitionResolver } from "./runtime-port.js";
7
7
  import { type AppsServiceOptions } from "./service.js";
8
8
  type CustomFieldsService = ReturnType<typeof createCustomFieldsService>;
9
9
  type Env = {
@@ -38,6 +38,8 @@ export interface AppsAdminRouteOptions extends AppsServiceOptions {
38
38
  platformApiVersion?: string;
39
39
  eventBus?: EventBus;
40
40
  customFields?: CustomFieldsService;
41
+ /** Host-verified Marketplace acquisition and setup authority. */
42
+ managedMarketplace?: ManagedMarketplaceAcquisitionResolver;
41
43
  }
42
44
  export declare function createAppsAdminRoutes(options?: AppsAdminRouteOptions): OpenAPIHono<Env, {}, "/">;
43
45
  export declare function resolveViewerRemoteAppScopes(scopes: readonly string[], catalog: AccessCatalog | undefined): string[];
package/dist/routes.js CHANGED
@@ -1,13 +1,17 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
2
  import { openApiValidationHook, parseJsonBody, parseQuery, RequestValidationError, requireUserId, } from "@voyant-travel/hono";
3
3
  import { hasApiKeyPermission, permissionStringsToPermissions, } from "@voyant-travel/types/api-keys";
4
+ import { eq } from "drizzle-orm";
4
5
  import { z } from "zod";
5
6
  import { grantableRemoteAppScopes } from "./consent.js";
6
7
  import { activateInstallationBodySchema, appCredentialRevocationSchema, appInstallationAuditQuerySchema, appInstallationListQuerySchema, appListQuerySchema, appOAuthAuthorizeQuerySchema, appOAuthTokenSchema, appSessionTokenExchangeSchema, appSessionTokenIssueSchema, appWebhookReplaySchema, createCustomAppRegistrationSchema, installAppSchema, lifecycleActionBodySchema, releaseManifestFetchSchema, releaseManifestUploadSchema, } from "./contracts.js";
7
8
  import { listAppReleases, listInstallationAudit, listInstallationSummaries, loadInstallationDetail, } from "./installation-read-model.js";
8
9
  import { createAppInstallationService } from "./installation-service.js";
10
+ import { createMarketplaceAcquisitionService, resolveMarketplaceInstallIntentSchema, } from "./marketplace-acquisition.js";
11
+ import { buildAppOAuthCallbackUrl } from "./oauth-redirect.js";
9
12
  import { createAppOAuthService } from "./oauth-service.js";
10
- import { activateAppInstallationRoute, authorizeAppOAuthRoute, createAppReleaseRoute, createCustomAppRoute, exchangeAppSessionTokenRoute, fetchAppReleaseRoute, getAppInstallationRoute, getAppRoute, installAppRoute, issueAppOAuthTokenRoute, issueAppSessionTokenRoute, listAppInstallationAuditRoute, listAppInstallationsRoute, listAppReleasesRoute, listAppsRoute, listAppWebhooksRoute, pauseAppInstallationRoute, previewAppInstallationPurgeRoute, replayAppWebhookRoute, resumeAppInstallationRoute, revokeAppInstallationCredentialsRoute, uninstallAppInstallationRoute, } from "./routes-openapi.js";
13
+ import { activateAppInstallationRoute, authorizeAppOAuthRoute, createAppReleaseRoute, createCustomAppRoute, createMarketplaceSetupHandoffRoute, exchangeAppSessionTokenRoute, fetchAppReleaseRoute, getAppInstallationRoute, getAppRoute, installAppRoute, issueAppOAuthTokenRoute, issueAppSessionTokenRoute, listAppInstallationAuditRoute, listAppInstallationsRoute, listAppReleasesRoute, listAppsRoute, listAppWebhooksRoute, pauseAppInstallationRoute, previewAppInstallationPurgeRoute, replayAppWebhookRoute, resolveMarketplaceInstallIntentRoute, resumeAppInstallationRoute, revokeAppInstallationCredentialsRoute, uninstallAppInstallationRoute, } from "./routes-openapi.js";
14
+ import { apps } from "./schema.js";
11
15
  import { createAppsService } from "./service.js";
12
16
  import { createAppSessionTokenService } from "./session-token-service.js";
13
17
  import { listAppWebhookHealth, replayAppWebhookDelivery } from "./webhook-delivery.js";
@@ -16,6 +20,13 @@ const installationIdParamSchema = z.object({ installationId: z.string().min(1) }
16
20
  export function createAppsAdminRoutes(options = {}) {
17
21
  const routes = new OpenAPIHono({ defaultHook: openApiValidationHook });
18
22
  const service = createAppsService(options);
23
+ const marketplace = options.managedMarketplace
24
+ ? createMarketplaceAcquisitionService({
25
+ eventCatalog: options.eventCatalog,
26
+ resolveAcquisitionIntent: options.managedMarketplace.resolveAcquisitionIntent,
27
+ createSetupHandoff: options.managedMarketplace.createSetupHandoff,
28
+ })
29
+ : null;
19
30
  const installations = createAppInstallationService({
20
31
  deploymentId: options.oauth?.deploymentId ?? options.deploymentId,
21
32
  managedInstallation: options.oauth?.managedInstallation,
@@ -62,9 +73,12 @@ export function createAppsAdminRoutes(options = {}) {
62
73
  operatorGrantedScopes: resolveOperatorGrantableRemoteAppScopes(c.get("scopes") ?? [], oauthAccessCatalog),
63
74
  grantedOptionalScopes: splitScopes(body.optional_scopes),
64
75
  });
65
- const redirectUrl = new URL(result.redirectUri);
66
- redirectUrl.searchParams.set("code", result.code);
67
- redirectUrl.searchParams.set("state", result.state);
76
+ const redirectUrl = buildAppOAuthCallbackUrl({
77
+ redirectUri: result.redirectUri,
78
+ code: result.code,
79
+ state: result.state,
80
+ ...(body.nonce ? { nonce: body.nonce } : {}),
81
+ });
68
82
  return c.json({ data: { redirectUrl: redirectUrl.toString(), state: result.state } }, 200);
69
83
  });
70
84
  routes.openapi(issueAppOAuthTokenRoute, async (c) => {
@@ -144,6 +158,24 @@ export function createAppsAdminRoutes(options = {}) {
144
158
  });
145
159
  return c.json({ data: result }, 201);
146
160
  });
161
+ routes.openapi(resolveMarketplaceInstallIntentRoute, async (c) => {
162
+ if (!marketplace)
163
+ return c.json({ error: "Managed Marketplace is not configured" }, 501);
164
+ const body = await parseJsonBody(c, resolveMarketplaceInstallIntentSchema);
165
+ const data = await marketplace.resolveAndAcquire(c.get("db"), {
166
+ intent: body.intent,
167
+ actorId: requireUserId(c),
168
+ });
169
+ return c.json({ data }, 201);
170
+ });
171
+ routes.openapi(createMarketplaceSetupHandoffRoute, async (c) => {
172
+ if (!marketplace)
173
+ return c.json({ error: "Managed Marketplace is not configured" }, 501);
174
+ requireUserId(c);
175
+ const { installationId } = parseInstallationParams(c.req.param());
176
+ const data = await marketplace.createSetupHandoff(c.get("db"), installationId);
177
+ return c.json({ data }, 201);
178
+ });
147
179
  routes.openapi(listAppInstallationsRoute, async (c) => {
148
180
  const query = parseQuery(c, appInstallationListQuerySchema);
149
181
  return c.json(await listInstallationSummaries(c.get("db"), query), 200);
@@ -185,6 +217,22 @@ export function createAppsAdminRoutes(options = {}) {
185
217
  installationId,
186
218
  actorId: body.actorId,
187
219
  });
220
+ if (options.managedMarketplace) {
221
+ const [registration] = await c
222
+ .get("db")
223
+ .select({ distribution: apps.distribution })
224
+ .from(apps)
225
+ .where(eq(apps.id, result.installation.appId))
226
+ .limit(1);
227
+ if (registration?.distribution === "marketplace") {
228
+ await options.managedMarketplace.notifyInstallationLifecycle({
229
+ event: "uninstalled",
230
+ installationId: result.installation.id,
231
+ appId: result.installation.appId,
232
+ releaseId: result.installation.releaseId,
233
+ });
234
+ }
235
+ }
188
236
  return c.json({ data: result }, 200);
189
237
  });
190
238
  routes.openapi(activateAppInstallationRoute, async (c) => {
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { createAppsRuntimePortContribution } from "./runtime-contributor.js";
3
- import { appsManagedAuthRuntimePort } from "./runtime-port.js";
3
+ import { appsManagedAuthRuntimePort, appsManagedMarketplaceRuntimePort } from "./runtime-port.js";
4
4
  function host(values) {
5
5
  return {
6
6
  hasRuntimePort: () => false,
@@ -52,4 +52,39 @@ describe("createAppsRuntimePortContribution", () => {
52
52
  releaseId: "release_2",
53
53
  })).resolves.toEqual({ contractGeneration: 9 });
54
54
  });
55
+ it("requires both opaque acquisition resolution and trusted setup handoff", () => {
56
+ expect(() => appsManagedMarketplaceRuntimePort.test({
57
+ deploymentId: "deployment-1",
58
+ acquisitionResolver: {
59
+ resolveAcquisitionIntent: async () => null,
60
+ createSetupHandoff: async () => ({
61
+ redirectUrl: "https://app.example.com/setup?code=opaque",
62
+ }),
63
+ notifyInstallationLifecycle: async () => undefined,
64
+ },
65
+ })).not.toThrow();
66
+ expect(() => appsManagedMarketplaceRuntimePort.test({
67
+ deploymentId: "deployment-1",
68
+ acquisitionResolver: { resolveAcquisitionIntent: async () => null },
69
+ })).toThrow(/createSetupHandoff/);
70
+ expect(() => appsManagedMarketplaceRuntimePort.test({
71
+ deploymentId: "deployment-1",
72
+ acquisitionResolver: {
73
+ resolveAcquisitionIntent: async () => null,
74
+ createSetupHandoff: async () => ({
75
+ redirectUrl: "https://app.example.com/setup?code=opaque",
76
+ }),
77
+ },
78
+ })).toThrow(/notifyInstallationLifecycle/);
79
+ expect(() => appsManagedMarketplaceRuntimePort.test({
80
+ deploymentId: "",
81
+ acquisitionResolver: {
82
+ resolveAcquisitionIntent: async () => null,
83
+ createSetupHandoff: async () => ({
84
+ redirectUrl: "https://app.example.com/setup?code=opaque",
85
+ }),
86
+ notifyInstallationLifecycle: async () => undefined,
87
+ },
88
+ })).toThrow(/deploymentId/);
89
+ });
55
90
  });
@@ -1,3 +1,4 @@
1
+ import type { HostVerifiedMarketplaceAcquisition } from "./marketplace-acquisition.js";
1
2
  /** Persisted host contract for one managed app installation. */
2
3
  export interface ManagedAppInstallationBinding {
3
4
  workloadEnvironmentId: string;
@@ -27,3 +28,38 @@ export interface AppsManagedAuthRuntime {
27
28
  sessionTokenTtlSeconds?: number;
28
29
  }
29
30
  export declare const appsManagedAuthRuntimePort: import("@voyant-travel/core/project").VoyantPort<AppsManagedAuthRuntime>;
31
+ export interface ManagedMarketplaceAcquisitionResolver {
32
+ /**
33
+ * Resolve an opaque, single-purpose install intent through host authority.
34
+ * The public runtime never accepts catalog coordinates, artifact URLs, or
35
+ * publisher assertions from the browser.
36
+ */
37
+ resolveAcquisitionIntent(input: {
38
+ intent: string;
39
+ }): Promise<HostVerifiedMarketplaceAcquisition | null>;
40
+ /**
41
+ * Mint and deliver a short-lived, host-signed setup assertion. The browser
42
+ * receives only the resulting one-time redirect and never chooses OAuth
43
+ * coordinates or assertion claims.
44
+ */
45
+ createSetupHandoff(input: {
46
+ installationId: string;
47
+ appId: string;
48
+ releaseId: string;
49
+ }): Promise<{
50
+ redirectUrl: string;
51
+ }>;
52
+ /** Deliver an idempotent host-signed lifecycle assertion to the publisher. */
53
+ notifyInstallationLifecycle(input: {
54
+ event: "uninstalled";
55
+ installationId: string;
56
+ appId: string;
57
+ releaseId: string;
58
+ }): Promise<void>;
59
+ }
60
+ export interface AppsManagedMarketplaceRuntime {
61
+ /** Stable host deployment identity used for deployment-local installation rows. */
62
+ deploymentId: string;
63
+ acquisitionResolver: ManagedMarketplaceAcquisitionResolver;
64
+ }
65
+ export declare const appsManagedMarketplaceRuntimePort: import("@voyant-travel/core/project").VoyantPort<AppsManagedMarketplaceRuntime>;
@@ -26,3 +26,23 @@ export const appsManagedAuthRuntimePort = definePort({
26
26
  }
27
27
  },
28
28
  });
29
+ export const appsManagedMarketplaceRuntimePort = definePort({
30
+ id: "apps.managed-marketplace",
31
+ test(runtime) {
32
+ if (!runtime || typeof runtime !== "object") {
33
+ throw new TypeError("apps.managed-marketplace must be an object.");
34
+ }
35
+ if (typeof runtime.deploymentId !== "string" || runtime.deploymentId.trim().length === 0) {
36
+ throw new TypeError("apps.managed-marketplace deploymentId must be a non-empty string.");
37
+ }
38
+ if (typeof runtime.acquisitionResolver?.resolveAcquisitionIntent !== "function") {
39
+ throw new TypeError("apps.managed-marketplace acquisitionResolver.resolveAcquisitionIntent must be a function.");
40
+ }
41
+ if (typeof runtime.acquisitionResolver.createSetupHandoff !== "function") {
42
+ throw new TypeError("apps.managed-marketplace acquisitionResolver.createSetupHandoff must be a function.");
43
+ }
44
+ if (typeof runtime.acquisitionResolver.notifyInstallationLifecycle !== "function") {
45
+ throw new TypeError("apps.managed-marketplace acquisitionResolver.notifyInstallationLifecycle must be a function.");
46
+ }
47
+ },
48
+ });
package/dist/voyant.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineModule, providePort, requirePort } from "@voyant-travel/core/project";
2
2
  import { customFieldValueLifecycleRuntimePort, customFieldValueOperationsRuntimePort, } from "@voyant-travel/core/runtime-port";
3
3
  import { financeAppApiRuntimePort } from "@voyant-travel/finance-contracts/runtime-port";
4
- import { appsManagedAuthRuntimePort } from "./runtime-port.js";
4
+ import { appsManagedAuthRuntimePort, appsManagedMarketplaceRuntimePort } from "./runtime-port.js";
5
5
  const appsAdminRuntime = {
6
6
  entry: "@voyant-travel/apps-react/admin",
7
7
  export: "createSelectedAppsAdminExtension",
@@ -31,9 +31,13 @@ export const appsVoyantModule = defineModule({
31
31
  }),
32
32
  requirePort(financeAppApiRuntimePort, { optional: true }),
33
33
  requirePort(appsManagedAuthRuntimePort, { optional: true }),
34
+ requirePort(appsManagedMarketplaceRuntimePort, { optional: true }),
34
35
  ],
35
36
  provides: {
36
- ports: [providePort(appsManagedAuthRuntimePort)],
37
+ ports: [
38
+ providePort(appsManagedAuthRuntimePort),
39
+ providePort(appsManagedMarketplaceRuntimePort),
40
+ ],
37
41
  },
38
42
  api: [
39
43
  {
@@ -25,6 +25,9 @@
25
25
  "/v1/admin/apps/install": {
26
26
  "post": { "summary": "Install an app release" }
27
27
  },
28
+ "/v1/admin/apps/marketplace/install-intents/resolve": {
29
+ "post": { "summary": "Resolve and admit an opaque Marketplace install intent" }
30
+ },
28
31
  "/v1/admin/apps/installations": {
29
32
  "get": { "summary": "List app installations" }
30
33
  },
@@ -52,6 +55,9 @@
52
55
  "/v1/admin/apps/installations/{installationId}/session-token": {
53
56
  "post": { "summary": "Issue an app extension session token" }
54
57
  },
58
+ "/v1/admin/apps/installations/{installationId}/setup-handoff": {
59
+ "post": { "summary": "Create a one-time Marketplace app setup handoff" }
60
+ },
55
61
  "/v1/admin/apps/installations/{installationId}/webhooks": {
56
62
  "get": { "summary": "List app webhook delivery health" }
57
63
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/apps",
3
- "version": "0.9.1",
3
+ "version": "0.10.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -64,6 +64,11 @@
64
64
  "import": "./dist/locale-resolution.js",
65
65
  "default": "./dist/locale-resolution.js"
66
66
  },
67
+ "./marketplace-acquisition": {
68
+ "types": "./dist/marketplace-acquisition.d.ts",
69
+ "import": "./dist/marketplace-acquisition.js",
70
+ "default": "./dist/marketplace-acquisition.js"
71
+ },
67
72
  "./installation-service": {
68
73
  "types": "./dist/installation-service.d.ts",
69
74
  "import": "./dist/installation-service.js",
@@ -128,13 +133,13 @@
128
133
  "zod": "^4.4.3",
129
134
  "@voyant-travel/admin": "^0.127.0",
130
135
  "@voyant-travel/admin-extension-sdk": "^0.2.0",
131
- "@voyant-travel/core": "^0.128.0",
132
- "@voyant-travel/custom-fields": "^0.2.5",
136
+ "@voyant-travel/core": "^0.129.0",
137
+ "@voyant-travel/custom-fields": "^0.2.6",
133
138
  "@voyant-travel/finance-contracts": "^0.107.0",
134
- "@voyant-travel/db": "^0.114.14",
135
- "@voyant-travel/hono": "^0.130.0",
136
- "@voyant-travel/types": "^0.109.4",
137
- "@voyant-travel/webhook-delivery": "^0.4.3"
139
+ "@voyant-travel/db": "^0.114.15",
140
+ "@voyant-travel/hono": "^0.130.1",
141
+ "@voyant-travel/types": "^0.109.5",
142
+ "@voyant-travel/webhook-delivery": "^0.4.4"
138
143
  },
139
144
  "devDependencies": {
140
145
  "@types/node": "^25.5.2",