@route-forge/core 2.2.1 → 3.0.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.
- package/README.md +31 -23
- package/README_zh.md +30 -23
- package/dist/codegen.cjs +7 -8
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.d.cts +2 -3
- package/dist/codegen.d.ts +2 -3
- package/dist/codegen.js +7 -8
- package/dist/codegen.js.map +1 -1
- package/dist/index.cjs +182 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -8
- package/dist/index.d.ts +27 -8
- package/dist/index.js +181 -83
- package/dist/index.js.map +1 -1
- package/dist/route-forge.global.js +182 -82
- package/dist/route-forge.global.js.map +1 -1
- package/dist/route-forge.global.min.js +2 -2
- package/dist/{types-CDKE8rw-.d.cts → types-B_vdcRqx.d.cts} +57 -18
- package/dist/{types-CDKE8rw-.d.ts → types-B_vdcRqx.d.ts} +57 -18
- package/package.json +4 -1
|
@@ -144,30 +144,56 @@ var RouteForge = (function (exports) {
|
|
|
144
144
|
if (opts.cause !== void 0) this.cause = opts.cause;
|
|
145
145
|
}
|
|
146
146
|
};
|
|
147
|
+
function formatCandidates(candidates) {
|
|
148
|
+
if (!candidates || candidates.length === 0) return "";
|
|
149
|
+
const MAX = 5;
|
|
150
|
+
const shown = candidates.slice(0, MAX).join(", ");
|
|
151
|
+
const more = candidates.length > MAX ? ` (+${candidates.length - MAX} more)` : "";
|
|
152
|
+
return ` Available: ${shown}${more}`;
|
|
153
|
+
}
|
|
147
154
|
var UnknownRouteError = class extends ForgeError {
|
|
148
|
-
constructor(route, level) {
|
|
149
|
-
super(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
constructor(route, level, candidates) {
|
|
156
|
+
super(
|
|
157
|
+
`Route "${route}" not found${level ? ` in level "${level}"` : ""}.${formatCandidates(candidates)}`,
|
|
158
|
+
{
|
|
159
|
+
code: "RF_FE_001",
|
|
160
|
+
route,
|
|
161
|
+
level,
|
|
162
|
+
context: candidates && candidates.length > 0 ? { candidates } : void 0
|
|
163
|
+
}
|
|
164
|
+
);
|
|
154
165
|
}
|
|
155
166
|
};
|
|
156
167
|
var UnknownLevelError = class extends ForgeError {
|
|
157
|
-
constructor(level) {
|
|
158
|
-
super(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
168
|
+
constructor(level, candidates) {
|
|
169
|
+
super(
|
|
170
|
+
`Level "${level}" not declared in options.levels.${formatCandidates(candidates)}`,
|
|
171
|
+
{
|
|
172
|
+
code: "RF_FE_002",
|
|
173
|
+
level,
|
|
174
|
+
context: candidates && candidates.length > 0 ? { candidates } : void 0
|
|
175
|
+
}
|
|
176
|
+
);
|
|
162
177
|
}
|
|
163
178
|
};
|
|
164
179
|
var MissingRouteParamError = class extends ForgeError {
|
|
165
|
-
constructor(route, missingParams) {
|
|
166
|
-
super(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
180
|
+
constructor(route, missingParams, uri) {
|
|
181
|
+
super(
|
|
182
|
+
`Missing path parameter(s) ${missingParams.join(", ")} for route "${route}"${uri ? ` (${uri})` : ""}`,
|
|
183
|
+
{
|
|
184
|
+
code: "RF_FE_003",
|
|
185
|
+
route,
|
|
186
|
+
context: { missingParams, ...uri !== void 0 ? { uri } : {} }
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var InvalidPathParamError = class extends ForgeError {
|
|
192
|
+
constructor(route, param, value) {
|
|
193
|
+
super(
|
|
194
|
+
`Path parameter "${param}" must be a primitive value (string, number, boolean), got ${typeof value}`,
|
|
195
|
+
{ code: "RF_FE_003", route, context: { param, value } }
|
|
196
|
+
);
|
|
171
197
|
}
|
|
172
198
|
};
|
|
173
199
|
var AdapterNotFoundError = class extends ForgeError {
|
|
@@ -200,6 +226,7 @@ var RouteForge = (function (exports) {
|
|
|
200
226
|
context: { status: opts.status, url: opts.url, method: opts.method },
|
|
201
227
|
cause: opts.cause
|
|
202
228
|
});
|
|
229
|
+
if (opts.response !== void 0) this.response = opts.response;
|
|
203
230
|
}
|
|
204
231
|
};
|
|
205
232
|
var RequestAbortedError = class extends ForgeError {
|
|
@@ -212,6 +239,14 @@ var RouteForge = (function (exports) {
|
|
|
212
239
|
});
|
|
213
240
|
}
|
|
214
241
|
};
|
|
242
|
+
var DiscoveryNotReadyError = class extends ForgeError {
|
|
243
|
+
constructor() {
|
|
244
|
+
super(
|
|
245
|
+
"Route data not available. Auto-discovery has not completed. Use forge.ready() or forge.use(level) first, or await ready() before calling route()/hasRoute().",
|
|
246
|
+
{ code: "RF_FE_010" }
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
215
250
|
|
|
216
251
|
// src/interceptors.ts
|
|
217
252
|
var InterceptorManagerImpl = class {
|
|
@@ -278,6 +313,43 @@ var RouteForge = (function (exports) {
|
|
|
278
313
|
function createInterceptorManager() {
|
|
279
314
|
return new InterceptorManagerImpl();
|
|
280
315
|
}
|
|
316
|
+
function normalizeInterceptorDeclaration(value) {
|
|
317
|
+
if (value === null || value === void 0) return {};
|
|
318
|
+
let rawResolve;
|
|
319
|
+
let rawReject;
|
|
320
|
+
if (typeof value === "function") {
|
|
321
|
+
rawResolve = value;
|
|
322
|
+
} else if (Array.isArray(value)) {
|
|
323
|
+
rawResolve = value[0];
|
|
324
|
+
rawReject = value[1];
|
|
325
|
+
} else if (typeof value === "object") {
|
|
326
|
+
const obj = value;
|
|
327
|
+
rawResolve = obj.resolve;
|
|
328
|
+
rawReject = obj.reject;
|
|
329
|
+
} else {
|
|
330
|
+
throw new TypeError(
|
|
331
|
+
`Interceptor declaration must be a function, a [resolve, reject] tuple, or a { resolve, reject } object; received ${typeof value}.`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
const handler = {};
|
|
335
|
+
if (rawResolve !== void 0 && rawResolve !== null) {
|
|
336
|
+
if (typeof rawResolve !== "function") {
|
|
337
|
+
throw new TypeError(
|
|
338
|
+
`Interceptor "resolve" (onFulfilled) must be a function; received ${typeof rawResolve}.`
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
handler.onFulfilled = rawResolve;
|
|
342
|
+
}
|
|
343
|
+
if (rawReject !== void 0 && rawReject !== null) {
|
|
344
|
+
if (typeof rawReject !== "function") {
|
|
345
|
+
throw new TypeError(
|
|
346
|
+
`Interceptor "reject" (onRejected) must be a function; received ${typeof rawReject}.`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
handler.onRejected = rawReject;
|
|
350
|
+
}
|
|
351
|
+
return handler;
|
|
352
|
+
}
|
|
281
353
|
|
|
282
354
|
// src/adapters/fetch-core.ts
|
|
283
355
|
function isAbortError(err, signal) {
|
|
@@ -378,7 +450,10 @@ var RouteForge = (function (exports) {
|
|
|
378
450
|
level: config.level,
|
|
379
451
|
status: res.status,
|
|
380
452
|
url,
|
|
381
|
-
method: config.method
|
|
453
|
+
method: config.method,
|
|
454
|
+
// 完整 ResponseData 随错误逐段传递(响应拦截器 onRejected 链 → 最终 catch),
|
|
455
|
+
// 供调用方检查响应体,如 Laravel 422 校验错误 err.response.data.errors
|
|
456
|
+
response: responseData
|
|
382
457
|
}
|
|
383
458
|
);
|
|
384
459
|
}
|
|
@@ -590,7 +665,7 @@ var RouteForge = (function (exports) {
|
|
|
590
665
|
}
|
|
591
666
|
}
|
|
592
667
|
if (missingRequired.length > 0) {
|
|
593
|
-
throw new MissingRouteParamError(meta.name, missingRequired);
|
|
668
|
+
throw new MissingRouteParamError(meta.name, missingRequired, meta.uri);
|
|
594
669
|
}
|
|
595
670
|
let uri = meta.uri.replace(/\{([^{}]+)\}/g, (match, raw) => {
|
|
596
671
|
const optional = raw.endsWith("?");
|
|
@@ -598,10 +673,7 @@ var RouteForge = (function (exports) {
|
|
|
598
673
|
if (values[name] !== void 0) {
|
|
599
674
|
const val = values[name];
|
|
600
675
|
if (typeof val === "object") {
|
|
601
|
-
throw new
|
|
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
|
-
);
|
|
676
|
+
throw new InvalidPathParamError(meta.name, name, val);
|
|
605
677
|
}
|
|
606
678
|
return encodeURIComponent(String(val));
|
|
607
679
|
}
|
|
@@ -674,24 +746,31 @@ var RouteForge = (function (exports) {
|
|
|
674
746
|
}
|
|
675
747
|
|
|
676
748
|
// src/auto-discovery.ts
|
|
749
|
+
var DEFAULT_ENDPOINT = "/_forge/routes";
|
|
677
750
|
async function fetchSummary(inputs, baseURL, fetchMeta) {
|
|
678
|
-
const { explicitLevels, explicitEndpoint } = inputs;
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
}
|
|
751
|
+
const { explicitLevels, explicitEndpoint, warnings } = inputs;
|
|
752
|
+
const endpoint = explicitEndpoint ?? DEFAULT_ENDPOINT;
|
|
753
|
+
const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
|
|
754
|
+
const ep = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
|
|
755
|
+
const url = `${base}${ep}`;
|
|
682
756
|
try {
|
|
683
|
-
const
|
|
684
|
-
const ep = explicitEndpoint.startsWith("/") ? explicitEndpoint : `/${explicitEndpoint}`;
|
|
685
|
-
const data = await fetchMeta("__forge__.summary", `${base}${ep}`);
|
|
757
|
+
const data = await fetchMeta("__forge__.summary", url);
|
|
686
758
|
return data;
|
|
687
759
|
} catch (e) {
|
|
688
760
|
if (explicitLevels && explicitLevels.length > 0) {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
761
|
+
if (warnings) {
|
|
762
|
+
console.warn(
|
|
763
|
+
`[route-forge] summary endpoint unreachable: ${e.message}; using explicit levels`
|
|
764
|
+
);
|
|
765
|
+
}
|
|
692
766
|
return null;
|
|
693
767
|
}
|
|
694
|
-
throw new
|
|
768
|
+
throw new NetworkError(
|
|
769
|
+
`Failed to fetch route summary from "${url}": ${e?.message ?? String(e)}; check the backend manifest endpoint or options.endpoint`,
|
|
770
|
+
void 0,
|
|
771
|
+
void 0,
|
|
772
|
+
e
|
|
773
|
+
);
|
|
695
774
|
}
|
|
696
775
|
}
|
|
697
776
|
function normalizeCacheTtl(raw) {
|
|
@@ -699,15 +778,15 @@ var RouteForge = (function (exports) {
|
|
|
699
778
|
return raw;
|
|
700
779
|
}
|
|
701
780
|
function applySummaryToState(summary, state, inputs) {
|
|
702
|
-
const { explicitLevels, explicitEager, explicitEndpoint } = inputs;
|
|
781
|
+
const { explicitLevels, explicitEager, explicitEndpoint, warnings } = inputs;
|
|
703
782
|
const schemeVersion = summary.schemeVersion ?? 1;
|
|
704
|
-
if (schemeVersion > 1) {
|
|
783
|
+
if (schemeVersion > 1 && warnings) {
|
|
705
784
|
console.warn(
|
|
706
785
|
`[route-forge] backend schemeVersion=${schemeVersion} > client supported 1; some features may be unavailable`
|
|
707
786
|
);
|
|
708
787
|
}
|
|
709
788
|
if (summary.config.endpoint_prefix && summary.config.endpoint_prefix !== explicitEndpoint) {
|
|
710
|
-
if (explicitEndpoint) {
|
|
789
|
+
if (explicitEndpoint && warnings) {
|
|
711
790
|
console.warn(
|
|
712
791
|
`[route-forge] backend endpoint_prefix "${summary.config.endpoint_prefix}" overrides frontend endpoint "${explicitEndpoint}"`
|
|
713
792
|
);
|
|
@@ -730,7 +809,7 @@ var RouteForge = (function (exports) {
|
|
|
730
809
|
if (explicitLevels && explicitLevels.length > 0) {
|
|
731
810
|
const intersection = explicitLevels.filter((l) => backendLevels.includes(l));
|
|
732
811
|
const removed = explicitLevels.filter((l) => !backendLevels.includes(l));
|
|
733
|
-
if (removed.length > 0) {
|
|
812
|
+
if (removed.length > 0 && warnings) {
|
|
734
813
|
console.warn(
|
|
735
814
|
`[route-forge] levels not in backend summary and dropped: ${removed.join(", ")}`
|
|
736
815
|
);
|
|
@@ -782,7 +861,7 @@ var RouteForge = (function (exports) {
|
|
|
782
861
|
}
|
|
783
862
|
assertLevelDeclared(level) {
|
|
784
863
|
if (!this.state.levels.includes(level)) {
|
|
785
|
-
throw new UnknownLevelError(level);
|
|
864
|
+
throw new UnknownLevelError(level, this.state.levels);
|
|
786
865
|
}
|
|
787
866
|
}
|
|
788
867
|
async fetchLevel(level) {
|
|
@@ -856,6 +935,7 @@ var RouteForge = (function (exports) {
|
|
|
856
935
|
}
|
|
857
936
|
getRoutes(level) {
|
|
858
937
|
if (level !== void 0) {
|
|
938
|
+
this.assertLevelDeclared(level);
|
|
859
939
|
const entry = this.cache.get(level);
|
|
860
940
|
const routes = entry?.routes ?? {};
|
|
861
941
|
const result2 = {};
|
|
@@ -887,6 +967,7 @@ var RouteForge = (function (exports) {
|
|
|
887
967
|
responseInterceptors,
|
|
888
968
|
load,
|
|
889
969
|
findRouteMeta,
|
|
970
|
+
getRouteNames,
|
|
890
971
|
baseURL,
|
|
891
972
|
state,
|
|
892
973
|
timeout,
|
|
@@ -938,7 +1019,10 @@ var RouteForge = (function (exports) {
|
|
|
938
1019
|
level: resp.level,
|
|
939
1020
|
status: resp.status,
|
|
940
1021
|
url: resp.url,
|
|
941
|
-
method: resp.method
|
|
1022
|
+
method: resp.method,
|
|
1023
|
+
// 完整 ResponseData 随错误逐段传递(响应拦截器 onRejected 链 → 最终 catch),
|
|
1024
|
+
// 供调用方检查响应体,如 Laravel 422 校验错误 err.response.data.errors
|
|
1025
|
+
response: resp
|
|
942
1026
|
}
|
|
943
1027
|
);
|
|
944
1028
|
}
|
|
@@ -976,7 +1060,7 @@ var RouteForge = (function (exports) {
|
|
|
976
1060
|
await load(level);
|
|
977
1061
|
const meta = findRouteMeta(level, name);
|
|
978
1062
|
if (!meta) {
|
|
979
|
-
throw new UnknownRouteError(name, level);
|
|
1063
|
+
throw new UnknownRouteError(name, level, getRouteNames(level));
|
|
980
1064
|
}
|
|
981
1065
|
return doApiCall(meta, params, ctrl.signal);
|
|
982
1066
|
})();
|
|
@@ -993,22 +1077,31 @@ var RouteForge = (function (exports) {
|
|
|
993
1077
|
}
|
|
994
1078
|
|
|
995
1079
|
// src/resolveRouteName.ts
|
|
1080
|
+
function stripTrailingSeparator(prefix, separator) {
|
|
1081
|
+
let normalized = prefix;
|
|
1082
|
+
while (normalized.endsWith(separator)) {
|
|
1083
|
+
normalized = normalized.slice(0, -separator.length);
|
|
1084
|
+
}
|
|
1085
|
+
return normalized;
|
|
1086
|
+
}
|
|
996
1087
|
async function resolveRouteName(forge, level, prefix, suffix, separator = ".") {
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1088
|
+
const normalized = stripTrailingSeparator(prefix, separator);
|
|
1089
|
+
if (!suffix) return normalized;
|
|
1090
|
+
const joined = `${normalized}${separator}${suffix}`;
|
|
1091
|
+
if (!suffix.startsWith(`${normalized}${separator}`)) return joined;
|
|
1000
1092
|
await forge.load(level);
|
|
1001
1093
|
if (forge.hasRoute(level, joined)) return joined;
|
|
1002
1094
|
if (forge.hasRoute(level, suffix)) return suffix;
|
|
1003
|
-
throw new UnknownRouteError(joined, level);
|
|
1095
|
+
throw new UnknownRouteError(joined, level, forge.getRouteNames?.(level));
|
|
1004
1096
|
}
|
|
1005
1097
|
function resolveRouteNameSync(forge, level, prefix, suffix, separator = ".") {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1098
|
+
const normalized = stripTrailingSeparator(prefix, separator);
|
|
1099
|
+
if (!suffix) return normalized;
|
|
1100
|
+
const joined = `${normalized}${separator}${suffix}`;
|
|
1101
|
+
if (!suffix.startsWith(`${normalized}${separator}`)) return joined;
|
|
1009
1102
|
if (forge.hasRoute(level, joined)) return joined;
|
|
1010
1103
|
if (forge.hasRoute(level, suffix)) return suffix;
|
|
1011
|
-
throw new UnknownRouteError(joined, level);
|
|
1104
|
+
throw new UnknownRouteError(joined, level, forge.getRouteNames?.(level));
|
|
1012
1105
|
}
|
|
1013
1106
|
|
|
1014
1107
|
// src/defineImmutableProps.ts
|
|
@@ -1028,7 +1121,7 @@ var RouteForge = (function (exports) {
|
|
|
1028
1121
|
// src/bound-forge.ts
|
|
1029
1122
|
function createBoundForgeFactory(deps) {
|
|
1030
1123
|
const { load, api, route, hasRoute, getRoutes, invalidate, isLoaded, loadingTracker } = deps;
|
|
1031
|
-
const resolver = { load, hasRoute };
|
|
1124
|
+
const resolver = { load, hasRoute, getRouteNames: (lvl) => Object.keys(getRoutes(lvl)) };
|
|
1032
1125
|
function createBoundForge(level, prefix) {
|
|
1033
1126
|
const levelLoadedPromise = load(level);
|
|
1034
1127
|
levelLoadedPromise.catch(() => {
|
|
@@ -1094,11 +1187,6 @@ var RouteForge = (function (exports) {
|
|
|
1094
1187
|
var DEFAULT_CACHE_TTL = 3600;
|
|
1095
1188
|
function createRouteForge(options = {}) {
|
|
1096
1189
|
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
1190
|
const {
|
|
1103
1191
|
adapter = "auto",
|
|
1104
1192
|
timeout = DEFAULT_TIMEOUT,
|
|
@@ -1106,6 +1194,7 @@ var RouteForge = (function (exports) {
|
|
|
1106
1194
|
interceptors: declarativeInterceptors,
|
|
1107
1195
|
cache: cacheOpts = {}
|
|
1108
1196
|
} = options;
|
|
1197
|
+
const warnings = options.warnings ?? true;
|
|
1109
1198
|
const loadingTracker = new LoadingTracker();
|
|
1110
1199
|
const explicitLevels = options.levels;
|
|
1111
1200
|
const explicitEager = options.eager;
|
|
@@ -1113,12 +1202,12 @@ var RouteForge = (function (exports) {
|
|
|
1113
1202
|
const discoveryState = {
|
|
1114
1203
|
levels: explicitLevels ?? [],
|
|
1115
1204
|
eager: explicitEager ?? [],
|
|
1116
|
-
endpoint: explicitEndpoint ?? bootstrapSummary?.config?.endpoint_prefix ??
|
|
1205
|
+
endpoint: explicitEndpoint ?? bootstrapSummary?.config?.endpoint_prefix ?? DEFAULT_ENDPOINT,
|
|
1117
1206
|
urlPrefix: "",
|
|
1118
1207
|
cacheTtl: void 0,
|
|
1119
1208
|
levelRoutes: {}
|
|
1120
1209
|
};
|
|
1121
|
-
const discoveryInputs = { explicitLevels, explicitEager, explicitEndpoint };
|
|
1210
|
+
const discoveryInputs = { explicitLevels, explicitEager, explicitEndpoint, warnings };
|
|
1122
1211
|
let autoDiscoveryCompleted = false;
|
|
1123
1212
|
let resolveReady;
|
|
1124
1213
|
let rejectReady;
|
|
@@ -1128,30 +1217,30 @@ var RouteForge = (function (exports) {
|
|
|
1128
1217
|
});
|
|
1129
1218
|
readyPromise.catch(() => {
|
|
1130
1219
|
});
|
|
1220
|
+
let readySettledOk = false;
|
|
1221
|
+
readyPromise.then(
|
|
1222
|
+
() => {
|
|
1223
|
+
readySettledOk = true;
|
|
1224
|
+
},
|
|
1225
|
+
() => {
|
|
1226
|
+
}
|
|
1227
|
+
);
|
|
1131
1228
|
const cacheTtl = cacheOpts.ttl ?? DEFAULT_CACHE_TTL;
|
|
1132
1229
|
const cacheStorage = cacheOpts.storage ?? "memory";
|
|
1133
1230
|
const cache = new RouteCache({ storage: cacheStorage, ttl: cacheTtl });
|
|
1134
1231
|
const requestInterceptors = new InterceptorManagerImpl();
|
|
1135
1232
|
const responseInterceptors = new InterceptorManagerImpl();
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
const [onFulfilled, onRejected] = entry;
|
|
1142
|
-
requestInterceptors.use(onFulfilled, onRejected);
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1233
|
+
const reqDecl = normalizeInterceptorDeclaration(
|
|
1234
|
+
declarativeInterceptors?.request
|
|
1235
|
+
);
|
|
1236
|
+
if (reqDecl.onFulfilled || reqDecl.onRejected) {
|
|
1237
|
+
requestInterceptors.use(reqDecl.onFulfilled, reqDecl.onRejected);
|
|
1145
1238
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
const [onFulfilled, onRejected] = entry;
|
|
1152
|
-
responseInterceptors.use(onFulfilled, onRejected);
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1239
|
+
const resDecl = normalizeInterceptorDeclaration(
|
|
1240
|
+
declarativeInterceptors?.response
|
|
1241
|
+
);
|
|
1242
|
+
if (resDecl.onFulfilled || resDecl.onRejected) {
|
|
1243
|
+
responseInterceptors.use(resDecl.onFulfilled, resDecl.onRejected);
|
|
1155
1244
|
}
|
|
1156
1245
|
const adapterPromise = resolveAdapter({
|
|
1157
1246
|
adapter,
|
|
@@ -1163,6 +1252,11 @@ var RouteForge = (function (exports) {
|
|
|
1163
1252
|
if (!adapterResolved) {
|
|
1164
1253
|
adapterObj = await adapterPromise.catch((e) => {
|
|
1165
1254
|
if (e instanceof AdapterNotFoundError) throw e;
|
|
1255
|
+
if (warnings) {
|
|
1256
|
+
console.warn(
|
|
1257
|
+
`[route-forge] adapter initialization failed (${e?.message ?? String(e)}); falling back to builtin`
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1166
1260
|
return resolveAdapter({
|
|
1167
1261
|
adapter: "builtin",
|
|
1168
1262
|
forgeInterceptors: { request: requestInterceptors, response: responseInterceptors }
|
|
@@ -1174,10 +1268,7 @@ var RouteForge = (function (exports) {
|
|
|
1174
1268
|
}
|
|
1175
1269
|
function assertDiscoveryReady() {
|
|
1176
1270
|
if (!autoDiscoveryCompleted && !explicitLevels?.length) {
|
|
1177
|
-
throw new
|
|
1178
|
-
"Route data not available. Auto-discovery has not completed. Use forge.ready() or forge.use(level) first.",
|
|
1179
|
-
{ code: "RF_FE_010" }
|
|
1180
|
-
);
|
|
1271
|
+
throw new DiscoveryNotReadyError();
|
|
1181
1272
|
}
|
|
1182
1273
|
}
|
|
1183
1274
|
async function fetchMeta(routeTag, url, level = "") {
|
|
@@ -1202,8 +1293,8 @@ var RouteForge = (function (exports) {
|
|
|
1202
1293
|
const resp = await doRawRequest(config);
|
|
1203
1294
|
if (!resp || resp.status < 200 || resp.status >= 300) {
|
|
1204
1295
|
throw new HTTPError(
|
|
1205
|
-
`Failed to fetch "${routeTag}": HTTP ${resp?.status}`,
|
|
1206
|
-
{ level, status: resp?.status, url, method: "GET" }
|
|
1296
|
+
`Failed to fetch "${routeTag}" (${url}): HTTP ${resp?.status}`,
|
|
1297
|
+
{ level, status: resp?.status, url, method: "GET", response: resp ?? void 0 }
|
|
1207
1298
|
);
|
|
1208
1299
|
}
|
|
1209
1300
|
return resp.data;
|
|
@@ -1240,11 +1331,14 @@ var RouteForge = (function (exports) {
|
|
|
1240
1331
|
function getRoutes(level) {
|
|
1241
1332
|
return level === void 0 ? store.getRoutes() : store.getRoutes(level);
|
|
1242
1333
|
}
|
|
1334
|
+
function getLevels() {
|
|
1335
|
+
return [...discoveryState.levels];
|
|
1336
|
+
}
|
|
1243
1337
|
function route(level, name, params) {
|
|
1244
1338
|
assertDiscoveryReady();
|
|
1245
1339
|
const meta = findRouteMeta(level, name);
|
|
1246
1340
|
if (!meta) {
|
|
1247
|
-
throw new UnknownRouteError(name, level);
|
|
1341
|
+
throw new UnknownRouteError(name, level, Object.keys(store.getRoutes(level)));
|
|
1248
1342
|
}
|
|
1249
1343
|
return buildRequestUrl(meta, params ?? {}, { baseURL, urlPrefix: discoveryState.urlPrefix });
|
|
1250
1344
|
}
|
|
@@ -1254,6 +1348,7 @@ var RouteForge = (function (exports) {
|
|
|
1254
1348
|
responseInterceptors,
|
|
1255
1349
|
load,
|
|
1256
1350
|
findRouteMeta,
|
|
1351
|
+
getRouteNames: (lvl) => Object.keys(store.getRoutes(lvl)),
|
|
1257
1352
|
baseURL,
|
|
1258
1353
|
state: discoveryState,
|
|
1259
1354
|
timeout,
|
|
@@ -1309,7 +1404,10 @@ var RouteForge = (function (exports) {
|
|
|
1309
1404
|
isLoaded,
|
|
1310
1405
|
hasRoute,
|
|
1311
1406
|
getRoutes,
|
|
1407
|
+
getLevels,
|
|
1408
|
+
warnings,
|
|
1312
1409
|
isLoading: () => loadingTracker.isLoading(),
|
|
1410
|
+
isReady: () => readySettledOk,
|
|
1313
1411
|
onLoadingChange: (cb) => loadingTracker.subscribe(cb),
|
|
1314
1412
|
interceptors: {
|
|
1315
1413
|
request: requestInterceptors,
|
|
@@ -1325,10 +1423,12 @@ var RouteForge = (function (exports) {
|
|
|
1325
1423
|
}
|
|
1326
1424
|
|
|
1327
1425
|
exports.AdapterNotFoundError = AdapterNotFoundError;
|
|
1426
|
+
exports.DiscoveryNotReadyError = DiscoveryNotReadyError;
|
|
1328
1427
|
exports.ForgeError = ForgeError;
|
|
1329
1428
|
exports.HTTPError = HTTPError;
|
|
1330
1429
|
exports.InterceptorManagerImpl = InterceptorManagerImpl;
|
|
1331
1430
|
exports.InvalidInterceptorReturnError = InvalidInterceptorReturnError;
|
|
1431
|
+
exports.InvalidPathParamError = InvalidPathParamError;
|
|
1332
1432
|
exports.LoadingTracker = LoadingTracker;
|
|
1333
1433
|
exports.MissingRouteParamError = MissingRouteParamError;
|
|
1334
1434
|
exports.NetworkError = NetworkError;
|