@voyant-travel/hono 0.119.0 → 0.120.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/openapi.d.ts CHANGED
@@ -124,30 +124,60 @@ export declare function mergeLazyOpenApiPaths(base: OpenApiDocument, mounts: rea
124
124
  * (`@asteasolutions/zod-to-openapi` must stay out of the Worker bundle).
125
125
  */
126
126
  export declare function generateModuleOpenApiDocuments(mounts: readonly ModuleMount[], options: GenerateOpenApiOptions): Promise<Map<string, OpenApiDocument>>;
127
+ /**
128
+ * Build the authoritative path → module ownership map from the mount manifest.
129
+ *
130
+ * Generates each module's isolated doc (see `generateModuleOpenApiDocuments`)
131
+ * only to learn which real absolute paths it owns — so `publicPath` overrides
132
+ * (whose prefix isn't the module name, e.g. `/v1/public/booking-engine`) map to
133
+ * the right module. Routes the manifest doesn't record (`additionalRoutes`,
134
+ * directly-mounted routes) are absent here and fall back to their path segment.
135
+ *
136
+ * Build-time only.
137
+ */
138
+ export declare function buildModulePathOwnership(mounts: readonly ModuleMount[], options: GenerateOpenApiOptions): Promise<Map<string, string>>;
127
139
  /**
128
140
  * Partition a composed document into one document per module, covering EVERY
129
141
  * admin/storefront path (voyant#2733).
130
142
  *
131
- * `generateModuleOpenApiDocuments` alone only sees routes recorded in the module
132
- * mount manifest it misses `additionalRoutes` and any route mounted directly
133
- * on the composed app (e.g. the operator's workflow-runs admin surface, the
134
- * `_meta/capabilities` route). Those were present in the old committed aggregate
135
- * and must not silently vanish from the committed per-module specs.
136
- *
137
- * This uses the manifest as the *authoritative* owner for the routes it knows
138
- * about — which is what makes `publicPath` overrides (whose prefix isn't the
139
- * module name, e.g. `/v1/public/booking-engine`) land under the right module —
140
- * and falls back to the path's own second segment for anything the manifest
141
- * doesn't claim. The result therefore partitions the full surface exactly: every
142
- * `/v1/admin/*` and `/v1/public/*` path lands in exactly one module document.
143
- * Non-surface routes (`/v1/<name>` webhooks, legacy `/v1/*`) live only in the
144
- * aggregate, as before.
143
+ * Uses the ownership map as the authoritative module owner, falling back to the
144
+ * path's own segment for anything the manifest doesn't claim (e.g.
145
+ * `additionalRoutes` mounts like the operator's workflow-runs admin surface).
146
+ * The full surface is therefore partitioned exactly: every `/v1/admin/*` and
147
+ * `/v1/public/*` path lands in exactly one module document. Non-surface routes
148
+ * (`/v1/<name>` webhooks, legacy `/v1/*`) live only in the aggregate, as before.
145
149
  *
146
150
  * Each per-module document carries the aggregate's shared `components` verbatim
147
151
  * (there is ~one), so it stays a valid, self-contained OpenAPI document.
152
+ */
153
+ export declare function partitionByModule(full: OpenApiDocument, owner: ReadonlyMap<string, string>): Map<string, OpenApiDocument>;
154
+ /**
155
+ * Convenience: build the ownership map and partition in one call. Prefer the
156
+ * two-step `buildModulePathOwnership` + `partitionByModule` when you also want
157
+ * to `stampModuleMetadata` the aggregate from the same map (so it's built once).
148
158
  *
149
159
  * Build-time only.
150
160
  */
151
161
  export declare function splitDocumentByModule(full: OpenApiDocument, mounts: readonly ModuleMount[], options: GenerateOpenApiOptions): Promise<Map<string, OpenApiDocument>>;
162
+ /**
163
+ * Stamp every operation with the metadata standard OpenAPI tooling expects
164
+ * (voyant#2733 / voyant#2729). All fields are non-destructive — a value a route
165
+ * already declares is never overwritten:
166
+ * - `operationId` — stable camelCase id from method + path, for readable
167
+ * generated client method names.
168
+ * - `summary` — the method + path signature, so viewers/linters have a title
169
+ * for every operation.
170
+ * - `tags: [module]` — so Swagger/Scalar group the sidebar by module (they
171
+ * key grouping off `tags` and ignore `x-*`).
172
+ * - `x-voyant-module` / `x-voyant-surface` — machine-readable owner + surface
173
+ * for custom tooling that shouldn't re-derive them from path prefixes.
174
+ *
175
+ * The module is the authoritative owner from the manifest, so `publicPath`
176
+ * overrides are labelled with their real owning module rather than their mount
177
+ * prefix. Applied to the aggregate before it's split, so the per-module and
178
+ * surface documents (all derived from it) inherit the stamps. Keys are appended,
179
+ * keeping order deterministic for the drift gate.
180
+ */
181
+ export declare function stampModuleMetadata(doc: OpenApiDocument, owner: ReadonlyMap<string, string>): OpenApiDocument;
152
182
  export {};
153
183
  //# sourceMappingURL=openapi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8EAA8E;IAC9E,CAAC,SAAS,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAA;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,CAAC,SAAS,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAA;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;CAC1B;AAGD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAEjC;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAA;AAE7E;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CASjB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,YAAY,CAAA;AAO/C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,GAAG,eAAe,CAMxF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,gBAAgB,CAAA;CACvB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACrC;AAYD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CA8D1B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAsCvC;AAOD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CA4BvC"}
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
package/dist/openapi.js CHANGED
@@ -173,46 +173,68 @@ export async function generateModuleOpenApiDocuments(mounts, options) {
173
173
  }
174
174
  return result;
175
175
  }
