@hey-api/shared 0.4.5 → 0.4.6

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/index.mjs CHANGED
@@ -293,6 +293,227 @@ function checkNodeVersion() {
293
293
  }
294
294
  }
295
295
  //#endregion
296
+ //#region src/normalize/coerce.ts
297
+ const COERCER = Symbol("coercer");
298
+ /**
299
+ * Wraps a function as a coercer — a field-level resolver that receives the
300
+ * raw user value and optional context, and returns the resolved field value.
301
+ *
302
+ * Unlike plain defaults, coercers run unconditionally on every resolution,
303
+ * giving full control over the output regardless of what the user provides.
304
+ *
305
+ * Use when a field's resolved value requires computation, context access,
306
+ * or delegation to another config normalizer.
307
+ *
308
+ * @param fn - Receives the raw input value and resolution context, returns
309
+ * the resolved field value.
310
+ *
311
+ * @example
312
+ * ```ts
313
+ * // Delegate watch resolution to a nested config normalizer
314
+ * watch: coerce((value) => watchConfig(value)),
315
+ *
316
+ * // Resolve a field from context
317
+ * output: coerce((value, ctx) => value ?? ctx.defaultOutput),
318
+ * ```
319
+ */
320
+ function coerce(fn) {
321
+ return { [COERCER]: fn };
322
+ }
323
+ function isCoercer(value) {
324
+ return (typeof value === "object" || typeof value === "function") && value !== null && COERCER in value;
325
+ }
326
+ //#endregion
327
+ //#region src/utils/object.ts
328
+ function isPlainObject(value) {
329
+ if (typeof value !== "object" || value === null) return false;
330
+ const proto = Object.getPrototypeOf(value);
331
+ return proto === Object.prototype || proto === null;
332
+ }
333
+ //#endregion
334
+ //#region src/normalize/opaque.ts
335
+ const OPAQUE = Symbol("opaque");
336
+ /**
337
+ * Marks a field as opaque — its value is assigned as-is without being
338
+ * recursed into or merged as config fields.
339
+ *
340
+ * Use when a field accepts an arbitrary object that should not be treated
341
+ * as a nested config table.
342
+ *
343
+ * @param defaultValue - The value to use when no input is provided.
344
+ * @param fallback - Optional. Called with the full table input when the field
345
+ * is absent from the input object. Return `undefined` to fall back to
346
+ * `defaultValue`.
347
+ *
348
+ * @example
349
+ * ```ts
350
+ * path: opaque<string | object>('', (input) =>
351
+ * input && typeof input === 'object' && !('path' in input)
352
+ * ? input
353
+ * : undefined
354
+ * ),
355
+ * ```
356
+ */
357
+ function opaque(defaultValue, fallback) {
358
+ return fallback ? {
359
+ [OPAQUE]: defaultValue,
360
+ fallback
361
+ } : { [OPAQUE]: defaultValue };
362
+ }
363
+ function isOpaque(value) {
364
+ return typeof value === "object" && value !== null && OPAQUE in value;
365
+ }
366
+ //#endregion
367
+ //#region src/normalize/value.ts
368
+ function resolveTable(input, table, { ancestor = {}, context = {}, resolvedCascade = {}, specAncestor = {} } = {}) {
369
+ const { $cascade: cascadeKeys = [], $coerce, $coerceAny, $finalize, ...entries } = table;
370
+ const result = {};
371
+ for (const [key, defaultVal] of Object.entries(entries)) if (!isCoercer(defaultVal) && !isPlainObject(defaultVal) && !isOpaque(defaultVal)) result[key] = defaultVal;
372
+ if (input !== void 0 && input !== null) {
373
+ if ($coerceAny) Object.assign(result, $coerceAny({
374
+ type: typeof input,
375
+ value: input
376
+ }));
377
+ if (isPlainObject(input)) for (const [key, val] of Object.entries(input)) {
378
+ const defaultVal = entries[key];
379
+ if (!isCoercer(defaultVal) && !isPlainObject(defaultVal) && !isOpaque(defaultVal)) result[key] = val;
380
+ }
381
+ else {
382
+ const handler = $coerce?.[typeof input];
383
+ if (handler) Object.assign(result, handler(input));
384
+ }
385
+ }
386
+ const localContext = { ...context };
387
+ const cascadeEntryKeys = cascadeKeys.filter((k) => k in entries);
388
+ const localResolvedCascade = { ...resolvedCascade };
389
+ for (const key of cascadeKeys) if (!cascadeEntryKeys.includes(key)) localContext[key] = result[key];
390
+ for (const key of cascadeEntryKeys) {
391
+ const userVal = isPlainObject(input) ? input[key] : void 0;
392
+ result[key] = resolveField(entries[key], result[key] ?? userVal, key, {
393
+ ancestor,
394
+ context: localContext,
395
+ resolvedCascade: localResolvedCascade,
396
+ specAncestor
397
+ });
398
+ localContext[key] = result[key];
399
+ if (isPlainObject(result[key])) localResolvedCascade[key] = result[key];
400
+ }
401
+ for (const [key, defaultVal] of Object.entries(entries)) {
402
+ if (cascadeEntryKeys.includes(key)) continue;
403
+ const userVal = isPlainObject(input) ? input[key] : void 0;
404
+ if (isOpaque(defaultVal)) {
405
+ if (result[key] !== void 0) {} else if (userVal !== void 0) result[key] = userVal;
406
+ else if (defaultVal.fallback) {
407
+ const fallbackResult = defaultVal.fallback(input);
408
+ result[key] = fallbackResult !== void 0 ? fallbackResult : defaultVal[OPAQUE];
409
+ } else result[key] = defaultVal[OPAQUE];
410
+ continue;
411
+ }
412
+ result[key] = resolveField(defaultVal, isCoercer(defaultVal) ? result[key] ?? userVal : userVal ?? result[key], key, {
413
+ ancestor,
414
+ context: localContext,
415
+ resolvedCascade: localResolvedCascade,
416
+ specAncestor
417
+ });
418
+ }
419
+ $finalize?.(result, input);
420
+ return result;
421
+ }
422
+ function collectDeps(spec, resolved, deps) {
423
+ const { $dependencies } = spec;
424
+ if ($dependencies) for (const key of $dependencies) {
425
+ const value = resolved[key];
426
+ if (value && typeof value === "string") deps.add(value);
427
+ }
428
+ for (const [key, specVal] of Object.entries(spec)) {
429
+ if (key.startsWith("$")) continue;
430
+ if (isPlainObject(specVal) && isPlainObject(resolved[key])) collectDeps(specVal, resolved[key], deps);
431
+ }
432
+ }
433
+ function resolveField(defaultVal, currentVal, key, { ancestor, context, resolvedCascade, specAncestor }) {
434
+ if (isCoercer(defaultVal)) return defaultVal[COERCER](currentVal, context);
435
+ if (isPlainObject(defaultVal)) {
436
+ const cascadeSpec = specAncestor[key];
437
+ const effectiveTable = cascadeSpec ? mergeSpecs(cascadeSpec, defaultVal) : mergeAncestorScalars(ancestor, defaultVal);
438
+ return resolveTable(currentVal !== void 0 ? currentVal : resolvedCascade[key], effectiveTable, {
439
+ ancestor,
440
+ context,
441
+ resolvedCascade,
442
+ specAncestor
443
+ });
444
+ }
445
+ return currentVal !== void 0 ? currentVal : defaultVal;
446
+ }
447
+ function mergeSpecs(cascadeSpec, localSpec) {
448
+ const result = { ...localSpec };
449
+ for (const [key, cascadeVal] of Object.entries(cascadeSpec)) {
450
+ if (key === "$coerceAny" || key === "$coerce" || key === "$cascade" || key === "$finalize") {
451
+ if (result[key] === void 0) result[key] = cascadeVal;
452
+ continue;
453
+ }
454
+ const localVal = result[key];
455
+ if (isPlainObject(cascadeVal) && isPlainObject(localVal)) result[key] = mergeSpecs(cascadeVal, localVal);
456
+ }
457
+ return result;
458
+ }
459
+ function mergeAncestorScalars(ancestor, target) {
460
+ const result = { ...target };
461
+ for (const [key, ancestorVal] of Object.entries(ancestor)) {
462
+ if (isPlainObject(ancestorVal)) continue;
463
+ if (result[key] === void 0) result[key] = ancestorVal;
464
+ }
465
+ return result;
466
+ }
467
+ //#endregion
468
+ //#region src/normalize/config.ts
469
+ /**
470
+ * Creates a typed config normalizer from a resolution table.
471
+ *
472
+ * @example
473
+ * ```ts
474
+ * const normalizePlugin = defineConfig<PluginInput, PluginResolved>({
475
+ * $coerce: {
476
+ * boolean: (enabled) => ({ enabled }),
477
+ * function: (name) => ({ name, enabled: true }),
478
+ * string: (name) => ({ name, enabled: true }),
479
+ * },
480
+ * enabled: false,
481
+ * name: '',
482
+ * output: coerce((val, ctx) => val ?? ctx.defaultOutput),
483
+ * });
484
+ * ```
485
+ */
486
+ function defineConfig(table) {
487
+ function normalize(config, externalContext) {
488
+ const resolvedTable = typeof table === "function" ? table(config) : table;
489
+ const { $cascade: cascadeKeys = [], ...entries } = resolvedTable;
490
+ const ancestor = {};
491
+ const specAncestor = {};
492
+ for (const key of cascadeKeys) {
493
+ const entrySpec = entries[key];
494
+ if (!(key in entries)) {
495
+ if (isPopulated(config, key)) ancestor[key] = config[key];
496
+ continue;
497
+ }
498
+ if (isPlainObject(entrySpec)) specAncestor[key] = entrySpec;
499
+ else {
500
+ const partial = resolveTable(config, { [key]: entrySpec });
501
+ if (partial[key] !== void 0) ancestor[key] = partial[key];
502
+ }
503
+ }
504
+ return resolveTable(config, resolvedTable, {
505
+ ancestor,
506
+ context: externalContext ?? {},
507
+ specAncestor
508
+ });
509
+ }
510
+ normalize[COERCER] = (value) => normalize(value);
511
+ return normalize;
512
+ }
513
+ function isPopulated(config, key) {
514
+ return typeof config === "object" && config !== null && key in config && config[key] !== void 0;
515
+ }
516
+ //#endregion
296
517
  //#region src/utils/input/heyApi.ts
