@startsimpli/api 0.2.5 → 0.3.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/package.json +1 -1
- package/src/lib/fetch-wrapper.ts +3 -0
- package/src/utils/url-builder.ts +22 -8
package/package.json
CHANGED
package/src/lib/fetch-wrapper.ts
CHANGED
|
@@ -75,12 +75,15 @@ export class FetchWrapper {
|
|
|
75
75
|
const headers = await this.buildHeaders(customHeaders);
|
|
76
76
|
|
|
77
77
|
// Execute request
|
|
78
|
+
const hasAuth = headers.has('Authorization');
|
|
79
|
+
console.log(`[FetchWrapper] ${method} ${url} (auth=${hasAuth})`);
|
|
78
80
|
let response = await fetch(url, {
|
|
79
81
|
method,
|
|
80
82
|
headers,
|
|
81
83
|
credentials: 'include',
|
|
82
84
|
...fetchOptions,
|
|
83
85
|
});
|
|
86
|
+
console.log(`[FetchWrapper] ${method} ${url} → ${response.status} ${response.statusText}`);
|
|
84
87
|
|
|
85
88
|
// Handle 401 Unauthorized - attempt token refresh
|
|
86
89
|
if (response.status === 401) {
|
package/src/utils/url-builder.ts
CHANGED
|
@@ -17,25 +17,39 @@ export function buildUrl({ baseUrl, endpoint, params, id }: UrlBuilderOptions):
|
|
|
17
17
|
const cleanBase = baseUrl.replace(/\/$/, '');
|
|
18
18
|
const cleanEndpoint = endpoint.replace(/^\//, '');
|
|
19
19
|
|
|
20
|
+
// Separate any inline query string from the endpoint path
|
|
21
|
+
const [pathPart, inlineQuery] = `${cleanBase}/${cleanEndpoint}`.split('?', 2);
|
|
22
|
+
|
|
20
23
|
// Build path with optional ID
|
|
21
|
-
let path =
|
|
24
|
+
let path = pathPart;
|
|
22
25
|
if (id !== undefined) {
|
|
23
26
|
path += `/${id}`;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
// Add trailing slash (Django convention)
|
|
27
|
-
|
|
29
|
+
// Add trailing slash (Django convention) — only when calling Django
|
|
30
|
+
// directly (baseUrl is set). When proxied through Next.js (baseUrl empty),
|
|
31
|
+
// the rewrite rule adds the slash; adding it here causes a 308 redirect
|
|
32
|
+
// that drops the Authorization header.
|
|
33
|
+
if (baseUrl && !path.endsWith('/')) {
|
|
28
34
|
path += '/';
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
// Merge inline query params with explicit params
|
|
38
|
+
const mergedParams = new URLSearchParams(inlineQuery || '');
|
|
39
|
+
if (params) {
|
|
40
|
+
const explicit = buildQueryString(params);
|
|
41
|
+
if (explicit) {
|
|
42
|
+
for (const [k, v] of new URLSearchParams(explicit)) {
|
|
43
|
+
mergedParams.append(k, v);
|
|
44
|
+
}
|
|
36
45
|
}
|
|
37
46
|
}
|
|
38
47
|
|
|
48
|
+
const qs = mergedParams.toString();
|
|
49
|
+
if (qs) {
|
|
50
|
+
path += `?${qs}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
return path;
|
|
40
54
|
}
|
|
41
55
|
|