@ablogcms/fetch-client 3.2.28-beta.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 ADDED
@@ -0,0 +1,36 @@
1
+ # @ablogcms/fetch-client
2
+
3
+ CSRF トークン(`window.csrfToken`)を自動付与する fetch ベースの HTTP クライアントと、
4
+ アップロード進捗を扱える XHR ベースのアップロード関数を提供するパッケージ。
5
+
6
+ ## 使い方
7
+
8
+ ```ts
9
+ import { fetchClient, isFetchError } from '@ablogcms/fetch-client';
10
+
11
+ try {
12
+ const { data } = await fetchClient.get<MyResponse>(url, { params: { page: 1 } });
13
+ } catch (error) {
14
+ if (isFetchError(error)) {
15
+ console.error(error.status, error.statusText);
16
+ }
17
+ }
18
+
19
+ await fetchClient.post(url, formData);
20
+ ```
21
+
22
+ - `fetchClient.get(url, config?)` / `fetchClient.post(url, body?, config?)`: リクエストを送り、
23
+ `{ data, status, statusText, headers }` を返す。`config.params` はクエリ文字列に変換される。
24
+ - `FetchError`: レスポンスが `ok` でない場合に throw されるエラー。`isFetchError(error)` で判別できる。
25
+ - `isAbortError(error)`: `AbortSignal` による中断エラーかどうかを判別する。
26
+
27
+ ```ts
28
+ import { xhrUpload } from '@ablogcms/fetch-client/xhr-upload';
29
+
30
+ await xhrUpload(url, formData, {
31
+ onUploadProgress: ({ loaded, total }) => console.log(loaded / total),
32
+ });
33
+ ```
34
+
35
+ - `xhrUpload(url, formData, options?)`: `XMLHttpRequest` でアップロードする。`onUploadProgress` で
36
+ 進捗を受け取れる(`fetch` の `Request`/`Response` では進捗イベントが取得できないため XHR を使う)。
@@ -0,0 +1,112 @@
1
+ // src/fetch-client.ts
2
+ var FetchError = class extends Error {
3
+ status;
4
+ statusText;
5
+ response;
6
+ constructor(message, status, statusText, response) {
7
+ super(message);
8
+ this.name = "FetchError";
9
+ this.status = status;
10
+ this.statusText = statusText;
11
+ this.response = response;
12
+ }
13
+ };
14
+ function isFetchError(error) {
15
+ return error instanceof FetchError;
16
+ }
17
+ function isAbortError(error) {
18
+ return error instanceof DOMException && error.name === "AbortError";
19
+ }
20
+ function getDefaultHeaders() {
21
+ return {
22
+ "X-Requested-With": "XMLHttpRequest",
23
+ "X-Csrf-Token": window.csrfToken || ""
24
+ };
25
+ }
26
+ function buildUrl(url, params) {
27
+ if (!params) return url;
28
+ const searchParams = new URLSearchParams();
29
+ for (const [key, value] of Object.entries(params)) {
30
+ if (value != null) {
31
+ if (Array.isArray(value)) {
32
+ value.forEach((v) => searchParams.append(key, v));
33
+ } else {
34
+ searchParams.append(key, String(value));
35
+ }
36
+ }
37
+ }
38
+ const queryString = searchParams.toString();
39
+ if (!queryString) return url;
40
+ const separator = url.includes("?") ? "&" : "?";
41
+ return `${url}${separator}${queryString}`;
42
+ }
43
+ async function parseResponse(response, responseType) {
44
+ if (responseType === "blob") {
45
+ return await response.blob();
46
+ }
47
+ if (responseType === "text") {
48
+ return await response.text();
49
+ }
50
+ const contentType = response.headers.get("content-type") || "";
51
+ if (contentType.includes("application/json")) {
52
+ return await response.json();
53
+ }
54
+ return await response.text();
55
+ }
56
+ async function request(url, init, config = {}) {
57
+ const finalUrl = buildUrl(url, config.params);
58
+ const headers = {
59
+ ...getDefaultHeaders(),
60
+ ...config.headers
61
+ };
62
+ if (init.body && !(init.body instanceof FormData) && !(init.body instanceof URLSearchParams)) {
63
+ headers["Content-Type"] = "application/json";
64
+ }
65
+ const response = await fetch(finalUrl, {
66
+ ...init,
67
+ headers,
68
+ signal: config.signal
69
+ });
70
+ if (!response.ok) {
71
+ const fetchResponse = {
72
+ data: await parseResponse(response, config.responseType),
73
+ status: response.status,
74
+ statusText: response.statusText,
75
+ headers: response.headers
76
+ };
77
+ throw new FetchError(
78
+ `Request failed with status ${response.status}`,
79
+ response.status,
80
+ response.statusText,
81
+ fetchResponse
82
+ );
83
+ }
84
+ const data = await parseResponse(response, config.responseType);
85
+ return {
86
+ data,
87
+ status: response.status,
88
+ statusText: response.statusText,
89
+ headers: response.headers
90
+ };
91
+ }
92
+ async function get(url, config) {
93
+ return request(url, { method: "GET" }, config);
94
+ }
95
+ async function post(url, body, config) {
96
+ let requestBody;
97
+ if (body instanceof FormData || body instanceof URLSearchParams) {
98
+ requestBody = body;
99
+ } else if (body != null) {
100
+ requestBody = JSON.stringify(body);
101
+ }
102
+ return request(url, { method: "POST", body: requestBody }, config);
103
+ }
104
+ var fetchClient = { get, post };
105
+
106
+ export {
107
+ FetchError,
108
+ isFetchError,
109
+ isAbortError,
110
+ fetchClient
111
+ };
112
+ //# sourceMappingURL=chunk-YZ4WXGT5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/fetch-client.ts"],"sourcesContent":["export interface FetchResponse<T> {\n data: T;\n status: number;\n statusText: string;\n headers: Headers;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class FetchError<T = any> extends Error {\n status: number;\n\n statusText: string;\n\n response?: FetchResponse<T>;\n\n constructor(message: string, status: number, statusText: string, response?: FetchResponse<T>) {\n super(message);\n this.name = 'FetchError';\n this.status = status;\n this.statusText = statusText;\n this.response = response;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isFetchError<T = any>(error: unknown): error is FetchError<T> {\n return error instanceof FetchError;\n}\n\nexport function isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === 'AbortError';\n}\n\nexport interface FetchClientConfig {\n params?: Record<string, string | number | boolean | null | undefined | string[]>;\n responseType?: 'json' | 'blob' | 'text';\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\nfunction getDefaultHeaders(): Record<string, string> {\n return {\n 'X-Requested-With': 'XMLHttpRequest',\n 'X-Csrf-Token': window.csrfToken || '',\n };\n}\n\nfunction buildUrl(url: string, params?: FetchClientConfig['params']): string {\n if (!params) return url;\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value != null) {\n if (Array.isArray(value)) {\n value.forEach((v) => searchParams.append(key, v));\n } else {\n searchParams.append(key, String(value));\n }\n }\n }\n const queryString = searchParams.toString();\n if (!queryString) return url;\n const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}${queryString}`;\n}\n\nasync function parseResponse<T>(response: Response, responseType?: string): Promise<T> {\n if (responseType === 'blob') {\n return (await response.blob()) as T;\n }\n if (responseType === 'text') {\n return (await response.text()) as T;\n }\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as T;\n}\n\nasync function request<T>(url: string, init: RequestInit, config: FetchClientConfig = {}): Promise<FetchResponse<T>> {\n const finalUrl = buildUrl(url, config.params);\n\n const headers: Record<string, string> = {\n ...getDefaultHeaders(),\n ...config.headers,\n };\n\n // FormData/URLSearchParamsの場合はContent-Typeを設定しない(ブラウザが自動設定)\n if (init.body && !(init.body instanceof FormData) && !(init.body instanceof URLSearchParams)) {\n headers['Content-Type'] = 'application/json';\n }\n\n const response = await fetch(finalUrl, {\n ...init,\n headers,\n signal: config.signal,\n });\n\n if (!response.ok) {\n const fetchResponse: FetchResponse<T> = {\n data: await parseResponse<T>(response, config.responseType),\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n };\n throw new FetchError<T>(\n `Request failed with status ${response.status}`,\n response.status,\n response.statusText,\n fetchResponse\n );\n }\n\n const data = await parseResponse<T>(response, config.responseType);\n return {\n data,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function get<T = any>(url: string, config?: FetchClientConfig): Promise<FetchResponse<T>> {\n return request<T>(url, { method: 'GET' }, config);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function post<T = any>(\n url: string,\n body?: FormData | URLSearchParams | Record<string, unknown> | null,\n config?: FetchClientConfig\n): Promise<FetchResponse<T>> {\n let requestBody: BodyInit | undefined;\n if (body instanceof FormData || body instanceof URLSearchParams) {\n requestBody = body;\n } else if (body != null) {\n requestBody = JSON.stringify(body);\n }\n return request<T>(url, { method: 'POST', body: requestBody }, config);\n}\n\nexport const fetchClient = { get, post };\n"],"mappings":"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","names":[]}
@@ -0,0 +1,27 @@
1
+ export interface FetchResponse<T> {
2
+ data: T;
3
+ status: number;
4
+ statusText: string;
5
+ headers: Headers;
6
+ }
7
+ export declare class FetchError<T = any> extends Error {
8
+ status: number;
9
+ statusText: string;
10
+ response?: FetchResponse<T>;
11
+ constructor(message: string, status: number, statusText: string, response?: FetchResponse<T>);
12
+ }
13
+ export declare function isFetchError<T = any>(error: unknown): error is FetchError<T>;
14
+ export declare function isAbortError(error: unknown): boolean;
15
+ export interface FetchClientConfig {
16
+ params?: Record<string, string | number | boolean | null | undefined | string[]>;
17
+ responseType?: 'json' | 'blob' | 'text';
18
+ signal?: AbortSignal;
19
+ headers?: Record<string, string>;
20
+ }
21
+ declare function get<T = any>(url: string, config?: FetchClientConfig): Promise<FetchResponse<T>>;
22
+ declare function post<T = any>(url: string, body?: FormData | URLSearchParams | Record<string, unknown> | null, config?: FetchClientConfig): Promise<FetchResponse<T>>;
23
+ export declare const fetchClient: {
24
+ get: typeof get;
25
+ post: typeof post;
26
+ };
27
+ export {};
@@ -0,0 +1 @@
1
+ export * from './fetch-client.js';
package/dist/index.mjs ADDED
@@ -0,0 +1,13 @@
1
+ import {
2
+ FetchError,
3
+ fetchClient,
4
+ isAbortError,
5
+ isFetchError
6
+ } from "./chunk-YZ4WXGT5.mjs";
7
+ export {
8
+ FetchError,
9
+ fetchClient,
10
+ isAbortError,
11
+ isFetchError
12
+ };
13
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ import { type FetchResponse } from './fetch-client.js';
2
+ interface XhrUploadOptions {
3
+ onUploadProgress?: (event: {
4
+ loaded: number;
5
+ total: number;
6
+ }) => void;
7
+ }
8
+ export declare function xhrUpload<T = any>(url: string, formData: FormData, options?: XhrUploadOptions): Promise<FetchResponse<T>>;
9
+ export {};
@@ -0,0 +1,69 @@
1
+ import {
2
+ FetchError
3
+ } from "./chunk-YZ4WXGT5.mjs";
4
+
5
+ // src/xhr-upload.ts
6
+ function xhrUpload(url, formData, options) {
7
+ return new Promise((resolve, reject) => {
8
+ const xhr = new XMLHttpRequest();
9
+ xhr.open("POST", url);
10
+ xhr.timeout = 12e4;
11
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
12
+ xhr.setRequestHeader("X-Csrf-Token", window.csrfToken || "");
13
+ if (options?.onUploadProgress) {
14
+ xhr.upload.addEventListener("progress", (e) => {
15
+ if (e.lengthComputable) {
16
+ options.onUploadProgress?.({ loaded: e.loaded, total: e.total });
17
+ }
18
+ });
19
+ }
20
+ xhr.addEventListener("load", () => {
21
+ const headers = new Headers();
22
+ const rawHeaders = xhr.getAllResponseHeaders().trim().split(/[\r\n]+/);
23
+ for (const line of rawHeaders) {
24
+ const index = line.indexOf(":");
25
+ if (index > -1) {
26
+ const key = line.slice(0, index).trim();
27
+ const value = line.slice(index + 1).trim();
28
+ headers.append(key, value);
29
+ }
30
+ }
31
+ if (xhr.status < 200 || xhr.status >= 300) {
32
+ reject(new FetchError(`Upload failed with status ${xhr.status}`, xhr.status, xhr.statusText));
33
+ return;
34
+ }
35
+ const contentType = xhr.getResponseHeader("Content-Type") || "";
36
+ if (contentType.includes("application/json")) {
37
+ let parsed;
38
+ try {
39
+ parsed = JSON.parse(xhr.responseText);
40
+ } catch {
41
+ reject(new TypeError("Failed to parse JSON response"));
42
+ return;
43
+ }
44
+ resolve({
45
+ data: parsed,
46
+ status: xhr.status,
47
+ statusText: xhr.statusText,
48
+ headers
49
+ });
50
+ } else {
51
+ reject(new TypeError(`Unexpected Content-Type: ${contentType}`));
52
+ }
53
+ });
54
+ xhr.addEventListener("error", () => {
55
+ reject(new Error("Upload failed"));
56
+ });
57
+ xhr.addEventListener("timeout", () => {
58
+ reject(new Error("Upload timed out"));
59
+ });
60
+ xhr.addEventListener("abort", () => {
61
+ reject(new Error("Upload aborted"));
62
+ });
63
+ xhr.send(formData);
64
+ });
65
+ }
66
+ export {
67
+ xhrUpload
68
+ };
69
+ //# sourceMappingURL=xhr-upload.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/xhr-upload.ts"],"sourcesContent":["import { FetchError, type FetchResponse } from './fetch-client';\n\ninterface XhrUploadOptions {\n onUploadProgress?: (event: { loaded: number; total: number }) => void;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function xhrUpload<T = any>(\n url: string,\n formData: FormData,\n options?: XhrUploadOptions\n): Promise<FetchResponse<T>> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('POST', url);\n xhr.timeout = 120_000;\n xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n xhr.setRequestHeader('X-Csrf-Token', window.csrfToken || '');\n\n if (options?.onUploadProgress) {\n xhr.upload.addEventListener('progress', (e) => {\n if (e.lengthComputable) {\n options.onUploadProgress?.({ loaded: e.loaded, total: e.total });\n }\n });\n }\n\n xhr.addEventListener('load', () => {\n const headers = new Headers();\n const rawHeaders = xhr\n .getAllResponseHeaders()\n .trim()\n .split(/[\\r\\n]+/);\n for (const line of rawHeaders) {\n const index = line.indexOf(':');\n if (index > -1) {\n const key = line.slice(0, index).trim();\n const value = line.slice(index + 1).trim();\n headers.append(key, value);\n }\n }\n\n if (xhr.status < 200 || xhr.status >= 300) {\n reject(new FetchError(`Upload failed with status ${xhr.status}`, xhr.status, xhr.statusText));\n return;\n }\n\n const contentType = xhr.getResponseHeader('Content-Type') || '';\n if (contentType.includes('application/json')) {\n let parsed: T;\n try {\n parsed = JSON.parse(xhr.responseText) as T;\n } catch {\n reject(new TypeError('Failed to parse JSON response'));\n return;\n }\n resolve({\n data: parsed,\n status: xhr.status,\n statusText: xhr.statusText,\n headers,\n });\n } else {\n reject(new TypeError(`Unexpected Content-Type: ${contentType}`));\n }\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Upload failed'));\n });\n\n xhr.addEventListener('timeout', () => {\n reject(new Error('Upload timed out'));\n });\n\n xhr.addEventListener('abort', () => {\n reject(new Error('Upload aborted'));\n });\n\n xhr.send(formData);\n });\n}\n"],"mappings":";;;;;AAOO,SAAS,UACd,KACA,UACA,SAC2B;AAC3B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,IAAI,eAAe;AAC/B,QAAI,KAAK,QAAQ,GAAG;AACpB,QAAI,UAAU;AACd,QAAI,iBAAiB,oBAAoB,gBAAgB;AACzD,QAAI,iBAAiB,gBAAgB,OAAO,aAAa,EAAE;AAE3D,QAAI,SAAS,kBAAkB;AAC7B,UAAI,OAAO,iBAAiB,YAAY,CAAC,MAAM;AAC7C,YAAI,EAAE,kBAAkB;AACtB,kBAAQ,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,MAAM,CAAC;AAAA,QACjE;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,iBAAiB,QAAQ,MAAM;AACjC,YAAM,UAAU,IAAI,QAAQ;AAC5B,YAAM,aAAa,IAChB,sBAAsB,EACtB,KAAK,EACL,MAAM,SAAS;AAClB,iBAAW,QAAQ,YAAY;AAC7B,cAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,YAAI,QAAQ,IAAI;AACd,gBAAM,MAAM,KAAK,MAAM,GAAG,KAAK,EAAE,KAAK;AACtC,gBAAM,QAAQ,KAAK,MAAM,QAAQ,CAAC,EAAE,KAAK;AACzC,kBAAQ,OAAO,KAAK,KAAK;AAAA,QAC3B;AAAA,MACF;AAEA,UAAI,IAAI,SAAS,OAAO,IAAI,UAAU,KAAK;AACzC,eAAO,IAAI,WAAW,6BAA6B,IAAI,MAAM,IAAI,IAAI,QAAQ,IAAI,UAAU,CAAC;AAC5F;AAAA,MACF;AAEA,YAAM,cAAc,IAAI,kBAAkB,cAAc,KAAK;AAC7D,UAAI,YAAY,SAAS,kBAAkB,GAAG;AAC5C,YAAI;AACJ,YAAI;AACF,mBAAS,KAAK,MAAM,IAAI,YAAY;AAAA,QACtC,QAAQ;AACN,iBAAO,IAAI,UAAU,+BAA+B,CAAC;AACrD;AAAA,QACF;AACA,gBAAQ;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,IAAI;AAAA,UACZ,YAAY,IAAI;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AACL,eAAO,IAAI,UAAU,4BAA4B,WAAW,EAAE,CAAC;AAAA,MACjE;AAAA,IACF,CAAC;AAED,QAAI,iBAAiB,SAAS,MAAM;AAClC,aAAO,IAAI,MAAM,eAAe,CAAC;AAAA,IACnC,CAAC;AAED,QAAI,iBAAiB,WAAW,MAAM;AACpC,aAAO,IAAI,MAAM,kBAAkB,CAAC;AAAA,IACtC,CAAC;AAED,QAAI,iBAAiB,SAAS,MAAM;AAClC,aAAO,IAAI,MAAM,gBAAgB,CAAC;AAAA,IACpC,CAAC;AAED,QAAI,KAAK,QAAQ;AAAA,EACnB,CAAC;AACH;","names":[]}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@ablogcms/fetch-client",
3
+ "version": "3.2.28-beta.0",
4
+ "type": "module",
5
+ "description": "CSRF トークン付き fetch / XHR アップロードクライアント",
6
+ "license": "MIT",
7
+ "homepage": "https://www.a-blogcms.jp",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+ssh://git@bitbucket.org:appleple/ablogcms.git",
11
+ "directory": "packages/frontend/fetch-client"
12
+ },
13
+ "sideEffects": false,
14
+ "devDependencies": {
15
+ "vitest": "^4.1.9"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.mjs",
21
+ "default": "./dist/index.mjs"
22
+ },
23
+ "./xhr-upload": {
24
+ "types": "./dist/xhr-upload.d.ts",
25
+ "import": "./dist/xhr-upload.mjs",
26
+ "default": "./dist/xhr-upload.mjs"
27
+ }
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "scripts": {
36
+ "build": "node ../../../tools/build-package.mjs"
37
+ }
38
+ }