@hey-api/shared 0.4.5 → 0.4.7

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
  }
@@ -564,12 +770,12 @@ function compileInputPath(input) {
564
770
  result.path = query ? `${compiledPath}?${query}` : compiledPath;
565
771
  return result;
566
772
  }
567
- function logInputPaths(inputPaths, jobIndex) {
773
+ function logInputPaths(inputPaths, jobIndex, logLevel) {
774
+ if (logLevel === "silent") return;
568
775
  const lines = [];
569
776
  const jobPrefix = colors.gray(`[Job ${jobIndex + 1}] `);
570
- const count = inputPaths.length;
571
- const baseString = colors.cyan(`Generating from ${count} ${count === 1 ? "input" : "inputs"}:`);
572
- lines.push(`${jobPrefix}⏳ ${baseString}`);
777
+ const baseString = colors.cyan(`Generating...`);
778
+ lines.push(`${jobPrefix}${colors.gray("~")} ${baseString}`);
573
779
  inputPaths.forEach((inputPath, index) => {
574
780
  const itemPrefixStr = ` [${index + 1}] `;
575
781
  const itemPrefix = colors.cyan(itemPrefixStr);
@@ -586,6 +792,7 @@ function logInputPaths(inputPaths, jobIndex) {
586
792
  if (inputPath.commit_sha) lines.push(`${jobPrefix}${detailIndent}${colors.gray("commit:")} ${colors.green(inputPath.commit_sha)}`);
587
793
  if (inputPath.tags?.length) lines.push(`${jobPrefix}${detailIndent}${colors.gray("tags:")} ${colors.green(inputPath.tags.join(", "))}`);
588
794
  if (inputPath.version) lines.push(`${jobPrefix}${detailIndent}${colors.gray("version:")} ${colors.green(inputPath.version)}`);
795
+ if (logLevel === "debug") lines.push(`${jobPrefix}${detailIndent}${colors.gray("url:")} ${colors.green(inputPath.path)}`);
589
796
  lines.push(`${jobPrefix}${detailIndent}${colors.gray("registry:")} ${colors.green("Hey API")}`);
590
797
  break;
591
798
  }
@@ -594,12 +801,14 @@ function logInputPaths(inputPaths, jobIndex) {
594
801
  if (!baseInput) lines.push(`${jobPrefix}${itemPrefix}${inputPath.path}`);
595
802
  else lines.push(`${jobPrefix}${itemPrefix}${baseInput}`);
596
803
  if (inputPath.uuid) lines.push(`${jobPrefix}${detailIndent}${colors.gray("uuid:")} ${colors.green(inputPath.uuid)}`);
804
+ if (logLevel === "debug" && baseInput) lines.push(`${jobPrefix}${detailIndent}${colors.gray("url:")} ${colors.green(inputPath.path)}`);
597
805
  lines.push(`${jobPrefix}${detailIndent}${colors.gray("registry:")} ${colors.green("ReadMe")}`);
598
806
  break;
599
807
  }
600
808
  case "scalar": {
601
809
  const baseInput = [inputPath.organization, inputPath.project].filter(Boolean).join("/");
602
810
  lines.push(`${jobPrefix}${itemPrefix}${baseInput}`);
811
+ if (logLevel === "debug") lines.push(`${jobPrefix}${detailIndent}${colors.gray("url:")} ${colors.green(inputPath.path)}`);
603
812
  lines.push(`${jobPrefix}${detailIndent}${colors.gray("registry:")} ${colors.green("Scalar")}`);
604
813
  break;
605
814
  }
@@ -612,18 +821,14 @@ function logInputPaths(inputPaths, jobIndex) {
612
821
  }
613
822
  //#endregion
614
823
  //#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;
824
+ const logsConfig = defineConfig({
825
+ $coerce: { string: (path) => ({ path }) },
826
+ file: true,
827
+ level: "info",
828
+ path: process.cwd()
829
+ });
830
+ function getLogs(input) {
831
+ return logsConfig(input);
627
832
  }
628
833
  //#endregion
629
834
  //#region src/config/output/postprocess.ts
@@ -646,65 +851,19 @@ function postprocessOutput(config, postProcessors, jobPrefix) {
646
851
  }
647
852
  }
648
853
  //#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
854
  //#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
- }
855
+ const sourceConfig = defineConfig({
856
+ $coerceAny: ({ value }) => ({ enabled: Boolean(value) }),
857
+ enabled: false,
858
+ extension: "json",
859
+ fileName: "source",
860
+ path: coerce((value) => {
861
+ if (value === true || value === void 0 || value === "") return "";
862
+ if (value === false || value === null) return null;
863
+ return value;
864
+ }),
865
+ serialize: coerce((value) => typeof value === "function" ? value : (input) => JSON.stringify(input, null, 2))
866
+ });
708
867
  //#endregion
709
868
  //#region src/config/parser/config.ts
710
869
  const defaultPaginationKeywords = [
@@ -715,93 +874,44 @@ const defaultPaginationKeywords = [
715
874
  "page",
716
875
  "start"
717
876
  ];
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
- }
877
+ const parserConfig = defineConfig({
878
+ hooks: {},
879
+ pagination: { keywords: defaultPaginationKeywords },
880
+ transforms: {
881
+ enums: {
882
+ $coerce: { string: (mode) => ({ mode }) },
883
+ $coerceAny: ({ value }) => ({ enabled: Boolean(value) }),
884
+ case: "PascalCase",
885
+ enabled: false,
886
+ mode: "root",
887
+ name: "{{name}}Enum"
888
+ },
889
+ propertiesRequiredByDefault: false,
890
+ readWrite: {
891
+ $coerceAny: ({ value }) => ({ enabled: Boolean(value) }),
892
+ enabled: true,
893
+ requests: {
894
+ $coerce: {
895
+ function: (name) => ({ name }),
896
+ string: (name) => ({ name })
741
897
  },
742
- schemaName: void 0
898
+ case: "preserve",
899
+ name: "{{name}}Writable"
743
900
  },
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
- });
901
+ responses: {
902
+ $coerce: {
903
+ function: (name) => ({ name }),
904
+ string: (name) => ({ name })
905
+ },
906
+ case: "preserve",
907
+ name: "{{name}}"
908
+ }
909
+ }
910
+ },
911
+ validate_EXPERIMENTAL: coerce((value) => value === true ? "warn" : value || false)
912
+ });
913
+ function getParser(input) {
914
+ return parserConfig(input.parser ?? {});
805
915
  }