176
- /** Second path segment after the surface prefix — `/v1/admin/<seg>/...`. */
177
- function moduleSegment(path) {
178
- return path.split("/")[3] ?? "misc";
176
+ /**
177
+ * The module a path belongs to, given the authoritative owner map: the manifest
178
+ * owner if known (which is what keeps `publicPath` overrides correct), else the
179
+ * path's own module segment — `<seg>` in `/v1/admin/<seg>/...`,
180
+ * `/v1/public/<seg>/...`, or `/v1/<seg>/...` (webhooks/legacy).
181
+ */
182
+ function moduleNameForPath(path, owner) {
183
+ const known = owner.get(path);
184
+ if (known)
185
+ return known;
186
+ const parts = path.split("/").filter(Boolean); // ["v1","admin","bookings",...]
187
+ const seg = parts[1] === "admin" || parts[1] === "public" ? parts[2] : parts[1];
188
+ return seg ?? "misc";
189
+ }
190
+ /** The API surface a path is served on, or `null` for non-surface routes. */
191
+ function surfaceForPath(path) {
192
+ if (path.startsWith("/v1/admin/"))
193
+ return "admin";
194
+ if (path.startsWith("/v1/public/"))
195
+ return "storefront";
196
+ return null;
179
197
  }
180
198
  /**
181
- * Partition a composed document into one document per module, covering EVERY
182
- * admin/storefront path (voyant#2733).
183
- *
184
- * `generateModuleOpenApiDocuments` alone only sees routes recorded in the module
185
- * mount manifest — it misses `additionalRoutes` and any route mounted directly
186
- * on the composed app (e.g. the operator's workflow-runs admin surface, the
187
- * `_meta/capabilities` route). Those were present in the old committed aggregate
188
- * and must not silently vanish from the committed per-module specs.
199
+ * Build the authoritative path module ownership map from the mount manifest.
189
200
  *
190
- * This uses the manifest as the *authoritative* owner for the routes it knows
191
- * about which is what makes `publicPath` overrides (whose prefix isn't the
192
- * module name, e.g. `/v1/public/booking-engine`) land under the right module —
193
- * and falls back to the path's own second segment for anything the manifest
194
- * doesn't claim. The result therefore partitions the full surface exactly: every
195
- * `/v1/admin/*` and `/v1/public/*` path lands in exactly one module document.
196
- * Non-surface routes (`/v1/<name>` webhooks, legacy `/v1/*`) live only in the
197
- * aggregate, as before.
198
- *
199
- * Each per-module document carries the aggregate's shared `components` verbatim
200
- * (there is ~one), so it stays a valid, self-contained OpenAPI document.
201
+ * Generates each module's isolated doc (see `generateModuleOpenApiDocuments`)
202
+ * only to learn which real absolute paths it owns — so `publicPath` overrides
203
+ * (whose prefix isn't the module name, e.g. `/v1/public/booking-engine`) map to
204
+ * the right module. Routes the manifest doesn't record (`additionalRoutes`,
205
+ * directly-mounted routes) are absent here and fall back to their path segment.
201
206
  *
202
207
  * Build-time only.
203
208
  */
204
- export async function splitDocumentByModule(full, mounts, options) {
209
+ export async function buildModulePathOwnership(mounts, options) {
205
210
  const moduleDocs = await generateModuleOpenApiDocuments(mounts, options);
206
211
  const owner = new Map();
207
212
  for (const [moduleName, doc] of moduleDocs) {
208
213
  for (const path of Object.keys(doc.paths ?? {}))
209
214
  owner.set(path, moduleName);
210
215
  }
216
+ return owner;
217
+ }
218
+ /**
219
+ * Partition a composed document into one document per module, covering EVERY
220
+ * admin/storefront path (voyant#2733).
221
+ *
222
+ * Uses the ownership map as the authoritative module owner, falling back to the
223
+ * path's own segment for anything the manifest doesn't claim (e.g.
224
+ * `additionalRoutes` mounts like the operator's workflow-runs admin surface).
225
+ * The full surface is therefore partitioned exactly: every `/v1/admin/*` and
226
+ * `/v1/public/*` path lands in exactly one module document. Non-surface routes
227
+ * (`/v1/<name>` webhooks, legacy `/v1/*`) live only in the aggregate, as before.
228
+ *
229
+ * Each per-module document carries the aggregate's shared `components` verbatim
230
+ * (there is ~one), so it stays a valid, self-contained OpenAPI document.
231
+ */
232
+ export function partitionByModule(full, owner) {
211
233
  const buckets = new Map();
212
234
  for (const [path, item] of Object.entries(full.paths ?? {})) {
213
235
  if (!path.startsWith("/v1/admin/") && !path.startsWith("/v1/public/"))
214
236
  continue;
215
- const moduleName = owner.get(path) ?? moduleSegment(path);
237
+ const moduleName = moduleNameForPath(path, owner);
216
238
  let bucket = buckets.get(moduleName);
217
239
  if (!bucket) {
218
240
  bucket = {};
@@ -230,3 +252,113 @@ export async function splitDocumentByModule(full, mounts, options) {
230
252
  }
231
253
  return result;
232
254
  }
255
+ /**
256
+ * Convenience: build the ownership map and partition in one call. Prefer the
257
+ * two-step `buildModulePathOwnership` + `partitionByModule` when you also want
258
+ * to `stampModuleMetadata` the aggregate from the same map (so it's built once).
259
+ *
260
+ * Build-time only.
261
+ */
262
+ export async function splitDocumentByModule(full, mounts, options) {
263
+ return partitionByModule(full, await buildModulePathOwnership(mounts, options));
264
+ }
265
+ const HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
266
+ /** PascalCase a path segment, splitting on non-alphanumerics (kebab, etc.). */
267
+ function pascalCase(segment) {
268
+ return segment
269
+ .split(/[^a-zA-Z0-9]+/)
270
+ .filter(Boolean)
271
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
272
+ .join("");
273
+ }
274
+ /**
275
+ * Stable camelCase operationId derived from method + path (voyant#2729) — gives
276
+ * client generators readable, deterministic method names instead of guessing.
277
+ * Path params render as `ByX`, the `v1` prefix is dropped:
278
+ * `GET /v1/admin/bookings/{id}` → `getAdminBookingsById`. Method + path is unique
279
+ * per OpenAPI, so the derived id is too (a numeric suffix guards edge cases).
280
+ */
281
+ function deriveOperationId(method, path) {
282
+ const parts = path
283
+ .split("/")
284
+ .filter(Boolean)
285
+ .filter((segment) => segment !== "v1")
286
+ .map((segment) => {
287
+ const param = /^\{(.+)\}$/.exec(segment);
288
+ return param?.[1] ? `By${pascalCase(param[1])}` : pascalCase(segment);
289
+ });
290
+ return `${method}${parts.join("")}`;
291
+ }
292
+ /**
293
+ * A readable, always-correct operation summary (voyant#2729): the method + path
294
+ * signature. Deliberately mechanical rather than guessed prose — a hand-authored
295
+ * per-route `summary` overrides it (forward-only).
296
+ */
297
+ function deriveSummary(method, path) {
298
+ return `${method.toUpperCase()} ${path}`;
299
+ }
300
+ /**
301
+ * Stamp every operation with the metadata standard OpenAPI tooling expects
302
+ * (voyant#2733 / voyant#2729). All fields are non-destructive — a value a route
303
+ * already declares is never overwritten:
304
+ * - `operationId` — stable camelCase id from method + path, for readable
305
+ * generated client method names.
306
+ * - `summary` — the method + path signature, so viewers/linters have a title
307
+ * for every operation.
308
+ * - `tags: [module]` — so Swagger/Scalar group the sidebar by module (they
309
+ * key grouping off `tags` and ignore `x-*`).
310
+ * - `x-voyant-module` / `x-voyant-surface` — machine-readable owner + surface
311
+ * for custom tooling that shouldn't re-derive them from path prefixes.
312
+ *
313
+ * The module is the authoritative owner from the manifest, so `publicPath`
314
+ * overrides are labelled with their real owning module rather than their mount
315
+ * prefix. Applied to the aggregate before it's split, so the per-module and
316
+ * surface documents (all derived from it) inherit the stamps. Keys are appended,
317
+ * keeping order deterministic for the drift gate.
318
+ */
319
+ export function stampModuleMetadata(doc, owner) {
320
+ const paths = {};
321
+ // operationId must be unique across the document; track what we've assigned
322
+ // (including route-declared ids) so a derived id never collides.
323
+ const usedOperationIds = new Set();
324
+ for (const [path, item] of Object.entries(doc.paths ?? {})) {
325
+ if (!item || typeof item !== "object") {
326
+ paths[path] = item;
327
+ continue;
328
+ }
329
+ const moduleName = moduleNameForPath(path, owner);
330
+ const surface = surfaceForPath(path);
331
+ const nextItem = { ...item };
332
+ for (const method of HTTP_METHODS) {
333
+ const op = nextItem[method];
334
+ if (!op || typeof op !== "object")
335
+ continue;
336
+ const operation = op;
337
+ const declaredId = typeof operation.operationId === "string" && operation.operationId.length > 0
338
+ ? operation.operationId
339
+ : null;
340
+ let operationId = declaredId ?? deriveOperationId(method, path);
341
+ if (!declaredId) {
342
+ let suffix = 2;
343
+ while (usedOperationIds.has(operationId)) {
344
+ operationId = `${deriveOperationId(method, path)}_${suffix++}`;
345
+ }
346
+ }
347
+ usedOperationIds.add(operationId);
348
+ const hasSummary = typeof operation.summary === "string" && operation.summary.length > 0;
349
+ // Swagger/Scalar group by `tags` (and ignore `x-*`) — without one a
350
+ // whole-surface document collapses under a single "default" group (#2733).
351
+ const hasTags = Array.isArray(operation.tags) && operation.tags.length > 0;
352
+ nextItem[method] = {
353
+ ...operation,
354
+ operationId,
355
+ ...(hasSummary ? {} : { summary: deriveSummary(method, path) }),
356
+ ...(hasTags ? {} : { tags: [moduleName] }),
357
+ "x-voyant-module": moduleName,
358
+ ...(surface ? { "x-voyant-surface": surface } : {}),
359
+ };
360
+ }
361
+ paths[path] = nextItem;
362
+ }
363
+ return { ...doc, paths };
364
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/hono",
3
- "version": "0.119.0",
3
+ "version": "0.120.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -140,14 +140,14 @@
140
140
  "@voyant-travel/storage": "^0.106.0",
141
141
  "@voyant-travel/types": "^0.106.1",
142
142
  "@voyant-travel/utils": "^0.105.5",
143
- "@voyant-travel/workflows": "^0.111.13"
143
+ "@voyant-travel/workflows": "^0.111.14"
144
144
  },
145
145
  "devDependencies": {
146
146
  "@cloudflare/workers-types": "^4.20260628.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.13"
150
+ "@voyant-travel/workflows-orchestrator": "^0.111.14"
151
151
  },
152
152
  "files": [
153
153
  "dist"