297
518
  const registryRegExp$2 = /^([\w-]+)\/([\w-]+)(?:\?([\w=&.-]*))?$/;
298
519
  const heyApiRegistryBaseUrl = "https://get.heyapi.dev";
@@ -462,50 +683,35 @@ function inputToApiRegistry(input) {
462
683
  }
463
684
  //#endregion
464
685
  //#region src/config/input/input.ts
465
- const defaultWatch = {
686
+ const watchConfig = defineConfig({
687
+ $coerce: {
688
+ boolean: (v) => ({ enabled: v }),
689
+ number: (v) => ({
690
+ enabled: true,
691
+ interval: v
692
+ })
693
+ },
466
694
  enabled: false,
467
695
  interval: 1e3,
468
696
  timeout: 6e4
469
- };
470
- function getWatch(input) {
471
- let watch = { ...defaultWatch };
472
- if (typeof input.path !== "string") return watch;
473
- if (typeof input.watch === "boolean") watch.enabled = input.watch;
474
- else if (typeof input.watch === "number") {
475
- watch.enabled = true;
476
- watch.interval = input.watch;
477
- } else if (input.watch) watch = {
478
- ...watch,
479
- ...input.watch
480
- };
481
- return watch;
482
- }
697
+ });
698
+ const inputConfig = defineConfig({
699
+ $coerce: { string: (path) => ({ path }) },
700
+ $finalize(config, input) {
701
+ if (input && typeof input === "object" && "organization" in input && config.path === "") config.path = heyApiRegistryBaseUrl;
702
+ },
703
+ path: opaque("", (input) => input && typeof input === "object" && !("path" in input) && !("organization" in input) ? input : void 0),
704
+ watch: coerce((value) => watchConfig(value))
705
+ });
483
706
  function getInput(userConfig) {
484
707
  const userInputs = userConfig.input instanceof Array ? userConfig.input : [userConfig.input];
485
708
  const inputs = [];
486
709
  for (const userInput of userInputs) {
487
- let input = {
488
- path: "",
489
- watch: defaultWatch
490
- };
491
- if (typeof userInput === "string") input.path = userInput;
492
- else if (userInput && (userInput.path !== void 0 || userInput.organization !== void 0)) {
493
- input = {
494
- ...input,
495
- path: heyApiRegistryBaseUrl,
496
- ...userInput
497
- };
498
- if (input.watch !== void 0) input.watch = getWatch(input);
499
- } else input = {
500
- ...input,
501
- path: userInput
502
- };
710
+ const input = inputConfig(userInput);
711
+ if (!input.path) continue;
503
712
  if (typeof input.path === "string") inputToApiRegistry(input);
504
- if (userConfig.watch !== void 0 && input.watch.enabled === defaultWatch.enabled && input.watch.interval === defaultWatch.interval && input.watch.timeout === defaultWatch.timeout) input.watch = getWatch({
505
- path: input.path,
506
- watch: userConfig.watch
507
- });
508
- if (input.path) inputs.push(input);
713
+ if (userConfig.watch !== void 0 && input.watch.enabled === false && input.watch.interval === 1e3 && input.watch.timeout === 6e4) input.watch = watchConfig(userConfig.watch);
714
+ inputs.push(input);
509
715
  }
510
716
  return inputs;
511
717
  }
@@ -612,18 +818,14 @@ function logInputPaths(inputPaths, jobIndex) {
612
818
  }
613
819
  //#endregion
614
820
  //#region src/config/logs.ts