806
916
  //#endregion
807
917
  //#region src/config/utils/dependencies.ts
@@ -1475,6 +1585,7 @@ async function getSpec({ fetchOptions, inputPath, timeout, watch }) {
1475
1585
  //#endregion
1476
1586
  //#region src/utils/minHeap.ts
1477
1587
  var MinHeap = class {
1588
+ declIndex;
1478
1589
  heap = [];
1479
1590
  constructor(declIndex) {
1480
1591
  this.declIndex = declIndex;
@@ -1872,7 +1983,7 @@ var PluginInstance = class {
1872
1983
  api;
1873
1984
  config;
1874
1985
  context;
1875
- dependencies = [];
1986
+ dependencies = /* @__PURE__ */ new Set();
1876
1987
  eventHooks;
1877
1988
  gen;
1878
1989
  handler;
@@ -1884,6 +1995,8 @@ var PluginInstance = class {
1884
1995
  * code generation.
1885
1996
  */
1886
1997
  package;
1998
+ /** Symbols declared in the plugin config. */
1999
+ symbols;
1887
2000
  constructor(props) {
1888
2001
  this.api = props.api ?? {};
1889
2002
  this.config = props.config;
@@ -1894,6 +2007,7 @@ var PluginInstance = class {
1894
2007
  this.handler = props.handler;
1895
2008
  this.name = props.name;
1896
2009
  this.package = props.context.package;
2010
+ this.symbols = this.buildSymbols(props.symbols);
1897
2011
  }
1898
2012
  external(resource, meta = {}) {
1899
2013
  return this.gen.symbols.reference({
@@ -2059,11 +2173,17 @@ var PluginInstance = class {
2059
2173
  });
2060
2174
  return result;
2061
2175
  }
2062
- querySymbol(filter) {
2063
- return this.querySymbols(filter)[0];
2176
+ querySymbol(filter, tags, predicate) {
2177
+ return this.querySymbols(filter, tags, predicate)[0];
2064
2178
  }
2065
- querySymbols(filter) {
2066
- return this.gen.symbols.query(filter);
2179
+ querySymbols(filter, tags, predicate) {
2180
+ const results = this.gen.symbols.query(filter);
2181
+ if (!tags?.length && !predicate) return results;
2182
+ const set = tags?.length ? new Set(tags) : null;
2183
+ return results.filter((symbol) => {
2184
+ if (set && !set.has(symbol.node?.["~dsl"] ?? "")) return false;
2185
+ return predicate ? predicate(symbol) : true;
2186
+ });
2067
2187
  }
2068
2188
  referenceSymbol(meta) {
2069
2189
  return this.gen.symbols.reference(meta);
@@ -2093,7 +2213,7 @@ var PluginInstance = class {
2093
2213
  const symbolIn = {
2094
2214
  ...symbol,
2095
2215
  meta: {
2096
- pluginName: path.isAbsolute(this.name) ? "custom" : this.name,
2216
+ ...symbol.external ? {} : { pluginName: path.isAbsolute(this.name) ? "custom" : this.name },
2097
2217
  ...meta
2098
2218
  },
2099
2219
  name
@@ -2140,6 +2260,9 @@ var PluginInstance = class {
2140
2260
  }
2141
2261
  return result;
2142
2262
  }
2263
+ buildSymbols(fn) {
2264
+ return fn ? fn(this) : {};
2265
+ }
2143
2266
  forEachError(error, event) {
2144
2267
  const originalError = error instanceof Error ? error : new Error(String(error));
2145
2268
  throw new HeyApiError({
@@ -2264,10 +2387,11 @@ var Context = class {
2264
2387
  api: plugin.api,
2265
2388
  config: plugin.config,
2266
2389
  context: this,
2267
- dependencies: plugin.dependencies ?? [],
2390
+ dependencies: plugin.dependencies ?? /* @__PURE__ */ new Set(),
2268
2391
  gen: this.gen,
2269
2392
  handler: plugin.handler,
2270
- name: plugin.name
2393
+ name: plugin.name,
2394
+ symbols: plugin.symbols
2271
2395
  });
2272
2396
  this.plugins[instance.name] = instance;
2273
2397
  return instance;
@@ -2601,8 +2725,9 @@ function hasFilters(config) {
2601
2725
  function collectOperations({ filters, parameters, requestBodies, resourceMetadata, responses, schemas }) {
2602
2726
  const finalSet = /* @__PURE__ */ new Set();
2603
2727
  const stack = [...filters.operations.include.size ? filters.operations.include : new Set(resourceMetadata.operations.keys())];
2604
- while (stack.length) {
2605
- const key = stack.pop();
2728
+ let index = 0;
2729
+ while (index < stack.length) {
2730
+ const key = stack[index++];
2606
2731
  if (filters.operations.exclude.has(key) || finalSet.has(key)) continue;
2607
2732
  const node = resourceMetadata.operations.get(key);
2608
2733
  if (!node) continue;
@@ -2633,8 +2758,9 @@ function collectOperations({ filters, parameters, requestBodies, resourceMetadat
2633
2758
  function collectParameters({ filters, resourceMetadata, schemas }) {
2634
2759
  const finalSet = /* @__PURE__ */ new Set();
2635
2760
  const stack = [...filters.parameters.include.size ? filters.parameters.include : new Set(resourceMetadata.parameters.keys())];
2636
- while (stack.length) {
2637
- const key = stack.pop();
2761
+ let index = 0;
2762
+ while (index < stack.length) {
2763
+ const key = stack[index++];
2638
2764
  if (filters.parameters.exclude.has(key) || finalSet.has(key)) continue;
2639
2765
  const node = resourceMetadata.parameters.get(key);
2640
2766
  if (!node) continue;
@@ -2663,8 +2789,9 @@ function collectParameters({ filters, resourceMetadata, schemas }) {
2663
2789
  function collectRequestBodies({ filters, resourceMetadata, schemas }) {
2664
2790
  const finalSet = /* @__PURE__ */ new Set();
2665
2791
  const stack = [...filters.requestBodies.include.size ? filters.requestBodies.include : new Set(resourceMetadata.requestBodies.keys())];
2666
- while (stack.length) {
2667
- const key = stack.pop();
2792
+ let index = 0;
2793
+ while (index < stack.length) {
2794
+ const key = stack[index++];
2668
2795
  if (filters.requestBodies.exclude.has(key) || finalSet.has(key)) continue;
2669
2796
  const node = resourceMetadata.requestBodies.get(key);
2670
2797
  if (!node) continue;
@@ -2693,8 +2820,9 @@ function collectRequestBodies({ filters, resourceMetadata, schemas }) {
2693
2820
  function collectResponses({ filters, resourceMetadata, schemas }) {
2694
2821
  const finalSet = /* @__PURE__ */ new Set();
2695
2822
  const stack = [...filters.responses.include.size ? filters.responses.include : new Set(resourceMetadata.responses.keys())];
2696
- while (stack.length) {
2697
- const key = stack.pop();
2823
+ let index = 0;
2824
+ while (index < stack.length) {
2825
+ const key = stack[index++];
2698
2826
  if (filters.responses.exclude.has(key) || finalSet.has(key)) continue;
2699
2827
  const node = resourceMetadata.responses.get(key);
2700
2828
  if (!node) continue;
@@ -2723,8 +2851,9 @@ function collectResponses({ filters, resourceMetadata, schemas }) {
2723
2851
  function collectSchemas({ filters, resourceMetadata }) {
2724
2852
  const finalSet = /* @__PURE__ */ new Set();
2725
2853
  const stack = [...filters.schemas.include.size ? filters.schemas.include : new Set(resourceMetadata.schemas.keys())];
2726
- while (stack.length) {
2727
- const key = stack.pop();
2854
+ let index = 0;
2855
+ while (index < stack.length) {
2856
+ const key = stack[index++];
2728
2857
  if (filters.schemas.exclude.has(key) || finalSet.has(key)) continue;
2729
2858
  const node = resourceMetadata.schemas.get(key);
2730
2859
  if (!node) continue;
@@ -2836,8 +2965,9 @@ function collectExplicitDependencies({ filters, resourceMetadata }) {
2836
2965
  function collectOperationDependencies({ operations, resourceMetadata }) {
2837
2966
  const finalSet = /* @__PURE__ */ new Set();
2838
2967
  const stack = [...new Set([...operations].flatMap((key) => [...resourceMetadata.operations.get(key)?.dependencies ?? []]))];
2839
- while (stack.length) {
2840
- const key = stack.pop();
2968
+ let index = 0;
2969
+ while (index < stack.length) {
2970
+ const key = stack[index++];
2841
2971
  if (finalSet.has(key)) continue;
2842
2972
  finalSet.add(key);
2843
2973
  const dependencies = getResourceDependencies(key, resourceMetadata);
@@ -4170,6 +4300,47 @@ const mergeParametersObjects = ({ source, target }) => {
4170
4300
  return result;
4171
4301
  };
4172
4302
  //#endregion
4303
+ //#region src/openApi/shared/utils/security.ts
4304
+ function securitySchemeSignature(scheme) {
4305
+ switch (scheme.type) {
4306
+ case "apiKey":
4307
+ if (!scheme.in || !scheme.name) return;
4308
+ if (scheme.in !== "header" && scheme.in !== "query" && scheme.in !== "cookie") return;
4309
+ return `apiKey:${scheme.in}:${scheme.name}`;
4310
+ case "basic": return "http:basic";
4311
+ case "http": {
4312
+ const httpScheme = (scheme.scheme ?? "").toLowerCase();
4313
+ if (httpScheme !== "bearer" && httpScheme !== "basic") return;
4314
+ return `http:${httpScheme}`;
4315
+ }
4316
+ case "oauth2":
4317
+ case "openIdConnect": return "http:bearer";
4318
+ default: return;
4319
+ }
4320
+ }
4321
+ /**
4322
+ * Build the set of security keys whose canonical signature collides
4323
+ * with another scheme. Only these keys should have their name preserved
4324
+ * on the IR `key` field — schemes with unique signatures don't need
4325
+ * disambiguation at runtime.
4326
+ */
4327
+ function computeAmbiguousSecurityKeys(schemes) {
4328
+ const buckets = /* @__PURE__ */ new Map();
4329
+ for (const [name, scheme] of schemes) {
4330
+ const signature = securitySchemeSignature(scheme);
4331
+ if (!signature) continue;
4332
+ const bucket = buckets.get(signature) ?? [];
4333
+ bucket.push(name);
4334
+ buckets.set(signature, bucket);
4335
+ }
4336
+ const ambiguous = /* @__PURE__ */ new Set();
4337
+ for (const bucket of buckets.values()) {
4338
+ if (bucket.length < 2) continue;
4339
+ for (const name of bucket) ambiguous.add(name);
4340
+ }
4341
+ return ambiguous;
4342
+ }
4343
+ //#endregion
4173
4344
  //#region src/openApi/shared/utils/validator.ts
4174
4345
  const isSimpleKey = (key) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
4175
4346
  const formatPath = (path) => path.map((segment, i) => {
@@ -4805,13 +4976,13 @@ const paginationField$2 = ({ context, name, schema }) => {
4805
4976
  };
4806
4977
  //#endregion
4807
4978
  //#region src/openApi/2.0.x/parser/operation.ts
4808
- const parseOperationJsDoc$2 = ({ irOperation, operation }) => {
4979
+ function parseOperationJsDoc$2({ irOperation, operation }) {
4809
4980
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
4810
4981
  if (operation.description) irOperation.description = operation.description;
4811
4982
  if (operation.summary) irOperation.summary = operation.summary;
4812
4983
  if (operation.tags?.length) irOperation.tags = operation.tags;
4813
- };
4814
- const initIrOperation$2 = ({ context, method, operation, path, state }) => {
4984
+ }
4985
+ function initIrOperation$2({ context, method, operation, path, state }) {
4815
4986
  const irOperation = {
4816
4987
  id: operationToId({
4817
4988
  context,
@@ -4833,8 +5004,8 @@ const initIrOperation$2 = ({ context, method, operation, path, state }) => {
4833
5004
  target: irOperation
4834
5005
  });
4835
5006
  return irOperation;
4836
- };
4837
- const operationToIrOperation$2 = ({ context, method, operation, path, securitySchemesMap, state }) => {
5007
+ }
5008
+ function operationToIrOperation$2({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
4838
5009
  const irOperation = initIrOperation$2({
4839
5010
  context,
4840
5011
  method,
@@ -4990,16 +5161,18 @@ const operationToIrOperation$2 = ({ context, method, operation, path, securitySc
4990
5161
  }
4991
5162
  }
4992
5163
  if (!irSecuritySchemeObject) continue;
5164
+ if (ambiguousSecurityKeys.has(name)) irSecuritySchemeObject.key = name;
4993
5165
  securitySchemeObjects.set(name, irSecuritySchemeObject);
4994
5166
  }
4995
5167
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
4996
5168
  }
4997
5169
  return irOperation;
4998
- };
4999
- const parsePathOperation$2 = ({ context, method, operation, path, securitySchemesMap, state }) => {
5170
+ }
5171
+ function parsePathOperation$2({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
5000
5172
  if (!context.ir.paths) context.ir.paths = {};
5001
5173
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
5002
5174
  context.ir.paths[path][method] = operationToIrOperation$2({
5175
+ ambiguousSecurityKeys,
5003
5176
  context,
5004
5177
  method,
5005
5178
  operation,
@@ -5007,7 +5180,7 @@ const parsePathOperation$2 = ({ context, method, operation, path, securityScheme
5007
5180
  securitySchemesMap,
5008
5181
  state
5009
5182
  });
5010
- };
5183
+ }
5011
5184
  //#endregion
5012
5185
  //#region src/openApi/2.0.x/parser/parameter.ts
5013
5186
  /**
@@ -5206,6 +5379,7 @@ const parseV2_0_X = (context) => {
5206
5379
  const securitySchemeObject = context.spec.securityDefinitions[name];
5207
5380
  securitySchemesMap.set(name, securitySchemeObject);
5208
5381
  }
5382
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
5209
5383
  if (context.spec.definitions) for (const name in context.spec.definitions) {
5210
5384
  const $ref = pathToJsonPointer(["definitions", name]);
5211
5385
  const schema = context.spec.definitions[name];
@@ -5230,6 +5404,7 @@ const parseV2_0_X = (context) => {
5230
5404
  security: context.spec.security
5231
5405
  };
5232
5406
  const operationArgs = {
5407
+ ambiguousSecurityKeys,
5233
5408
  context,
5234
5409
  operation: {
5235
5410
  ...commonOperation,
@@ -6182,13 +6357,13 @@ const paginationField$1 = ({ context, name, schema }) => {
6182
6357
  };
6183
6358
  //#endregion
6184
6359
  //#region src/openApi/3.0.x/parser/operation.ts
6185
- const parseOperationJsDoc$1 = ({ irOperation, operation }) => {
6360
+ function parseOperationJsDoc$1({ irOperation, operation }) {
6186
6361
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
6187
6362
  if (operation.description) irOperation.description = operation.description;
6188
6363
  if (operation.summary) irOperation.summary = operation.summary;
6189
6364
  if (operation.tags?.length) irOperation.tags = operation.tags;
6190
- };
6191
- const initIrOperation$1 = ({ context, method, operation, path, state }) => {
6365
+ }
6366
+ function initIrOperation$1({ context, method, operation, path, state }) {
6192
6367
  const irOperation = {
6193
6368
  id: operationToId({
6194
6369
  context,
@@ -6210,8 +6385,8 @@ const initIrOperation$1 = ({ context, method, operation, path, state }) => {
6210
6385
  target: irOperation
6211
6386
  });
6212
6387
  return irOperation;
6213
- };
6214
- const operationToIrOperation$1 = ({ context, method, operation, path, securitySchemesMap, state }) => {
6388
+ }
6389
+ function operationToIrOperation$1({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
6215
6390
  const irOperation = initIrOperation$1({
6216
6391
  context,
6217
6392
  method,
@@ -6286,17 +6461,19 @@ const operationToIrOperation$1 = ({ context, method, operation, path, securitySc
6286
6461
  for (const securityRequirementObject of operation.security) for (const name in securityRequirementObject) {
6287
6462
  const securitySchemeObject = securitySchemesMap.get(name);
6288
6463
  if (!securitySchemeObject) continue;
6464
+ if (ambiguousSecurityKeys.has(name)) securitySchemeObject.key = name;
6289
6465
  securitySchemeObjects.set(name, securitySchemeObject);
6290
6466
  }
6291
6467
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
6292
6468
  }
6293
6469
  return irOperation;
6294
- };
6295
- const parsePathOperation$1 = ({ context, method, operation, path, securitySchemesMap, state }) => {
6470
+ }
6471
+ function parsePathOperation$1({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
6296
6472
  if (!context.ir.paths) context.ir.paths = {};
6297
6473
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
6298
6474
  if (operation.servers) context.ir.servers = [...context.ir.servers ?? [], ...operation.servers];
6299
6475
  context.ir.paths[path][method] = operationToIrOperation$1({
6476
+ ambiguousSecurityKeys,
6300
6477
  context,
6301
6478
  method,
6302
6479
  operation,
@@ -6304,7 +6481,7 @@ const parsePathOperation$1 = ({ context, method, operation, path, securityScheme
6304
6481
  securitySchemesMap,
6305
6482
  state
6306
6483
  });
6307
- };
6484
+ }
6308
6485
  //#endregion
6309
6486
  //#region src/openApi/3.0.x/parser/parameter.ts
6310
6487
  /**
@@ -6590,6 +6767,7 @@ const parseV3_0_X = (context) => {
6590
6767
  });
6591
6768
  }
6592
6769
  }
6770
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
6593
6771
  parseServers$1({ context });
6594
6772
  for (const path in context.spec.paths) {
6595
6773
  if (path.startsWith("x-")) continue;
@@ -6599,6 +6777,7 @@ const parseV3_0_X = (context) => {
6599
6777
  ...pathItem
6600
6778
  } : pathItem;
6601
6779
  const operationArgs = {
6780
+ ambiguousSecurityKeys,
6602
6781
  context,
6603
6782
  operation: {
6604
6783
  description: finalPathItem.description,
@@ -7637,13 +7816,13 @@ const paginationField = ({ context, name, schema }) => {
7637
7816
  };
7638
7817
  //#endregion
7639
7818
  //#region src/openApi/3.1.x/parser/operation.ts
7640
- const parseOperationJsDoc = ({ irOperation, operation }) => {
7819
+ function parseOperationJsDoc({ irOperation, operation }) {
7641
7820
  if (operation.deprecated !== void 0) irOperation.deprecated = operation.deprecated;
7642
7821
  if (operation.description) irOperation.description = operation.description;
7643
7822
  if (operation.summary) irOperation.summary = operation.summary;
7644
7823
  if (operation.tags?.length) irOperation.tags = operation.tags;
7645
- };
7646
- const initIrOperation = ({ context, method, operation, path, state }) => {
7824
+ }
7825
+ function initIrOperation({ context, method, operation, path, state }) {
7647
7826
  const irOperation = {
7648
7827
  id: operationToId({
7649
7828
  context,
@@ -7665,8 +7844,8 @@ const initIrOperation = ({ context, method, operation, path, state }) => {
7665
7844
  target: irOperation
7666
7845
  });
7667
7846
  return irOperation;
7668
- };
7669
- const operationToIrOperation = ({ context, method, operation, path, securitySchemesMap, state }) => {
7847
+ }
7848
+ function operationToIrOperation({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
7670
7849
  const irOperation = initIrOperation({
7671
7850
  context,
7672
7851
  method,
@@ -7732,15 +7911,17 @@ const operationToIrOperation = ({ context, method, operation, path, securitySche
7732
7911
  for (const securityRequirementObject of operation.security) for (const name in securityRequirementObject) {
7733
7912
  const securitySchemeObject = securitySchemesMap.get(name);
7734
7913
  if (!securitySchemeObject) continue;
7914
+ if (ambiguousSecurityKeys.has(name)) securitySchemeObject.key = name;
7735
7915
  securitySchemeObjects.set(name, securitySchemeObject);
7736
7916
  }
7737
7917
  if (securitySchemeObjects.size) irOperation.security = Array.from(securitySchemeObjects.values());
7738
7918
  }
7739
7919
  return irOperation;
7740
- };
7741
- const parseOperationObject = ({ context, method, operation, path, securitySchemesMap, state }) => {
7920
+ }
7921
+ function parseOperationObject({ ambiguousSecurityKeys, context, method, operation, path, securitySchemesMap, state }) {
7742
7922
  if (operation.servers) context.ir.servers = [...context.ir.servers ?? [], ...operation.servers];
7743
7923
  return { parsed: operationToIrOperation({
7924
+ ambiguousSecurityKeys,
7744
7925
  context,
7745
7926
  method,
7746
7927
  operation,
@@ -7748,8 +7929,8 @@ const parseOperationObject = ({ context, method, operation, path, securityScheme
7748
7929
  securitySchemesMap,
7749
7930
  state
7750
7931
  }) };
7751
- };
7752
- const parsePathOperation = ({ context, method, path, ...options }) => {
7932
+ }
7933
+ function parsePathOperation({ context, method, path, ...options }) {
7753
7934
  if (!context.ir.paths) context.ir.paths = {};
7754
7935
  if (!context.ir.paths[path]) context.ir.paths[path] = {};
7755
7936
  const { parsed } = parseOperationObject({
@@ -7759,8 +7940,8 @@ const parsePathOperation = ({ context, method, path, ...options }) => {
7759
7940
  ...options
7760
7941
  });
7761
7942
  context.ir.paths[path][method] = parsed;
7762
- };
7763
- const parseWebhookOperation = ({ context, key, method, ...options }) => {
7943
+ }
7944
+ function parseWebhookOperation({ context, key, method, ...options }) {
7764
7945
  if (!context.ir.webhooks) context.ir.webhooks = {};
7765
7946
  if (!context.ir.webhooks[key]) context.ir.webhooks[key] = {};
7766
7947
  const { parsed } = parseOperationObject({
@@ -7770,7 +7951,7 @@ const parseWebhookOperation = ({ context, key, method, ...options }) => {
7770
7951
  ...options
7771
7952
  });
7772
7953
  context.ir.webhooks[key][method] = parsed;
7773
- };
7954
+ }
7774
7955
  //#endregion
7775
7956
  //#region src/openApi/3.1.x/parser/parameter.ts
7776
7957
  /**
@@ -7983,7 +8164,7 @@ const validateOpenApiSpec = (spec, logger) => {
7983
8164
  };
7984
8165
  //#endregion
7985
8166
  //#region src/openApi/3.1.x/parser/webhook.ts
7986
- const parseWebhooks = ({ context, securitySchemesMap }) => {
8167
+ function parseWebhooks({ ambiguousSecurityKeys, context, securitySchemesMap }) {
7987
8168
  const state = { ids: /* @__PURE__ */ new Map() };
7988
8169
  for (const key in context.spec.webhooks) {
7989
8170
  const webhook = context.spec.webhooks[key];
@@ -7992,6 +8173,7 @@ const parseWebhooks = ({ context, securitySchemesMap }) => {
7992
8173
  ...webhook
7993
8174
  } : webhook;
7994
8175
  const operationArgs = {
8176
+ ambiguousSecurityKeys,
7995
8177
  context,
7996
8178
  key,
7997
8179
  operation: {
@@ -8128,7 +8310,7 @@ const parseWebhooks = ({ context, securitySchemesMap }) => {
8128
8310
  }
8129
8311
  });
8130
8312
  }
8131
- };
8313
+ }
8132
8314
  //#endregion
8133
8315
  //#region src/openApi/3.1.x/parser/index.ts
8134
8316
  const parseV3_1_X = (context) => {
@@ -8200,6 +8382,7 @@ const parseV3_1_X = (context) => {
8200
8382
  });
8201
8383
  }
8202
8384
  }
8385
+ const ambiguousSecurityKeys = computeAmbiguousSecurityKeys(securitySchemesMap);
8203
8386
  parseServers({ context });
8204
8387
  for (const path in context.spec.paths) {
8205
8388
  if (path.startsWith("x-")) continue;
@@ -8209,6 +8392,7 @@ const parseV3_1_X = (context) => {
8209
8392
  ...pathItem
8210
8393
  } : pathItem;
8211
8394
  const operationArgs = {
8395
+ ambiguousSecurityKeys,
8212
8396
  context,
8213
8397
  operation: {
8214
8398
  description: finalPathItem.description,
@@ -8346,6 +8530,7 @@ const parseV3_1_X = (context) => {
8346
8530
  });
8347
8531
  }
8348
8532
  parseWebhooks({
8533
+ ambiguousSecurityKeys,
8349
8534
  context,
8350
8535
  securitySchemesMap
8351
8536
  });
@@ -8378,15 +8563,43 @@ function parseOpenApiSpec(context) {
8378
8563
  * Built-in strategies for operations.
8379
8564
  */
8380
8565
  const OperationStrategy = {
8566
+ /**
8567
+ * Creates one root container per operation tag.
8568
+ *
8569
+ * Operations with multiple tags appear in multiple root containers.
8570
+ * Operations without tags use the fallback root container.
8571
+ *
8572
+ * @example
8573
+ * // Operation with tags: ['users', 'admin']
8574
+ * // Path function returns: ['list']
8575
+ * // Result: [{ path: ['users', 'list'], shell }, { path: ['admin', 'list'], shell }]
8576
+ */
8381
8577
  byTags: (config) => (operation) => {
8382
8578
  const tags = operation.tags && operation.tags.length ? operation.tags : [config.fallback];
8383
8579
  const pathSegments = (config.path ?? OperationPath.id())(operation);
8384
8580
  return tags.map((tag) => [tag, ...pathSegments]);
8385
8581
  },
8582
+ /**
8583
+ * Creates flat functions without any container.
8584
+ *
8585
+ * Each operation becomes a standalone function at the root level.
8586
+ * No shell is applied.
8587
+ *
8588
+ * @example
8589
+ * // Operation id: 'getUsers'
8590
+ * // Result: [{ path: ['getUsers'] }]
8591
+ */
8386
8592
  flat: (config) => (operation) => {
8387
8593
  const pathSegments = (config?.path ?? OperationPath.id())(operation);
8388
8594
  return [[pathSegments[pathSegments.length - 1]]];
8389
8595
  },
8596
+ /**
8597
+ * Places all operations under a single root container.
8598
+ *
8599
+ * @example
8600
+ * // Root: 'Sdk', path function returns: ['users', 'list']
8601
+ * // Result: [{ path: ['Sdk', 'users', 'list'], shell }]
8602
+ */
8390
8603
  single: (config) => (operation) => {
8391
8604
  const pathSegments = (config.path ?? OperationPath.id())(operation);
8392
8605
  return [[config.root, ...pathSegments]];
@@ -8396,6 +8609,17 @@ const OperationStrategy = {
8396
8609
  * Built-in path derivation helpers for operations.
8397
8610
  */
8398
8611
  const OperationPath = {
8612
+ /**
8613
+ * Splits operationId by delimiters to create nested paths.
8614
+ *
8615
+ * @example
8616
+ * // operationId: 'users.accounts.list'
8617
+ * // Result: ['users', 'accounts', 'list']
8618
+ *
8619
+ * @example
8620
+ * // operationId: 'users/accounts/getAll'
8621
+ * // Result: ['users', 'accounts', 'getAll']
8622
+ */
8399
8623
  fromOperationId: (config) => (operation) => {
8400
8624
  const fallback = config?.fallback ?? OperationPath.id();
8401
8625
  if (!operation.operationId) return fallback(operation);
@@ -8403,6 +8627,23 @@ const OperationPath = {
8403
8627
  const segments = operation.operationId.split(delimiters).filter(Boolean);
8404
8628
  return !segments.length ? fallback(operation) : segments;
8405
8629
  },
8630
+ /**
8631
+ * Splits path by delimiters to create nested paths.
8632
+ *
8633
+ * Can include the method as a prefix or suffix segment.
8634
+ *
8635
+ * @example
8636
+ * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'none'
8637
+ * // Result: ['users', 'id', 'accounts']
8638
+ *
8639
+ * @example
8640
+ * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'prefix'
8641
+ * // Result: ['get', 'users', 'id', 'accounts']
8642
+ *
8643
+ * @example
8644
+ * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'suffix'
8645
+ * // Result: ['users', 'id', 'accounts', 'get']
8646
+ */
8406
8647
  fromPath: (config) => (operation) => {
8407
8648
  const delimiters = config?.delimiters ?? /[./]/;
8408
8649
  const segments = operation.path.split(delimiters).filter(Boolean);
@@ -8417,6 +8658,13 @@ const OperationPath = {
8417
8658
  }
8418
8659
  return segments;
8419
8660
  },
8661
+ /**
8662
+ * Uses operation.id as a single path segment.
8663
+ *
8664
+ * @example
8665
+ * // operation.id: 'getUserById'
8666
+ * // Result: ['getUserById']
8667
+ */
8420
8668
  id: () => (operation) => [operation.id]
8421
8669
  };
8422
8670
  //#endregion
@@ -8559,31 +8807,22 @@ function warnOnConflictingDuplicatePlugins(plugins) {
8559
8807
  }
8560
8808
  //#endregion
8561
8809
  //#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
- };
8810
+ function definePluginConfig(pluginConfig) {
8811
+ return (userConfig) => ({
8812
+ ...pluginConfig,
8813
+ config: {
8814
+ ...pluginConfig.config,
8815
+ ...userConfig ?? {}
8816
+ },
8817
+ /**
8818
+ * Cast name to `any` so it doesn't throw type error in `plugins` array.
8819
+ * We could allow any `string` as plugin `name` in the object syntax, but
8820
+ * that TypeScript trick would cause all string methods to appear as
8821
+ * suggested auto completions, which is undesirable.
8822
+ */
8823
+ name: pluginConfig.name
8824
+ });
8825
+ }
8587
8826
  //#endregion
8588
8827
  //#region src/plugins/symbol.ts
8589
8828
  /**
@@ -8647,9 +8886,15 @@ function escapeComment(value) {
8647
8886
  * Utilities shared across the package.
8648
8887
  */
8649
8888
  const utils = {
8889
+ /**
8890
+ * @deprecated use `toCase` instead
8891
+ */
8650
8892
  stringCase({ case: casing, stripLeadingSeparators, value }) {
8651
8893
  return toCase(value, casing, { stripLeadingSeparators });
8652
8894
  },
8895
+ /**
8896
+ * Converts the given string to the specified casing.
8897
+ */
8653
8898
  toCase
8654
8899
  };
8655
8900
  //#endregion
@@ -8773,6 +9018,6 @@ function pathToName(path, options) {
8773
9018
  return names.join("-");
8774
9019
  }
8775
9020
  //#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 };
9021
+ 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
9022
 
8778
9023
  //# sourceMappingURL=index.mjs.map