@route-forge/core 1.3.1 → 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/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 request(config) {
282
- const finalConfig = await runRequestInterceptors(requestMgr, config);
281
+ async function requestRaw(config) {
283
282
  const signal = combineSignals(
284
- finalConfig.signal,
285
- finalConfig.timeout && finalConfig.timeout > 0 ? AbortSignal.timeout(finalConfig.timeout) : void 0
283
+ config.signal,
284
+ config.timeout && config.timeout > 0 ? AbortSignal.timeout(config.timeout) : void 0
286
285
  );
287
- let url = finalConfig.url;
288
- if (finalConfig.paramsSerializer && finalConfig.params) {
289
- const qs = finalConfig.paramsSerializer(finalConfig.params);
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(finalConfig.headers);
293
+ const headers = new Headers(config.headers);
295
294
  const fetchInit = {
296
- method: finalConfig.method,
295
+ method: config.method,
297
296
  headers
298
297
  };
299
298
  if (signal) fetchInit.signal = signal;
300
- if (finalConfig.body !== void 0 && !["GET", "HEAD"].includes(finalConfig.method.toUpperCase())) {
301
- if (typeof finalConfig.body === "string" || isPassthroughBody(finalConfig.body)) {
302
- fetchInit.body = finalConfig.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(finalConfig.body);
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
- finalConfig.route,
318
- finalConfig.level,
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: finalConfig.route,
333
- level: finalConfig.level,
334
- method: finalConfig.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: finalConfig
338
+ config
340
339
  };
341
- const source = res.status >= 200 && res.status < 300 ? Promise.resolve(responseData) : Promise.reject(
342
- new HTTPError(
343
- `HTTP ${res.status} for route "${finalConfig.route}" (${finalConfig.method} ${url})`,
344
- {
345
- route: finalConfig.route,
346
- level: finalConfig.level,
347
- status: res.status,
348
- url,
349
- method: finalConfig.method
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({ adapter: "builtin" });
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 resp = await adp.request(config);
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}`,
@@ -1011,7 +1014,8 @@ function createRouteForge(options) {
1011
1014
  }
1012
1015
  const forgeResolver = { load, hasRoute };
1013
1016
  function createBoundForge(level, prefix) {
1014
- const levelLoadedPromise = load(level).catch(() => {
1017
+ const levelLoadedPromise = load(level);
1018
+ levelLoadedPromise.catch(() => {
1015
1019
  });
1016
1020
  const apiFn = prefix ? (name, params) => resolveRouteName(forgeResolver, level, prefix, name).then(
1017
1021
  (resolved) => api(level, resolved, params)