615
- function getLogs(userLogs) {
616
- let logs = {
617
- file: true,
618
- level: "info",
619
- path: process.cwd()
620
- };
621
- if (typeof userLogs === "string") logs.path = userLogs;
622
- else logs = {
623
- ...logs,
624
- ...userLogs
625
- };
626
- return logs;
821
+ const logsConfig = defineConfig({
822
+ $coerce: { string: (path) => ({ path }) },
823
+ file: true,
824
+ level: "info",
825
+ path: process.cwd()
826
+ });
827
+ function getLogs(input) {
828
+ return logsConfig(input);
627
829
  }
628
830
  //#endregion
629
831
  //#region src/config/output/postprocess.ts
@@ -646,65 +848,19 @@ function postprocessOutput(config, postProcessors, jobPrefix) {
646
848
  }
647
849
  }
648
850
  //#endregion
649
- //#region src/config/utils/config.ts
650
- const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && typeof value !== "function";
651
- const mergeResult = (result, mapped) => {
652
- for (const [key, value] of Object.entries(mapped)) if (value !== void 0 && value !== "") result[key] = value;
653
- return result;
654
- };
655
- const valueToObject = ({ defaultValue, mappers, value }) => {
656
- let result = { ...defaultValue };
657
- switch (typeof value) {
658
- case "boolean":
659
- if (mappers && "boolean" in mappers) {
660
- const mapper = mappers.boolean;
661
- result = mergeResult(result, mapper(value));
662
- }
663
- break;
664
- case "function":
665
- if (mappers && "function" in mappers) {
666
- const mapper = mappers.function;
667
- result = mergeResult(result, mapper(value));
668
- }
669
- break;
670
- case "number":
671
- if (mappers && "number" in mappers) {
672
- const mapper = mappers.number;
673
- result = mergeResult(result, mapper(value));
674
- }
675
- break;
676
- case "string":
677
- if (mappers && "string" in mappers) {
678
- const mapper = mappers.string;
679
- result = mergeResult(result, mapper(value));
680
- }
681
- break;
682
- case "object":
683
- if (isPlainObject(value)) if (mappers && "object" in mappers && typeof mappers.object === "function") {
684
- const mapper = mappers.object;
685
- result = mergeResult(result, mapper(value, defaultValue));
686
- } else result = mergeResult(result, value);
687
- break;
688
- }
689
- return result;
690
- };
691
- //#endregion
692
851
  //#region src/config/output/source/config.ts
693
- function resolveSource(config) {
694
- const source = valueToObject({
695
- defaultValue: {
696
- enabled: Boolean(config.source),
697
- extension: "json",
698
- fileName: "source",
699
- serialize: (input) => JSON.stringify(input, null, 2)
700
- },
701
- mappers: { boolean: (enabled) => ({ enabled }) },
702
- value: config.source
703
- });
704
- if (source.path === void 0 || source.path === true) source.path = "";
705
- else if (source.path === false) source.path = null;
706
- return source;
707
- }
852
+ const sourceConfig = defineConfig({
853
+ $coerceAny: ({ value }) => ({ enabled: Boolean(value) }),
854
+ enabled: false,
855
+ extension: "json",
856
+ fileName: "source",
857
+ path: coerce((value) => {
858
+ if (value === true || value === void 0 || value === "") return "";
859
+ if (value === false || value === null) return null;
860
+ return value;
861
+ }),
862
+ serialize: coerce((value) => typeof value === "function" ? value : (input) => JSON.stringify(input, null, 2))
863
+ });
708
864
  //#endregion
709
865
  //#region src/config/parser/config.ts
