@hey-api/shared 0.4.4 → 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
@@ -968,17 +1075,13 @@ function deduplicateSchema({ detectFormat = true, schema }) {
968
1075
  }
969
1076
  uniqueItems.push(item);
970
1077
  }
971
- let result = { ...schema };
972
- result.items = uniqueItems;
973
- if (result.items.length <= 1 && result.type !== "array" && result.type !== "enum" && result.type !== "tuple") {
974
- const liftedSchema = result.items[0];
975
- delete result.logicalOperator;
976
- delete result.items;
977
- result = {
978
- ...result,
979
- ...liftedSchema
980
- };
981
- }
1078
+ const result = { ...schema };
1079
+ if (uniqueItems.length <= 1 && result.type !== "array" && result.type !== "enum" && result.type !== "tuple") {
1080
+ const liftedSchema = uniqueItems[0];
1081
+ result.items = void 0;
1082
+ result.logicalOperator = void 0;
1083
+ Object.assign(result, liftedSchema);
1084
+ } else result.items = uniqueItems;
982
1085
  if (result.type === "unknown") return {};
983
1086
  return result;
984
1087
  }
@@ -1000,10 +1103,7 @@ function addItemsToSchema({ items, logicalOperator = "or", mutateSchemaOneItem =
1000
1103
  return schema;
1001
1104
  }
1002
1105
  if (mutateSchemaOneItem) {
1003
- schema = {
1004
- ...schema,
1005
- ...items[0]
1006
- };
1106
+ Object.assign(schema, items[0]);
1007
1107
  return schema;
1008
1108
  }
1009
1109
  schema.items = items;
@@ -1482,6 +1582,7 @@ async function getSpec({ fetchOptions, inputPath, timeout, watch }) {
1482
1582
  //#endregion
1483
1583
  //#region src/utils/minHeap.ts
1484
1584
  var MinHeap = class {
1585
+ declIndex;
1485
1586
  heap = [];
1486
1587
  constructor(declIndex) {
1487
1588
  this.declIndex = declIndex;
@@ -1694,6 +1795,14 @@ const irTopLevelKinds = [
1694
1795
  "server",
1695
1796
  "webhook"
1696
1797
  ];
1798
+ const irPatterns = {
1799
+ operation: /^#\/paths\/[^/]+\/(get|put|post|delete|options|head|patch|trace)$/,
1800
+ parameter: /^#\/components\/parameters\/[^/]+$/,
1801
+ requestBody: /^#\/components\/requestBodies\/[^/]+$/,
1802
+ schema: /^#\/components\/schemas\/[^/]+$/,
1803
+ server: /^#\/servers\/(\d+|[^/]+)$/,
1804
+ webhook: /^#\/webhooks\/[^/]+\/(get|put|post|delete|options|head|patch|trace)$/
1805
+ };
1697
1806
  /**
1698
1807
  * Checks if a pointer matches a known top-level IR component (schema, parameter, etc) and returns match info.
1699
1808
  *
@@ -1702,25 +1811,14 @@ const irTopLevelKinds = [
1702
1811
  * @returns { matched: true, kind: IrTopLevelKind } | { matched: false } - Whether it matched, and the matched kind if so
1703
1812
  */
1704
1813
  const matchIrPointerToGroup = (pointer, kind) => {
1705
- const patterns = {
1706
- operation: /^#\/paths\/[^/]+\/(get|put|post|delete|options|head|patch|trace)$/,
1707
- parameter: /^#\/components\/parameters\/[^/]+$/,
1708
- requestBody: /^#\/components\/requestBodies\/[^/]+$/,
1709
- schema: /^#\/components\/schemas\/[^/]+$/,
1710
- server: /^#\/servers\/(\d+|[^/]+)$/,
1711
- webhook: /^#\/webhooks\/[^/]+\/(get|put|post|delete|options|head|patch|trace)$/
1712
- };
1713
- if (kind) return patterns[kind].test(pointer) ? {
1814
+ if (kind) return irPatterns[kind].test(pointer) ? {
1714
1815
  kind,
1715
1816
  matched: true
1716
1817
  } : { matched: false };
1717
- for (const key of Object.keys(patterns)) {
1718
- const kind = key;
1719
- if (patterns[kind].test(pointer)) return {
1720
- kind,
1721
- matched: true
1722
- };
1723
- }
1818
+ for (const key of irTopLevelKinds) if (irPatterns[key].test(pointer)) return {
1819
+ kind: key,
1820
+ matched: true
1821
+ };
1724
1822
  return { matched: false };
1725
1823
  };
1726
1824
  const preferGroups = [
@@ -1786,6 +1884,7 @@ function jsonPointerToPath(pointer) {
1786
1884
  if (clean.startsWith("#")) clean = clean.slice(1);
1787
1885
  if (clean.startsWith("/")) clean = clean.slice(1);
1788
1886
  if (!clean) return [];
1887
+ if (!clean.includes("~")) return clean.split("/");
1789
1888
  return clean.split("/").map((part) => part.replaceAll("~1", "/").replaceAll("~0", "~"));
1790
1889
  }
1791
1890
  /**
@@ -1830,9 +1929,21 @@ function pathToJsonPointer(path) {
1830
1929
  * @returns true if the ref points to a top-level component, false otherwise
1831
1930
  */
1832
1931
  function isTopLevelComponent(refOrPath) {
1833
- const path = refOrPath instanceof Array ? refOrPath : jsonPointerToPath(refOrPath);
1834
- if (path[0] === "components") return path.length === 3;
1835
- if (path[0] === "definitions") return path.length === 2;
1932
+ if (typeof refOrPath !== "string") {
1933
+ if (refOrPath[0] === "components") return refOrPath.length === 3;
1934
+ if (refOrPath[0] === "definitions") return refOrPath.length === 2;
1935
+ return false;
1936
+ }
1937
+ if (refOrPath.startsWith("#/components/")) {
1938
+ const typeEnd = refOrPath.indexOf("/", 13);
1939
+ if (typeEnd === -1) return false;
1940
+ const nameStart = typeEnd + 1;
1941
+ return nameStart < refOrPath.length && refOrPath.indexOf("/", nameStart) === -1;
1942
+ }
1943
+ if (refOrPath.startsWith("#/definitions/")) {
1944
+ const nameStart = 14;
1945
+ return nameStart < refOrPath.length && refOrPath.indexOf("/", nameStart) === -1;
1946
+ }
1836
1947
  return false;
1837
1948
  }
1838
1949
  function resolveRef({ $ref, spec }) {
@@ -1869,7 +1980,7 @@ var PluginInstance = class {
1869
1980
  api;
1870
1981
  config;
1871
1982
  context;
1872
- dependencies = [];
1983
+ dependencies = /* @__PURE__ */ new Set();
1873
1984
  eventHooks;
1874
1985
  gen;
1875
1986
  handler;
@@ -1881,6 +1992,8 @@ var PluginInstance = class {
1881
1992
  * code generation.
1882
1993
  */
1883
1994
  package;
1995
+ /** Symbols declared in the plugin config. */
1996
+ symbols;
1884
1997
  constructor(props) {
1885
1998
  this.api = props.api ?? {};
1886
1999
  this.config = props.config;
@@ -1891,6 +2004,7 @@ var PluginInstance = class {
1891
2004
  this.handler = props.handler;
1892
2005
  this.name = props.name;
1893
2006
  this.package = props.context.package;
2007
+ this.symbols = this.buildSymbols(props.symbols);
1894
2008
  }
1895
2009
  external(resource, meta = {}) {
1896
2010
  return this.gen.symbols.reference({
@@ -1988,6 +2102,15 @@ var PluginInstance = class {
1988
2102
  }
1989
2103
  }, options);
1990
2104
  }
2105
+ getHooks(selector, ...customHooks) {
2106
+ const result = [];
2107
+ for (const hook of customHooks) if (hook) result.push(hook);
2108
+ const local = selector(this.config["~hooks"] ?? {});
2109
+ if (local) result.push(local);
2110
+ const global = selector(this.context.config.parser.hooks);
2111
+ if (global) result.push(global);
2112
+ return result;
2113
+ }
1991
2114
  /**
1992
2115
  * Retrieves a registered plugin instance by its name from the context. This
1993
2116
  * allows plugins to access other plugins that have been registered in the
@@ -2081,7 +2204,7 @@ var PluginInstance = class {
2081
2204
  const symbolIn = {
2082
2205
  ...symbol,
2083
2206
  meta: {
2084
- pluginName: path.isAbsolute(this.name) ? "custom" : this.name,
2207
+ ...symbol.external ? {} : { pluginName: path.isAbsolute(this.name) ? "custom" : this.name },
2085
2208
  ...meta
2086
2209
  },
2087
2210
  name
@@ -2128,6 +2251,9 @@ var PluginInstance = class {
2128
2251
  }
2129
2252
  return result;
2130
2253
  }
2254
+ buildSymbols(fn) {
2255
+ return fn ? fn(this) : {};
2256
+ }
2131
2257
  forEachError(error, event) {
2132
2258
  const originalError = error instanceof Error ? error : new Error(String(error));
2133
2259
  throw new HeyApiError({
@@ -2139,9 +2265,8 @@ var PluginInstance = class {
2139
2265
  });
2140
2266
  }
2141
2267
  getSymbolExportFromFilePath(symbol) {
2142
- const hooks = [this.config["~hooks"]?.symbols, this.context.config.parser.hooks.symbols];
2143
- for (const hook of hooks) {
2144
- const result = hook?.getExportFromFilePath?.(symbol);
2268
+ for (const hook of this.getHooks((hooks) => hooks.symbols?.getExportFromFilePath)) {
2269
+ const result = hook(symbol);
2145
2270
  if (result !== void 0) return result;
2146
2271
  }
2147
2272
  const entryFile = this.context.config.output.indexFile ?? this.context.config.output.entryFile;
@@ -2155,9 +2280,8 @@ var PluginInstance = class {
2155
2280
  return [moduleEntryName];
2156
2281
  }
2157
2282
  getSymbolFilePath(symbol) {
2158
- const hooks = [this.config["~hooks"]?.symbols, this.context.config.parser.hooks.symbols];
2159
- for (const hook of hooks) {
2160
- const result = hook?.getFilePath?.(symbol);
2283
+ for (const hook of this.getHooks((hooks) => hooks.symbols?.getFilePath)) {
2284
+ const result = hook(symbol);
2161
2285
  if (result !== void 0) return result;
2162
2286
  }
2163
2287
  return defaultGetFilePath(symbol);
@@ -2254,10 +2378,11 @@ var Context = class {
2254
2378
  api: plugin.api,
2255
2379
  config: plugin.config,
2256
2380
  context: this,
2257
- dependencies: plugin.dependencies ?? [],
2381
+ dependencies: plugin.dependencies ?? /* @__PURE__ */ new Set(),
2258
2382
  gen: this.gen,
2259
2383
  handler: plugin.handler,
2260
- name: plugin.name
2384
+ name: plugin.name,
2385
+ symbols: plugin.symbols
2261
2386
  });
2262
2387
  this.plugins[instance.name] = instance;
2263
2388
  return instance;
@@ -2407,8 +2532,8 @@ function visitTyped(schema, ctx, visitor, walk) {
2407
2532
  */
2408
2533
  function childContext(ctx, ...segments) {
2409
2534
  return {
2410
- ...ctx,
2411
- path: ref([...fromRef(ctx.path), ...segments])
2535
+ path: ref([...fromRef(ctx.path), ...segments]),
2536
+ plugin: ctx.plugin
2412
2537
  };
2413
2538
  }
2414
2539
  //#endregion
@@ -2591,8 +2716,9 @@ function hasFilters(config) {
2591
2716
  function collectOperations({ filters, parameters, requestBodies, resourceMetadata, responses, schemas }) {
2592
2717
  const finalSet = /* @__PURE__ */ new Set();
2593
2718
  const stack = [...filters.operations.include.size ? filters.operations.include : new Set(resourceMetadata.operations.keys())];
2594
- while (stack.length) {
2595
- const key = stack.pop();
2719
+ let index = 0;
2720
+ while (index < stack.length) {
2721
+ const key = stack[index++];
2596
2722
  if (filters.operations.exclude.has(key) || finalSet.has(key)) continue;
2597
2723
  const node = resourceMetadata.operations.get(key);
2598
2724
  if (!node) continue;
@@ -2623,8 +2749,9 @@ function collectOperations({ filters, parameters, requestBodies, resourceMetadat
2623
2749
  function collectParameters({ filters, resourceMetadata, schemas }) {
2624
2750
  const finalSet = /* @__PURE__ */ new Set();
2625
2751
  const stack = [...filters.parameters.include.size ? filters.parameters.include : new Set(resourceMetadata.parameters.keys())];
2626
- while (stack.length) {
2627
- const key = stack.pop();
2752
+ let index = 0;
2753
+ while (index < stack.length) {
2754
+ const key = stack[index++];
2628
2755
  if (filters.parameters.exclude.has(key) || finalSet.has(key)) continue;
2629
2756
  const node = resourceMetadata.parameters.get(key);
2630
2757
  if (!node) continue;
@@ -2653,8 +2780,9 @@ function collectParameters({ filters, resourceMetadata, schemas }) {
2653
2780
  function collectRequestBodies({ filters, resourceMetadata, schemas }) {
2654
2781
  const finalSet = /* @__PURE__ */ new Set();
2655
2782
  const stack = [...filters.requestBodies.include.size ? filters.requestBodies.include : new Set(resourceMetadata.requestBodies.keys())];
2656
- while (stack.length) {
2657
- const key = stack.pop();
2783
+ let index = 0;
2784
+ while (index < stack.length) {
2785
+ const key = stack[index++];
2658
2786
  if (filters.requestBodies.exclude.has(key) || finalSet.has(key)) continue;
2659
2787
  const node = resourceMetadata.requestBodies.get(key);
2660
2788
  if (!node) continue;
@@ -2683,8 +2811,9 @@ function collectRequestBodies({ filters, resourceMetadata, schemas }) {
2683
2811
  function collectResponses({ filters, resourceMetadata, schemas }) {
2684
2812
  const finalSet = /* @__PURE__ */ new Set();
2685
2813
  const stack = [...filters.responses.include.size ? filters.responses.include : new Set(resourceMetadata.responses.keys())];
2686
- while (stack.length) {
2687
- const key = stack.pop();
2814
+ let index = 0;
2815
+ while (index < stack.length) {
2816
+ const key = stack[index++];
2688
2817
  if (filters.responses.exclude.has(key) || finalSet.has(key)) continue;
2689
2818
  const node = resourceMetadata.responses.get(key);
2690
2819
  if (!node) continue;
@@ -2713,8 +2842,9 @@ function collectResponses({ filters, resourceMetadata, schemas }) {
2713
2842
  function collectSchemas({ filters, resourceMetadata }) {
2714
2843
  const finalSet = /* @__PURE__ */ new Set();
2715
2844
  const stack = [...filters.schemas.include.size ? filters.schemas.include : new Set(resourceMetadata.schemas.keys())];
2716
- while (stack.length) {
2717
- const key = stack.pop();
2845
+ let index = 0;
2846
+ while (index < stack.length) {
2847
+ const key = stack[index++];
2718
2848
  if (filters.schemas.exclude.has(key) || finalSet.has(key)) continue;
2719
2849
  const node = resourceMetadata.schemas.get(key);
2720
2850
  if (!node) continue;
@@ -2826,8 +2956,9 @@ function collectExplicitDependencies({ filters, resourceMetadata }) {
2826
2956
  function collectOperationDependencies({ operations, resourceMetadata }) {
2827
2957
  const finalSet = /* @__PURE__ */ new Set();
2828
2958
  const stack = [...new Set([...operations].flatMap((key) => [...resourceMetadata.operations.get(key)?.dependencies ?? []]))];
2829
- while (stack.length) {
2830
- const key = stack.pop();
2959
+ let index = 0;
2960
+ while (index < stack.length) {
2961
+ const key = stack[index++];
2831
2962
  if (finalSet.has(key)) continue;
2832
2963
  finalSet.add(key);
2833
2964
  const dependencies = getResourceDependencies(key, resourceMetadata);
@@ -3335,42 +3466,37 @@ const annotateChildScopes = (nodes) => {
3335
3466
  * Recursively collects all $ref dependencies in the subtree rooted at `pointer`.
3336
3467
  */
3337
3468
  const collectPointerDependencies = ({ cache, graph, pointer, visited }) => {
3338
- const cached = cache.transitiveDependencies.get(pointer);
3339
- if (cached) return {
3340
- subtreeDependencies: cache.subtreeDependencies.get(pointer),
3341
- transitiveDependencies: cached
3469
+ if (cache.transitiveDependencies.has(pointer)) return {
3470
+ subtreeDependencies: cache.subtreeDependencies.get(pointer) ?? null,
3471
+ transitiveDependencies: cache.transitiveDependencies.get(pointer) ?? null
3342
3472
  };
3343
3473
  if (visited.has(pointer)) return {
3344
- subtreeDependencies: /* @__PURE__ */ new Set(),
3345
- transitiveDependencies: /* @__PURE__ */ new Set()
3474
+ subtreeDependencies: null,
3475
+ transitiveDependencies: null
3346
3476
  };
3347
3477
  visited.add(pointer);
3348
3478
  if (!graph.nodes.get(pointer)) return {
3349
- subtreeDependencies: /* @__PURE__ */ new Set(),
3350
- transitiveDependencies: /* @__PURE__ */ new Set()
3479
+ subtreeDependencies: null,
3480
+ transitiveDependencies: null
3351
3481
  };
3352
- const transitiveDependencies = /* @__PURE__ */ new Set();
3353
- const subtreeDependencies = /* @__PURE__ */ new Set();
3482
+ let transitiveDependencies = null;
3483
+ let subtreeDependencies = null;
3354
3484
  const nodeDependencies = graph.nodeDependencies.get(pointer);
3355
3485
  if (nodeDependencies) for (const depPointer of nodeDependencies) {
3356
- transitiveDependencies.add(depPointer);
3357
- subtreeDependencies.add(depPointer);
3486
+ (transitiveDependencies ??= /* @__PURE__ */ new Set()).add(depPointer);
3487
+ (subtreeDependencies ??= /* @__PURE__ */ new Set()).add(depPointer);
3358
3488
  const depResult = collectPointerDependencies({
3359
3489
  cache,
3360
3490
  graph,
3361
3491
  pointer: depPointer,
3362
3492
  visited
3363
3493
  });
3364
- for (const dependency of depResult.transitiveDependencies) transitiveDependencies.add(dependency);
3494
+ if (depResult.transitiveDependencies) for (const dependency of depResult.transitiveDependencies) transitiveDependencies.add(dependency);
3365
3495
  }
3366
3496
  const children = cache.parentToChildren.get(pointer) ?? [];
3367
3497
  for (const childPointer of children) {
3368
- let childResult = {
3369
- subtreeDependencies: cache.subtreeDependencies.get(childPointer),
3370
- transitiveDependencies: cache.transitiveDependencies.get(childPointer)
3371
- };
3372
- if (!childResult.subtreeDependencies || !childResult.transitiveDependencies) {
3373
- childResult = collectPointerDependencies({
3498
+ if (!cache.transitiveDependencies.has(childPointer)) {
3499
+ const childResult = collectPointerDependencies({
3374
3500
  cache,
3375
3501
  graph,
3376
3502
  pointer: childPointer,
@@ -3379,8 +3505,10 @@ const collectPointerDependencies = ({ cache, graph, pointer, visited }) => {
3379
3505
  cache.transitiveDependencies.set(childPointer, childResult.transitiveDependencies);
3380
3506
  cache.subtreeDependencies.set(childPointer, childResult.subtreeDependencies);
3381
3507
  }
3382
- for (const dependency of childResult.transitiveDependencies) transitiveDependencies.add(dependency);
3383
- for (const dependency of childResult.subtreeDependencies) subtreeDependencies.add(dependency);
3508
+ const childTransitive = cache.transitiveDependencies.get(childPointer) ?? null;
3509
+ const childSubtree = cache.subtreeDependencies.get(childPointer) ?? null;
3510
+ if (childTransitive) for (const dependency of childTransitive) (transitiveDependencies ??= /* @__PURE__ */ new Set()).add(dependency);
3511
+ if (childSubtree) for (const dependency of childSubtree) (subtreeDependencies ??= /* @__PURE__ */ new Set()).add(dependency);
3384
3512
  }
3385
3513
  cache.transitiveDependencies.set(pointer, transitiveDependencies);
3386
3514
  cache.subtreeDependencies.set(pointer, subtreeDependencies);
@@ -3538,8 +3666,8 @@ function buildGraph(root, logger) {
3538
3666
  pointer,
3539
3667
  visited: /* @__PURE__ */ new Set()
3540
3668
  });
3541
- graph.transitiveDependencies.set(pointer, result.transitiveDependencies);
3542
- graph.subtreeDependencies.set(pointer, result.subtreeDependencies);
3669
+ if (result.transitiveDependencies) graph.transitiveDependencies.set(pointer, result.transitiveDependencies);
3670
+ if (result.subtreeDependencies) graph.subtreeDependencies.set(pointer, result.subtreeDependencies);
3543
3671
  }
3544
3672
  eventBuildGraph.timeEnd();
3545
3673
  return { graph };
@@ -4163,6 +4291,47 @@ const mergeParametersObjects = ({ source, target }) => {
4163
4291
  return result;
4164
4292
  };
4165
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
4166
4335
  //#region src/openApi/shared/utils/validator.ts
4167
4336
  const isSimpleKey = (key) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
4168
4337
  const formatPath = (path) => path.map((segment, i) => {
@@ -4346,7 +4515,7 @@ const discriminatorValues = ($ref, mapping, shouldUseRefAsValue) => {
4346
4515
  };
4347
4516
  //#endregion
4348
4517
  //#region src/openApi/2.0.x/parser/schema.ts
4349
- function getSchemaType$1({ schema }) {
4518
+ function getSchemaType$1(schema) {
4350
4519
  if (schema.type) return schema.type;
4351
4520
  if (schema.properties) return "object";
4352
4521
  }
@@ -4385,10 +4554,7 @@ function parseArray$2({ context, irSchema = {}, schema, state }) {
4385
4554
  else if ("$ref" in schema.items) schemaItems.push(irItemsSchema);
4386
4555
  else {
4387
4556
  const ofArray = schema.items.allOf;
4388
- if (ofArray && ofArray.length > 1 && !schema.items["x-nullable"]) irSchema = {
4389
- ...irSchema,
4390
- ...irItemsSchema
4391
- };
4557
+ if (ofArray && ofArray.length > 1 && !schema.items["x-nullable"]) Object.assign(irSchema, irItemsSchema);
4392
4558
  else schemaItems.push(irItemsSchema);
4393
4559
  }
4394
4560
  }
@@ -4408,20 +4574,24 @@ function parseNumber$2({ irSchema = {}, schema }) {
4408
4574
  }
4409
4575
  function parseObject$2({ context, irSchema = {}, schema, state }) {
4410
4576
  irSchema.type = "object";
4411
- const schemaProperties = {};
4412
- for (const name in schema.properties) {
4413
- const property = schema.properties[name];
4414
- if (typeof property === "boolean") {} else schemaProperties[name] = schemaToIrSchema$2({
4415
- context,
4416
- schema: property,
4417
- state
4418
- });
4577
+ let isSchemaPropertiesEmpty = true;
4578
+ if (schema.properties) {
4579
+ const schemaProperties = {};
4580
+ for (const name in schema.properties) {
4581
+ isSchemaPropertiesEmpty = false;
4582
+ const property = schema.properties[name];
4583
+ if (typeof property === "boolean") {} else schemaProperties[name] = schemaToIrSchema$2({
4584
+ context,
4585
+ schema: property,
4586
+ state
4587
+ });
4588
+ }
4589
+ if (!isSchemaPropertiesEmpty) irSchema.properties = schemaProperties;
4419
4590
  }
4420
- if (Object.keys(schemaProperties).length) irSchema.properties = schemaProperties;
4421
4591
  if (schema.additionalProperties === void 0) {
4422
4592
  if (!irSchema.properties) irSchema.additionalProperties = { type: "unknown" };
4423
4593
  } else if (typeof schema.additionalProperties === "boolean") {
4424
- if (!(state.inAllOf && schema.additionalProperties === false && (!schema.properties || !Object.keys(schema.properties).length))) irSchema.additionalProperties = { type: schema.additionalProperties ? "unknown" : "never" };
4594
+ if (!(state.inAllOf && schema.additionalProperties === false && (!schema.properties || isSchemaPropertiesEmpty))) irSchema.additionalProperties = { type: schema.additionalProperties ? "unknown" : "never" };
4425
4595
  } else irSchema.additionalProperties = schemaToIrSchema$2({
4426
4596
  context,
4427
4597
  schema: schema.additionalProperties,
@@ -4452,7 +4622,7 @@ function initIrSchema$2({ schema }) {
4452
4622
  function parseAllOf$2({ context, schema, state }) {
4453
4623
  let irSchema = initIrSchema$2({ schema });
4454
4624
  const schemaItems = [];
4455
- const schemaType = getSchemaType$1({ schema });
4625
+ const schemaType = getSchemaType$1(schema);
4456
4626
  const compositionSchemas = schema.allOf;
4457
4627
  for (const compositionSchema of compositionSchemas) {
4458
4628
  const originalInAllOf = state.inAllOf;
@@ -4463,8 +4633,7 @@ function parseAllOf$2({ context, schema, state }) {
4463
4633
  state
4464
4634
  });
4465
4635
  state.inAllOf = originalInAllOf;
4466
- if (state.inAllOf === void 0) delete state.inAllOf;
4467
- if (schema.required) if (irCompositionSchema.required) irCompositionSchema.required = [...irCompositionSchema.required, ...schema.required];
4636
+ if (schema.required) if (irCompositionSchema.required) irCompositionSchema.required.push(...schema.required);
4468
4637
  else irCompositionSchema.required = schema.required;
4469
4638
  schemaItems.push(irCompositionSchema);
4470
4639
  if (compositionSchema.$ref) {
@@ -4498,7 +4667,7 @@ function parseAllOf$2({ context, schema, state }) {
4498
4667
  if (irObjectSchema.properties) {
4499
4668
  for (const requiredProperty of irObjectSchema.required ?? []) if (!irObjectSchema.properties[requiredProperty]) for (const compositionSchema of compositionSchemas) {
4500
4669
  const finalCompositionSchema = compositionSchema.$ref ? context.resolveRef(compositionSchema.$ref) : compositionSchema;
4501
- if (getSchemaType$1({ schema: finalCompositionSchema }) === "object") {
4670
+ if (getSchemaType$1(finalCompositionSchema) === "object") {
4502
4671
  const irCompositionSchema = parseOneType$2({
4503
4672
  context,
4504
4673
  schema: {
@@ -4542,7 +4711,11 @@ function parseEnum$2({ context, schema, state }) {
4542
4711
  });
4543
4712
  irSchema.type = "enum";
4544
4713
  const schemaItems = [];
4545
- for (const [index, enumValue] of schema.enum.entries()) {
4714
+ const xEnumDescriptions = schema["x-enum-descriptions"];
4715
+ const xEnumVarnames = schema["x-enum-varnames"];
4716
+ const xEnumNames = schema["x-enumNames"];
4717
+ for (let index = 0, len = schema.enum.length; index < len; index++) {
4718
+ const enumValue = schema.enum[index];
4546
4719
  const typeOfEnumValue = typeof enumValue;
4547
4720
  let enumType;
4548
4721
  if (typeOfEnumValue === "string" || typeOfEnumValue === "number" || typeOfEnumValue === "boolean") enumType = typeOfEnumValue;
@@ -4554,8 +4727,8 @@ function parseEnum$2({ context, schema, state }) {
4554
4727
  const irTypeSchema = parseOneType$2({
4555
4728
  context,
4556
4729
  schema: {
4557
- description: schema["x-enum-descriptions"]?.[index],
4558
- title: schema["x-enum-varnames"]?.[index] ?? schema["x-enumNames"]?.[index],
4730
+ description: xEnumDescriptions?.[index],
4731
+ title: xEnumVarnames?.[index] ?? xEnumNames?.[index],
4559
4732
  type: enumType === "null" ? "string" : enumType
4560
4733
  },
4561
4734
  state
@@ -4627,7 +4800,7 @@ function parseType$2({ context, schema, state }) {
4627
4800
  irSchema,
4628
4801
  schema
4629
4802
  });
4630
- const type = getSchemaType$1({ schema });
4803
+ const type = getSchemaType$1(schema);
4631
4804
  if (!type) return irSchema;
4632
4805
  if (schema["x-nullable"]) return parseNullableType$1({
4633
4806
  context,
@@ -4779,7 +4952,7 @@ const paginationField$2 = ({ context, name, schema }) => {
4779
4952
  for (const name in schema.properties) if (getPaginationKeywordsRegExp(context.config.parser.pagination).test(name)) {
4780
4953
  const property = schema.properties[name];
4781
4954
  if (typeof property !== "boolean" && !("$ref" in property)) {
4782
- if (isPaginationType$2(getSchemaType$1({ schema: property }))) return name;
4955
+ if (isPaginationType$2(getSchemaType$1(property))) return name;
4783
4956
  }
4784
4957
  }
4785
4958
  for (const allOf of schema.allOf ?? []) {
@@ -4794,13 +4967,13 @@ const paginationField$2 = ({ context, name, schema }) => {
4794
4967
  };
4795
4968
  //#endregion
4796
4969
  //#region src/openApi/2.0.x/parser/operation.ts
4797
- const parseOperationJsDoc$2 = ({ irOperation, operation }) => {
4970
+ function parseOperationJsDoc$2({ irOperation, operation }) {
4798
4971
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
4799
4972
  if (operation.description) irOperation.description = operation.description;
4800
4973
  if (operation.summary) irOperation.summary = operation.summary;
4801
4974
  if (operation.tags?.length) irOperation.tags = operation.tags;
4802
- };
4803
- const initIrOperation$2 = ({ context, method, operation, path, state }) => {
4975
+ }
4976
+ function initIrOperation$2({ context, method, operation, path, state }) {
4804
4977
  const irOperation = {
4805
4978
  id: operationToId({
4806
4979
  context,
@@ -4822,8 +4995,8 @@ const initIrOperation$2 = ({ context, method, operation, path, state }) => {
4822
4995
  target: irOperation
4823
4996
  });
4824
4997
  return irOperation;
4825
- };
4826
- const operationToIrOperation$2 = ({ context, method, operation, path, securitySchemesMap, state }) => {
4998
+ }
4999
+ function operationToIrOperation$2({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
4827
5000
  const irOperation = initIrOperation$2({
4828
5001
  context,
4829
5002
  method,
@@ -4979,16 +5152,18 @@ const operationToIrOperation$2 = ({ context, method, operation, path, securitySc
4979
5152
  }
4980
5153
  }
4981
5154
  if (!irSecuritySchemeObject) continue;
5155
+ if (ambiguousSecurityKeys.has(name)) irSecuritySchemeObject.key = name;
4982
5156
  securitySchemeObjects.set(name, irSecuritySchemeObject);
4983
5157
  }
4984
5158
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
4985
5159
  }
4986
5160
  return irOperation;
4987
- };
4988
- const parsePathOperation$2 = ({ context, method, operation, path, securitySchemesMap, state }) => {
5161
+ }
5162
+ function parsePathOperation$2({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
4989
5163
  if (!context.ir.paths) context.ir.paths = {};
4990
5164
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
4991
5165
  context.ir.paths[path][method] = operationToIrOperation$2({
5166
+ ambiguousSecurityKeys,
4992
5167
  context,
4993
5168
  method,
4994
5169
  operation,
@@ -4996,7 +5171,7 @@ const parsePathOperation$2 = ({ context, method, operation, path, securityScheme
4996
5171
  securitySchemesMap,
4997
5172
  state
4998
5173
  });
4999
- };
5174
+ }
5000
5175
  //#endregion
5001
5176
  //#region src/openApi/2.0.x/parser/parameter.ts
5002
5177
  /**
@@ -5195,8 +5370,9 @@ const parseV2_0_X = (context) => {
5195
5370
  const securitySchemeObject = context.spec.securityDefinitions[name];
5196
5371
  securitySchemesMap.set(name, securitySchemeObject);
5197
5372
  }
5373
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
5198
5374
  if (context.spec.definitions) for (const name in context.spec.definitions) {
5199
- const $ref = `#/definitions/${name}`;
5375
+ const $ref = pathToJsonPointer(["definitions", name]);
5200
5376
  const schema = context.spec.definitions[name];
5201
5377
  parseSchema$2({
5202
5378
  $ref,
@@ -5219,6 +5395,7 @@ const parseV2_0_X = (context) => {
5219
5395
  security: context.spec.security
5220
5396
  };
5221
5397
  const operationArgs = {
5398
+ ambiguousSecurityKeys,
5222
5399
  context,
5223
5400
  operation: {
5224
5401
  ...commonOperation,
@@ -5464,7 +5641,7 @@ const mediaTypeObjects$1 = ({ content }) => {
5464
5641
  };
5465
5642
  //#endregion
5466
5643
  //#region src/openApi/3.0.x/parser/schema.ts
5467
- function getSchemaType({ schema }) {
5644
+ function getSchemaType(schema) {
5468
5645
  if (schema.type) return schema.type;
5469
5646
  if (schema.properties) return "object";
5470
5647
  }
@@ -5519,7 +5696,7 @@ function findDiscriminatorsInSchema$1({ context, discriminators = [], schema })
5519
5696
  */
5520
5697
  function getAllDiscriminatorValues$1({ discriminator, schemaRef }) {
5521
5698
  const values = [];
5522
- for (const [value, mappedSchemaRef] of Object.entries(discriminator.mapping || {})) if (mappedSchemaRef === schemaRef) values.push(value);
5699
+ for (const value in discriminator.mapping) if (discriminator.mapping[value] === schemaRef) values.push(value);
5523
5700
  return values;
5524
5701
  }
5525
5702
  function parseSchemaJsDoc$1({ irSchema, schema }) {
@@ -5559,10 +5736,7 @@ function parseArray$1({ context, irSchema = {}, schema, state }) {
5559
5736
  else if ("$ref" in schema.items) schemaItems.push(irItemsSchema);
5560
5737
  else {
5561
5738
  const ofArray = schema.items.allOf || schema.items.anyOf || schema.items.oneOf;
5562
- if (ofArray && ofArray.length > 1 && !schema.items.nullable) irSchema = {
5563
- ...irSchema,
5564
- ...irItemsSchema
5565
- };
5739
+ if (ofArray && ofArray.length > 1 && !schema.items.nullable) Object.assign(irSchema, irItemsSchema);
5566
5740
  else schemaItems.push(irItemsSchema);
5567
5741
  }
5568
5742
  }
@@ -5582,20 +5756,24 @@ function parseNumber$1({ irSchema = {}, schema }) {
5582
5756
  }
5583
5757
  function parseObject$1({ context, irSchema = {}, schema, state }) {
5584
5758
  irSchema.type = "object";
5585
- const schemaProperties = {};
5586
- for (const name in schema.properties) {
5587
- const property = schema.properties[name];
5588
- if (typeof property === "boolean") {} else schemaProperties[name] = schemaToIrSchema$1({
5589
- context,
5590
- schema: property,
5591
- state
5592
- });
5759
+ let isSchemaPropertiesEmpty = true;
5760
+ if (schema.properties) {
5761
+ const schemaProperties = {};
5762
+ for (const name in schema.properties) {
5763
+ isSchemaPropertiesEmpty = false;
5764
+ const property = schema.properties[name];
5765
+ if (typeof property === "boolean") {} else schemaProperties[name] = schemaToIrSchema$1({
5766
+ context,
5767
+ schema: property,
5768
+ state
5769
+ });
5770
+ }
5771
+ if (!isSchemaPropertiesEmpty) irSchema.properties = schemaProperties;
5593
5772
  }
5594
- if (Object.keys(schemaProperties).length) irSchema.properties = schemaProperties;
5595
5773
  if (schema.additionalProperties === void 0) {
5596
5774
  if (!irSchema.properties) irSchema.additionalProperties = { type: "unknown" };
5597
5775
  } else if (typeof schema.additionalProperties === "boolean") {
5598
- if (!(state.inAllOf && schema.additionalProperties === false && (!schema.properties || !Object.keys(schema.properties).length))) irSchema.additionalProperties = { type: schema.additionalProperties ? "unknown" : "never" };
5776
+ if (!(state.inAllOf && schema.additionalProperties === false && (!schema.properties || isSchemaPropertiesEmpty))) irSchema.additionalProperties = { type: schema.additionalProperties ? "unknown" : "never" };
5599
5777
  } else irSchema.additionalProperties = schemaToIrSchema$1({
5600
5778
  context,
5601
5779
  schema: schema.additionalProperties,
@@ -5645,7 +5823,7 @@ function initIrSchema$1({ schema }) {
5645
5823
  function parseAllOf$1({ context, schema, state }) {
5646
5824
  let irSchema = initIrSchema$1({ schema });
5647
5825
  const schemaItems = [];
5648
- const schemaType = getSchemaType({ schema });
5826
+ const schemaType = getSchemaType(schema);
5649
5827
  const compositionSchemas = schema.allOf;
5650
5828
  const discriminatorsToAdd = [];
5651
5829
  for (const compositionSchema of compositionSchemas) {
@@ -5657,8 +5835,7 @@ function parseAllOf$1({ context, schema, state }) {
5657
5835
  state
5658
5836
  });
5659
5837
  state.inAllOf = originalInAllOf;
5660
- if (state.inAllOf === void 0) delete state.inAllOf;
5661
- if (schema.required) if (irCompositionSchema.required) irCompositionSchema.required = [...irCompositionSchema.required, ...schema.required];
5838
+ if (schema.required) if (irCompositionSchema.required) irCompositionSchema.required.push(...schema.required);
5662
5839
  else irCompositionSchema.required = schema.required;
5663
5840
  schemaItems.push(irCompositionSchema);
5664
5841
  if ("$ref" in compositionSchema) {
@@ -5733,7 +5910,7 @@ function parseAllOf$1({ context, schema, state }) {
5733
5910
  inlineSchema.properties[discriminator.propertyName] = discriminatorProperty;
5734
5911
  if (isRequired) {
5735
5912
  if (!inlineSchema.required) inlineSchema.required = [];
5736
- if (!inlineSchema.required.includes(discriminator.propertyName)) inlineSchema.required = [...inlineSchema.required, discriminator.propertyName];
5913
+ if (!inlineSchema.required.includes(discriminator.propertyName)) inlineSchema.required.push(discriminator.propertyName);
5737
5914
  }
5738
5915
  } else {
5739
5916
  const irDiscriminatorSchema = {
@@ -5756,7 +5933,7 @@ function parseAllOf$1({ context, schema, state }) {
5756
5933
  if (irObjectSchema.properties) {
5757
5934
  for (const requiredProperty of irObjectSchema.required ?? []) if (!irObjectSchema.properties[requiredProperty]) for (const compositionSchema of compositionSchemas) {
5758
5935
  const finalCompositionSchema = "$ref" in compositionSchema ? context.resolveRef(compositionSchema.$ref) : compositionSchema;
5759
- if (getSchemaType({ schema: finalCompositionSchema }) === "object") {
5936
+ if (getSchemaType(finalCompositionSchema) === "object") {
5760
5937
  const irCompositionSchema = parseOneType$1({
5761
5938
  context,
5762
5939
  schema: {
@@ -5795,7 +5972,7 @@ function parseAllOf$1({ context, schema, state }) {
5795
5972
  function parseAnyOf$1({ context, schema, state }) {
5796
5973
  let irSchema = initIrSchema$1({ schema });
5797
5974
  const schemaItems = [];
5798
- const schemaType = getSchemaType({ schema });
5975
+ const schemaType = getSchemaType(schema);
5799
5976
  const compositionSchemas = schema.anyOf;
5800
5977
  const discriminatorPropertyType = schema.discriminator ? findDiscriminatorPropertyType$1({
5801
5978
  context,
@@ -5854,7 +6031,11 @@ function parseEnum$1({ context, schema, state }) {
5854
6031
  });
5855
6032
  irSchema.type = "enum";
5856
6033
  const schemaItems = [];
5857
- for (const [index, enumValue] of schema.enum.entries()) {
6034
+ const xEnumDescriptions = schema["x-enum-descriptions"];
6035
+ const xEnumVarnames = schema["x-enum-varnames"];
6036
+ const xEnumNames = schema["x-enumNames"];
6037
+ for (let index = 0, len = schema.enum.length; index < len; index++) {
6038
+ const enumValue = schema.enum[index];
5858
6039
  const typeOfEnumValue = typeof enumValue;
5859
6040
  let enumType;
5860
6041
  if (typeOfEnumValue === "string" || typeOfEnumValue === "number" || typeOfEnumValue === "boolean") enumType = typeOfEnumValue;
@@ -5866,8 +6047,8 @@ function parseEnum$1({ context, schema, state }) {
5866
6047
  const irTypeSchema = parseOneType$1({
5867
6048
  context,
5868
6049
  schema: {
5869
- description: schema["x-enum-descriptions"]?.[index],
5870
- title: schema["x-enum-varnames"]?.[index] ?? schema["x-enumNames"]?.[index],
6050
+ description: xEnumDescriptions?.[index],
6051
+ title: xEnumVarnames?.[index] ?? xEnumNames?.[index],
5871
6052
  type: enumType === "null" ? "string" : enumType
5872
6053
  },
5873
6054
  state
@@ -5886,7 +6067,7 @@ function parseEnum$1({ context, schema, state }) {
5886
6067
  function parseOneOf$1({ context, schema, state }) {
5887
6068
  let irSchema = initIrSchema$1({ schema });
5888
6069
  let schemaItems = [];
5889
- const schemaType = getSchemaType({ schema });
6070
+ const schemaType = getSchemaType(schema);
5890
6071
  const compositionSchemas = schema.oneOf;
5891
6072
  const discriminatorPropertyType = schema.discriminator ? findDiscriminatorPropertyType$1({
5892
6073
  context,
@@ -5994,7 +6175,7 @@ function parseType$1({ context, schema, state }) {
5994
6175
  irSchema,
5995
6176
  schema
5996
6177
  });
5997
- const type = getSchemaType({ schema });
6178
+ const type = getSchemaType(schema);
5998
6179
  if (!type) return irSchema;
5999
6180
  if (!schema.nullable) return parseOneType$1({
6000
6181
  context,
@@ -6152,7 +6333,7 @@ const paginationField$1 = ({ context, name, schema }) => {
6152
6333
  for (const name in schema.properties) if (getPaginationKeywordsRegExp(context.config.parser.pagination).test(name)) {
6153
6334
  const property = schema.properties[name];
6154
6335
  if (typeof property !== "boolean" && !("$ref" in property)) {
6155
- if (isPaginationType$1(getSchemaType({ schema: property }))) return name;
6336
+ if (isPaginationType$1(getSchemaType(property))) return name;
6156
6337
  }
6157
6338
  }
6158
6339
  for (const allOf of schema.allOf ?? []) {
@@ -6167,13 +6348,13 @@ const paginationField$1 = ({ context, name, schema }) => {
6167
6348
  };
6168
6349
  //#endregion
6169
6350
  //#region src/openApi/3.0.x/parser/operation.ts
6170
- const parseOperationJsDoc$1 = ({ irOperation, operation }) => {
6351
+ function parseOperationJsDoc$1({ irOperation, operation }) {
6171
6352
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
6172
6353
  if (operation.description) irOperation.description = operation.description;
6173
6354
  if (operation.summary) irOperation.summary = operation.summary;
6174
6355
  if (operation.tags?.length) irOperation.tags = operation.tags;
6175
- };
6176
- const initIrOperation$1 = ({ context, method, operation, path, state }) => {
6356
+ }
6357
+ function initIrOperation$1({ context, method, operation, path, state }) {
6177
6358
  const irOperation = {
6178
6359
  id: operationToId({
6179
6360
  context,
@@ -6195,8 +6376,8 @@ const initIrOperation$1 = ({ context, method, operation, path, state }) => {
6195
6376
  target: irOperation
6196
6377
  });
6197
6378
  return irOperation;
6198
- };
6199
- const operationToIrOperation$1 = ({ context, method, operation, path, securitySchemesMap, state }) => {
6379
+ }
6380
+ function operationToIrOperation$1({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
6200
6381
  const irOperation = initIrOperation$1({
6201
6382
  context,
6202
6383
  method,
@@ -6271,17 +6452,19 @@ const operationToIrOperation$1 = ({ context, method, operation, path, securitySc
6271
6452
  for (const securityRequirementObject of operation.security) for (const name in securityRequirementObject) {
6272
6453
  const securitySchemeObject = securitySchemesMap.get(name);
6273
6454
  if (!securitySchemeObject) continue;
6455
+ if (ambiguousSecurityKeys.has(name)) securitySchemeObject.key = name;
6274
6456
  securitySchemeObjects.set(name, securitySchemeObject);
6275
6457
  }
6276
6458
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
6277
6459
  }
6278
6460
  return irOperation;
6279
- };
6280
- const parsePathOperation$1 = ({ context, method, operation, path, securitySchemesMap, state }) => {
6461
+ }
6462
+ function parsePathOperation$1({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
6281
6463
  if (!context.ir.paths) context.ir.paths = {};
6282
6464
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
6283
6465
  if (operation.servers) context.ir.servers = [...context.ir.servers ?? [], ...operation.servers];
6284
6466
  context.ir.paths[path][method] = operationToIrOperation$1({
6467
+ ambiguousSecurityKeys,
6285
6468
  context,
6286
6469
  method,
6287
6470
  operation,
@@ -6289,7 +6472,7 @@ const parsePathOperation$1 = ({ context, method, operation, path, securityScheme
6289
6472
  securitySchemesMap,
6290
6473
  state
6291
6474
  });
6292
- };
6475
+ }
6293
6476
  //#endregion
6294
6477
  //#region src/openApi/3.0.x/parser/parameter.ts
6295
6478
  /**
@@ -6536,7 +6719,11 @@ const parseV3_0_X = (context) => {
6536
6719
  securitySchemesMap.set(name, securitySchemeObject);
6537
6720
  }
6538
6721
  for (const name in context.spec.components.parameters) {
6539
- const $ref = `#/components/parameters/${name}`;
6722
+ const $ref = pathToJsonPointer([
6723
+ "components",
6724
+ "parameters",
6725
+ name
6726
+ ]);
6540
6727
  const parameterOrReference = context.spec.components.parameters[name];
6541
6728
  parseParameter$1({
6542
6729
  $ref,
@@ -6545,7 +6732,11 @@ const parseV3_0_X = (context) => {
6545
6732
  });
6546
6733
  }
6547
6734
  for (const name in context.spec.components.requestBodies) {
6548
- const $ref = `#/components/requestBodies/${name}`;
6735
+ const $ref = pathToJsonPointer([
6736
+ "components",
6737
+ "requestBodies",
6738
+ name
6739
+ ]);
6549
6740
  const requestBodyOrReference = context.spec.components.requestBodies[name];
6550
6741
  parseRequestBody$1({
6551
6742
  $ref,
@@ -6554,7 +6745,11 @@ const parseV3_0_X = (context) => {
6554
6745
  });
6555
6746
  }
6556
6747
  for (const name in context.spec.components.schemas) {
6557
- const $ref = `#/components/schemas/${name}`;
6748
+ const $ref = pathToJsonPointer([
6749
+ "components",
6750
+ "schemas",
6751
+ name
6752
+ ]);
6558
6753
  const schema = context.spec.components.schemas[name];
6559
6754
  parseSchema$1({
6560
6755
  $ref,
@@ -6563,6 +6758,7 @@ const parseV3_0_X = (context) => {
6563
6758
  });
6564
6759
  }
6565
6760
  }
6761
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
6566
6762
  parseServers$1({ context });
6567
6763
  for (const path in context.spec.paths) {
6568
6764
  if (path.startsWith("x-")) continue;
@@ -6572,6 +6768,7 @@ const parseV3_0_X = (context) => {
6572
6768
  ...pathItem
6573
6769
  } : pathItem;
6574
6770
  const operationArgs = {
6771
+ ambiguousSecurityKeys,
6575
6772
  context,
6576
6773
  operation: {
6577
6774
  description: finalPathItem.description,
@@ -6805,7 +7002,7 @@ const mediaTypeObjects = ({ content }) => {
6805
7002
  };
6806
7003
  //#endregion
6807
7004
  //#region src/openApi/3.1.x/parser/schema.ts
6808
- function getSchemaTypes({ schema }) {
7005
+ function getSchemaTypes(schema) {
6809
7006
  if (typeof schema.type === "string") return [schema.type];
6810
7007
  if (schema.type) return schema.type;
6811
7008
  if (schema.properties) return ["object"];
@@ -6864,7 +7061,7 @@ function findDiscriminatorsInSchema({ context, discriminators = [], schema }) {
6864
7061
  */
6865
7062
  function getAllDiscriminatorValues({ discriminator, schemaRef }) {
6866
7063
  const values = [];
6867
- for (const [value, mappedSchemaRef] of Object.entries(discriminator.mapping || {})) if (mappedSchemaRef === schemaRef) values.push(value);
7064
+ for (const value in discriminator.mapping) if (discriminator.mapping[value] === schemaRef) values.push(value);
6868
7065
  return values;
6869
7066
  }
6870
7067
  function parseSchemaJsDoc({ irSchema, schema }) {
@@ -6926,10 +7123,7 @@ function parseArray({ context, irSchema = {}, schema, state }) {
6926
7123
  if (!schemaItems.length && schema.maxItems && schema.maxItems === schema.minItems) schemaItems = Array(schema.maxItems).fill(irItemsSchema);
6927
7124
  else {
6928
7125
  const ofArray = schema.items.allOf || schema.items.anyOf || schema.items.oneOf;
6929
- if (ofArray && ofArray.length > 1 && !getSchemaTypes({ schema: schema.items }).includes("null")) irSchema = {
6930
- ...irSchema,
6931
- ...irItemsSchema
6932
- };
7126
+ if (ofArray && ofArray.length > 1 && !getSchemaTypes(schema.items).includes("null")) Object.assign(irSchema, irItemsSchema);
6933
7127
  else schemaItems.push(irItemsSchema);
6934
7128
  }
6935
7129
  }
@@ -6953,25 +7147,21 @@ function parseNumber({ irSchema = {}, schema }) {
6953
7147
  }
6954
7148
  function parseObject({ context, irSchema = {}, schema, state }) {
6955
7149
  irSchema.type = "object";
6956
- const schemaProperties = {};
6957
- for (const name in schema.properties) {
6958
- const property = schema.properties[name];
6959
- if (typeof property === "boolean") {} else schemaProperties[name] = schemaToIrSchema({
6960
- context,
6961
- schema: property,
6962
- state
6963
- });
7150
+ let isSchemaPropertiesEmpty = true;
7151
+ if (schema.properties) {
7152
+ const schemaProperties = {};
7153
+ for (const name in schema.properties) {
7154
+ isSchemaPropertiesEmpty = false;
7155
+ const property = schema.properties[name];
7156
+ if (typeof property === "boolean") {} else schemaProperties[name] = schemaToIrSchema({
7157
+ context,
7158
+ schema: property,
7159
+ state
7160
+ });
7161
+ }
7162
+ if (!isSchemaPropertiesEmpty) irSchema.properties = schemaProperties;
6964
7163
  }
6965
- if (Object.keys(schemaProperties).length) irSchema.properties = schemaProperties;
6966
- if (schema.additionalProperties === void 0) {
6967
- if (!irSchema.properties) irSchema.additionalProperties = { type: "unknown" };
6968
- } else if (typeof schema.additionalProperties === "boolean") {
6969
- if (!(state.inAllOf && schema.additionalProperties === false && (!schema.properties || !Object.keys(schema.properties).length) && (!schema.patternProperties || !Object.keys(schema.patternProperties).length))) irSchema.additionalProperties = { type: schema.additionalProperties ? "unknown" : "never" };
6970
- } else irSchema.additionalProperties = schemaToIrSchema({
6971
- context,
6972
- schema: schema.additionalProperties,
6973
- state
6974
- });
7164
+ let isPatternPropertiesEmpty = true;
6975
7165
  if (schema.patternProperties) {
6976
7166
  const patternProperties = {};
6977
7167
  for (const pattern in schema.patternProperties) {
@@ -6981,9 +7171,19 @@ function parseObject({ context, irSchema = {}, schema, state }) {
6981
7171
  schema: patternSchema,
6982
7172
  state
6983
7173
  });
7174
+ isPatternPropertiesEmpty = false;
6984
7175
  }
6985
- if (Object.keys(patternProperties).length) irSchema.patternProperties = patternProperties;
7176
+ if (!isPatternPropertiesEmpty) irSchema.patternProperties = patternProperties;
6986
7177
  }
7178
+ if (schema.additionalProperties === void 0) {
7179
+ if (!irSchema.properties) irSchema.additionalProperties = { type: "unknown" };
7180
+ } else if (typeof schema.additionalProperties === "boolean") {
7181
+ if (!(state.inAllOf && schema.additionalProperties === false && (!schema.properties || isSchemaPropertiesEmpty) && (!schema.patternProperties || isPatternPropertiesEmpty))) irSchema.additionalProperties = { type: schema.additionalProperties ? "unknown" : "never" };
7182
+ } else irSchema.additionalProperties = schemaToIrSchema({
7183
+ context,
7184
+ schema: schema.additionalProperties,
7185
+ state
7186
+ });
6987
7187
  if (schema.propertyNames) irSchema.propertyNames = schemaToIrSchema({
6988
7188
  context,
6989
7189
  schema: schema.propertyNames,
@@ -7037,7 +7237,7 @@ function parseAllOf({ context, schema, state }) {
7037
7237
  schema
7038
7238
  });
7039
7239
  const schemaItems = [];
7040
- const schemaTypes = getSchemaTypes({ schema });
7240
+ const schemaTypes = getSchemaTypes(schema);
7041
7241
  const compositionSchemas = schema.allOf;
7042
7242
  const discriminatorsToAdd = [];
7043
7243
  for (const compositionSchema of compositionSchemas) {
@@ -7049,8 +7249,7 @@ function parseAllOf({ context, schema, state }) {
7049
7249
  state
7050
7250
  });
7051
7251
  state.inAllOf = originalInAllOf;
7052
- if (state.inAllOf === void 0) delete state.inAllOf;
7053
- if (schema.required) if (irCompositionSchema.required) irCompositionSchema.required = [...irCompositionSchema.required, ...schema.required];
7252
+ if (schema.required) if (irCompositionSchema.required) irCompositionSchema.required.push(...schema.required);
7054
7253
  else irCompositionSchema.required = schema.required;
7055
7254
  schemaItems.push(irCompositionSchema);
7056
7255
  if (compositionSchema.$ref) {
@@ -7125,7 +7324,7 @@ function parseAllOf({ context, schema, state }) {
7125
7324
  inlineSchema.properties[discriminator.propertyName] = discriminatorProperty;
7126
7325
  if (isRequired) {
7127
7326
  if (!inlineSchema.required) inlineSchema.required = [];
7128
- if (!inlineSchema.required.includes(discriminator.propertyName)) inlineSchema.required = [...inlineSchema.required, discriminator.propertyName];
7327
+ if (!inlineSchema.required.includes(discriminator.propertyName)) inlineSchema.required.push(discriminator.propertyName);
7129
7328
  }
7130
7329
  } else {
7131
7330
  const irDiscriminatorSchema = {
@@ -7148,7 +7347,7 @@ function parseAllOf({ context, schema, state }) {
7148
7347
  if (irObjectSchema.properties) {
7149
7348
  for (const requiredProperty of irObjectSchema.required ?? []) if (!irObjectSchema.properties[requiredProperty]) for (const compositionSchema of compositionSchemas) {
7150
7349
  const finalCompositionSchema = compositionSchema.$ref ? context.resolveRef(compositionSchema.$ref) : compositionSchema;
7151
- if (getSchemaTypes({ schema: finalCompositionSchema }).includes("object")) {
7350
+ if (getSchemaTypes(finalCompositionSchema).includes("object")) {
7152
7351
  const irCompositionSchema = parseOneType({
7153
7352
  context,
7154
7353
  schema: {
@@ -7189,7 +7388,7 @@ function parseAnyOf({ context, schema, state }) {
7189
7388
  schema
7190
7389
  });
7191
7390
  const schemaItems = [];
7192
- const schemaTypes = getSchemaTypes({ schema });
7391
+ const schemaTypes = getSchemaTypes(schema);
7193
7392
  const compositionSchemas = schema.anyOf;
7194
7393
  const discriminatorPropertyType = schema.discriminator ? findDiscriminatorPropertyType({
7195
7394
  context,
@@ -7248,8 +7447,12 @@ function parseEnum({ context, schema, state }) {
7248
7447
  });
7249
7448
  irSchema.type = "enum";
7250
7449
  const schemaItems = [];
7251
- const schemaTypes = getSchemaTypes({ schema });
7252
- for (const [index, enumValue] of schema.enum.entries()) {
7450
+ const schemaTypes = getSchemaTypes(schema);
7451
+ const xEnumDescriptions = schema["x-enum-descriptions"];
7452
+ const xEnumVarnames = schema["x-enum-varnames"];
7453
+ const xEnumNames = schema["x-enumNames"];
7454
+ for (let index = 0, len = schema.enum.length; index < len; index++) {
7455
+ const enumValue = schema.enum[index];
7253
7456
  const typeOfEnumValue = typeof enumValue;
7254
7457
  let enumType;
7255
7458
  if (typeOfEnumValue === "string" || typeOfEnumValue === "number" || typeOfEnumValue === "boolean") enumType = typeOfEnumValue;
@@ -7262,8 +7465,8 @@ function parseEnum({ context, schema, state }) {
7262
7465
  context,
7263
7466
  schema: {
7264
7467
  const: enumValue,
7265
- description: schema["x-enum-descriptions"]?.[index],
7266
- title: schema["x-enum-varnames"]?.[index] ?? schema["x-enumNames"]?.[index],
7468
+ description: xEnumDescriptions?.[index],
7469
+ title: xEnumVarnames?.[index] ?? xEnumNames?.[index],
7267
7470
  type: enumType
7268
7471
  },
7269
7472
  state
@@ -7283,7 +7486,7 @@ function parseOneOf({ context, schema, state }) {
7283
7486
  schema
7284
7487
  });
7285
7488
  let schemaItems = [];
7286
- const schemaTypes = getSchemaTypes({ schema });
7489
+ const schemaTypes = getSchemaTypes(schema);
7287
7490
  const compositionSchemas = schema.oneOf;
7288
7491
  const discriminatorPropertyType = schema.discriminator ? findDiscriminatorPropertyType({
7289
7492
  context,
@@ -7464,7 +7667,7 @@ function parseType({ context, schema, state }) {
7464
7667
  irSchema,
7465
7668
  schema
7466
7669
  });
7467
- const schemaTypes = getSchemaTypes({ schema });
7670
+ const schemaTypes = getSchemaTypes(schema);
7468
7671
  if (schemaTypes.length === 1) return parseOneType({
7469
7672
  context,
7470
7673
  irSchema,
@@ -7582,11 +7785,11 @@ const paginationField = ({ context, name, schema }) => {
7582
7785
  for (const name in schema.properties) if (getPaginationKeywordsRegExp(context.config.parser.pagination).test(name)) {
7583
7786
  const property = schema.properties[name];
7584
7787
  if (typeof property !== "boolean") {
7585
- const schemaTypes = getSchemaTypes({ schema: property });
7788
+ const schemaTypes = getSchemaTypes(property);
7586
7789
  if (!schemaTypes.length) {
7587
7790
  const nonNullCompositionSchemas = (property.anyOf ?? property.oneOf ?? []).filter((schema) => schema.type !== "null");
7588
7791
  if (nonNullCompositionSchemas.length === 1) {
7589
- if (isPaginationType(getSchemaTypes({ schema: nonNullCompositionSchemas[0] }))) return name;
7792
+ if (isPaginationType(getSchemaTypes(nonNullCompositionSchemas[0]))) return name;
7590
7793
  }
7591
7794
  }
7592
7795
  if (isPaginationType(schemaTypes)) return name;
@@ -7604,13 +7807,13 @@ const paginationField = ({ context, name, schema }) => {
7604
7807
  };
7605
7808
  //#endregion
7606
7809
  //#region src/openApi/3.1.x/parser/operation.ts
7607
- const parseOperationJsDoc = ({ irOperation, operation }) => {
7810
+ function parseOperationJsDoc({ irOperation, operation }) {
7608
7811
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
7609
7812
  if (operation.description) irOperation.description = operation.description;
7610
7813
  if (operation.summary) irOperation.summary = operation.summary;
7611
7814
  if (operation.tags?.length) irOperation.tags = operation.tags;
7612
- };
7613
- const initIrOperation = ({ context, method, operation, path, state }) => {
7815
+ }
7816
+ function initIrOperation({ context, method, operation, path, state }) {
7614
7817
  const irOperation = {
7615
7818
  id: operationToId({
7616
7819
  context,
@@ -7632,8 +7835,8 @@ const initIrOperation = ({ context, method, operation, path, state }) => {
7632
7835
  target: irOperation
7633
7836
  });
7634
7837
  return irOperation;
7635
- };
7636
- const operationToIrOperation = ({ context, method, operation, path, securitySchemesMap, state }) => {
7838
+ }
7839
+ function operationToIrOperation({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
7637
7840
  const irOperation = initIrOperation({
7638
7841
  context,
7639
7842
  method,
@@ -7699,15 +7902,17 @@ const operationToIrOperation = ({ context, method, operation, path, securitySche
7699
7902
  for (const securityRequirementObject of operation.security) for (const name in securityRequirementObject) {
7700
7903
  const securitySchemeObject = securitySchemesMap.get(name);
7701
7904
  if (!securitySchemeObject) continue;
7905
+ if (ambiguousSecurityKeys.has(name)) securitySchemeObject.key = name;
7702
7906
  securitySchemeObjects.set(name, securitySchemeObject);
7703
7907
  }
7704
7908
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
7705
7909
  }
7706
7910
  return irOperation;
7707
- };
7708
- const parseOperationObject = ({ context, method, operation, path, securitySchemesMap, state }) => {
7911
+ }
7912
+ function parseOperationObject({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
7709
7913
  if (operation.servers) context.ir.servers = [...context.ir.servers ?? [], ...operation.servers];
7710
7914
  return { parsed: operationToIrOperation({
7915
+ ambiguousSecurityKeys,
7711
7916
  context,
7712
7917
  method,
7713
7918
  operation,
@@ -7715,8 +7920,8 @@ const parseOperationObject = ({ context, method, operation, path, securityScheme
7715
7920
  securitySchemesMap,
7716
7921
  state
7717
7922
  }) };
7718
- };
7719
- const parsePathOperation = ({ context, method, path, ...options }) => {
7923
+ }
7924
+ function parsePathOperation({ context, method, path, ...options }) {
7720
7925
  if (!context.ir.paths) context.ir.paths = {};
7721
7926
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
7722
7927
  const { parsed } = parseOperationObject({
@@ -7726,8 +7931,8 @@ const parsePathOperation = ({ context, method, path, ...options }) => {
7726
7931
  ...options
7727
7932
  });
7728
7933
  context.ir.paths[path][method] = parsed;
7729
- };
7730
- const parseWebhookOperation = ({ context, key, method, ...options }) => {
7934
+ }
7935
+ function parseWebhookOperation({ context, key, method, ...options }) {
7731
7936
  if (!context.ir.webhooks) context.ir.webhooks = {};
7732
7937
  if (!context.ir.webhooks[key]) context.ir.webhooks[key] = {};
7733
7938
  const { parsed } = parseOperationObject({
@@ -7737,7 +7942,7 @@ const parseWebhookOperation = ({ context, key, method, ...options }) => {
7737
7942
  ...options
7738
7943
  });
7739
7944
  context.ir.webhooks[key][method] = parsed;
7740
- };
7945
+ }
7741
7946
  //#endregion
7742
7947
  //#region src/openApi/3.1.x/parser/parameter.ts
7743
7948
  /**
@@ -7950,7 +8155,7 @@ const validateOpenApiSpec = (spec, logger) => {
7950
8155
  };
7951
8156
  //#endregion
7952
8157
  //#region src/openApi/3.1.x/parser/webhook.ts
7953
- const parseWebhooks = ({ context, securitySchemesMap }) => {
8158
+ function parseWebhooks({ ambiguousSecurityKeys, context, securitySchemesMap }) {
7954
8159
  const state = { ids: /* @__PURE__ */ new Map() };
7955
8160
  for (const key in context.spec.webhooks) {
7956
8161
  const webhook = context.spec.webhooks[key];
@@ -7959,6 +8164,7 @@ const parseWebhooks = ({ context, securitySchemesMap }) => {
7959
8164
  ...webhook
7960
8165
  } : webhook;
7961
8166
  const operationArgs = {
8167
+ ambiguousSecurityKeys,
7962
8168
  context,
7963
8169
  key,
7964
8170
  operation: {
@@ -8095,7 +8301,7 @@ const parseWebhooks = ({ context, securitySchemesMap }) => {
8095
8301
  }
8096
8302
  });
8097
8303
  }
8098
- };
8304
+ }
8099
8305
  //#endregion
8100
8306
  //#region src/openApi/3.1.x/parser/index.ts
8101
8307
  const parseV3_1_X = (context) => {
@@ -8128,7 +8334,11 @@ const parseV3_1_X = (context) => {
8128
8334
  securitySchemesMap.set(name, securitySchemeObject);
8129
8335
  }
8130
8336
  for (const name in context.spec.components.parameters) {
8131
- const $ref = `#/components/parameters/${name}`;
8337
+ const $ref = pathToJsonPointer([
8338
+ "components",
8339
+ "parameters",
8340
+ name
8341
+ ]);
8132
8342
  const parameterOrReference = context.spec.components.parameters[name];
8133
8343
  parseParameter({
8134
8344
  $ref,
@@ -8137,7 +8347,11 @@ const parseV3_1_X = (context) => {
8137
8347
  });
8138
8348
  }
8139
8349
  for (const name in context.spec.components.requestBodies) {
8140
- const $ref = `#/components/requestBodies/${name}`;
8350
+ const $ref = pathToJsonPointer([
8351
+ "components",
8352
+ "requestBodies",
8353
+ name
8354
+ ]);
8141
8355
  const requestBodyOrReference = context.spec.components.requestBodies[name];
8142
8356
  parseRequestBody({
8143
8357
  $ref,
@@ -8146,7 +8360,11 @@ const parseV3_1_X = (context) => {
8146
8360
  });
8147
8361
  }
8148
8362
  for (const name in context.spec.components.schemas) {
8149
- const $ref = `#/components/schemas/${name}`;
8363
+ const $ref = pathToJsonPointer([
8364
+ "components",
8365
+ "schemas",
8366
+ name
8367
+ ]);
8150
8368
  const schema = context.spec.components.schemas[name];
8151
8369
  parseSchema({
8152
8370
  $ref,
@@ -8155,6 +8373,7 @@ const parseV3_1_X = (context) => {
8155
8373
  });
8156
8374
  }
8157
8375
  }
8376
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
8158
8377
  parseServers({ context });
8159
8378
  for (const path in context.spec.paths) {
8160
8379
  if (path.startsWith("x-")) continue;
@@ -8164,6 +8383,7 @@ const parseV3_1_X = (context) => {
8164
8383
  ...pathItem
8165
8384
  } : pathItem;
8166
8385
  const operationArgs = {
8386
+ ambiguousSecurityKeys,
8167
8387
  context,
8168
8388
  operation: {
8169
8389
  description: finalPathItem.description,
@@ -8301,6 +8521,7 @@ const parseV3_1_X = (context) => {
8301
8521
  });
8302
8522
  }
8303
8523
  parseWebhooks({
8524
+ ambiguousSecurityKeys,
8304
8525
  context,
8305
8526
  securitySchemesMap
8306
8527
  });
@@ -8333,15 +8554,43 @@ function parseOpenApiSpec(context) {
8333
8554
  * Built-in strategies for operations.
8334
8555
  */
8335
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
+ */
8336
8568
  byTags: (config) => (operation) => {
8337
8569
  const tags = operation.tags && operation.tags.length ? operation.tags : [config.fallback];
8338
8570
  const pathSegments = (config.path ?? OperationPath.id())(operation);
8339
8571
  return tags.map((tag) => [tag, ...pathSegments]);
8340
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
+ */
8341
8583
  flat: (config) => (operation) => {
8342
8584
  const pathSegments = (config?.path ?? OperationPath.id())(operation);
8343
8585
  return [[pathSegments[pathSegments.length - 1]]];
8344
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
+ */
8345
8594
  single: (config) => (operation) => {
8346
8595
  const pathSegments = (config.path ?? OperationPath.id())(operation);
8347
8596
  return [[config.root, ...pathSegments]];
@@ -8351,6 +8600,17 @@ const OperationStrategy = {
8351
8600
  * Built-in path derivation helpers for operations.
8352
8601
  */
8353
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
+ */
8354
8614
  fromOperationId: (config) => (operation) => {
8355
8615
  const fallback = config?.fallback ?? OperationPath.id();
8356
8616
  if (!operation.operationId) return fallback(operation);
@@ -8358,6 +8618,23 @@ const OperationPath = {
8358
8618
  const segments = operation.operationId.split(delimiters).filter(Boolean);
8359
8619
  return !segments.length ? fallback(operation) : segments;
8360
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
+ */
8361
8638
  fromPath: (config) => (operation) => {
8362
8639
  const delimiters = config?.delimiters ?? /[./]/;
8363
8640
  const segments = operation.path.split(delimiters).filter(Boolean);
@@ -8372,6 +8649,13 @@ const OperationPath = {
8372
8649
  }
8373
8650
  return segments;
8374
8651
  },
8652
+ /**
8653
+ * Uses operation.id as a single path segment.
8654
+ *
8655
+ * @example
8656
+ * // operation.id: 'getUserById'
8657
+ * // Result: ['getUserById']
8658
+ */
8375
8659
  id: () => (operation) => [operation.id]
8376
8660
  };
8377
8661
  //#endregion
@@ -8514,30 +8798,30 @@ function warnOnConflictingDuplicatePlugins(plugins) {
8514
8798
  }
8515
8799
  //#endregion
8516
8800
  //#region src/plugins/shared/utils/config.ts
8517
- const definePluginConfig = (defaultConfig) => (userConfig) => ({
8518
- ...defaultConfig,
8519
- config: {
8520
- ...defaultConfig.config,
8521
- ...userConfig
8522
- }
8523
- });
8524
- /**
8525
- * Reusable mappers for `enabled` and `name` fields.
8526
- */
8527
- const mappers = {
8528
- boolean: (enabled) => ({ enabled }),
8529
- function: (name) => ({ name }),
8530
- string: (name) => ({ name })
8531
- };
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
+ }
8532
8817
  //#endregion
8533
8818
  //#region src/plugins/symbol.ts
8534
8819
  /**
8535
8820
  * Helper function to build the input for symbol registration, applying naming hooks if provided.
8536
8821
  */
8537
8822
  function buildSymbolIn({ plugin, ...ctx }) {
8538
- const hooks = [plugin.config["~hooks"]?.symbols?.getName, plugin.context.config.parser.hooks.symbols?.getName];
8823
+ const hooks = plugin.getHooks((hooks) => hooks.symbols?.getName);
8539
8824
  for (const hook of hooks) {
8540
- if (!hook) continue;
8541
8825
  const result = hook(ctx);
8542
8826
  if (typeof result === "function") {
8543
8827
  const name = result(ctx);
@@ -8593,9 +8877,15 @@ function escapeComment(value) {
8593
8877
  * Utilities shared across the package.
8594
8878
  */
8595
8879
  const utils = {
8880
+ /**
8881
+ * @deprecated use `toCase` instead
8882
+ */
8596
8883
  stringCase({ case: casing, stripLeadingSeparators, value }) {
8597
8884
  return toCase(value, casing, { stripLeadingSeparators });
8598
8885
  },
8886
+ /**
8887
+ * Converts the given string to the specified casing.
8888
+ */
8599
8889
  toCase
8600
8890
  };
8601
8891
  //#endregion
@@ -8719,6 +9009,6 @@ function pathToName(path, options) {
8719
9009
  return names.join("-");
8720
9010
  }
8721
9011
  //#endregion
8722
- 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 };
8723
9013
 
8724
9014
  //# sourceMappingURL=index.mjs.map