@karbonjs/api 0.1.0 → 0.2.1
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 +2 -2
- package/dist/client.d.ts +0 -27
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -80
- package/dist/client.js.map +0 -1
- package/dist/server.d.ts +0 -11
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -53
- package/dist/server.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@karbonjs/api",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Type-safe API client for Karbon backends with SSR and client support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@karbonjs/types": "0.1
|
|
18
|
+
"@karbonjs/types": "0.2.1"
|
|
19
19
|
},
|
|
20
20
|
"publishConfig": {
|
|
21
21
|
"access": "public"
|
package/dist/client.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { ApiCallOptions, ApiResult } from '@karbonjs/types';
|
|
2
|
-
export interface ClientApiConfig {
|
|
3
|
-
baseUrl: string;
|
|
4
|
-
/** Return current auth token */
|
|
5
|
-
getToken: () => string | null;
|
|
6
|
-
/** Called to refresh an expired token. Return new token or null. */
|
|
7
|
-
refreshToken?: () => Promise<string | null>;
|
|
8
|
-
/** Called when refresh fails (user should be logged out) */
|
|
9
|
-
onAuthFailure?: () => void;
|
|
10
|
-
timeout?: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Client-side API helper with automatic token refresh on 401.
|
|
14
|
-
*
|
|
15
|
-
* ```ts
|
|
16
|
-
* const api = createClientApi({
|
|
17
|
-
* baseUrl: '/api/v1',
|
|
18
|
-
* getToken: () => authStore.token,
|
|
19
|
-
* refreshToken: () => authStore.refresh(),
|
|
20
|
-
* onAuthFailure: () => goto('/login'),
|
|
21
|
-
* })
|
|
22
|
-
*
|
|
23
|
-
* const data = await api<{ data: Article[] }>('/articles')
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export declare function createClientApi(config: ClientApiConfig): <T extends ApiResult = ApiResult>(endpoint: string, options?: ApiCallOptions) => Promise<T>;
|
|
27
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,gCAAgC;IAChC,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;IAC7B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC3C,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,IAG3B,CAAC,SAAS,SAAS,GAAG,SAAS,EACvD,UAAU,MAAM,EAChB,UAAS,cAAmB,KAC3B,OAAO,CAAC,CAAC,CAAC,CAmEd"}
|
package/dist/client.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-side API helper with automatic token refresh on 401.
|
|
3
|
-
*
|
|
4
|
-
* ```ts
|
|
5
|
-
* const api = createClientApi({
|
|
6
|
-
* baseUrl: '/api/v1',
|
|
7
|
-
* getToken: () => authStore.token,
|
|
8
|
-
* refreshToken: () => authStore.refresh(),
|
|
9
|
-
* onAuthFailure: () => goto('/login'),
|
|
10
|
-
* })
|
|
11
|
-
*
|
|
12
|
-
* const data = await api<{ data: Article[] }>('/articles')
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
export function createClientApi(config) {
|
|
16
|
-
let refreshPromise = null;
|
|
17
|
-
return async function api(endpoint, options = {}) {
|
|
18
|
-
const { method = 'GET', body, headers: extraHeaders, timeout } = options;
|
|
19
|
-
const token = options.token ?? config.getToken();
|
|
20
|
-
const headers = {
|
|
21
|
-
'Content-Type': 'application/json',
|
|
22
|
-
...extraHeaders,
|
|
23
|
-
};
|
|
24
|
-
if (token) {
|
|
25
|
-
headers['Authorization'] = `Bearer ${token}`;
|
|
26
|
-
}
|
|
27
|
-
const doFetch = async (authToken) => {
|
|
28
|
-
const h = { ...headers };
|
|
29
|
-
if (authToken)
|
|
30
|
-
h['Authorization'] = `Bearer ${authToken}`;
|
|
31
|
-
const controller = new AbortController();
|
|
32
|
-
const timer = setTimeout(() => controller.abort(), timeout ?? config.timeout ?? 15_000);
|
|
33
|
-
const res = await fetch(`${config.baseUrl}${endpoint}`, {
|
|
34
|
-
method,
|
|
35
|
-
headers: h,
|
|
36
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
37
|
-
signal: controller.signal,
|
|
38
|
-
});
|
|
39
|
-
clearTimeout(timer);
|
|
40
|
-
return res;
|
|
41
|
-
};
|
|
42
|
-
try {
|
|
43
|
-
let res = await doFetch(token);
|
|
44
|
-
// Auto-refresh on 401
|
|
45
|
-
if (res.status === 401 && config.refreshToken) {
|
|
46
|
-
if (!refreshPromise) {
|
|
47
|
-
refreshPromise = config.refreshToken().finally(() => { refreshPromise = null; });
|
|
48
|
-
}
|
|
49
|
-
const newToken = await refreshPromise;
|
|
50
|
-
if (newToken) {
|
|
51
|
-
res = await doFetch(newToken);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
config.onAuthFailure?.();
|
|
55
|
-
return { ok: false, status: 401, message: 'Authentication failed' };
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (!res.ok) {
|
|
59
|
-
const text = await res.text();
|
|
60
|
-
let message;
|
|
61
|
-
try {
|
|
62
|
-
const parsed = JSON.parse(text);
|
|
63
|
-
message = parsed.message || text;
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
message = text;
|
|
67
|
-
}
|
|
68
|
-
return { ok: false, status: res.status, message };
|
|
69
|
-
}
|
|
70
|
-
if (res.status === 204)
|
|
71
|
-
return { ok: true };
|
|
72
|
-
const data = await res.json();
|
|
73
|
-
return { ok: true, ...data };
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
return { ok: false, status: 0, message: 'Network error' };
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ApiCallOptions, ApiResult } from '@karbonjs/types';
|
|
2
|
-
/**
|
|
3
|
-
* Server-side API client (for SSR / SvelteKit load functions / Next.js getServerSideProps).
|
|
4
|
-
* Uses fetch with AbortController timeout.
|
|
5
|
-
*
|
|
6
|
-
* ```ts
|
|
7
|
-
* const data = await callApi<{ data: Article[] }>('/articles?per_page=10')
|
|
8
|
-
* ```
|
|
9
|
-
*/
|
|
10
|
-
export declare function createServerApi(baseUrl: string, defaultTimeout?: number): <T extends ApiResult = ApiResult>(endpoint: string, options?: ApiCallOptions) => Promise<T>;
|
|
11
|
-
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhE;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,SAAS,IACxC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC3D,UAAU,MAAM,EAChB,UAAS,cAAmB,KAC3B,OAAO,CAAC,CAAC,CAAC,CA4Cd"}
|
package/dist/server.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server-side API client (for SSR / SvelteKit load functions / Next.js getServerSideProps).
|
|
3
|
-
* Uses fetch with AbortController timeout.
|
|
4
|
-
*
|
|
5
|
-
* ```ts
|
|
6
|
-
* const data = await callApi<{ data: Article[] }>('/articles?per_page=10')
|
|
7
|
-
* ```
|
|
8
|
-
*/
|
|
9
|
-
export function createServerApi(baseUrl, defaultTimeout = 15_000) {
|
|
10
|
-
return async function callApi(endpoint, options = {}) {
|
|
11
|
-
const { method = 'GET', body, token, headers: extraHeaders, timeout } = options;
|
|
12
|
-
const headers = {
|
|
13
|
-
'Content-Type': 'application/json',
|
|
14
|
-
...extraHeaders,
|
|
15
|
-
};
|
|
16
|
-
if (token) {
|
|
17
|
-
headers['Authorization'] = `Bearer ${token}`;
|
|
18
|
-
}
|
|
19
|
-
let res;
|
|
20
|
-
try {
|
|
21
|
-
const controller = new AbortController();
|
|
22
|
-
const timer = setTimeout(() => controller.abort(), timeout ?? defaultTimeout);
|
|
23
|
-
res = await fetch(`${baseUrl}${endpoint}`, {
|
|
24
|
-
method,
|
|
25
|
-
headers,
|
|
26
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
27
|
-
signal: controller.signal,
|
|
28
|
-
});
|
|
29
|
-
clearTimeout(timer);
|
|
30
|
-
}
|
|
31
|
-
catch (err) {
|
|
32
|
-
console.error(`[karbon-api] Connection failed to ${baseUrl}:`, err);
|
|
33
|
-
return { ok: false, status: 503, message: 'Service temporarily unavailable' };
|
|
34
|
-
}
|
|
35
|
-
if (!res.ok) {
|
|
36
|
-
const text = await res.text();
|
|
37
|
-
let message;
|
|
38
|
-
try {
|
|
39
|
-
const parsed = JSON.parse(text);
|
|
40
|
-
message = parsed.message || text;
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
message = text;
|
|
44
|
-
}
|
|
45
|
-
return { ok: false, status: res.status, message };
|
|
46
|
-
}
|
|
47
|
-
if (res.status === 204)
|
|
48
|
-
return { ok: true };
|
|
49
|
-
const data = await res.json();
|
|
50
|
-
return { ok: true, ...data };
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,cAAc,GAAG,MAAM;IACtE,OAAO,KAAK,UAAU,OAAO,CAC3B,QAAgB,EAChB,UAA0B,EAAE;QAE5B,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,OAAO,CAAA;QAE/E,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,GAAG,YAAY;SAChB,CAAA;QAED,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAA;QAC9C,CAAC;QAED,IAAI,GAAa,CAAA;QACjB,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,IAAI,cAAc,CAAC,CAAA;YAC7E,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,GAAG,QAAQ,EAAE,EAAE;gBACzC,MAAM;gBACN,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC7C,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAA;YACF,YAAY,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,qCAAqC,OAAO,GAAG,EAAE,GAAG,CAAC,CAAA;YACnE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,iCAAiC,EAAO,CAAA;QACpF,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;YAC7B,IAAI,OAAe,CAAA;YACnB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBAC/B,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAA;YAClC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,IAAI,CAAA;YAChB,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAO,CAAA;QACxD,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAO,CAAA;QAChD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QAC7B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,EAAO,CAAA;IACnC,CAAC,CAAA;AACH,CAAC"}
|