@route-forge/core 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,12 +64,28 @@ var RouteForge = (function (exports) {
64
64
  }
65
65
  return entry;
66
66
  }
67
- set(resp) {
67
+ /**
68
+ * 写入某层级缓存。后端 TTL 唯一来源为摘要 config.cache_ttl(全局),经参数 backendTtl 传入:
69
+ * - null → 后端声明"不缓存":不写 storage,仅留内存镜像供 route() 同步读(load 层"每次重取"由调用方跳过 get 短路实现)
70
+ * - 0 → 永久缓存(内存 + storage)
71
+ * - undefined → 后端未下发该字段:用前端兜底 TTL(options.cache.ttl)
72
+ * - 正整数 → min(后端, 前端兜底):后端为上限,前端只能缩短不能延长(SPEC §5.3)
73
+ */
74
+ set(resp, backendTtl) {
68
75
  let ttl;
69
- if (resp.cache !== void 0 && resp.cache !== null) {
70
- ttl = resp.cache > 0 ? Math.min(resp.cache, this.fallbackTtl) : resp.cache;
71
- } else {
76
+ let persist;
77
+ if (backendTtl === null) {
78
+ ttl = 0;
79
+ persist = false;
80
+ } else if (backendTtl === void 0) {
72
81
  ttl = this.fallbackTtl;
82
+ persist = true;
83
+ } else if (backendTtl === 0) {
84
+ ttl = 0;
85
+ persist = true;
86
+ } else {
87
+ ttl = Math.min(backendTtl, this.fallbackTtl);
88
+ persist = true;
73
89
  }
74
90
  const entry = {
75
91
  level: resp.level,
@@ -78,7 +94,7 @@ var RouteForge = (function (exports) {
78
94
  cachedAt: Date.now()
79
95
  };
80
96
  this.memory.set(resp.level, entry);
81
- if (this.storage === "memory" || !this.backend) {
97
+ if (!persist || this.storage === "memory" || !this.backend) {
82
98
  return;
83
99
  }
84
100
  try {
@@ -491,39 +507,6 @@ var RouteForge = (function (exports) {
491
507
  return createBuiltinHttp(opts.forgeInterceptors);
492
508
  }
493
509
 
494
- // src/resolveRouteName.ts
495
- async function resolveRouteName(forge, level, prefix, suffix, separator = ".") {
496
- if (!suffix) return prefix;
497
- const joined = `${prefix}${separator}${suffix}`;
498
- if (!suffix.startsWith(`${prefix}${separator}`)) return joined;
499
- await forge.load(level);
500
- if (forge.hasRoute(level, joined)) return joined;
501
- if (forge.hasRoute(level, suffix)) return suffix;
502
- throw new UnknownRouteError(joined, level);
503
- }
504
- function resolveRouteNameSync(forge, level, prefix, suffix, separator = ".") {
505
- if (!suffix) return prefix;
506
- const joined = `${prefix}${separator}${suffix}`;
507
- if (!suffix.startsWith(`${prefix}${separator}`)) return joined;
508
- if (forge.hasRoute(level, joined)) return joined;
509
- if (forge.hasRoute(level, suffix)) return suffix;
510
- throw new UnknownRouteError(joined, level);
511
- }
512
-
513
- // src/defineImmutableProps.ts
514
- function defineImmutableProps(target, props) {
515
- for (const key of Object.keys(props)) {
516
- const val = props[key];
517
- Object.defineProperty(target, key, {
518
- value: val !== null && typeof val === "object" ? Object.freeze(val) : val,
519
- writable: false,
520
- enumerable: false,
521
- configurable: false
522
- });
523
- }
524
- return target;
525
- }
526
-
527
510
  // src/loading.ts
528
511
  var LoadingTracker = class {
529
512
  constructor() {
@@ -583,328 +566,333 @@ var RouteForge = (function (exports) {
583
566
  }
584
567
  };
585
568
 
586
- // src/forge.ts
587
- var DEFAULT_TIMEOUT = 3e4;
588
- var DEFAULT_CACHE_TTL = 3600;
589
- var UNASSIGNED_LEVEL = "unassigned";
590
- function createRouteForge(options) {
591
- if (!options.endpoint) throw new TypeError("options.endpoint is required");
592
- const {
593
- adapter = "auto",
594
- timeout = DEFAULT_TIMEOUT,
595
- baseURL = "",
596
- interceptors: declarativeInterceptors,
597
- cache: cacheOpts = {}
598
- } = options;
599
- const loadingTracker = new LoadingTracker();
600
- const explicitLevels = options.levels;
601
- const explicitEager = options.eager;
602
- const explicitEndpoint = options.endpoint;
603
- let effectiveLevels = explicitLevels ?? [];
604
- let effectiveEager = explicitEager ?? [];
605
- let effectiveEndpoint = explicitEndpoint;
606
- let effectiveUrlPrefix = "";
607
- let summaryUnassigned;
608
- let backendHasUnassignedLevel = false;
609
- const fetchSummary = async () => {
610
- try {
611
- const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
612
- const ep = explicitEndpoint.startsWith("/") ? explicitEndpoint : `/${explicitEndpoint}`;
613
- const data = await fetchMeta("__forge__.summary", `${base}${ep}`);
614
- return data;
615
- } catch (e) {
616
- if (explicitLevels && explicitLevels.length > 0) {
617
- console.warn(
618
- `[route-forge] summary endpoint unreachable: ${e.message}; using explicit levels`
619
- );
620
- return null;
621
- }
622
- throw new UnknownLevelError("(auto-discovery)");
623
- }
624
- };
625
- let summaryPromise;
626
- const summaryWaiters = [];
627
- const whenSummary = () => summaryPromise ?? new Promise((resolve) => summaryWaiters.push(resolve));
628
- const autoDiscoveryPromise = whenSummary().then((summary) => {
629
- if (summary === null) {
630
- return;
631
- }
632
- const schemaVersion = summary.schemaVersion ?? 1;
633
- if (schemaVersion > 1) {
634
- console.warn(
635
- `[route-forge] backend schemaVersion=${schemaVersion} > client supported 1; some features may be unavailable`
636
- );
637
- }
638
- if (summary.config.endpoint_prefix && summary.config.endpoint_prefix !== explicitEndpoint) {
639
- console.warn(
640
- `[route-forge] backend endpoint_prefix "${summary.config.endpoint_prefix}" overrides frontend endpoint "${explicitEndpoint}"`
641
- );
642
- effectiveEndpoint = summary.config.endpoint_prefix;
643
- }
644
- if (summary.config.url_prefix) {
645
- effectiveUrlPrefix = summary.config.url_prefix.endsWith("/") ? summary.config.url_prefix.slice(0, -1) : summary.config.url_prefix;
646
- }
647
- const backendLevels = Object.keys(summary.levels);
648
- backendHasUnassignedLevel = backendLevels.includes(UNASSIGNED_LEVEL);
649
- if (Array.isArray(summary.unassigned) && summary.unassigned.length > 0 && !backendHasUnassignedLevel) {
650
- summaryUnassigned = summary.unassigned;
651
- }
652
- const availableLevels = backendLevels.slice();
653
- if (summaryUnassigned && !backendHasUnassignedLevel) {
654
- availableLevels.push(UNASSIGNED_LEVEL);
569
+ // src/url-builder.ts
570
+ function buildUrl(level, ctx) {
571
+ const base = ctx.baseURL.endsWith("/") ? ctx.baseURL.slice(0, -1) : ctx.baseURL;
572
+ const ep = ctx.endpoint.startsWith("/") ? ctx.endpoint : `/${ctx.endpoint}`;
573
+ return `${base}${ep}/${encodeURIComponent(level)}`;
574
+ }
575
+ function buildRequestUrl(meta, params, ctx) {
576
+ const defaults = meta.parameter_defaults ?? {};
577
+ const missingRequired = [];
578
+ const values = {};
579
+ for (const p of meta.parameters) {
580
+ let v = params[p];
581
+ if ((v === void 0 || v === null) && p in defaults) {
582
+ v = defaults[p];
655
583
  }
656
- if (explicitLevels && explicitLevels.length > 0) {
657
- const intersection = explicitLevels.filter((l) => availableLevels.includes(l));
658
- const removed = explicitLevels.filter((l) => !availableLevels.includes(l));
659
- if (removed.length > 0) {
660
- console.warn(
661
- `[route-forge] levels not in backend summary and dropped: ${removed.join(", ")}`
662
- );
584
+ if (v === void 0 || v === null) {
585
+ if (!meta.uri.includes(`{${p}?}`)) {
586
+ missingRequired.push(p);
663
587
  }
664
- effectiveLevels = intersection;
665
588
  } else {
666
- effectiveLevels = availableLevels;
589
+ values[p] = v;
667
590
  }
668
- const backendEager = backendLevels.filter((lvl) => summary.levels[lvl]?.load === "eager");
669
- if (!explicitEager) {
670
- effectiveEager = backendEager;
671
- } else {
672
- const union = /* @__PURE__ */ new Set([...backendEager, ...explicitEager]);
673
- effectiveEager = [...union];
591
+ }
592
+ if (missingRequired.length > 0) {
593
+ throw new MissingRouteParamError(meta.name, missingRequired);
594
+ }
595
+ let uri = meta.uri.replace(/\{([^{}]+)\}/g, (match, raw) => {
596
+ const optional = raw.endsWith("?");
597
+ const name = optional ? raw.slice(0, -1) : raw;
598
+ if (values[name] !== void 0) {
599
+ const val = values[name];
600
+ if (typeof val === "object") {
601
+ throw new ForgeError(
602
+ `Path parameter "${name}" must be a primitive value (string, number, boolean), got ${typeof val}`,
603
+ { code: "RF_FE_003", route: meta.name, context: { param: name, value: val } }
604
+ );
605
+ }
606
+ return encodeURIComponent(String(val));
674
607
  }
608
+ return optional ? "" : match;
675
609
  });
676
- let autoDiscoveryError = null;
677
- autoDiscoveryPromise.catch((e) => {
678
- autoDiscoveryError = e;
679
- });
680
- let autoDiscoveryCompleted = false;
681
- let resolveReady;
682
- let rejectReady;
683
- const readyPromise = new Promise((resolve, reject) => {
684
- resolveReady = resolve;
685
- rejectReady = reject;
686
- });
687
- readyPromise.catch(() => {
688
- });
689
- const cacheTtl = cacheOpts.ttl ?? DEFAULT_CACHE_TTL;
690
- const cacheStorage = cacheOpts.storage ?? "memory";
691
- const cache = new RouteCache({ storage: cacheStorage, ttl: cacheTtl });
692
- const requestInterceptors = new InterceptorManagerImpl();
693
- const responseInterceptors = new InterceptorManagerImpl();
694
- if (declarativeInterceptors?.request) {
695
- for (const entry of declarativeInterceptors.request) {
696
- if (typeof entry === "function") {
697
- requestInterceptors.use(entry);
698
- } else {
699
- const [onFulfilled, onRejected] = entry;
700
- requestInterceptors.use(onFulfilled, onRejected);
701
- }
610
+ uri = uri.replace(/\/+/g, "/").replace(/\/$/, "");
611
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(ctx.urlPrefix)) {
612
+ const prefix2 = ctx.urlPrefix.endsWith("/") ? ctx.urlPrefix.slice(0, -1) : ctx.urlPrefix;
613
+ return uri.startsWith("/") ? `${prefix2}${uri}` : `${prefix2}/${uri}`;
614
+ }
615
+ const base = ctx.baseURL.endsWith("/") ? ctx.baseURL.slice(0, -1) : ctx.baseURL;
616
+ const prefix = ctx.urlPrefix;
617
+ return uri.startsWith("/") ? `${base}${prefix}${uri}` : `${base}${prefix}/${uri}`;
618
+ }
619
+ function pickMethod(meta) {
620
+ const m = meta.methods.find((x) => x.toUpperCase() !== "HEAD");
621
+ return (m ?? meta.methods[0] ?? "GET").toUpperCase();
622
+ }
623
+ function appendQuery(url, query) {
624
+ if (!query) return url;
625
+ const usp = new URLSearchParams();
626
+ for (const [k, v] of Object.entries(query)) {
627
+ if (v === void 0 || v === null) continue;
628
+ usp.append(k, String(v));
629
+ }
630
+ const qs = usp.toString();
631
+ if (!qs) return url;
632
+ return url.includes("?") ? `${url}&${qs}` : `${url}?${qs}`;
633
+ }
634
+ function resolveApiParams(input) {
635
+ const {
636
+ params: explicitParams,
637
+ query: rawQuery,
638
+ body: rawBody,
639
+ headers: rawHeaders,
640
+ timeout: perCallTimeout,
641
+ ...flatRest
642
+ } = input;
643
+ const pathParams = explicitParams ? { ...explicitParams } : {};
644
+ for (const [k, v] of Object.entries(flatRest)) {
645
+ if (!(k in pathParams)) {
646
+ pathParams[k] = v;
702
647
  }
703
648
  }
704
- if (declarativeInterceptors?.response) {
705
- for (const entry of declarativeInterceptors.response) {
706
- if (typeof entry === "function") {
707
- responseInterceptors.use(entry);
708
- } else {
709
- const [onFulfilled, onRejected] = entry;
710
- responseInterceptors.use(onFulfilled, onRejected);
711
- }
649
+ let query;
650
+ let body;
651
+ let headers;
652
+ if (rawQuery !== void 0) {
653
+ if (typeof rawQuery === "object" && rawQuery !== null) {
654
+ query = rawQuery;
655
+ } else if (!("query" in pathParams)) {
656
+ pathParams.query = rawQuery;
712
657
  }
713
658
  }
714
- const adapterPromise = resolveAdapter({
715
- adapter,
716
- forgeInterceptors: { request: requestInterceptors, response: responseInterceptors }
717
- });
718
- Promise.resolve().then(() => {
719
- summaryPromise = fetchSummary();
720
- for (const resolve of summaryWaiters) resolve(summaryPromise);
721
- });
722
- let adapterResolved = false;
723
- let adapterObj = null;
724
- async function ensureAdapter() {
725
- if (!adapterResolved) {
726
- adapterObj = await adapterPromise.catch((e) => {
727
- if (e instanceof AdapterNotFoundError) throw e;
728
- return resolveAdapter({
729
- adapter: "builtin",
730
- forgeInterceptors: { request: requestInterceptors, response: responseInterceptors }
731
- });
732
- });
733
- adapterResolved = true;
659
+ if (rawBody !== void 0) {
660
+ if (typeof rawBody !== "string" && typeof rawBody !== "number") {
661
+ body = rawBody;
662
+ } else if (!("body" in pathParams)) {
663
+ pathParams.body = rawBody;
734
664
  }
735
- return adapterObj;
736
665
  }
737
- const inflight = /* @__PURE__ */ new Map();
738
- const invalidationGens = /* @__PURE__ */ new Map();
739
- function assertLevelDeclared(level) {
740
- if (!effectiveLevels.includes(level)) {
741
- throw new UnknownLevelError(level);
666
+ if (rawHeaders !== void 0) {
667
+ if (typeof rawHeaders === "object" && rawHeaders !== null) {
668
+ headers = rawHeaders;
669
+ } else if (!("headers" in pathParams)) {
670
+ pathParams.headers = rawHeaders;
742
671
  }
743
672
  }
744
- function assertDiscoveryReady() {
745
- if (!autoDiscoveryCompleted && !explicitLevels?.length) {
746
- throw new ForgeError(
747
- "Route data not available. Auto-discovery has not completed. Use forge.ready() or forge.use(level) first.",
748
- { code: "RF_FE_010" }
673
+ return { pathParams, query, body, headers, timeout: perCallTimeout };
674
+ }
675
+
676
+ // src/auto-discovery.ts
677
+ async function fetchSummary(inputs, baseURL, fetchMeta) {
678
+ const { explicitLevels, explicitEndpoint } = inputs;
679
+ if (!explicitEndpoint) {
680
+ throw new UnknownLevelError("(auto-discovery)");
681
+ }
682
+ try {
683
+ const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
684
+ const ep = explicitEndpoint.startsWith("/") ? explicitEndpoint : `/${explicitEndpoint}`;
685
+ const data = await fetchMeta("__forge__.summary", `${base}${ep}`);
686
+ return data;
687
+ } catch (e) {
688
+ if (explicitLevels && explicitLevels.length > 0) {
689
+ console.warn(
690
+ `[route-forge] summary endpoint unreachable: ${e.message}; using explicit levels`
749
691
  );
692
+ return null;
750
693
  }
694
+ throw new UnknownLevelError("(auto-discovery)");
751
695
  }
752
- function buildUrl(level) {
753
- const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
754
- const ep = effectiveEndpoint.startsWith("/") ? effectiveEndpoint : `/${effectiveEndpoint}`;
755
- return `${base}${ep}/${encodeURIComponent(level)}`;
696
+ }
697
+ function normalizeCacheTtl(raw) {
698
+ if (typeof raw === "number" && raw < 0) return null;
699
+ return raw;
700
+ }
701
+ function applySummaryToState(summary, state, inputs) {
702
+ const { explicitLevels, explicitEager, explicitEndpoint } = inputs;
703
+ const schemeVersion = summary.schemeVersion ?? 1;
704
+ if (schemeVersion > 1) {
705
+ console.warn(
706
+ `[route-forge] backend schemeVersion=${schemeVersion} > client supported 1; some features may be unavailable`
707
+ );
756
708
  }
757
- async function fetchMeta(routeTag, url, level = "") {
758
- const adp = await ensureAdapter();
759
- const config = {
760
- route: routeTag,
761
- level,
762
- method: "GET",
763
- url,
764
- headers: { Accept: "application/json" },
765
- params: {},
766
- timeout,
767
- meta: {
768
- name: routeTag,
769
- uri: url,
770
- methods: ["GET"],
771
- parameters: [],
772
- level
773
- }
774
- };
775
- const doRawRequest = adp.requestRaw ?? adp.request;
776
- const resp = await doRawRequest(config);
777
- if (!resp || resp.status < 200 || resp.status >= 300) {
778
- throw new HTTPError(
779
- `Failed to fetch "${routeTag}": HTTP ${resp?.status}`,
780
- { level, status: resp?.status, url, method: "GET" }
709
+ if (summary.config.endpoint_prefix && summary.config.endpoint_prefix !== explicitEndpoint) {
710
+ if (explicitEndpoint) {
711
+ console.warn(
712
+ `[route-forge] backend endpoint_prefix "${summary.config.endpoint_prefix}" overrides frontend endpoint "${explicitEndpoint}"`
781
713
  );
782
714
  }
783
- return resp.data;
715
+ state.endpoint = summary.config.endpoint_prefix;
716
+ }
717
+ if (summary.config.url_prefix) {
718
+ state.urlPrefix = summary.config.url_prefix.endsWith("/") ? summary.config.url_prefix.slice(0, -1) : summary.config.url_prefix;
719
+ }
720
+ state.cacheTtl = normalizeCacheTtl(summary.config.cache_ttl);
721
+ const backendLevels = Object.keys(summary.levels);
722
+ const levelRoutes = {};
723
+ for (const lvl of backendLevels) {
724
+ const r = summary.levels[lvl]?.route;
725
+ if (r && typeof r.uri === "string") {
726
+ levelRoutes[lvl] = { uri: r.uri, methods: r.methods ?? ["GET", "HEAD"] };
727
+ }
728
+ }
729
+ state.levelRoutes = levelRoutes;
730
+ if (explicitLevels && explicitLevels.length > 0) {
731
+ const intersection = explicitLevels.filter((l) => backendLevels.includes(l));
732
+ const removed = explicitLevels.filter((l) => !backendLevels.includes(l));
733
+ if (removed.length > 0) {
734
+ console.warn(
735
+ `[route-forge] levels not in backend summary and dropped: ${removed.join(", ")}`
736
+ );
737
+ }
738
+ state.levels = intersection;
739
+ } else {
740
+ state.levels = backendLevels.slice();
741
+ }
742
+ const backendEager = backendLevels.filter((lvl) => summary.levels[lvl]?.load === "eager");
743
+ if (!explicitEager) {
744
+ state.eager = backendEager;
745
+ } else {
746
+ const union = /* @__PURE__ */ new Set([...backendEager, ...explicitEager]);
747
+ state.eager = [...union];
748
+ }
749
+ }
750
+
751
+ // src/embedded-summary.ts
752
+ var EMBEDDED_GLOBAL_KEY = "__ROUTE_FORGE__";
753
+ var memo;
754
+ function readEmbeddedSummary() {
755
+ if (memo !== void 0) return memo;
756
+ if (typeof window === "undefined") {
757
+ memo = null;
758
+ return null;
759
+ }
760
+ let raw;
761
+ try {
762
+ raw = window[EMBEDDED_GLOBAL_KEY];
763
+ } catch {
764
+ raw = void 0;
765
+ }
766
+ memo = raw !== null && typeof raw === "object" ? raw : null;
767
+ return memo;
768
+ }
769
+
770
+ // src/route-store.ts
771
+ var RouteStore = class {
772
+ constructor(deps) {
773
+ this.inflight = /* @__PURE__ */ new Map();
774
+ /** 每个层级的失效代数,用于检测 loadOne 期间是否发生了 invalidate */
775
+ this.invalidationGens = /* @__PURE__ */ new Map();
776
+ this.cache = deps.cache;
777
+ this.state = deps.state;
778
+ this.baseURL = deps.baseURL;
779
+ this.fetchMeta = deps.fetchMeta;
780
+ this.autoDiscoveryPromise = deps.autoDiscoveryPromise;
781
+ this.getAutoDiscoveryError = deps.getAutoDiscoveryError;
782
+ }
783
+ assertLevelDeclared(level) {
784
+ if (!this.state.levels.includes(level)) {
785
+ throw new UnknownLevelError(level);
786
+ }
784
787
  }
785
- async function fetchLevel(level) {
786
- return await fetchMeta(`__forge__.load.${level}`, buildUrl(level), level);
788
+ async fetchLevel(level) {
789
+ const uri = this.state.levelRoutes[level]?.uri;
790
+ const url = uri ? this.joinBaseAndPath(this.baseURL, uri) : buildUrl(level, { baseURL: this.baseURL, endpoint: this.state.endpoint });
791
+ return await this.fetchMeta(`route-forge.${level}`, url, level);
792
+ }
793
+ /** baseURL 与后端下发的绝对 path 拼接(规范化斜杠),与 buildUrl 的 base 处理一致 */
794
+ joinBaseAndPath(baseURL, path) {
795
+ const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
796
+ const p = path.startsWith("/") ? path : `/${path}`;
797
+ return `${base}${p}`;
787
798
  }
788
- async function loadOne(level) {
799
+ async loadOne(level) {
800
+ const autoDiscoveryError = this.getAutoDiscoveryError();
789
801
  if (autoDiscoveryError) throw autoDiscoveryError;
790
- assertLevelDeclared(level);
791
- if (cache.get(level)) return;
792
- const existing = inflight.get(level);
802
+ this.assertLevelDeclared(level);
803
+ const noCache = this.state.cacheTtl === null;
804
+ if (!noCache && this.cache.get(level)) return;
805
+ const existing = this.inflight.get(level);
793
806
  if (existing) return existing;
794
- const gen = invalidationGens.get(level) ?? 0;
807
+ const gen = this.invalidationGens.get(level) ?? 0;
795
808
  const p = (async () => {
796
809
  try {
797
- if (level === UNASSIGNED_LEVEL && !backendHasUnassignedLevel && summaryUnassigned) {
798
- const routes = {};
799
- for (const r of summaryUnassigned) {
800
- routes[r.name] = { ...r, level: UNASSIGNED_LEVEL };
801
- }
802
- cache.set({ level: UNASSIGNED_LEVEL, routes, cache: null });
803
- return;
804
- }
805
- const resp = await fetchLevel(level);
806
- if ((invalidationGens.get(level) ?? 0) === gen) {
807
- cache.set(resp);
810
+ const resp = await this.fetchLevel(level);
811
+ if ((this.invalidationGens.get(level) ?? 0) === gen) {
812
+ this.cache.set(resp, this.state.cacheTtl);
808
813
  }
809
814
  } finally {
810
- inflight.delete(level);
815
+ this.inflight.delete(level);
811
816
  }
812
817
  })();
813
- inflight.set(level, p);
818
+ this.inflight.set(level, p);
814
819
  return p;
815
820
  }
816
- async function load(level) {
817
- await autoDiscoveryPromise;
821
+ async load(level) {
822
+ await this.autoDiscoveryPromise;
818
823
  const list = Array.isArray(level) ? level : [level];
819
- await Promise.all(list.map(loadOne));
824
+ await Promise.all(list.map((l) => this.loadOne(l)));
820
825
  }
821
- function route(level, name, params) {
822
- assertDiscoveryReady();
823
- const meta = findRouteMeta(level, name);
824
- if (!meta) {
825
- throw new UnknownRouteError(name, level);
826
- }
827
- return buildRequestUrl(meta, params ?? {});
828
- }
829
- function buildRequestUrl(meta, params) {
830
- const defaults = meta.parameter_defaults ?? {};
831
- const missingRequired = [];
832
- const values = {};
833
- for (const p of meta.parameters) {
834
- let v = params[p];
835
- if ((v === void 0 || v === null) && p in defaults) {
836
- v = defaults[p];
826
+ invalidate(level) {
827
+ if (level === void 0) {
828
+ this.cache.clear();
829
+ this.inflight.clear();
830
+ for (const lvl of this.state.levels) {
831
+ this.invalidationGens.set(lvl, (this.invalidationGens.get(lvl) ?? 0) + 1);
837
832
  }
838
- if (v === void 0 || v === null) {
839
- if (!meta.uri.includes(`{${p}?}`)) {
840
- missingRequired.push(p);
841
- }
842
- } else {
843
- values[p] = v;
833
+ } else if (Array.isArray(level)) {
834
+ for (const lvl of level) {
835
+ this.cache.del(lvl);
836
+ this.inflight.delete(lvl);
837
+ this.invalidationGens.set(lvl, (this.invalidationGens.get(lvl) ?? 0) + 1);
844
838
  }
839
+ } else {
840
+ this.cache.del(level);
841
+ this.inflight.delete(level);
842
+ this.invalidationGens.set(level, (this.invalidationGens.get(level) ?? 0) + 1);
845
843
  }
846
- if (missingRequired.length > 0) {
847
- throw new MissingRouteParamError(meta.name, missingRequired);
848
- }
849
- let uri = meta.uri.replace(/\{([^{}]+)\}/g, (match, raw) => {
850
- const optional = raw.endsWith("?");
851
- const name = optional ? raw.slice(0, -1) : raw;
852
- if (values[name] !== void 0) {
853
- const val = values[name];
854
- if (typeof val === "object") {
855
- throw new ForgeError(
856
- `Path parameter "${name}" must be a primitive value (string, number, boolean), got ${typeof val}`,
857
- { code: "RF_FE_003", route: meta.name, context: { param: name, value: val } }
858
- );
859
- }
860
- return encodeURIComponent(String(val));
861
- }
862
- return optional ? "" : match;
863
- });
864
- uri = uri.replace(/\/+/g, "/").replace(/\/$/, "");
865
- if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(effectiveUrlPrefix)) {
866
- const prefix2 = effectiveUrlPrefix.endsWith("/") ? effectiveUrlPrefix.slice(0, -1) : effectiveUrlPrefix;
867
- return uri.startsWith("/") ? `${prefix2}${uri}` : `${prefix2}/${uri}`;
868
- }
869
- const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
870
- const prefix = effectiveUrlPrefix;
871
- return uri.startsWith("/") ? `${base}${prefix}${uri}` : `${base}${prefix}/${uri}`;
872
844
  }
873
- function findRouteMeta(level, name) {
874
- const entry = cache.get(level);
845
+ isLoaded(level) {
846
+ if (level) return this.cache.get(level) !== void 0;
847
+ return this.state.levels.length > 0 && this.state.levels.every((lvl) => this.cache.get(lvl) !== void 0);
848
+ }
849
+ findRouteMeta(level, name) {
850
+ const entry = this.cache.get(level);
875
851
  const meta = entry?.routes[name];
876
852
  if (meta) {
877
853
  return { ...meta, level };
878
854
  }
879
855
  return void 0;
880
856
  }
881
- function api(level, name, params = {}) {
882
- let ctrl;
883
- let abortedBeforeInit = false;
884
- let abortReason;
885
- const work = (async () => {
886
- ctrl = new AbortController();
887
- if (abortedBeforeInit) {
888
- ctrl.abort(abortReason);
889
- }
890
- await autoDiscoveryPromise;
891
- await load(level);
892
- const meta = findRouteMeta(level, name);
893
- if (!meta) {
894
- throw new UnknownRouteError(name, level);
857
+ getRoutes(level) {
858
+ if (level !== void 0) {
859
+ const entry = this.cache.get(level);
860
+ const routes = entry?.routes ?? {};
861
+ const result2 = {};
862
+ for (const [k, v] of Object.entries(routes)) {
863
+ result2[k] = JSON.parse(JSON.stringify(v));
895
864
  }
896
- return doApiCall(meta, params, ctrl.signal);
897
- })();
898
- const request = work;
899
- request.abort = () => {
900
- if (ctrl) {
901
- ctrl.abort();
902
- } else {
903
- abortedBeforeInit = true;
865
+ return result2;
866
+ }
867
+ const result = {};
868
+ for (const lvl of this.state.levels) {
869
+ const entry = this.cache.get(lvl);
870
+ if (entry) {
871
+ const levelRoutes = {};
872
+ for (const [k, v] of Object.entries(entry.routes)) {
873
+ levelRoutes[k] = JSON.parse(JSON.stringify(v));
874
+ }
875
+ result[lvl] = levelRoutes;
904
876
  }
905
- };
906
- return request;
877
+ }
878
+ return result;
907
879
  }
880
+ };
881
+
882
+ // src/http-runner.ts
883
+ function createHttpRunner(deps) {
884
+ const {
885
+ ensureAdapter,
886
+ requestInterceptors,
887
+ responseInterceptors,
888
+ load,
889
+ findRouteMeta,
890
+ baseURL,
891
+ state,
892
+ timeout,
893
+ loadingTracker,
894
+ autoDiscoveryPromise
895
+ } = deps;
908
896
  async function doApiCall(meta, params, signal) {
909
897
  const {
910
898
  pathParams,
@@ -917,7 +905,10 @@ var RouteForge = (function (exports) {
917
905
  throw new RequestAbortedError(meta.name, meta.level, signal.reason);
918
906
  }
919
907
  const method = pickMethod(meta);
920
- const urlWithQuery = appendQuery(buildRequestUrl(meta, pathParams), query);
908
+ const urlWithQuery = appendQuery(
909
+ buildRequestUrl(meta, pathParams, { baseURL, urlPrefix: state.urlPrefix }),
910
+ query
911
+ );
921
912
  const config = {
922
913
  route: meta.name,
923
914
  level: meta.level ?? "",
@@ -972,88 +963,77 @@ var RouteForge = (function (exports) {
972
963
  loadingTracker.stop();
973
964
  }
974
965
  }
975
- function invalidate(level) {
976
- if (level === void 0) {
977
- cache.clear();
978
- inflight.clear();
979
- for (const lvl of effectiveLevels) {
980
- invalidationGens.set(lvl, (invalidationGens.get(lvl) ?? 0) + 1);
981
- }
982
- } else if (Array.isArray(level)) {
983
- for (const lvl of level) {
984
- cache.del(lvl);
985
- inflight.delete(lvl);
986
- invalidationGens.set(lvl, (invalidationGens.get(lvl) ?? 0) + 1);
966
+ return function api(level, name, params = {}) {
967
+ let ctrl;
968
+ let abortedBeforeInit = false;
969
+ let abortReason;
970
+ const work = (async () => {
971
+ ctrl = new AbortController();
972
+ if (abortedBeforeInit) {
973
+ ctrl.abort(abortReason);
987
974
  }
988
- } else {
989
- cache.del(level);
990
- inflight.delete(level);
991
- invalidationGens.set(level, (invalidationGens.get(level) ?? 0) + 1);
992
- }
993
- }
994
- function isLoaded(level) {
995
- if (level) return cache.get(level) !== void 0;
996
- return effectiveLevels.length > 0 && effectiveLevels.every((lvl) => cache.get(lvl) !== void 0);
997
- }
998
- function hasRoute(level, name) {
999
- assertDiscoveryReady();
1000
- return findRouteMeta(level, name) !== void 0;
1001
- }
1002
- function getRoutes(level) {
1003
- if (level !== void 0) {
1004
- const entry = cache.get(level);
1005
- const routes = entry?.routes ?? {};
1006
- const result2 = {};
1007
- for (const [k, v] of Object.entries(routes)) {
1008
- result2[k] = JSON.parse(JSON.stringify(v));
975
+ await autoDiscoveryPromise;
976
+ await load(level);
977
+ const meta = findRouteMeta(level, name);
978
+ if (!meta) {
979
+ throw new UnknownRouteError(name, level);
1009
980
  }
1010
- return result2;
1011
- }
1012
- const result = {};
1013
- for (const lvl of effectiveLevels) {
1014
- const entry = cache.get(lvl);
1015
- if (entry) {
1016
- const levelRoutes = {};
1017
- for (const [k, v] of Object.entries(entry.routes)) {
1018
- levelRoutes[k] = JSON.parse(JSON.stringify(v));
1019
- }
1020
- result[lvl] = levelRoutes;
981
+ return doApiCall(meta, params, ctrl.signal);
982
+ })();
983
+ const request = work;
984
+ request.abort = () => {
985
+ if (ctrl) {
986
+ ctrl.abort();
987
+ } else {
988
+ abortedBeforeInit = true;
1021
989
  }
1022
- }
1023
- return result;
1024
- }
1025
- void autoDiscoveryPromise.then(() => {
1026
- autoDiscoveryCompleted = true;
1027
- if (effectiveEager.length > 0) {
1028
- return Promise.allSettled(effectiveEager.map((lvl) => load(lvl))).then((results) => {
1029
- results.forEach((r, i) => {
1030
- if (r.status === "rejected") {
1031
- console.error(
1032
- `[route-forge] eager load failed for level "${effectiveEager[i]}":`,
1033
- r.reason
1034
- );
1035
- }
1036
- });
1037
- });
1038
- }
1039
- }).then(() => {
1040
- resolveReady(forgeInstance);
1041
- }).catch((e) => {
1042
- rejectReady(e);
1043
- });
1044
- function ready(onFulfilled, onRejected) {
1045
- if (onFulfilled) {
1046
- const p = readyPromise.then(onFulfilled, onRejected);
1047
- return p.then(() => forgeInstance);
1048
- }
1049
- return readyPromise;
990
+ };
991
+ return request;
992
+ };
993
+ }
994
+
995
+ // src/resolveRouteName.ts
996
+ async function resolveRouteName(forge, level, prefix, suffix, separator = ".") {
997
+ if (!suffix) return prefix;
998
+ const joined = `${prefix}${separator}${suffix}`;
999
+ if (!suffix.startsWith(`${prefix}${separator}`)) return joined;
1000
+ await forge.load(level);
1001
+ if (forge.hasRoute(level, joined)) return joined;
1002
+ if (forge.hasRoute(level, suffix)) return suffix;
1003
+ throw new UnknownRouteError(joined, level);
1004
+ }
1005
+ function resolveRouteNameSync(forge, level, prefix, suffix, separator = ".") {
1006
+ if (!suffix) return prefix;
1007
+ const joined = `${prefix}${separator}${suffix}`;
1008
+ if (!suffix.startsWith(`${prefix}${separator}`)) return joined;
1009
+ if (forge.hasRoute(level, joined)) return joined;
1010
+ if (forge.hasRoute(level, suffix)) return suffix;
1011
+ throw new UnknownRouteError(joined, level);
1012
+ }
1013
+
1014
+ // src/defineImmutableProps.ts
1015
+ function defineImmutableProps(target, props) {
1016
+ for (const key of Object.keys(props)) {
1017
+ const val = props[key];
1018
+ Object.defineProperty(target, key, {
1019
+ value: val !== null && typeof val === "object" ? Object.freeze(val) : val,
1020
+ writable: false,
1021
+ enumerable: false,
1022
+ configurable: false
1023
+ });
1050
1024
  }
1051
- const forgeResolver = { load, hasRoute };
1025
+ return target;
1026
+ }
1027
+
1028
+ // src/bound-forge.ts
1029
+ function createBoundForgeFactory(deps) {
1030
+ const { load, api, route, hasRoute, getRoutes, invalidate, isLoaded, loadingTracker } = deps;
1031
+ const resolver = { load, hasRoute };
1052
1032
  function createBoundForge(level, prefix) {
1053
1033
  const levelLoadedPromise = load(level);
1054
1034
  levelLoadedPromise.catch(() => {
1055
1035
  });
1056
- const apiFn = prefix ? (name, params) => resolveRouteName(forgeResolver, level, prefix, name).then(
1036
+ const apiFn = prefix ? (name, params) => resolveRouteName(resolver, level, prefix, name).then(
1057
1037
  (resolved) => api(level, resolved, params)
1058
1038
  ) : (name, params) => api(level, name, params);
1059
1039
  const callable = apiFn;
@@ -1061,8 +1041,8 @@ var RouteForge = (function (exports) {
1061
1041
  level,
1062
1042
  ...prefix !== void 0 ? { prefix } : {},
1063
1043
  api: apiFn,
1064
- route: prefix ? (name, params) => route(level, resolveRouteNameSync(forgeResolver, level, prefix, name), params) : (name, params) => route(level, name, params),
1065
- url: prefix ? (name, params) => route(level, resolveRouteNameSync(forgeResolver, level, prefix, name), params) : (name, params) => route(level, name, params),
1044
+ route: prefix ? (name, params) => route(level, resolveRouteNameSync(resolver, level, prefix, name), params) : (name, params) => route(level, name, params),
1045
+ url: prefix ? (name, params) => route(level, resolveRouteNameSync(resolver, level, prefix, name), params) : (name, params) => route(level, name, params),
1066
1046
  hasRoute: (name) => hasRoute(level, name),
1067
1047
  getRoutes: () => getRoutes(level),
1068
1048
  load: () => load(level),
@@ -1106,6 +1086,220 @@ var RouteForge = (function (exports) {
1106
1086
  attachBoundMethods(bound, levelLoadedPromise, level);
1107
1087
  return bound;
1108
1088
  }
1089
+ return createBoundForgeWithMethods;
1090
+ }
1091
+
1092
+ // src/forge.ts
1093
+ var DEFAULT_TIMEOUT = 3e4;
1094
+ var DEFAULT_CACHE_TTL = 3600;
1095
+ function createRouteForge(options) {
1096
+ const bootstrapSummary = readEmbeddedSummary() ?? options.summary ?? null;
1097
+ if (!bootstrapSummary && !options.endpoint) {
1098
+ throw new TypeError(
1099
+ "createRouteForge: \u9700\u8981 options.endpoint\uFF0C\u6216 options.summary\uFF0C\u6216\u9875\u9762\u5185\u5D4C window.__ROUTE_FORGE__"
1100
+ );
1101
+ }
1102
+ const {
1103
+ adapter = "auto",
1104
+ timeout = DEFAULT_TIMEOUT,
1105
+ baseURL = "",
1106
+ interceptors: declarativeInterceptors,
1107
+ cache: cacheOpts = {}
1108
+ } = options;
1109
+ const loadingTracker = new LoadingTracker();
1110
+ const explicitLevels = options.levels;
1111
+ const explicitEager = options.eager;
1112
+ const explicitEndpoint = options.endpoint;
1113
+ const discoveryState = {
1114
+ levels: explicitLevels ?? [],
1115
+ eager: explicitEager ?? [],
1116
+ endpoint: explicitEndpoint ?? bootstrapSummary?.config?.endpoint_prefix ?? "",
1117
+ urlPrefix: "",
1118
+ cacheTtl: void 0,
1119
+ levelRoutes: {}
1120
+ };
1121
+ const discoveryInputs = { explicitLevels, explicitEager, explicitEndpoint };
1122
+ let autoDiscoveryCompleted = false;
1123
+ let resolveReady;
1124
+ let rejectReady;
1125
+ const readyPromise = new Promise((resolve, reject) => {
1126
+ resolveReady = resolve;
1127
+ rejectReady = reject;
1128
+ });
1129
+ readyPromise.catch(() => {
1130
+ });
1131
+ const cacheTtl = cacheOpts.ttl ?? DEFAULT_CACHE_TTL;
1132
+ const cacheStorage = cacheOpts.storage ?? "memory";
1133
+ const cache = new RouteCache({ storage: cacheStorage, ttl: cacheTtl });
1134
+ const requestInterceptors = new InterceptorManagerImpl();
1135
+ const responseInterceptors = new InterceptorManagerImpl();
1136
+ if (declarativeInterceptors?.request) {
1137
+ for (const entry of declarativeInterceptors.request) {
1138
+ if (typeof entry === "function") {
1139
+ requestInterceptors.use(entry);
1140
+ } else {
1141
+ const [onFulfilled, onRejected] = entry;
1142
+ requestInterceptors.use(onFulfilled, onRejected);
1143
+ }
1144
+ }
1145
+ }
1146
+ if (declarativeInterceptors?.response) {
1147
+ for (const entry of declarativeInterceptors.response) {
1148
+ if (typeof entry === "function") {
1149
+ responseInterceptors.use(entry);
1150
+ } else {
1151
+ const [onFulfilled, onRejected] = entry;
1152
+ responseInterceptors.use(onFulfilled, onRejected);
1153
+ }
1154
+ }
1155
+ }
1156
+ const adapterPromise = resolveAdapter({
1157
+ adapter,
1158
+ forgeInterceptors: { request: requestInterceptors, response: responseInterceptors }
1159
+ });
1160
+ let adapterResolved = false;
1161
+ let adapterObj = null;
1162
+ async function ensureAdapter() {
1163
+ if (!adapterResolved) {
1164
+ adapterObj = await adapterPromise.catch((e) => {
1165
+ if (e instanceof AdapterNotFoundError) throw e;
1166
+ return resolveAdapter({
1167
+ adapter: "builtin",
1168
+ forgeInterceptors: { request: requestInterceptors, response: responseInterceptors }
1169
+ });
1170
+ });
1171
+ adapterResolved = true;
1172
+ }
1173
+ return adapterObj;
1174
+ }
1175
+ function assertDiscoveryReady() {
1176
+ if (!autoDiscoveryCompleted && !explicitLevels?.length) {
1177
+ throw new ForgeError(
1178
+ "Route data not available. Auto-discovery has not completed. Use forge.ready() or forge.use(level) first.",
1179
+ { code: "RF_FE_010" }
1180
+ );
1181
+ }
1182
+ }
1183
+ async function fetchMeta(routeTag, url, level = "") {
1184
+ const adp = await ensureAdapter();
1185
+ const config = {
1186
+ route: routeTag,
1187
+ level,
1188
+ method: "GET",
1189
+ url,
1190
+ headers: { Accept: "application/json" },
1191
+ params: {},
1192
+ timeout,
1193
+ meta: {
1194
+ name: routeTag,
1195
+ uri: url,
1196
+ methods: ["GET"],
1197
+ parameters: [],
1198
+ level
1199
+ }
1200
+ };
1201
+ const doRawRequest = adp.requestRaw ?? adp.request;
1202
+ const resp = await doRawRequest(config);
1203
+ if (!resp || resp.status < 200 || resp.status >= 300) {
1204
+ throw new HTTPError(
1205
+ `Failed to fetch "${routeTag}": HTTP ${resp?.status}`,
1206
+ { level, status: resp?.status, url, method: "GET" }
1207
+ );
1208
+ }
1209
+ return resp.data;
1210
+ }
1211
+ let autoDiscoveryPromise;
1212
+ if (bootstrapSummary) {
1213
+ applySummaryToState(bootstrapSummary, discoveryState, discoveryInputs);
1214
+ autoDiscoveryCompleted = true;
1215
+ autoDiscoveryPromise = Promise.resolve();
1216
+ } else {
1217
+ autoDiscoveryPromise = fetchSummary(discoveryInputs, baseURL, fetchMeta).then((summary) => {
1218
+ if (summary === null) {
1219
+ return;
1220
+ }
1221
+ applySummaryToState(summary, discoveryState, discoveryInputs);
1222
+ });
1223
+ }
1224
+ let autoDiscoveryError = null;
1225
+ autoDiscoveryPromise.catch((e) => {
1226
+ autoDiscoveryError = e;
1227
+ });
1228
+ const store = new RouteStore({
1229
+ cache,
1230
+ state: discoveryState,
1231
+ baseURL,
1232
+ fetchMeta,
1233
+ autoDiscoveryPromise,
1234
+ getAutoDiscoveryError: () => autoDiscoveryError
1235
+ });
1236
+ const load = (level) => store.load(level);
1237
+ const findRouteMeta = (level, name) => store.findRouteMeta(level, name);
1238
+ const invalidate = (level) => store.invalidate(level);
1239
+ const isLoaded = (level) => store.isLoaded(level);
1240
+ function getRoutes(level) {
1241
+ return level === void 0 ? store.getRoutes() : store.getRoutes(level);
1242
+ }
1243
+ function route(level, name, params) {
1244
+ assertDiscoveryReady();
1245
+ const meta = findRouteMeta(level, name);
1246
+ if (!meta) {
1247
+ throw new UnknownRouteError(name, level);
1248
+ }
1249
+ return buildRequestUrl(meta, params ?? {}, { baseURL, urlPrefix: discoveryState.urlPrefix });
1250
+ }
1251
+ const api = createHttpRunner({
1252
+ ensureAdapter,
1253
+ requestInterceptors,
1254
+ responseInterceptors,
1255
+ load,
1256
+ findRouteMeta,
1257
+ baseURL,
1258
+ state: discoveryState,
1259
+ timeout,
1260
+ loadingTracker,
1261
+ autoDiscoveryPromise
1262
+ });
1263
+ function hasRoute(level, name) {
1264
+ assertDiscoveryReady();
1265
+ return findRouteMeta(level, name) !== void 0;
1266
+ }
1267
+ void autoDiscoveryPromise.then(() => {
1268
+ autoDiscoveryCompleted = true;
1269
+ if (discoveryState.eager.length > 0) {
1270
+ return Promise.allSettled(discoveryState.eager.map((lvl) => load(lvl))).then((results) => {
1271
+ results.forEach((r, i) => {
1272
+ if (r.status === "rejected") {
1273
+ console.error(
1274
+ `[route-forge] eager load failed for level "${discoveryState.eager[i]}":`,
1275
+ r.reason
1276
+ );
1277
+ }
1278
+ });
1279
+ });
1280
+ }
1281
+ }).then(() => {
1282
+ resolveReady(forgeInstance);
1283
+ }).catch((e) => {
1284
+ rejectReady(e);
1285
+ });
1286
+ function ready(onFulfilled, onRejected) {
1287
+ if (onFulfilled) {
1288
+ const p = readyPromise.then(onFulfilled, onRejected);
1289
+ return p.then(() => forgeInstance);
1290
+ }
1291
+ return readyPromise;
1292
+ }
1293
+ const createBoundForgeWithMethods = createBoundForgeFactory({
1294
+ load,
1295
+ api,
1296
+ route,
1297
+ hasRoute,
1298
+ getRoutes,
1299
+ invalidate,
1300
+ isLoaded,
1301
+ loadingTracker
1302
+ });
1109
1303
  const forgeInstance = {
1110
1304
  api,
1111
1305
  load,
@@ -1129,62 +1323,6 @@ var RouteForge = (function (exports) {
1129
1323
  };
1130
1324
  return forgeInstance;
1131
1325
  }
1132
- function pickMethod(meta) {
1133
- const m = meta.methods.find((x) => x.toUpperCase() !== "HEAD");
1134
- return (m ?? meta.methods[0] ?? "GET").toUpperCase();
1135
- }
1136
- function appendQuery(url, query) {
1137
- if (!query) return url;
1138
- const usp = new URLSearchParams();
1139
- for (const [k, v] of Object.entries(query)) {
1140
- if (v === void 0 || v === null) continue;
1141
- usp.append(k, String(v));
1142
- }
1143
- const qs = usp.toString();
1144
- if (!qs) return url;
1145
- return url.includes("?") ? `${url}&${qs}` : `${url}?${qs}`;
1146
- }
1147
- function resolveApiParams(input) {
1148
- const {
1149
- params: explicitParams,
1150
- query: rawQuery,
1151
- body: rawBody,
1152
- headers: rawHeaders,
1153
- timeout: perCallTimeout,
1154
- ...flatRest
1155
- } = input;
1156
- const pathParams = explicitParams ? { ...explicitParams } : {};
1157
- for (const [k, v] of Object.entries(flatRest)) {
1158
- if (!(k in pathParams)) {
1159
- pathParams[k] = v;
1160
- }
1161
- }
1162
- let query;
1163
- let body;
1164
- let headers;
1165
- if (rawQuery !== void 0) {
1166
- if (typeof rawQuery === "object" && rawQuery !== null) {
1167
- query = rawQuery;
1168
- } else if (!("query" in pathParams)) {
1169
- pathParams.query = rawQuery;
1170
- }
1171
- }
1172
- if (rawBody !== void 0) {
1173
- if (typeof rawBody !== "string" && typeof rawBody !== "number") {
1174
- body = rawBody;
1175
- } else if (!("body" in pathParams)) {
1176
- pathParams.body = rawBody;
1177
- }
1178
- }
1179
- if (rawHeaders !== void 0) {
1180
- if (typeof rawHeaders === "object" && rawHeaders !== null) {
1181
- headers = rawHeaders;
1182
- } else if (!("headers" in pathParams)) {
1183
- pathParams.headers = rawHeaders;
1184
- }
1185
- }
1186
- return { pathParams, query, body, headers, timeout: perCallTimeout };
1187
- }
1188
1326
 
1189
1327
  exports.AdapterNotFoundError = AdapterNotFoundError;
1190
1328
  exports.ForgeError = ForgeError;