@route-forge/core 1.3.0 → 1.4.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 +40 -0
- package/dist/codegen.d.cts +1 -1
- package/dist/codegen.d.ts +1 -1
- package/dist/index.cjs +73 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +73 -53
- package/dist/index.js.map +1 -1
- package/dist/route-forge.global.js +73 -53
- package/dist/route-forge.global.js.map +1 -1
- package/dist/route-forge.global.min.js +2 -2
- package/dist/{types-D4PMbR4-.d.cts → types-BFlrOTrN.d.cts} +20 -12
- package/dist/{types-D4PMbR4-.d.ts → types-BFlrOTrN.d.ts} +20 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -278,30 +278,29 @@ function combineSignals(...signals) {
|
|
|
278
278
|
function createBuiltinHttp(forgeInterceptors) {
|
|
279
279
|
const requestMgr = forgeInterceptors?.request ?? createInterceptorManager();
|
|
280
280
|
const responseMgr = forgeInterceptors?.response ?? createInterceptorManager();
|
|
281
|
-
async function
|
|
282
|
-
const finalConfig = await runRequestInterceptors(requestMgr, config);
|
|
281
|
+
async function requestRaw(config) {
|
|
283
282
|
const signal = combineSignals(
|
|
284
|
-
|
|
285
|
-
|
|
283
|
+
config.signal,
|
|
284
|
+
config.timeout && config.timeout > 0 ? AbortSignal.timeout(config.timeout) : void 0
|
|
286
285
|
);
|
|
287
|
-
let url =
|
|
288
|
-
if (
|
|
289
|
-
const qs =
|
|
286
|
+
let url = config.url;
|
|
287
|
+
if (config.paramsSerializer && config.params) {
|
|
288
|
+
const qs = config.paramsSerializer(config.params);
|
|
290
289
|
if (qs) {
|
|
291
290
|
url = url.includes("?") ? `${url}&${qs}` : `${url}?${qs}`;
|
|
292
291
|
}
|
|
293
292
|
}
|
|
294
|
-
const headers = new Headers(
|
|
293
|
+
const headers = new Headers(config.headers);
|
|
295
294
|
const fetchInit = {
|
|
296
|
-
method:
|
|
295
|
+
method: config.method,
|
|
297
296
|
headers
|
|
298
297
|
};
|
|
299
298
|
if (signal) fetchInit.signal = signal;
|
|
300
|
-
if (
|
|
301
|
-
if (typeof
|
|
302
|
-
fetchInit.body =
|
|
299
|
+
if (config.body !== void 0 && !["GET", "HEAD"].includes(config.method.toUpperCase())) {
|
|
300
|
+
if (typeof config.body === "string" || isPassthroughBody(config.body)) {
|
|
301
|
+
fetchInit.body = config.body;
|
|
303
302
|
} else {
|
|
304
|
-
fetchInit.body = JSON.stringify(
|
|
303
|
+
fetchInit.body = JSON.stringify(config.body);
|
|
305
304
|
if (!headers.has("Content-Type")) {
|
|
306
305
|
headers.set("Content-Type", "application/json");
|
|
307
306
|
}
|
|
@@ -314,8 +313,8 @@ function createBuiltinHttp(forgeInterceptors) {
|
|
|
314
313
|
if (isAbortError(e)) throw e;
|
|
315
314
|
throw new NetworkError(
|
|
316
315
|
e instanceof Error ? e.message : String(e),
|
|
317
|
-
|
|
318
|
-
|
|
316
|
+
config.route,
|
|
317
|
+
config.level,
|
|
319
318
|
e
|
|
320
319
|
);
|
|
321
320
|
}
|
|
@@ -329,27 +328,32 @@ function createBuiltinHttp(forgeInterceptors) {
|
|
|
329
328
|
}
|
|
330
329
|
}
|
|
331
330
|
const responseData = {
|
|
332
|
-
route:
|
|
333
|
-
level:
|
|
334
|
-
method:
|
|
331
|
+
route: config.route,
|
|
332
|
+
level: config.level,
|
|
333
|
+
method: config.method,
|
|
335
334
|
url,
|
|
336
335
|
status: res.status,
|
|
337
336
|
headers: res.headers,
|
|
338
337
|
data,
|
|
339
|
-
config
|
|
338
|
+
config
|
|
340
339
|
};
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
340
|
+
if (res.status >= 200 && res.status < 300) {
|
|
341
|
+
return responseData;
|
|
342
|
+
}
|
|
343
|
+
throw new HTTPError(
|
|
344
|
+
`HTTP ${res.status} for route "${config.route}" (${config.method} ${url})`,
|
|
345
|
+
{
|
|
346
|
+
route: config.route,
|
|
347
|
+
level: config.level,
|
|
348
|
+
status: res.status,
|
|
349
|
+
url,
|
|
350
|
+
method: config.method
|
|
351
|
+
}
|
|
352
352
|
);
|
|
353
|
+
}
|
|
354
|
+
async function request(config) {
|
|
355
|
+
const finalConfig = await runRequestInterceptors(requestMgr, config);
|
|
356
|
+
const source = Promise.resolve(finalConfig).then(requestRaw);
|
|
353
357
|
return runResponseInterceptors(
|
|
354
358
|
responseMgr,
|
|
355
359
|
source
|
|
@@ -362,6 +366,7 @@ function createBuiltinHttp(forgeInterceptors) {
|
|
|
362
366
|
const del = (url, config) => request({ ...config, url, method: "DELETE" });
|
|
363
367
|
return {
|
|
364
368
|
request,
|
|
369
|
+
requestRaw,
|
|
365
370
|
interceptors: {
|
|
366
371
|
request: requestMgr,
|
|
367
372
|
response: responseMgr
|
|
@@ -573,7 +578,6 @@ function createRouteForge(options) {
|
|
|
573
578
|
const loadingTracker = new LoadingTracker();
|
|
574
579
|
const explicitLevels = options.levels;
|
|
575
580
|
const explicitEager = options.eager;
|
|
576
|
-
const explicitStrict = options.strict ?? false;
|
|
577
581
|
const explicitEndpoint = options.endpoint;
|
|
578
582
|
let effectiveLevels = explicitLevels ?? [];
|
|
579
583
|
let effectiveEager = explicitEager ?? [];
|
|
@@ -621,11 +625,6 @@ function createRouteForge(options) {
|
|
|
621
625
|
if (summary.config.url_prefix) {
|
|
622
626
|
effectiveUrlPrefix = summary.config.url_prefix.endsWith("/") ? summary.config.url_prefix.slice(0, -1) : summary.config.url_prefix;
|
|
623
627
|
}
|
|
624
|
-
if (summary.config.strict_mode && !explicitStrict) {
|
|
625
|
-
console.warn(
|
|
626
|
-
"[route-forge] backend strict_mode=true overrides frontend strict=false; forcing strict=true"
|
|
627
|
-
);
|
|
628
|
-
}
|
|
629
628
|
const backendLevels = Object.keys(summary.levels);
|
|
630
629
|
backendHasUnassignedLevel = backendLevels.includes(UNASSIGNED_LEVEL);
|
|
631
630
|
if (Array.isArray(summary.unassigned) && summary.unassigned.length > 0 && !backendHasUnassignedLevel) {
|
|
@@ -699,7 +698,10 @@ function createRouteForge(options) {
|
|
|
699
698
|
if (!adapterResolved) {
|
|
700
699
|
adapterObj = await adapterPromise.catch((e) => {
|
|
701
700
|
if (e instanceof AdapterNotFoundError) throw e;
|
|
702
|
-
return resolveAdapter({
|
|
701
|
+
return resolveAdapter({
|
|
702
|
+
adapter: "builtin",
|
|
703
|
+
forgeInterceptors: { request: requestInterceptors, response: responseInterceptors }
|
|
704
|
+
});
|
|
703
705
|
});
|
|
704
706
|
adapterResolved = true;
|
|
705
707
|
}
|
|
@@ -743,7 +745,8 @@ function createRouteForge(options) {
|
|
|
743
745
|
level
|
|
744
746
|
}
|
|
745
747
|
};
|
|
746
|
-
const
|
|
748
|
+
const doRawRequest = adp.requestRaw ?? adp.request;
|
|
749
|
+
const resp = await doRawRequest(config);
|
|
747
750
|
if (!resp || resp.status < 200 || resp.status >= 300) {
|
|
748
751
|
throw new HTTPError(
|
|
749
752
|
`Failed to load level "${level}": HTTP ${resp?.status}`,
|
|
@@ -846,23 +849,40 @@ function createRouteForge(options) {
|
|
|
846
849
|
}
|
|
847
850
|
return void 0;
|
|
848
851
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
852
|
+
function api(level, name, params = {}) {
|
|
853
|
+
let ctrl;
|
|
854
|
+
let abortedBeforeInit = false;
|
|
855
|
+
let abortReason;
|
|
856
|
+
const work = (async () => {
|
|
857
|
+
ctrl = new AbortController();
|
|
858
|
+
if (abortedBeforeInit) {
|
|
859
|
+
ctrl.abort(abortReason);
|
|
860
|
+
}
|
|
861
|
+
await autoDiscoveryPromise;
|
|
862
|
+
await load(level);
|
|
863
|
+
const meta = findRouteMeta(level, name);
|
|
864
|
+
if (!meta) {
|
|
865
|
+
throw new UnknownRouteError(name, level);
|
|
866
|
+
}
|
|
867
|
+
return doApiCall(meta, params, ctrl.signal);
|
|
868
|
+
})();
|
|
869
|
+
const request = work;
|
|
870
|
+
request.abort = () => {
|
|
871
|
+
if (ctrl) {
|
|
872
|
+
ctrl.abort();
|
|
873
|
+
} else {
|
|
874
|
+
abortedBeforeInit = true;
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
return request;
|
|
857
878
|
}
|
|
858
|
-
async function doApiCall(meta, params) {
|
|
879
|
+
async function doApiCall(meta, params, signal) {
|
|
859
880
|
const {
|
|
860
881
|
pathParams,
|
|
861
882
|
query,
|
|
862
883
|
body,
|
|
863
884
|
headers,
|
|
864
|
-
timeout: perCallTimeout
|
|
865
|
-
signal
|
|
885
|
+
timeout: perCallTimeout
|
|
866
886
|
} = resolveApiParams(params);
|
|
867
887
|
if (signal?.aborted) {
|
|
868
888
|
throw new RequestAbortedError(meta.name, meta.level, signal.reason);
|
|
@@ -906,7 +926,7 @@ function createRouteForge(options) {
|
|
|
906
926
|
},
|
|
907
927
|
(err) => {
|
|
908
928
|
if (err instanceof ForgeError) throw err;
|
|
909
|
-
if (isAbortError2(err,
|
|
929
|
+
if (isAbortError2(err, signal)) {
|
|
910
930
|
throw new RequestAbortedError(meta.name, meta.level, err);
|
|
911
931
|
}
|
|
912
932
|
throw new NetworkError(
|
|
@@ -994,7 +1014,8 @@ function createRouteForge(options) {
|
|
|
994
1014
|
}
|
|
995
1015
|
const forgeResolver = { load, hasRoute };
|
|
996
1016
|
function createBoundForge(level, prefix) {
|
|
997
|
-
const levelLoadedPromise = load(level)
|
|
1017
|
+
const levelLoadedPromise = load(level);
|
|
1018
|
+
levelLoadedPromise.catch(() => {
|
|
998
1019
|
});
|
|
999
1020
|
const apiFn = prefix ? (name, params) => resolveRouteName(forgeResolver, level, prefix, name).then(
|
|
1000
1021
|
(resolved) => api(level, resolved, params)
|
|
@@ -1094,7 +1115,6 @@ function resolveApiParams(input) {
|
|
|
1094
1115
|
body: rawBody,
|
|
1095
1116
|
headers: rawHeaders,
|
|
1096
1117
|
timeout: perCallTimeout,
|
|
1097
|
-
signal,
|
|
1098
1118
|
...flatRest
|
|
1099
1119
|
} = input;
|
|
1100
1120
|
const pathParams = explicitParams ? { ...explicitParams } : {};
|
|
@@ -1127,7 +1147,7 @@ function resolveApiParams(input) {
|
|
|
1127
1147
|
pathParams.headers = rawHeaders;
|
|
1128
1148
|
}
|
|
1129
1149
|
}
|
|
1130
|
-
return { pathParams, query, body, headers, timeout: perCallTimeout
|
|
1150
|
+
return { pathParams, query, body, headers, timeout: perCallTimeout };
|
|
1131
1151
|
}
|
|
1132
1152
|
function isAbortError2(err, signal) {
|
|
1133
1153
|
if (signal?.aborted) return true;
|