@workos/oagen 0.24.2 → 0.24.4

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.
@@ -252,6 +252,28 @@ function walkTypeRef(ref, visitor) {
252
252
  default: assertNever(ref);
253
253
  }
254
254
  }
255
+ /**
256
+ * Validate model-placement hints against the FULL spec. Run once at the start of
257
+ * generation — where the complete model/service universe is known — so typos in
258
+ * `modelHints` fail loud even though {@link assignModelsToServices} is
259
+ * intentionally lenient about the partial slices it may be handed.
260
+ */
261
+ function validateModelHints(models, services, hints) {
262
+ const modelNames = new Set(models.map((m) => m.name));
263
+ const serviceNames = new Set(services.map((s) => s.name));
264
+ for (const [modelName, serviceName] of Object.entries(hints)) {
265
+ if (!modelNames.has(modelName)) {
266
+ const err = /* @__PURE__ */ new Error(`modelHints: unknown model "${modelName}". Hint keys must match an IR model name (post-cleanSchemaName/schemaNameTransform).`);
267
+ err.name = "ConfigError";
268
+ throw err;
269
+ }
270
+ if (!serviceNames.has(serviceName)) {
271
+ const err = /* @__PURE__ */ new Error(`modelHints: unknown service "${serviceName}" for model "${modelName}". Hint values must match an IR service name (PascalCase, derived from the operation's first tag).`);
272
+ err.name = "ConfigError";
273
+ throw err;
274
+ }
275
+ }
276
+ }
255
277
  //#endregion
256
278
  //#region src/utils/naming.ts
257
279
  /**
@@ -5837,13 +5859,18 @@ function buildEmitterContext(spec, options) {
5837
5859
  let scopedModelNames;
5838
5860
  let scopedEnumNames;
5839
5861
  if (options.scopedServices && options.scopedServices.size > 0) {
5840
- const scope = options.scopedServices;
5841
- const present = options.presentServiceKeys ?? /* @__PURE__ */ new Set();
5842
- const postMountOf = (service) => resolvedOperations.find((r) => r.service.name === service.name)?.mountOn ?? service.name;
5843
- const reachable = collectReferencedNames(spec.services.filter((s) => {
5844
- const postMount = postMountOf(s);
5845
- return scope.has(postMount) || present.has(canonicalServiceKey(postMount));
5846
- }), spec.models, { preserveAllDiscriminated: false });
5862
+ const selected = options.scopedServices;
5863
+ const selectedOpsByService = /* @__PURE__ */ new Map();
5864
+ for (const r of resolvedOperations) {
5865
+ if (!selected.has(r.mountOn)) continue;
5866
+ const ops = selectedOpsByService.get(r.service.name) ?? [];
5867
+ ops.push(r.operation);
5868
+ selectedOpsByService.set(r.service.name, ops);
5869
+ }
5870
+ const reachable = collectReferencedNames(spec.services.filter((s) => selectedOpsByService.has(s.name)).map((s) => ({
5871
+ ...s,
5872
+ operations: selectedOpsByService.get(s.name)
5873
+ })), spec.models, { preserveAllDiscriminated: false });
5847
5874
  scopedModelNames = reachable.models;
5848
5875
  scopedEnumNames = reachable.enums;
5849
5876
  }
@@ -6420,6 +6447,7 @@ async function removeEmptyParents(startDir, stopDir) {
6420
6447
  //#endregion
6421
6448
  //#region src/engine/orchestrator.ts
6422
6449
  async function generate(spec, emitter, options) {
6450
+ if (options.modelHints) validateModelHints(spec.models, spec.services, options.modelHints);
6423
6451
  const scopedServices = options.services && options.services.length > 0 ? resolveScopedServices(spec, options.services, options.mountRules) : void 0;
6424
6452
  const scoped = scopedServices !== void 0;
6425
6453
  const noPrune = options.noPrune === true || scoped;