Repository: igorkamyshev/farfetched (ts)

Issue:
Использование относительных URL в запросах
После обновления перестали работать запросы к API в приложениях, как выяснилось, проблема в том, что в новых версиях относительные URL считаются не валидными

Хотелось бы продолжить использовать относительные URL, кроме того, было бы здорово видеть ошибки, которые прерывают запрос, в консоли, потому что сейчас запросы просто молча не отправлялись, довольно долго пришлось разбираться, что вообще происходит

Pull request description:
Fix support of relative urls in `createJsonQuery` and `createJsonMutation`
fixes #493

Patch:
diff --git a/.changeset/light-jars-destroy.md b/.changeset/light-jars-destroy.md
new file mode 100644
index 0000000..8864057
--- /dev/null
+++ b/.changeset/light-jars-destroy.md
@@ -0,0 +1,5 @@
+---
+"@farfetched/core": patch
+---
+
+Fix support of relative urls in `createJsonQuery` and `createJsonMutation`
diff --git a/packages/core/src/fetch/lib.ts b/packages/core/src/fetch/lib.ts
index a6d87d3..f2c5a9b 100644
--- a/packages/core/src/fetch/lib.ts
+++ b/packages/core/src/fetch/lib.ts
@@ -73,6 +73,11 @@ export function formatUrl(
   url: string,
   queryRecord: FetchApiRecord | string
 ): URL {
+  let urlBase: string | undefined;
+  if (url.startsWith('/')) {
+    urlBase = window.location.origin;
+  }
+
   let urlString: string;
   let queryString: string;
 
@@ -89,7 +94,7 @@ export function formatUrl(
   }
 
   try {
-    return new URL(urlString);
+    return new URL(urlString, urlBase);
   } catch (e) {
     throw configurationError({
       reason: 'Invalid URL',


Test patch:
diff --git a/packages/core/src/__tests__/relative_urls_in_jsdom.test.ts b/packages/core/src/__tests__/relative_urls_in_jsdom.test.ts
new file mode 100644
index 0000000..ac82c61
--- /dev/null
+++ b/packages/core/src/__tests__/relative_urls_in_jsdom.test.ts
@@ -0,0 +1,54 @@
+/**
+ * @vitest-environment jsdom
+ */
+import { describe, test, expect } from 'vitest';
+import { allSettled, fork } from 'effector';
+
+import { createJsonQuery } from '../query/create_json_query';
+import { unknownContract } from '../contract/unknown_contract';
+import { fetchFx } from '../fetch/fetch';
+
+describe('relative paths in createJsonQuery, issue #493', () => {
+  test('does not throw error for valid relative path', async () => {
+    const query = createJsonQuery({
+      request: { url: '/api', method: 'GET' },
+      response: { contract: unknownContract },
+    });
+
+    const scope = fork({
+      // We have to to mock fetchFx, because URL validation embed in createJsonQuery.__.executeFx
+      handlers: [[fetchFx, () => new Response(JSON.stringify('DATA'))]],
+    });
+
+    await allSettled(query.start, { scope });
+
+    expect(scope.getState(query.$error)).toBe(null);
+    expect(scope.getState(query.$data)).toBe('DATA');
+  });
+
+  test('does throw error for invalid relative path', async () => {
+    const query = createJsonQuery({
+      request: { url: 'api **** jkjj', method: 'GET' },
+      response: { contract: unknownContract },
+    });
+
+    const scope = fork({
+      // We have to to mock fetchFx, because URL validation embed in createJsonQuery.__.executeFx
+      handlers: [[fetchFx, () => new Response(JSON.stringify('DATA'))]],
+    });
+
+    await allSettled(query.start, { scope });
+
+    expect(scope.getState(query.$error)).toMatchInlineSnapshot(`
+      {
+        "errorType": "CONFIGURATION",
+        "explanation": "Operation is misconfigured",
+        "reason": "Invalid URL",
+        "validationErrors": [
+          ""api **** jkjj" is not valid URL",
+        ],
+      }
+    `);
+    expect(scope.getState(query.$data)).toBe(null);
+  });
+});