710
866
  const defaultPaginationKeywords = [
@@ -715,93 +871,44 @@ const defaultPaginationKeywords = [
715
871
  "page",
716
872
  "start"
717
873
  ];
718
- function getParser(userConfig) {
719
- return valueToObject({
720
- defaultValue: {
721
- hooks: {},
722
- pagination: { keywords: defaultPaginationKeywords },
723
- transforms: {
724
- enums: {
725
- case: "PascalCase",
726
- enabled: false,
727
- mode: "root",
728
- name: "{{name}}Enum"
729
- },
730
- propertiesRequiredByDefault: false,
731
- readWrite: {
732
- enabled: true,
733
- requests: {
734
- case: "preserve",
735
- name: "{{name}}Writable"
736
- },
737
- responses: {
738
- case: "preserve",
739
- name: "{{name}}"
740
- }
874
+ const parserConfig = defineConfig({
875
+ hooks: {},
876
+ pagination: { keywords: defaultPaginationKeywords },
877
+ transforms: {
878
+ enums: {
879
+ $coerce: { string: (mode) => ({ mode }) },
880
+ $coerceAny: ({ value }) => ({ enabled: Boolean(value) }),
881
+ case: "PascalCase",
882
+ enabled: false,
883
+ mode: "root",
884
+ name: "{{name}}Enum"
885
+ },
886
+ propertiesRequiredByDefault: false,
887
+ readWrite: {
888
+ $coerceAny: ({ value }) => ({ enabled: Boolean(value) }),
889
+ enabled: true,
890
+ requests: {
891
+ $coerce: {
892
+ function: (name) => ({ name }),
893
+ string: (name) => ({ name })
741
894
  },
742
- schemaName: void 0
895
+ case: "preserve",
896
+ name: "{{name}}Writable"
743
897
  },
744
- validate_EXPERIMENTAL: false
745
- },
746
- mappers: { object: (fields, defaultValue) => ({
747
- ...fields,
748
- pagination: valueToObject({
749
- defaultValue: { ...defaultValue.pagination },
750
- value: fields.pagination
751
- }),
752
- transforms: valueToObject({
753
- defaultValue: { ...defaultValue.transforms },
754
- mappers: { object: (fields, defaultValue) => ({
755
- ...fields,
756
- enums: valueToObject({
757
- defaultValue: {
758
- ...defaultValue.enums,
759
- enabled: fields.enums !== void 0 ? Boolean(fields.enums) : defaultValue.enums.enabled
760
- },
761
- mappers: {
762
- boolean: (enabled) => ({ enabled }),
763
- string: (mode) => ({ mode })
764
- },
765
- value: fields.enums
766
- }),
767
- propertiesRequiredByDefault: fields.propertiesRequiredByDefault !== void 0 ? fields.propertiesRequiredByDefault : defaultValue.propertiesRequiredByDefault,
768
- readWrite: valueToObject({
769
- defaultValue: {
770
- ...defaultValue.readWrite,
771
- enabled: fields.readWrite !== void 0 ? Boolean(fields.readWrite) : defaultValue.readWrite.enabled
772
- },
773
- mappers: {
774
- boolean: (enabled) => ({ enabled }),
775
- object: (fields, defaultValue) => ({
776
- ...fields,
777
- requests: valueToObject({
778
- defaultValue: { ...defaultValue.requests },
779
- mappers: {
780
- function: (name) => ({ name }),
781
- string: (name) => ({ name })
782
- },
783
- value: fields.requests
784
- }),
785
- responses: valueToObject({
786
- defaultValue: { ...defaultValue.responses },
787
- mappers: {
788
- function: (name) => ({ name }),
789
- string: (name) => ({ name })
790
- },
791
- value: fields.responses
792
- })
793
- })
794
- },
795
- value: fields.readWrite
796
- }),
797
- schemaName: fields.schemaName !== void 0 ? fields.schemaName : defaultValue.schemaName
798
- }) },
799
- value: fields.transforms
800
- }),
801
- validate_EXPERIMENTAL: fields.validate_EXPERIMENTAL === true ? "warn" : fields.validate_EXPERIMENTAL
802
- }) },
803
- value: userConfig.parser
804
- });
898
+ responses: {
899
+ $coerce: {
900
+ function: (name) => ({ name }),
901
+ string: (name) => ({ name })
902
+ },
903
+ case: "preserve",
904
+ name: "{{name}}"
905
+ }
906
+ }
907
+ },
908
+ validate_EXPERIMENTAL: coerce((value) => value === true ? "warn" : value || false)
909
+ });
910
+ function getParser(input) {
911
+ return parserConfig(input.parser ?? {});
805
912
  }
806
913
  //#endregion
807
914
  //#region src/config/utils/dependencies.ts
@@ -1475,6 +1582,7 @@ async function getSpec({ fetchOptions, inputPath, timeout, watch }) {
1475
1582
  //#endregion
1476
1583
  //#region src/utils/minHeap.ts
1477
1584
  var MinHeap = class {
1585
+ declIndex;
1478
1586
  heap = [];
1479
1587
  constructor(declIndex) {
1480
1588
  this.declIndex = declIndex;
@@ -1872,7 +1980,7 @@ var PluginInstance = class {
1872
1980
  api;
1873
1981
  config;
1874
1982
  context;
1875
- dependencies = [];
1983
+ dependencies = /* @__PURE__ */ new Set();
1876
1984
  eventHooks;
1877
1985
  gen;
1878
1986
  handler;
@@ -1884,6 +1992,8 @@ var PluginInstance = class {
1884
1992
  * code generation.
1885
1993
  */
1886
1994
  package;
1995
+ /** Symbols declared in the plugin config. */
1996
+ symbols;
1887
1997
  constructor(props) {
1888
1998
  this.api = props.api ?? {};
1889
1999
  this.config = props.config;
@@ -1894,6 +2004,7 @@ var PluginInstance = class {
1894
2004
  this.handler = props.handler;
1895
2005
  this.name = props.name;
1896
2006
  this.package = props.context.package;
2007
+ this.symbols = this.buildSymbols(props.symbols);
1897
2008
  }
1898
2009
  external(resource, meta = {}) {
1899
2010
  return this.gen.symbols.reference({
@@ -2093,7 +2204,7 @@ var PluginInstance = class {
2093
2204
  const symbolIn = {
2094
2205
  ...symbol,
2095
2206
  meta: {
2096
- pluginName: path.isAbsolute(this.name) ? "custom" : this.name,
2207
+ ...symbol.external ? {} : { pluginName: path.isAbsolute(this.name) ? "custom" : this.name },
2097
2208
  ...meta
2098
2209
  },
2099
2210
  name
@@ -2140,6 +2251,9 @@ var PluginInstance = class {
2140
2251
  }
2141
2252
  return result;
2142
2253
  }
2254
+ buildSymbols(fn) {
2255
+ return fn ? fn(this) : {};
2256
+ }
2143
2257
  forEachError(error, event) {
2144
2258
  const originalError = error instanceof Error ? error : new Error(String(error));
2145
2259
  throw new HeyApiError({
@@ -2264,10 +2378,11 @@ var Context = class {
2264
2378
  api: plugin.api,
2265
2379
  config: plugin.config,
2266
2380
  context: this,
2267
- dependencies: plugin.dependencies ?? [],
2381
+ dependencies: plugin.dependencies ?? /* @__PURE__ */ new Set(),
2268
2382
  gen: this.gen,
2269
2383
  handler: plugin.handler,
2270
- name: plugin.name
2384
+ name: plugin.name,
2385
+ symbols: plugin.symbols
2271
2386
  });
2272
2387
  this.plugins[instance.name] = instance;
2273
2388
  return instance;
@@ -2601,8 +2716,9 @@ function hasFilters(config) {
2601
2716
  function collectOperations({ filters, parameters, requestBodies, resourceMetadata, responses, schemas }) {
2602
2717
  const finalSet = /* @__PURE__ */ new Set();
2603
2718
  const stack = [...filters.operations.include.size ? filters.operations.include : new Set(resourceMetadata.operations.keys())];
2604
- while (stack.length) {
2605
- const key = stack.pop();
2719
+ let index = 0;
2720
+ while (index < stack.length) {
2721
+ const key = stack[index++];
2606
2722
  if (filters.operations.exclude.has(key) || finalSet.has(key)) continue;
2607
2723
  const node = resourceMetadata.operations.get(key);
2608
2724
  if (!node) continue;
@@ -2633,8 +2749,9 @@ function collectOperations({ filters, parameters, requestBodies, resourceMetadat
2633
2749
  function collectParameters({ filters, resourceMetadata, schemas }) {
2634
2750
  const finalSet = /* @__PURE__ */ new Set();
2635
2751
  const stack = [...filters.parameters.include.size ? filters.parameters.include : new Set(resourceMetadata.parameters.keys())];
2636
- while (stack.length) {
2637
- const key = stack.pop();
2752
+ let index = 0;
2753
+ while (index < stack.length) {
2754
+ const key = stack[index++];
2638
2755
  if (filters.parameters.exclude.has(key) || finalSet.has(key)) continue;
2639
2756
  const node = resourceMetadata.parameters.get(key);
2640
2757
  if (!node) continue;
@@ -2663,8 +2780,9 @@ function collectParameters({ filters, resourceMetadata, schemas }) {
2663
2780
  function collectRequestBodies({ filters, resourceMetadata, schemas }) {
2664
2781
  const finalSet = /* @__PURE__ */ new Set();
2665
2782
  const stack = [...filters.requestBodies.include.size ? filters.requestBodies.include : new Set(resourceMetadata.requestBodies.keys())];
2666
- while (stack.length) {
2667
- const key = stack.pop();
2783
+ let index = 0;
2784
+ while (index < stack.length) {
2785
+ const key = stack[index++];
2668
2786
  if (filters.requestBodies.exclude.has(key) || finalSet.has(key)) continue;
2669
2787
  const node = resourceMetadata.requestBodies.get(key);
2670
2788
  if (!node) continue;
@@ -2693,8 +2811,9 @@ function collectRequestBodies({ filters, resourceMetadata, schemas }) {
2693
2811
  function collectResponses({ filters, resourceMetadata, schemas }) {
2694
2812
  const finalSet = /* @__PURE__ */ new Set();
2695
2813
  const stack = [...filters.responses.include.size ? filters.responses.include : new Set(resourceMetadata.responses.keys())];
2696
- while (stack.length) {
2697
- const key = stack.pop();
2814
+ let index = 0;
2815
+ while (index < stack.length) {
2816
+ const key = stack[index++];
2698
2817
  if (filters.responses.exclude.has(key) || finalSet.has(key)) continue;
2699
2818
  const node = resourceMetadata.responses.get(key);
2700
2819
  if (!node) continue;
@@ -2723,8 +2842,9 @@ function collectResponses({ filters, resourceMetadata, schemas }) {
2723
2842
  function collectSchemas({ filters, resourceMetadata }) {
2724
2843
  const finalSet = /* @__PURE__ */ new Set();
2725
2844
  const stack = [...filters.schemas.include.size ? filters.schemas.include : new Set(resourceMetadata.schemas.keys())];
2726
- while (stack.length) {
2727
- const key = stack.pop();
2845
+ let index = 0;
2846
+ while (index < stack.length) {
2847
+ const key = stack[index++];
2728
2848
  if (filters.schemas.exclude.has(key) || finalSet.has(key)) continue;
2729
2849
  const node = resourceMetadata.schemas.get(key);
2730
2850
  if (!node) continue;
@@ -2836,8 +2956,9 @@ function collectExplicitDependencies({ filters, resourceMetadata }) {
2836
2956
  function collectOperationDependencies({ operations, resourceMetadata }) {
2837
2957
  const finalSet = /* @__PURE__ */ new Set();
2838
2958
  const stack = [...new Set([...operations].flatMap((key) => [...resourceMetadata.operations.get(key)?.dependencies ?? []]))];
2839
- while (stack.length) {
2840
- const key = stack.pop();
2959
+ let index = 0;
2960
+ while (index < stack.length) {
2961
+ const key = stack[index++];
2841
2962
  if (finalSet.has(key)) continue;
2842
2963
  finalSet.add(key);
2843
2964
  const dependencies = getResourceDependencies(key, resourceMetadata);
@@ -4170,6 +4291,47 @@ const mergeParametersObjects = ({ source, target }) => {
4170
4291
  return result;
4171
4292
  };
4172
4293
  //#endregion
4294
+ //#region src/openApi/shared/utils/security.ts
4295
+ function securitySchemeSignature(scheme) {
4296
+ switch (scheme.type) {
4297
+ case "apiKey":
4298
+ if (!scheme.in || !scheme.name) return;
4299
+ if (scheme.in !== "header" && scheme.in !== "query" && scheme.in !== "cookie") return;
4300
+ return `apiKey:${scheme.in}:${scheme.name}`;
4301
+ case "basic": return "http:basic";
4302
+ case "http": {
4303
+ const httpScheme = (scheme.scheme ?? "").toLowerCase();
4304
+ if (httpScheme !== "bearer" && httpScheme !== "basic") return;
4305
+ return `http:${httpScheme}`;
4306
+ }
4307
+ case "oauth2":
4308
+ case "openIdConnect": return "http:bearer";
4309
+ default: return;
4310
+ }
4311
+ }
4312
+ /**
4313
+ * Build the set of security keys whose canonical signature collides
4314
+ * with another scheme. Only these keys should have their name preserved
4315
+ * on the IR `key` field — schemes with unique signatures don't need
4316
+ * disambiguation at runtime.
4317
+ */
4318
+ function computeAmbiguousSecurityKeys(schemes) {
4319
+ const buckets = /* @__PURE__ */ new Map();
4320
+ for (const [name, scheme] of schemes) {
4321
+ const signature = securitySchemeSignature(scheme);
4322
+ if (!signature) continue;
4323
+ const bucket = buckets.get(signature) ?? [];
4324
+ bucket.push(name);
4325
+ buckets.set(signature, bucket);
4326
+ }
4327
+ const ambiguous = /* @__PURE__ */ new Set();
4328
+ for (const bucket of buckets.values()) {
4329
+ if (bucket.length < 2) continue;
4330
+ for (const name of bucket) ambiguous.add(name);
4331
+ }
4332
+ return ambiguous;
4333
+ }
4334
+ //#endregion
4173
4335
  //#region src/openApi/shared/utils/validator.ts
4174
4336
  const isSimpleKey = (key) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
4175
4337
  const formatPath = (path) => path.map((segment, i) => {
@@ -4805,13 +4967,13 @@ const paginationField$2 = ({ context, name, schema }) => {
4805
4967
  };
4806
4968
  //#endregion
4807
4969
  //#region src/openApi/2.0.x/parser/operation.ts
4808
- const parseOperationJsDoc$2 = ({ irOperation, operation }) => {
4970
+ function parseOperationJsDoc$2({ irOperation, operation }) {
4809
4971
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
4810
4972
  if (operation.description) irOperation.description = operation.description;
4811
4973
  if (operation.summary) irOperation.summary = operation.summary;
4812
4974
  if (operation.tags?.length) irOperation.tags = operation.tags;
4813
- };
4814
- const initIrOperation$2 = ({ context, method, operation, path, state }) => {
4975
+ }
4976
+ function initIrOperation$2({ context, method, operation, path, state }) {
4815
4977
  const irOperation = {
4816
4978
  id: operationToId({
4817
4979
  context,
@@ -4833,8 +4995,8 @@ const initIrOperation$2 = ({ context, method, operation, path, state }) => {
4833
4995
  target: irOperation
4834
4996
  });
4835
4997
  return irOperation;
4836
- };
4837
- const operationToIrOperation$2 = ({ context, method, operation, path, securitySchemesMap, state }) => {
4998
+ }
4999
+ function operationToIrOperation$2({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
4838
5000
  const irOperation = initIrOperation$2({
4839
5001
  context,
4840
5002
  method,
@@ -4990,16 +5152,18 @@ const operationToIrOperation$2 = ({ context, method, operation, path, securitySc
4990
5152
  }
4991
5153
  }
4992
5154
  if (!irSecuritySchemeObject) continue;
5155
+ if (ambiguousSecurityKeys.has(name)) irSecuritySchemeObject.key = name;
4993
5156
  securitySchemeObjects.set(name, irSecuritySchemeObject);
4994
5157
  }
4995
5158
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
4996
5159
  }
4997
5160
  return irOperation;
4998
- };
4999
- const parsePathOperation$2 = ({ context, method, operation, path, securitySchemesMap, state }) => {
5161
+ }
5162
+ function parsePathOperation$2({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
5000
5163
  if (!context.ir.paths) context.ir.paths = {};
5001
5164
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
5002
5165
  context.ir.paths[path][method] = operationToIrOperation$2({
5166
+ ambiguousSecurityKeys,
5003
5167
  context,
5004
5168
  method,
5005
5169
  operation,
@@ -5007,7 +5171,7 @@ const parsePathOperation$2 = ({ context, method, operation, path, securityScheme
5007
5171
  securitySchemesMap,
5008
5172
  state
5009
5173
  });
5010
- };
5174
+ }
5011
5175
  //#endregion
5012
5176
  //#region src/openApi/2.0.x/parser/parameter.ts
5013
5177
  /**
@@ -5206,6 +5370,7 @@ const parseV2_0_X = (context) => {
5206
5370
  const securitySchemeObject = context.spec.securityDefinitions[name];
5207
5371
  securitySchemesMap.set(name, securitySchemeObject);
5208
5372
  }
5373
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
5209
5374
  if (context.spec.definitions) for (const name in context.spec.definitions) {
5210
5375
  const $ref = pathToJsonPointer(["definitions", name]);
5211
5376
  const schema = context.spec.definitions[name];
@@ -5230,6 +5395,7 @@ const parseV2_0_X = (context) => {
5230
5395
  security: context.spec.security
5231
5396
  };
5232
5397
  const operationArgs = {
5398
+ ambiguousSecurityKeys,
5233
5399
  context,
5234
5400
  operation: {
5235
5401
  ...commonOperation,
@@ -6182,13 +6348,13 @@ const paginationField$1 = ({ context, name, schema }) => {
6182
6348
  };
6183
6349
  //#endregion
6184
6350
  //#region src/openApi/3.0.x/parser/operation.ts
6185
- const parseOperationJsDoc$1 = ({ irOperation, operation }) => {
6351
+ function parseOperationJsDoc$1({ irOperation, operation }) {
6186
6352
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
6187
6353
  if (operation.description) irOperation.description = operation.description;
6188
6354
  if (operation.summary) irOperation.summary = operation.summary;
6189
6355
  if (operation.tags?.length) irOperation.tags = operation.tags;
6190
- };
6191
- const initIrOperation$1 = ({ context, method, operation, path, state }) => {
6356
+ }
6357
+ function initIrOperation$1({ context, method, operation, path, state }) {
6192
6358
  const irOperation = {
6193
6359
  id: operationToId({
6194
6360
  context,
@@ -6210,8 +6376,8 @@ const initIrOperation$1 = ({ context, method, operation, path, state }) => {
6210
6376
  target: irOperation
6211
6377
  });
6212
6378
  return irOperation;
6213
- };
6214
- const operationToIrOperation$1 = ({ context, method, operation, path, securitySchemesMap, state }) => {
6379
+ }
6380
+ function operationToIrOperation$1({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
6215
6381
  const irOperation = initIrOperation$1({
6216
6382
  context,
6217
6383
  method,
@@ -6286,17 +6452,19 @@ const operationToIrOperation$1 = ({ context, method, operation, path, securitySc
6286
6452
  for (const securityRequirementObject of operation.security) for (const name in securityRequirementObject) {
6287
6453
  const securitySchemeObject = securitySchemesMap.get(name);
6288
6454
  if (!securitySchemeObject) continue;
6455
+ if (ambiguousSecurityKeys.has(name)) securitySchemeObject.key = name;
6289
6456
  securitySchemeObjects.set(name, securitySchemeObject);
6290
6457
  }
6291
6458
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
6292
6459
  }
6293
6460
  return irOperation;
6294
- };
6295
- const parsePathOperation$1 = ({ context, method, operation, path, securitySchemesMap, state }) => {
6461
+ }
6462
+ function parsePathOperation$1({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
6296
6463
  if (!context.ir.paths) context.ir.paths = {};
6297
6464
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
6298
6465
  if (operation.servers) context.ir.servers = [...context.ir.servers ?? [], ...operation.servers];
6299
6466
  context.ir.paths[path][method] = operationToIrOperation$1({
6467
+ ambiguousSecurityKeys,
6300
6468
  context,
6301
6469
  method,
6302
6470
  operation,
@@ -6304,7 +6472,7 @@ const parsePathOperation$1 = ({ context, method, operation, path, securityScheme
6304
6472
  securitySchemesMap,
6305
6473
  state
6306
6474
  });
6307
- };
6475
+ }
6308
6476
  //#endregion
6309
6477
  //#region src/openApi/3.0.x/parser/parameter.ts
6310
6478
  /**
@@ -6590,6 +6758,7 @@ const parseV3_0_X = (context) => {
6590
6758
  });
6591
6759
  }
6592
6760
  }
6761
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
6593
6762
  parseServers$1({ context });
6594
6763
  for (const path in context.spec.paths) {
6595
6764
  if (path.startsWith("x-")) continue;
@@ -6599,6 +6768,7 @@ const parseV3_0_X = (context) => {
6599
6768
  ...pathItem
6600
6769
  } : pathItem;
6601
6770
  const operationArgs = {
6771
+ ambiguousSecurityKeys,
6602
6772
  context,
6603
6773
  operation: {
6604
6774
  description: finalPathItem.description,
@@ -7637,13 +7807,13 @@ const paginationField = ({ context, name, schema }) => {
7637
7807
  };
7638
7808
  //#endregion
7639
7809
  //#region src/openApi/3.1.x/parser/operation.ts
7640
- const parseOperationJsDoc = ({ irOperation, operation }) => {
7810
+ function parseOperationJsDoc({ irOperation, operation }) {
7641
7811
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
7642
7812
  if (operation.description) irOperation.description = operation.description;
7643
7813
  if (operation.summary) irOperation.summary = operation.summary;
7644
7814
  if (operation.tags?.length) irOperation.tags = operation.tags;
7645
- };
7646
- const initIrOperation = ({ context, method, operation, path, state }) => {
7815
+ }
7816
+ function initIrOperation({ context, method, operation, path, state }) {
7647
7817
  const irOperation = {
7648
7818
  id: operationToId({
7649
7819
  context,
@@ -7665,8 +7835,8 @@ const initIrOperation = ({ context, method, operation, path, state }) => {
7665
7835
  target: irOperation
7666
7836
  });
7667
7837
  return irOperation;
7668
- };
7669
- const operationToIrOperation = ({ context, method, operation, path, securitySchemesMap, state }) => {
7838
+ }
7839
+ function operationToIrOperation({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
7670
7840
  const irOperation = initIrOperation({
7671
7841
  context,
7672
7842
  method,
@@ -7732,15 +7902,17 @@ const operationToIrOperation = ({ context, method, operation, path, securitySche
7732
7902
  for (const securityRequirementObject of operation.security) for (const name in securityRequirementObject) {
7733
7903
  const securitySchemeObject = securitySchemesMap.get(name);
7734
7904
  if (!securitySchemeObject) continue;
7905
+ if (ambiguousSecurityKeys.has(name)) securitySchemeObject.key = name;
7735
7906
  securitySchemeObjects.set(name, securitySchemeObject);
7736
7907
  }
7737
7908
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
7738
7909
  }
7739
7910
  return irOperation;
7740
- };
7741
- const parseOperationObject = ({ context, method, operation, path, securitySchemesMap, state }) => {
7911
+ }
7912
+ function parseOperationObject({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
7742
7913
  if (operation.servers) context.ir.servers = [...context.ir.servers ?? [], ...operation.servers];
7743
7914
  return { parsed: operationToIrOperation({
7915
+ ambiguousSecurityKeys,
7744
7916
  context,
7745
7917
  method,
7746
7918
  operation,
@@ -7748,8 +7920,8 @@ const parseOperationObject = ({ context, method, operation, path, securityScheme
7748
7920
  securitySchemesMap,
7749
7921
  state
7750
7922
  }) };
7751
- };
7752
- const parsePathOperation = ({ context, method, path, ...options }) => {
7923
+ }
7924
+ function parsePathOperation({ context, method, path, ...options }) {
7753
7925
  if (!context.ir.paths) context.ir.paths = {};
7754
7926
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
7755
7927
  const { parsed } = parseOperationObject({
@@ -7759,8 +7931,8 @@ const parsePathOperation = ({ context, method, path, ...options }) => {
7759
7931
  ...options
7760
7932
  });
7761
7933
  context.ir.paths[path][method] = parsed;
7762
- };
7763
- const parseWebhookOperation = ({ context, key, method, ...options }) => {
7934
+ }
7935
+ function parseWebhookOperation({ context, key, method, ...options }) {
7764
7936
  if (!context.ir.webhooks) context.ir.webhooks = {};
7765
7937
  if (!context.ir.webhooks[key]) context.ir.webhooks[key] = {};
7766
7938
  const { parsed } = parseOperationObject({
@@ -7770,7 +7942,7 @@ const parseWebhookOperation = ({ context, key, method, ...options }) => {
7770
7942
  ...options
7771
7943
  });
7772
7944
  context.ir.webhooks[key][method] = parsed;
7773
- };
7945
+ }
7774
7946
  //#endregion
7775
7947
  //#region src/openApi/3.1.x/parser/parameter.ts
7776
7948
  /**
@@ -7983,7 +8155,7 @@ const validateOpenApiSpec = (spec, logger) => {
7983
8155
  };
7984
8156
  //#endregion
7985
8157
  //#region src/openApi/3.1.x/parser/webhook.ts
7986
- const parseWebhooks = ({ context, securitySchemesMap }) => {
8158
+ function parseWebhooks({ ambiguousSecurityKeys, context, securitySchemesMap }) {
7987
8159
  const state = { ids: /* @__PURE__ */ new Map() };
7988
8160
  for (const key in context.spec.webhooks) {
7989
8161
  const webhook = context.spec.webhooks[key];
@@ -7992,6 +8164,7 @@ const parseWebhooks = ({ context, securitySchemesMap }) => {
7992
8164
  ...webhook
7993
8165
  } : webhook;
7994
8166
  const operationArgs = {
8167
+ ambiguousSecurityKeys,
7995
8168
  context,
7996
8169
  key,
7997
8170
  operation: {
@@ -8128,7 +8301,7 @@ const parseWebhooks = ({ context, securitySchemesMap }) => {
8128
8301
  }
8129
8302
  });
8130
8303
  }
8131
- };
8304
+ }
8132
8305
  //#endregion
8133
8306
  //#region src/openApi/3.1.x/parser/index.ts
8134
8307
  const parseV3_1_X = (context) => {
@@ -8200,6 +8373,7 @@ const parseV3_1_X = (context) => {
8200
8373
  });
8201
8374
  }
8202
8375
  }
8376
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
8203
8377
  parseServers({ context });
8204
8378
  for (const path in context.spec.paths) {
8205
8379
  if (path.startsWith("x-")) continue;
@@ -8209,6 +8383,7 @@ const parseV3_1_X = (context) => {
8209
8383
  ...pathItem
8210
8384
  } : pathItem;
8211
8385
  const operationArgs = {
8386
+ ambiguousSecurityKeys,
8212
8387
  context,
8213
8388
  operation: {
8214
8389
  description: finalPathItem.description,
@@ -8346,6 +8521,7 @@ const parseV3_1_X = (context) => {
8346
8521
  });
8347
8522
  }
8348
8523
  parseWebhooks({
8524
+ ambiguousSecurityKeys,
8349
8525
  context,
8350
8526
  securitySchemesMap
8351
8527
  });
@@ -8378,15 +8554,43 @@ function parseOpenApiSpec(context) {
8378
8554
  * Built-in strategies for operations.
8379
8555
  */
8380
8556
  const OperationStrategy = {
8557
+ /**
8558
+ * Creates one root container per operation tag.
8559
+ *
8560
+ * Operations with multiple tags appear in multiple root containers.
8561
+ * Operations without tags use the fallback root container.
8562
+ *
8563
+ * @example
8564
+ * // Operation with tags: ['users', 'admin']
8565
+ * // Path function returns: ['list']
8566
+ * // Result: [{ path: ['users', 'list'], shell }, { path: ['admin', 'list'], shell }]
8567
+ */
8381
8568
  byTags: (config) => (operation) => {
8382
8569
  const tags = operation.tags && operation.tags.length ? operation.tags : [config.fallback];
8383
8570
  const pathSegments = (config.path ?? OperationPath.id())(operation);
8384
8571
  return tags.map((tag) => [tag, ...pathSegments]);
8385
8572
  },
8573
+ /**
8574
+ * Creates flat functions without any container.
8575
+ *
8576
+ * Each operation becomes a standalone function at the root level.
8577
+ * No shell is applied.
8578
+ *
8579
+ * @example
8580
+ * // Operation id: 'getUsers'
8581
+ * // Result: [{ path: ['getUsers'] }]
8582
+ */
8386
8583
  flat: (config) => (operation) => {
8387
8584
  const pathSegments = (config?.path ?? OperationPath.id())(operation);
8388
8585
  return [[pathSegments[pathSegments.length - 1]]];
8389
8586
  },
8587
+ /**
8588
+ * Places all operations under a single root container.
8589
+ *
8590
+ * @example
8591
+ * // Root: 'Sdk', path function returns: ['users', 'list']
8592
+ * // Result: [{ path: ['Sdk', 'users', 'list'], shell }]
8593
+ */
8390
8594
  single: (config) => (operation) => {
8391
8595
  const pathSegments = (config.path ?? OperationPath.id())(operation);
8392
8596
  return [[config.root, ...pathSegments]];
@@ -8396,6 +8600,17 @@ const OperationStrategy = {
8396
8600
  * Built-in path derivation helpers for operations.
8397
8601
  */
8398
8602
  const OperationPath = {
8603
+ /**
8604
+ * Splits operationId by delimiters to create nested paths.
8605
+ *
8606
+ * @example
8607
+ * // operationId: 'users.accounts.list'
8608
+ * // Result: ['users', 'accounts', 'list']
8609
+ *
8610
+ * @example
8611
+ * // operationId: 'users/accounts/getAll'
8612
+ * // Result: ['users', 'accounts', 'getAll']
8613
+ */
8399
8614
  fromOperationId: (config) => (operation) => {
8400
8615
  const fallback = config?.fallback ?? OperationPath.id();
8401
8616
  if (!operation.operationId) return fallback(operation);
@@ -8403,6 +8618,23 @@ const OperationPath = {
8403
8618
  const segments = operation.operationId.split(delimiters).filter(Boolean);
8404
8619
  return !segments.length ? fallback(operation) : segments;
8405
8620
  },
8621
+ /**
8622
+ * Splits path by delimiters to create nested paths.
8623
+ *
8624
+ * Can include the method as a prefix or suffix segment.
8625
+ *
8626
+ * @example
8627
+ * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'none'
8628
+ * // Result: ['users', 'id', 'accounts']
8629
+ *
8630
+ * @example
8631
+ * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'prefix'
8632
+ * // Result: ['get', 'users', 'id', 'accounts']
8633
+ *
8634
+ * @example
8635
+ * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'suffix'
8636
+ * // Result: ['users', 'id', 'accounts', 'get']
8637
+ */
8406
8638
  fromPath: (config) => (operation) => {
8407
8639
  const delimiters = config?.delimiters ?? /[./]/;
8408
8640
  const segments = operation.path.split(delimiters).filter(Boolean);
@@ -8417,6 +8649,13 @@ const OperationPath = {
8417
8649
  }
8418
8650
  return segments;
8419
8651
  },
8652
+ /**
8653
+ * Uses operation.id as a single path segment.
8654
+ *
8655
+ * @example
8656
+ * // operation.id: 'getUserById'
8657
+ * // Result: ['getUserById']
8658
+ */
8420
8659
  id: () => (operation) => [operation.id]
8421
8660
  };
8422
8661
  //#endregion
@@ -8559,31 +8798,22 @@ function warnOnConflictingDuplicatePlugins(plugins) {
8559
8798
  }
8560
8799
  //#endregion
8561
8800
  //#region src/plugins/shared/utils/config.ts
8562
- const definePluginConfig = (defaultConfig) => (userConfig) => ({
8563
- ...defaultConfig,
8564
- config: {
8565
- ...defaultConfig.config,
8566
- ...userConfig
8567
- }
8568
- });
8569
- /**
8570
- * Reusable mappers for `enabled` and `name` fields.
8571
- */
8572
- const mappers = {
8573
- boolean: (enabled) => ({ enabled }),
8574
- function: (name) => ({
8575
- enabled: true,
8576
- name
8577
- }),
8578
- object: (fields) => ({
8579
- enabled: true,
8580
- ...fields
8581
- }),
8582
- string: (name) => ({
8583
- enabled: true,
8584
- name
8585
- })
8586
- };
8801
+ function definePluginConfig(pluginConfig) {
8802
+ return (userConfig) => ({
8803
+ ...pluginConfig,
8804
+ config: {
8805
+ ...pluginConfig.config,
8806
+ ...userConfig ?? {}
8807
+ },
8808
+ /**
8809
+ * Cast name to `any` so it doesn't throw type error in `plugins` array.
8810
+ * We could allow any `string` as plugin `name` in the object syntax, but
8811
+ * that TypeScript trick would cause all string methods to appear as
8812
+ * suggested auto completions, which is undesirable.
8813
+ */
8814
+ name: pluginConfig.name
8815
+ });
8816
+ }
8587
8817
  //#endregion
8588
8818
  //#region src/plugins/symbol.ts
8589
8819
  /**
@@ -8647,9 +8877,15 @@ function escapeComment(value) {
8647
8877
  * Utilities shared across the package.
8648
8878
  */
8649
8879
  const utils = {
8880
+ /**
8881
+ * @deprecated use `toCase` instead
8882
+ */
8650
8883
  stringCase({ case: casing, stripLeadingSeparators, value }) {
8651
8884
  return toCase(value, casing, { stripLeadingSeparators });
8652
8885
  },
8886
+ /**
8887
+ * Converts the given string to the specified casing.
8888
+ */
8653
8889
  toCase
8654
8890
  };
8655
8891
  //#endregion
@@ -8773,6 +9009,6 @@ function pathToName(path, options) {
8773
9009
  return names.join("-");
8774
9010
  }
8775
9011
  //#endregion
8776
- export { ConfigError, ConfigValidationError, Context, HeyApiError, InputError, IntentContext, JobError, MinHeap, OperationPath, OperationStrategy, PluginInstance, addItemsToSchema, applyNaming, buildGraph, buildSymbolIn, checkNodeVersion, childContext, compileInputPath, createOperationKey, createSchemaProcessor, createSchemaWalker, debugTools, deduplicateSchema, defaultPaginationKeywords, definePluginConfig, dependencyFactory, encodeJsonPointerSegment, ensureDirSync, escapeComment, findPackageJson, findTsConfigPath, getInput, getInputError, getLogs, getParser, getSpec, hasOperationDataRequired, hasParameterGroupObjectRequired, hasParametersObjectRequired, heyApiRegistryBaseUrl, inputToApiRegistry, isEnvironment, isTopLevelComponent, jsonPointerToPath, loadPackageJson, logCrashReport, logInputPaths, mappers, normalizeJsonPointer, openGitHubIssueWithCrashReport, operationPagination, operationResponsesMap, outputHeaderToPrefix, parameterWithPagination, parseOpenApiSpec, parseUrl, parseV2_0_X, parseV3_0_X, parseV3_1_X, patchOpenApiSpec, pathToJsonPointer, pathToName, postprocessOutput, printCliIntro, printCrashReport, refToName, requestValidatorLayers, resolveNaming, resolveRef, resolveSource, resolveValidatorLayer, satisfies, shouldReportCrash, statusCodeToGroup, toCase, utils, valueToObject, warnOnConflictingDuplicatePlugins };
9012
+ export { COERCER, ConfigError, ConfigValidationError, Context, HeyApiError, InputError, IntentContext, JobError, MinHeap, OperationPath, OperationStrategy, PluginInstance, addItemsToSchema, applyNaming, buildGraph, buildSymbolIn, checkNodeVersion, childContext, coerce, collectDeps, compileInputPath, createOperationKey, createSchemaProcessor, createSchemaWalker, debugTools, deduplicateSchema, defaultPaginationKeywords, defineConfig, definePluginConfig, dependencyFactory, encodeJsonPointerSegment, ensureDirSync, escapeComment, findPackageJson, findTsConfigPath, getInput, getInputError, getLogs, getParser, getSpec, hasOperationDataRequired, hasParameterGroupObjectRequired, hasParametersObjectRequired, heyApiRegistryBaseUrl, inputToApiRegistry, isCoercer, isEnvironment, isPlainObject, isTopLevelComponent, jsonPointerToPath, loadPackageJson, logCrashReport, logInputPaths, normalizeJsonPointer, openGitHubIssueWithCrashReport, operationPagination, operationResponsesMap, outputHeaderToPrefix, parameterWithPagination, parseOpenApiSpec, parseUrl, parseV2_0_X, parseV3_0_X, parseV3_1_X, patchOpenApiSpec, pathToJsonPointer, pathToName, postprocessOutput, printCliIntro, printCrashReport, refToName, requestValidatorLayers, resolveNaming, resolveRef, resolveValidatorLayer, satisfies, shouldReportCrash, sourceConfig, statusCodeToGroup, toCase, utils, warnOnConflictingDuplicatePlugins };
8777
9013
 
8778
9014
  //# sourceMappingURL=index.mjs.map