@workos/oagen 0.29.4 → 0.30.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.
@@ -6360,6 +6360,43 @@ function resolveResponseModelName(op) {
6360
6360
  if (ref.kind === "nullable" && ref.inner.kind === "model") return ref.inner.name;
6361
6361
  return null;
6362
6362
  }
6363
+ /**
6364
+ * Find every pair of distinct paths that resolve to the same SDK method name.
6365
+ *
6366
+ * Emitters already refuse to generate on a collision, but they only run inside
6367
+ * the per-language build matrix — so a spec addition that collides fails every
6368
+ * matrix job minutes in, with no cheap way to catch it first. Surfacing the same
6369
+ * check from `oagen resolve` turns that into a seconds-long precheck.
6370
+ *
6371
+ * Returns every collision rather than throwing on the first, so a spec that
6372
+ * introduces several is fixed in one pass instead of one CI round-trip each.
6373
+ *
6374
+ * Callers that generate a subset of services must filter to the operations they
6375
+ * will actually emit before calling this: a collision between two out-of-scope
6376
+ * paths is not that run's problem.
6377
+ */
6378
+ function findResolvedMethodCollisions(resolved) {
6379
+ const seen = /* @__PURE__ */ new Map();
6380
+ const collisions = [];
6381
+ for (const r of resolved) {
6382
+ const key = `${r.mountOn}.${r.methodName}`;
6383
+ const current = {
6384
+ httpMethod: r.operation.httpMethod.toUpperCase(),
6385
+ path: r.operation.path
6386
+ };
6387
+ const existing = seen.get(key);
6388
+ if (existing && (existing.path !== current.path || existing.httpMethod !== current.httpMethod)) {
6389
+ collisions.push({
6390
+ key,
6391
+ first: existing,
6392
+ second: current
6393
+ });
6394
+ continue;
6395
+ }
6396
+ if (!existing) seen.set(key, current);
6397
+ }
6398
+ return collisions;
6399
+ }
6363
6400
  //#endregion
6364
6401
  //#region src/engine/scoped-services.ts
6365
6402
  /**
@@ -10910,6 +10947,11 @@ async function resolveCommand(opts) {
10910
10947
  });
10911
10948
  if (opts.docUrl) ir = expandDocUrls(ir, opts.docUrl);
10912
10949
  const resolved = resolveOperations(ir, opts.operationHints, opts.mountRules);
10950
+ const collisions = findResolvedMethodCollisions(resolved);
10951
+ if (collisions.length > 0) {
10952
+ const detail = collisions.map((c) => ` ${c.key}: ${c.first.httpMethod} ${c.first.path} conflicts with ${c.second.httpMethod} ${c.second.path}`).join("\n");
10953
+ throw new CommandError(`Resolved operation name collision${collisions.length > 1 ? "s" : ""}:\n${detail}`, "Give one of each pair an explicit `name` in operationHints. Rename the NEW path — renaming an already-shipped method breaks released SDKs.", 1);
10954
+ }
10913
10955
  if ((opts.format ?? "table") === "json") {
10914
10956
  const output = resolved.map(toJsonRow);
10915
10957
  console.log(JSON.stringify(output, null, 2));
@@ -10994,7 +11036,10 @@ function applyConfig(config) {
10994
11036
  function handleError(err) {
10995
11037
  const exitCode = err instanceof CommandError ? err.exitCode : 1;
10996
11038
  const message = err instanceof Error ? err.message : String(err);
10997
- if (message) console.error(message);
11039
+ if (message) {
11040
+ const label = err instanceof CommandError ? "" : `${err instanceof Error ? err.name : "Error"}: `;
11041
+ console.error(`${label}${message}`);
11042
+ }
10998
11043
  process.exit(exitCode);
10999
11044
  }
11000
11045
  const configArgIdx = process.argv.indexOf("--config");