accessio 1.1.1 → 1.2.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 +98 -1
- package/cjs/accessio.cjs +102 -10
- package/cjs/accessio.cjs.map +1 -1
- package/cjs/core/accessioError.cjs +1 -0
- package/cjs/core/accessioError.cjs.map +1 -1
- package/cjs/core/buildURL.cjs +16 -2
- package/cjs/core/buildURL.cjs.map +1 -1
- package/cjs/core/fetchAdapter.cjs +224 -0
- package/cjs/core/fetchAdapter.cjs.map +1 -0
- package/cjs/core/mergeConfig.cjs +2 -2
- package/cjs/core/mergeConfig.cjs.map +1 -1
- package/cjs/core/request.cjs +74 -199
- package/cjs/core/request.cjs.map +1 -1
- package/cjs/core/retry.cjs +23 -4
- package/cjs/core/retry.cjs.map +1 -1
- package/cjs/defaults/transforms.cjs.map +1 -1
- package/cjs/helpers/auth.cjs +45 -0
- package/cjs/helpers/auth.cjs.map +1 -0
- package/cjs/helpers/flattenHeaders.cjs +78 -0
- package/cjs/helpers/flattenHeaders.cjs.map +1 -0
- package/cjs/helpers/memoryCache.cjs +51 -0
- package/cjs/helpers/memoryCache.cjs.map +1 -0
- package/cjs/helpers/parseHeaders.cjs +16 -4
- package/cjs/helpers/parseHeaders.cjs.map +1 -1
- package/cjs/helpers/rateLimiter.cjs +18 -8
- package/cjs/helpers/rateLimiter.cjs.map +1 -1
- package/cjs/helpers/toFormData.cjs +50 -0
- package/cjs/helpers/toFormData.cjs.map +1 -0
- package/cjs/helpers/transformData.cjs +2 -2
- package/cjs/helpers/transformData.cjs.map +1 -1
- package/cjs/index.cjs +4 -1
- package/cjs/index.cjs.map +1 -1
- package/package.json +4 -3
- package/src/accessio.ts +126 -10
- package/src/core/accessioError.ts +1 -0
- package/src/core/buildURL.ts +17 -2
- package/src/core/fetchAdapter.ts +227 -0
- package/src/core/mergeConfig.ts +2 -2
- package/src/core/request.ts +100 -250
- package/src/core/retry.ts +26 -6
- package/src/defaults/transforms.ts +4 -1
- package/src/helpers/auth.ts +26 -0
- package/src/helpers/flattenHeaders.ts +59 -0
- package/src/helpers/memoryCache.ts +30 -0
- package/src/helpers/parseHeaders.ts +19 -6
- package/src/helpers/rateLimiter.ts +18 -8
- package/src/helpers/toFormData.ts +25 -0
- package/src/helpers/transformData.ts +4 -4
- package/src/index.ts +4 -1
- package/src/types.ts +32 -3
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var flattenHeaders_exports = {};
|
|
20
|
+
__export(flattenHeaders_exports, {
|
|
21
|
+
buildFetchHeaders: () => buildFetchHeaders,
|
|
22
|
+
flattenHeaders: () => flattenHeaders,
|
|
23
|
+
removeContentType: () => removeContentType
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(flattenHeaders_exports);
|
|
26
|
+
const METHOD_KEYS = /* @__PURE__ */ new Set([
|
|
27
|
+
"common",
|
|
28
|
+
"delete",
|
|
29
|
+
"get",
|
|
30
|
+
"head",
|
|
31
|
+
"options",
|
|
32
|
+
"post",
|
|
33
|
+
"put",
|
|
34
|
+
"patch"
|
|
35
|
+
]);
|
|
36
|
+
function flattenHeaders(headers, method) {
|
|
37
|
+
if (!headers) return {};
|
|
38
|
+
const merged = {};
|
|
39
|
+
const methodLower = (method || "get").toLowerCase();
|
|
40
|
+
if (headers["common"]) {
|
|
41
|
+
Object.assign(merged, headers["common"]);
|
|
42
|
+
}
|
|
43
|
+
if (headers[methodLower]) {
|
|
44
|
+
Object.assign(merged, headers[methodLower]);
|
|
45
|
+
}
|
|
46
|
+
for (const key in headers) {
|
|
47
|
+
if (Object.prototype.hasOwnProperty.call(headers, key) && !METHOD_KEYS.has(key)) {
|
|
48
|
+
merged[key] = headers[key];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return merged;
|
|
52
|
+
}
|
|
53
|
+
function removeContentType(headers) {
|
|
54
|
+
const keys = Object.keys(headers).filter((k) => k.toLowerCase() === "content-type");
|
|
55
|
+
for (const key of keys) {
|
|
56
|
+
delete headers[key];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function buildFetchHeaders(headers) {
|
|
60
|
+
const fetchHeaders = new Headers();
|
|
61
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
for (const v of value) {
|
|
64
|
+
fetchHeaders.append(key, v);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
fetchHeaders.set(key, value);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return fetchHeaders;
|
|
71
|
+
}
|
|
72
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
73
|
+
0 && (module.exports = {
|
|
74
|
+
buildFetchHeaders,
|
|
75
|
+
flattenHeaders,
|
|
76
|
+
removeContentType
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=flattenHeaders.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/flattenHeaders.ts"],"sourcesContent":["const METHOD_KEYS = new Set<string>([\n 'common',\n 'delete',\n 'get',\n 'head',\n 'options',\n 'post',\n 'put',\n 'patch',\n]);\n\ntype HeadersConfig = Record<string, Record<string, string | string[]>>;\n\nexport function flattenHeaders(\n headers: HeadersConfig | undefined,\n method?: string,\n): Record<string, string | string[]> {\n if (!headers) return {};\n\n const merged: Record<string, string | string[]> = {};\n const methodLower = (method || 'get').toLowerCase();\n\n if (headers['common']) {\n Object.assign(merged, headers['common']);\n }\n\n if (headers[methodLower]) {\n Object.assign(merged, headers[methodLower]);\n }\n\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key) && !METHOD_KEYS.has(key)) {\n merged[key] = headers[key] as unknown as string | string[];\n }\n }\n\n return merged;\n}\n\nexport function removeContentType(headers: Record<string, string | string[]>): void {\n const keys = Object.keys(headers).filter((k) => k.toLowerCase() === 'content-type');\n for (const key of keys) {\n delete headers[key];\n }\n}\n\nexport function buildFetchHeaders(headers: Record<string, string | string[]>): Headers {\n const fetchHeaders = new Headers();\n for (const [key, value] of Object.entries(headers)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n fetchHeaders.append(key, v);\n }\n } else {\n fetchHeaders.set(key, value);\n }\n }\n return fetchHeaders;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAM,cAAc,oBAAI,IAAY;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAIM,SAAS,eACd,SACA,QACmC;AACnC,MAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,QAAM,SAA4C,CAAC;AACnD,QAAM,eAAe,UAAU,OAAO,YAAY;AAElD,MAAI,QAAQ,QAAQ,GAAG;AACrB,WAAO,OAAO,QAAQ,QAAQ,QAAQ,CAAC;AAAA,EACzC;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,OAAO,QAAQ,QAAQ,WAAW,CAAC;AAAA,EAC5C;AAEA,aAAW,OAAO,SAAS;AACzB,QAAI,OAAO,UAAU,eAAe,KAAK,SAAS,GAAG,KAAK,CAAC,YAAY,IAAI,GAAG,GAAG;AAC/E,aAAO,GAAG,IAAI,QAAQ,GAAG;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,kBAAkB,SAAkD;AAClF,QAAM,OAAO,OAAO,KAAK,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,MAAM,cAAc;AAClF,aAAW,OAAO,MAAM;AACtB,WAAO,QAAQ,GAAG;AAAA,EACpB;AACF;AAEO,SAAS,kBAAkB,SAAqD;AACrF,QAAM,eAAe,IAAI,QAAQ;AACjC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,iBAAW,KAAK,OAAO;AACrB,qBAAa,OAAO,KAAK,CAAC;AAAA,MAC5B;AAAA,IACF,OAAO;AACL,mBAAa,IAAI,KAAK,KAAK;AAAA,IAC7B;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var memoryCache_exports = {};
|
|
20
|
+
__export(memoryCache_exports, {
|
|
21
|
+
defaultMemoryCache: () => defaultMemoryCache
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(memoryCache_exports);
|
|
24
|
+
class MemoryCache {
|
|
25
|
+
cache = /* @__PURE__ */ new Map();
|
|
26
|
+
get(key) {
|
|
27
|
+
const item = this.cache.get(key);
|
|
28
|
+
if (!item) return null;
|
|
29
|
+
if (item.expiry && Date.now() > item.expiry) {
|
|
30
|
+
this.cache.delete(key);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return item.value;
|
|
34
|
+
}
|
|
35
|
+
set(key, value, ttl) {
|
|
36
|
+
const expiry = ttl ? Date.now() + ttl : null;
|
|
37
|
+
this.cache.set(key, { value, expiry });
|
|
38
|
+
}
|
|
39
|
+
delete(key) {
|
|
40
|
+
this.cache.delete(key);
|
|
41
|
+
}
|
|
42
|
+
clear() {
|
|
43
|
+
this.cache.clear();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const defaultMemoryCache = new MemoryCache();
|
|
47
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
+
0 && (module.exports = {
|
|
49
|
+
defaultMemoryCache
|
|
50
|
+
});
|
|
51
|
+
//# sourceMappingURL=memoryCache.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/memoryCache.ts"],"sourcesContent":["import type { CacheProvider } from '../types';\n\nclass MemoryCache implements CacheProvider {\n private cache = new Map<string, { value: any; expiry: number | null }>();\n\n get(key: string) {\n const item = this.cache.get(key);\n if (!item) return null;\n if (item.expiry && Date.now() > item.expiry) {\n this.cache.delete(key);\n return null;\n }\n return item.value;\n }\n\n set(key: string, value: any, ttl?: number) {\n const expiry = ttl ? Date.now() + ttl : null;\n this.cache.set(key, { value, expiry });\n }\n\n delete(key: string) {\n this.cache.delete(key);\n }\n\n clear() {\n this.cache.clear();\n }\n}\n\nexport const defaultMemoryCache = new MemoryCache();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,MAAM,YAAqC;AAAA,EACjC,QAAQ,oBAAI,IAAmD;AAAA,EAEvE,IAAI,KAAa;AACf,UAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAC/B,QAAI,CAAC,KAAM,QAAO;AAClB,QAAI,KAAK,UAAU,KAAK,IAAI,IAAI,KAAK,QAAQ;AAC3C,WAAK,MAAM,OAAO,GAAG;AACrB,aAAO;AAAA,IACT;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,KAAa,OAAY,KAAc;AACzC,UAAM,SAAS,MAAM,KAAK,IAAI,IAAI,MAAM;AACxC,SAAK,MAAM,IAAI,KAAK,EAAE,OAAO,OAAO,CAAC;AAAA,EACvC;AAAA,EAEA,OAAO,KAAa;AAClB,SAAK,MAAM,OAAO,GAAG;AAAA,EACvB;AAAA,EAEA,QAAQ;AACN,SAAK,MAAM,MAAM;AAAA,EACnB;AACF;AAEO,MAAM,qBAAqB,IAAI,YAAY;","names":[]}
|
|
@@ -24,9 +24,21 @@ module.exports = __toCommonJS(parseHeaders_exports);
|
|
|
24
24
|
function parseHeaders(headers) {
|
|
25
25
|
const parsed = {};
|
|
26
26
|
if (!headers) return parsed;
|
|
27
|
+
const addHeader = (key, value) => {
|
|
28
|
+
const k = key.toLowerCase();
|
|
29
|
+
if (parsed[k]) {
|
|
30
|
+
if (Array.isArray(parsed[k])) {
|
|
31
|
+
parsed[k].push(value);
|
|
32
|
+
} else {
|
|
33
|
+
parsed[k] = [parsed[k], value];
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
parsed[k] = value;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
27
39
|
if (typeof headers.forEach === "function") {
|
|
28
40
|
headers.forEach((value, key) => {
|
|
29
|
-
|
|
41
|
+
addHeader(key, value);
|
|
30
42
|
});
|
|
31
43
|
return parsed;
|
|
32
44
|
}
|
|
@@ -34,16 +46,16 @@ function parseHeaders(headers) {
|
|
|
34
46
|
headers.split("\n").forEach((line) => {
|
|
35
47
|
const index = line.indexOf(":");
|
|
36
48
|
if (index > 0) {
|
|
37
|
-
const key = line.substring(0, index).trim()
|
|
49
|
+
const key = line.substring(0, index).trim();
|
|
38
50
|
const value = line.substring(index + 1).trim();
|
|
39
|
-
|
|
51
|
+
addHeader(key, value);
|
|
40
52
|
}
|
|
41
53
|
});
|
|
42
54
|
return parsed;
|
|
43
55
|
}
|
|
44
56
|
if (typeof headers === "object") {
|
|
45
57
|
Object.keys(headers).forEach((key) => {
|
|
46
|
-
|
|
58
|
+
addHeader(key, headers[key]);
|
|
47
59
|
});
|
|
48
60
|
return parsed;
|
|
49
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/helpers/parseHeaders.ts"],"sourcesContent":["export default function parseHeaders(headers: any): Record<string, string> {\n const parsed: Record<string, string> = {};\n\n if (!headers) return parsed;\n\n if (typeof headers.forEach === 'function') {\n headers.forEach((value: string, key: string) => {\n
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/parseHeaders.ts"],"sourcesContent":["export default function parseHeaders(headers: any): Record<string, string | string[]> {\n const parsed: Record<string, string | string[]> = {};\n\n if (!headers) return parsed;\n\n const addHeader = (key: string, value: string) => {\n const k = key.toLowerCase();\n if (parsed[k]) {\n if (Array.isArray(parsed[k])) {\n (parsed[k] as string[]).push(value);\n } else {\n parsed[k] = [parsed[k] as string, value];\n }\n } else {\n parsed[k] = value;\n }\n };\n\n if (typeof headers.forEach === 'function') {\n headers.forEach((value: string, key: string) => {\n addHeader(key, value);\n });\n return parsed;\n }\n\n if (typeof headers === 'string') {\n headers.split('\\n').forEach((line: string) => {\n const index = line.indexOf(':');\n if (index > 0) {\n const key = line.substring(0, index).trim();\n const value = line.substring(index + 1).trim();\n addHeader(key, value);\n }\n });\n return parsed;\n }\n\n if (typeof headers === 'object') {\n Object.keys(headers).forEach((key) => {\n addHeader(key, headers[key]);\n });\n return parsed;\n }\n\n return parsed;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAe,SAAR,aAA8B,SAAiD;AACpF,QAAM,SAA4C,CAAC;AAEnD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,YAAY,CAAC,KAAa,UAAkB;AAChD,UAAM,IAAI,IAAI,YAAY;AAC1B,QAAI,OAAO,CAAC,GAAG;AACb,UAAI,MAAM,QAAQ,OAAO,CAAC,CAAC,GAAG;AAC5B,QAAC,OAAO,CAAC,EAAe,KAAK,KAAK;AAAA,MACpC,OAAO;AACL,eAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAa,KAAK;AAAA,MACzC;AAAA,IACF,OAAO;AACL,aAAO,CAAC,IAAI;AAAA,IACd;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,YAAY,YAAY;AACzC,YAAQ,QAAQ,CAAC,OAAe,QAAgB;AAC9C,gBAAU,KAAK,KAAK;AAAA,IACtB,CAAC;AACD,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,YAAY,UAAU;AAC/B,YAAQ,MAAM,IAAI,EAAE,QAAQ,CAAC,SAAiB;AAC5C,YAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,UAAI,QAAQ,GAAG;AACb,cAAM,MAAM,KAAK,UAAU,GAAG,KAAK,EAAE,KAAK;AAC1C,cAAM,QAAQ,KAAK,UAAU,QAAQ,CAAC,EAAE,KAAK;AAC7C,kBAAU,KAAK,KAAK;AAAA,MACtB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,QAAQ;AACpC,gBAAU,KAAK,QAAQ,GAAG,CAAC;AAAA,IAC7B,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -36,7 +36,10 @@ function createRateLimiter(maxConcurrent = Infinity, maxQueueSize = Infinity) {
|
|
|
36
36
|
}
|
|
37
37
|
let active = 0;
|
|
38
38
|
let destroyed = false;
|
|
39
|
-
|
|
39
|
+
let head = 0;
|
|
40
|
+
let tail = 0;
|
|
41
|
+
let pendingCount = 0;
|
|
42
|
+
const queue = {};
|
|
40
43
|
function acquire() {
|
|
41
44
|
if (destroyed) {
|
|
42
45
|
return Promise.reject(new Error("[Accessio] Rate limiter has been destroyed"));
|
|
@@ -45,30 +48,37 @@ function createRateLimiter(maxConcurrent = Infinity, maxQueueSize = Infinity) {
|
|
|
45
48
|
active++;
|
|
46
49
|
return Promise.resolve();
|
|
47
50
|
}
|
|
48
|
-
if (
|
|
51
|
+
if (pendingCount >= maxQueueSize) {
|
|
49
52
|
return Promise.reject(
|
|
50
53
|
new Error(`[Accessio] Rate limiter queue size exceeded maxQueueSize (${maxQueueSize})`)
|
|
51
54
|
);
|
|
52
55
|
}
|
|
53
56
|
return new Promise((resolve, reject) => {
|
|
54
|
-
queue
|
|
57
|
+
queue[tail++] = { resolve, reject };
|
|
58
|
+
pendingCount++;
|
|
55
59
|
});
|
|
56
60
|
}
|
|
57
61
|
function release() {
|
|
58
62
|
if (destroyed) return;
|
|
59
63
|
if (active <= 0) return;
|
|
60
64
|
active--;
|
|
61
|
-
if (
|
|
65
|
+
if (pendingCount > 0 && active < maxConcurrent) {
|
|
62
66
|
active++;
|
|
63
|
-
const next = queue
|
|
67
|
+
const next = queue[head];
|
|
68
|
+
delete queue[head];
|
|
69
|
+
head++;
|
|
70
|
+
pendingCount--;
|
|
64
71
|
next?.resolve();
|
|
65
72
|
}
|
|
66
73
|
}
|
|
67
74
|
function destroy() {
|
|
68
75
|
destroyed = true;
|
|
69
76
|
const reason = new Error("[Accessio] Rate limiter destroyed \u2014 pending request cancelled");
|
|
70
|
-
while (
|
|
71
|
-
const next = queue
|
|
77
|
+
while (pendingCount > 0) {
|
|
78
|
+
const next = queue[head];
|
|
79
|
+
delete queue[head];
|
|
80
|
+
head++;
|
|
81
|
+
pendingCount--;
|
|
72
82
|
next?.reject(reason);
|
|
73
83
|
}
|
|
74
84
|
}
|
|
@@ -77,7 +87,7 @@ function createRateLimiter(maxConcurrent = Infinity, maxQueueSize = Infinity) {
|
|
|
77
87
|
release,
|
|
78
88
|
destroy,
|
|
79
89
|
get pending() {
|
|
80
|
-
return
|
|
90
|
+
return pendingCount;
|
|
81
91
|
},
|
|
82
92
|
get active() {
|
|
83
93
|
return active;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/helpers/rateLimiter.ts"],"sourcesContent":["import type { RateLimiter, AccessioRequestConfig, AccessioResponse } from '../types';\n\ninterface QueueItem {\n resolve: () => void;\n reject: (reason: Error) => void;\n}\n\nexport function createRateLimiter(\n maxConcurrent: number = Infinity,\n maxQueueSize: number = Infinity,\n): RateLimiter {\n if (maxConcurrent !== Infinity && (!Number.isInteger(maxConcurrent) || maxConcurrent < 1)) {\n throw new RangeError(\n `[Accessio] maxConcurrent must be a positive integer or Infinity, got: ${maxConcurrent}`,\n );\n }\n if (maxQueueSize !== Infinity && (!Number.isInteger(maxQueueSize) || maxQueueSize < 1)) {\n throw new RangeError(\n `[Accessio] maxQueueSize must be a positive integer or Infinity, got: ${maxQueueSize}`,\n );\n }\n let active = 0;\n let destroyed = false;\n const queue: QueueItem
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/rateLimiter.ts"],"sourcesContent":["import type { RateLimiter, AccessioRequestConfig, AccessioResponse } from '../types';\n\ninterface QueueItem {\n resolve: () => void;\n reject: (reason: Error) => void;\n}\n\nexport function createRateLimiter(\n maxConcurrent: number = Infinity,\n maxQueueSize: number = Infinity,\n): RateLimiter {\n if (maxConcurrent !== Infinity && (!Number.isInteger(maxConcurrent) || maxConcurrent < 1)) {\n throw new RangeError(\n `[Accessio] maxConcurrent must be a positive integer or Infinity, got: ${maxConcurrent}`,\n );\n }\n if (maxQueueSize !== Infinity && (!Number.isInteger(maxQueueSize) || maxQueueSize < 1)) {\n throw new RangeError(\n `[Accessio] maxQueueSize must be a positive integer or Infinity, got: ${maxQueueSize}`,\n );\n }\n let active = 0;\n let destroyed = false;\n let head = 0;\n let tail = 0;\n let pendingCount = 0;\n const queue: Record<number, QueueItem> = {};\n\n function acquire(): Promise<void> {\n if (destroyed) {\n return Promise.reject(new Error('[Accessio] Rate limiter has been destroyed'));\n }\n\n if (active < maxConcurrent) {\n active++;\n return Promise.resolve();\n }\n\n if (pendingCount >= maxQueueSize) {\n return Promise.reject(\n new Error(`[Accessio] Rate limiter queue size exceeded maxQueueSize (${maxQueueSize})`),\n );\n }\n\n return new Promise((resolve, reject) => {\n queue[tail++] = { resolve, reject };\n pendingCount++;\n });\n }\n\n function release(): void {\n if (destroyed) return;\n\n if (active <= 0) return;\n\n active--;\n\n if (pendingCount > 0 && active < maxConcurrent) {\n active++;\n const next = queue[head];\n delete queue[head];\n head++;\n pendingCount--;\n next?.resolve();\n }\n }\n\n function destroy(): void {\n destroyed = true;\n const reason = new Error('[Accessio] Rate limiter destroyed — pending request cancelled');\n while (pendingCount > 0) {\n const next = queue[head];\n delete queue[head];\n head++;\n pendingCount--;\n next?.reject(reason);\n }\n }\n\n return {\n acquire,\n release,\n destroy,\n get pending() {\n return pendingCount;\n },\n get active() {\n return active;\n },\n get destroyed() {\n return destroyed;\n },\n };\n}\n\nexport async function rateLimitedRequest<T = unknown>(\n dispatchFn: (config: AccessioRequestConfig) => Promise<AccessioResponse<T>>,\n limiter: RateLimiter,\n config: AccessioRequestConfig,\n): Promise<AccessioResponse<T>> {\n await limiter.acquire();\n try {\n return await dispatchFn(config);\n } finally {\n limiter.release();\n }\n}\n\nexport default createRateLimiter;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,SAAS,kBACd,gBAAwB,UACxB,eAAuB,UACV;AACb,MAAI,kBAAkB,aAAa,CAAC,OAAO,UAAU,aAAa,KAAK,gBAAgB,IAAI;AACzF,UAAM,IAAI;AAAA,MACR,yEAAyE,aAAa;AAAA,IACxF;AAAA,EACF;AACA,MAAI,iBAAiB,aAAa,CAAC,OAAO,UAAU,YAAY,KAAK,eAAe,IAAI;AACtF,UAAM,IAAI;AAAA,MACR,wEAAwE,YAAY;AAAA,IACtF;AAAA,EACF;AACA,MAAI,SAAS;AACb,MAAI,YAAY;AAChB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,eAAe;AACnB,QAAM,QAAmC,CAAC;AAE1C,WAAS,UAAyB;AAChC,QAAI,WAAW;AACb,aAAO,QAAQ,OAAO,IAAI,MAAM,4CAA4C,CAAC;AAAA,IAC/E;AAEA,QAAI,SAAS,eAAe;AAC1B;AACA,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAEA,QAAI,gBAAgB,cAAc;AAChC,aAAO,QAAQ;AAAA,QACb,IAAI,MAAM,6DAA6D,YAAY,GAAG;AAAA,MACxF;AAAA,IACF;AAEA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,MAAM,IAAI,EAAE,SAAS,OAAO;AAClC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAAS,UAAgB;AACvB,QAAI,UAAW;AAEf,QAAI,UAAU,EAAG;AAEjB;AAEA,QAAI,eAAe,KAAK,SAAS,eAAe;AAC9C;AACA,YAAM,OAAO,MAAM,IAAI;AACvB,aAAO,MAAM,IAAI;AACjB;AACA;AACA,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF;AAEA,WAAS,UAAgB;AACvB,gBAAY;AACZ,UAAM,SAAS,IAAI,MAAM,oEAA+D;AACxF,WAAO,eAAe,GAAG;AACvB,YAAM,OAAO,MAAM,IAAI;AACvB,aAAO,MAAM,IAAI;AACjB;AACA;AACA,YAAM,OAAO,MAAM;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,IACA,IAAI,SAAS;AACX,aAAO;AAAA,IACT;AAAA,IACA,IAAI,YAAY;AACd,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,YACA,SACA,QAC8B;AAC9B,QAAM,QAAQ,QAAQ;AACtB,MAAI;AACF,WAAO,MAAM,WAAW,MAAM;AAAA,EAChC,UAAE;AACA,YAAQ,QAAQ;AAAA,EAClB;AACF;AAEA,IAAO,sBAAQ;","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var toFormData_exports = {};
|
|
20
|
+
__export(toFormData_exports, {
|
|
21
|
+
toFormData: () => toFormData
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(toFormData_exports);
|
|
24
|
+
function toFormData(obj, form, namespace) {
|
|
25
|
+
const fd = form || new FormData();
|
|
26
|
+
let formKey;
|
|
27
|
+
if (obj === null || obj === void 0) {
|
|
28
|
+
return fd;
|
|
29
|
+
}
|
|
30
|
+
if (obj instanceof Date) {
|
|
31
|
+
fd.append(namespace || "", obj.toISOString());
|
|
32
|
+
} else if (typeof obj === "object" && !(obj instanceof File) && !(obj instanceof Blob)) {
|
|
33
|
+
Object.keys(obj).forEach((key) => {
|
|
34
|
+
if (Array.isArray(obj)) {
|
|
35
|
+
formKey = namespace ? `${namespace}[${key}]` : key;
|
|
36
|
+
} else {
|
|
37
|
+
formKey = namespace ? `${namespace}.${key}` : key;
|
|
38
|
+
}
|
|
39
|
+
toFormData(obj[key], fd, formKey);
|
|
40
|
+
});
|
|
41
|
+
} else {
|
|
42
|
+
fd.append(namespace || "", obj);
|
|
43
|
+
}
|
|
44
|
+
return fd;
|
|
45
|
+
}
|
|
46
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
47
|
+
0 && (module.exports = {
|
|
48
|
+
toFormData
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=toFormData.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/toFormData.ts"],"sourcesContent":["export function toFormData(obj: any, form?: FormData, namespace?: string): FormData {\n const fd = form || new FormData();\n let formKey: string;\n\n if (obj === null || obj === undefined) {\n return fd;\n }\n\n if (obj instanceof Date) {\n fd.append(namespace || '', obj.toISOString());\n } else if (typeof obj === 'object' && !(obj instanceof File) && !(obj instanceof Blob)) {\n Object.keys(obj).forEach((key) => {\n if (Array.isArray(obj)) {\n formKey = namespace ? `${namespace}[${key}]` : key;\n } else {\n formKey = namespace ? `${namespace}.${key}` : key;\n }\n toFormData(obj[key], fd, formKey);\n });\n } else {\n fd.append(namespace || '', obj);\n }\n\n return fd;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,SAAS,WAAW,KAAU,MAAiB,WAA8B;AAClF,QAAM,KAAK,QAAQ,IAAI,SAAS;AAChC,MAAI;AAEJ,MAAI,QAAQ,QAAQ,QAAQ,QAAW;AACrC,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,MAAM;AACvB,OAAG,OAAO,aAAa,IAAI,IAAI,YAAY,CAAC;AAAA,EAC9C,WAAW,OAAO,QAAQ,YAAY,EAAE,eAAe,SAAS,EAAE,eAAe,OAAO;AACtF,WAAO,KAAK,GAAG,EAAE,QAAQ,CAAC,QAAQ;AAChC,UAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,kBAAU,YAAY,GAAG,SAAS,IAAI,GAAG,MAAM;AAAA,MACjD,OAAO;AACL,kBAAU,YAAY,GAAG,SAAS,IAAI,GAAG,KAAK;AAAA,MAChD;AACA,iBAAW,IAAI,GAAG,GAAG,IAAI,OAAO;AAAA,IAClC,CAAC;AAAA,EACH,OAAO;AACL,OAAG,OAAO,aAAa,IAAI,GAAG;AAAA,EAChC;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -32,7 +32,7 @@ __export(transformData_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(transformData_exports);
|
|
34
34
|
var import_accessioError = __toESM(require("../core/accessioError"), 1);
|
|
35
|
-
function transformData(transforms, data, headers, config) {
|
|
35
|
+
async function transformData(transforms, data, headers, config) {
|
|
36
36
|
if (!transforms || !Array.isArray(transforms)) {
|
|
37
37
|
return data;
|
|
38
38
|
}
|
|
@@ -40,7 +40,7 @@ function transformData(transforms, data, headers, config) {
|
|
|
40
40
|
for (const transform of transforms) {
|
|
41
41
|
if (typeof transform === "function") {
|
|
42
42
|
try {
|
|
43
|
-
result = transform(result, headers);
|
|
43
|
+
result = await transform(result, headers);
|
|
44
44
|
} catch (err) {
|
|
45
45
|
throw import_accessioError.default.from(
|
|
46
46
|
err instanceof Error ? err : new Error(String(err)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/helpers/transformData.ts"],"sourcesContent":["import AccessioError from '../core/accessioError';\nimport type { TransformFunction, AccessioRequestConfig } from '../types';\n\nexport default function transformData(\n transforms: TransformFunction | TransformFunction[] | undefined,\n data: unknown,\n headers: Record<string, string>,\n config?: AccessioRequestConfig,\n): unknown {\n if (!transforms || !Array.isArray(transforms)) {\n return data;\n }\n\n let result = data;\n\n for (const transform of transforms) {\n if (typeof transform === 'function') {\n try {\n result = transform(result, headers);\n } catch (err) {\n throw AccessioError.from(\n err instanceof Error ? err : new Error(String(err)),\n AccessioError.ERR_BAD_REQUEST,\n config ?? null,\n null,\n null,\n );\n }\n }\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAA0B;
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/transformData.ts"],"sourcesContent":["import AccessioError from '../core/accessioError';\nimport type { TransformFunction, AccessioRequestConfig } from '../types';\n\nexport default async function transformData(\n transforms: TransformFunction | TransformFunction[] | undefined,\n data: unknown,\n headers: Record<string, string | string[]>,\n config?: AccessioRequestConfig,\n): Promise<unknown> {\n if (!transforms || !Array.isArray(transforms)) {\n return data;\n }\n\n let result = data;\n\n for (const transform of transforms) {\n if (typeof transform === 'function') {\n try {\n result = await transform(result, headers);\n } catch (err) {\n throw AccessioError.from(\n err instanceof Error ? err : new Error(String(err)),\n AccessioError.ERR_BAD_REQUEST,\n config ?? null,\n null,\n null,\n );\n }\n }\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAA0B;AAG1B,eAAO,cACL,YACA,MACA,SACA,QACkB;AAClB,MAAI,CAAC,cAAc,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC7C,WAAO;AAAA,EACT;AAEA,MAAI,SAAS;AAEb,aAAW,aAAa,YAAY;AAClC,QAAI,OAAO,cAAc,YAAY;AACnC,UAAI;AACF,iBAAS,MAAM,UAAU,QAAQ,OAAO;AAAA,MAC1C,SAAS,KAAK;AACZ,cAAM,qBAAAA,QAAc;AAAA,UAClB,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,UAClD,qBAAAA,QAAc;AAAA,UACd,UAAU;AAAA,UACV;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":["AccessioError"]}
|
package/cjs/index.cjs
CHANGED
package/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import Accessio from './accessio';\nimport defaults from './defaults';\nimport AccessioError from './core/accessioError';\nimport mergeConfig from './core/mergeConfig';\nimport buildURL from './core/buildURL';\nimport InterceptorManager from './interceptors/interceptorManager';\nimport { createRateLimiter } from './helpers/rateLimiter';\nimport { logRequest, logResponse, logError } from './helpers/debug';\nimport { ERR_CANCELED } from './constants/errorCodes';\nimport type { AccessioRequestConfig
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import Accessio from './accessio';\nimport defaults from './defaults';\nimport AccessioError from './core/accessioError';\nimport mergeConfig from './core/mergeConfig';\nimport buildURL from './core/buildURL';\nimport InterceptorManager from './interceptors/interceptorManager';\nimport { createRateLimiter } from './helpers/rateLimiter';\nimport { logRequest, logResponse, logError } from './helpers/debug';\nimport { ERR_CANCELED } from './constants/errorCodes';\nimport type { AccessioRequestConfig } from './types';\n\nconst PUBLIC_METHODS = [\n 'request',\n 'getUri',\n 'get',\n 'delete',\n 'head',\n 'options',\n 'post',\n 'put',\n 'patch',\n 'postForm',\n 'putForm',\n 'patchForm',\n 'stream',\n 'autoPaginate',\n 'gql',\n];\n\nfunction createInstance(defaultConfig: AccessioRequestConfig) {\n const context = new Accessio(defaultConfig);\n\n const instance: any = function accessio(\n configOrUrl: string | AccessioRequestConfig,\n config?: AccessioRequestConfig,\n ) {\n return context.request(configOrUrl, config);\n };\n\n for (const key of PUBLIC_METHODS) {\n const method: any = (context as any)[key];\n if (typeof method === 'function') {\n instance[key] = method.bind(context);\n }\n }\n\n instance.defaults = context.defaults;\n instance.interceptors = context.interceptors;\n instance.all = function all(promises: any[]): Promise<any[]> {\n return Promise.all(promises);\n };\n instance.spread = function spread<T>(callback: (...args: any[]) => T): (arr: any[]) => T {\n return function wrap(arr: any[]): T {\n return callback(...arr);\n };\n };\n instance.isCancel = function isCancel(value: any): boolean {\n return !!(value && value.isAccessioError && value.code === ERR_CANCELED);\n };\n instance.isAccessioError = function isAccessioError(value: any): boolean {\n return (\n value instanceof AccessioError ||\n !!(value && typeof value === 'object' && value.isAccessioError === true)\n );\n };\n instance.AccessioError = AccessioError;\n instance.Accessio = Accessio;\n instance.mergeConfig = mergeConfig;\n instance.buildURL = buildURL;\n instance.InterceptorManager = InterceptorManager;\n instance.createRateLimiter = createRateLimiter;\n\n return instance;\n}\n\nconst accessio = createInstance(defaults);\n\nfunction create(instanceConfig?: AccessioRequestConfig) {\n return createInstance(mergeConfig(defaults, instanceConfig));\n}\n\naccessio.create = create;\n\nexport default accessio;\n\nexport {\n Accessio,\n AccessioError,\n mergeConfig,\n buildURL,\n InterceptorManager,\n createInstance,\n createRateLimiter,\n logRequest,\n logResponse,\n logError,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,kCAAAA;AAAA,EAAA,0CAAAC;AAAA,EAAA,oDAAAC;AAAA,EAAA,gCAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wCAAAC;AAAA;AAAA;AAAA,sBAAqB;AACrB,sBAAqB;AACrB,2BAA0B;AAC1B,yBAAwB;AACxB,sBAAqB;AACrB,gCAA+B;AAC/B,yBAAkC;AAClC,mBAAkD;AAClD,wBAA6B;AAG7B,MAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,eAAe,eAAsC;AAC5D,QAAM,UAAU,IAAI,gBAAAJ,QAAS,aAAa;AAE1C,QAAM,WAAgB,SAASK,UAC7B,aACA,QACA;AACA,WAAO,QAAQ,QAAQ,aAAa,MAAM;AAAA,EAC5C;AAEA,aAAW,OAAO,gBAAgB;AAChC,UAAM,SAAe,QAAgB,GAAG;AACxC,QAAI,OAAO,WAAW,YAAY;AAChC,eAAS,GAAG,IAAI,OAAO,KAAK,OAAO;AAAA,IACrC;AAAA,EACF;AAEA,WAAS,WAAW,QAAQ;AAC5B,WAAS,eAAe,QAAQ;AAChC,WAAS,MAAM,SAAS,IAAI,UAAiC;AAC3D,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC7B;AACA,WAAS,SAAS,SAAS,OAAU,UAAoD;AACvF,WAAO,SAAS,KAAK,KAAe;AAClC,aAAO,SAAS,GAAG,GAAG;AAAA,IACxB;AAAA,EACF;AACA,WAAS,WAAW,SAAS,SAAS,OAAqB;AACzD,WAAO,CAAC,EAAE,SAAS,MAAM,mBAAmB,MAAM,SAAS;AAAA,EAC7D;AACA,WAAS,kBAAkB,SAAS,gBAAgB,OAAqB;AACvE,WACE,iBAAiB,qBAAAJ,WACjB,CAAC,EAAE,SAAS,OAAO,UAAU,YAAY,MAAM,oBAAoB;AAAA,EAEvE;AACA,WAAS,gBAAgB,qBAAAA;AACzB,WAAS,WAAW,gBAAAD;AACpB,WAAS,cAAc,mBAAAI;AACvB,WAAS,WAAW,gBAAAD;AACpB,WAAS,qBAAqB,0BAAAD;AAC9B,WAAS,oBAAoB;AAE7B,SAAO;AACT;AAEA,MAAM,WAAW,eAAe,gBAAAI,OAAQ;AAExC,SAAS,OAAO,gBAAwC;AACtD,SAAO,mBAAe,mBAAAF,SAAY,gBAAAE,SAAU,cAAc,CAAC;AAC7D;AAEA,SAAS,SAAS;AAElB,IAAO,cAAQ;","names":["Accessio","AccessioError","InterceptorManager","buildURL","mergeConfig","accessio","defaults"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "accessio",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Fast, flexible HTTP client — simple, modular, and dependency-free",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./cjs/index.cjs",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"./core/buildURL": {
|
|
30
30
|
"types": "./index.d.ts",
|
|
31
31
|
"import": "./src/core/buildURL.ts",
|
|
32
|
-
"require": "./cjs/
|
|
32
|
+
"require": "./cjs/core/buildURL.cjs"
|
|
33
33
|
},
|
|
34
34
|
"./core/mergeConfig": {
|
|
35
35
|
"types": "./index.d.ts",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"test": "vitest run",
|
|
78
78
|
"test:watch": "vitest",
|
|
79
79
|
"test:coverage": "vitest run --coverage",
|
|
80
|
-
"test:browser": "vitest run --config vitest.browser.config.
|
|
80
|
+
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
81
81
|
"release:npm": "gh workflow run publish-npm.yml -f publish_tag=$(git describe --tags --abbrev=0)",
|
|
82
82
|
"typecheck": "tsc --noEmit"
|
|
83
83
|
},
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
"prettier": "^3.8.3",
|
|
104
104
|
"tsup": "^8.0.0",
|
|
105
105
|
"typescript": "^5.0.0",
|
|
106
|
+
"typescript-eslint": "^8.59.3",
|
|
106
107
|
"vitest": "^3.1.0"
|
|
107
108
|
}
|
|
108
109
|
}
|
package/src/accessio.ts
CHANGED
|
@@ -6,6 +6,7 @@ import buildURL from './core/buildURL';
|
|
|
6
6
|
import retryRequest from './core/retry';
|
|
7
7
|
import { logRequest, logResponse, logError } from './helpers/debug';
|
|
8
8
|
import { rateLimitedRequest } from './helpers/rateLimiter';
|
|
9
|
+
import { toFormData } from './helpers/toFormData';
|
|
9
10
|
import type {
|
|
10
11
|
AccessioRequestConfig,
|
|
11
12
|
AccessioResponse,
|
|
@@ -52,11 +53,13 @@ export class Accessio {
|
|
|
52
53
|
|
|
53
54
|
const requestInterceptors: any[] = [];
|
|
54
55
|
const responseInterceptors: any[] = [];
|
|
56
|
+
let synchronousRequestInterceptors = true;
|
|
55
57
|
|
|
56
58
|
this.interceptors.request.forEach((interceptor: InterceptorHandler) => {
|
|
57
59
|
if (interceptor.runWhen && !interceptor.runWhen(mergedConfig)) {
|
|
58
60
|
return;
|
|
59
61
|
}
|
|
62
|
+
synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;
|
|
60
63
|
requestInterceptors.unshift(interceptor);
|
|
61
64
|
});
|
|
62
65
|
|
|
@@ -64,15 +67,51 @@ export class Accessio {
|
|
|
64
67
|
responseInterceptors.push(interceptor);
|
|
65
68
|
});
|
|
66
69
|
|
|
67
|
-
let promise: Promise<any
|
|
70
|
+
let promise: Promise<any>;
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
if (synchronousRequestInterceptors) {
|
|
73
|
+
let newConfig = mergedConfig;
|
|
74
|
+
let rejectReason: any = null;
|
|
75
|
+
let isRejected = false;
|
|
76
|
+
|
|
77
|
+
for (const interceptor of requestInterceptors) {
|
|
78
|
+
if (!isRejected) {
|
|
79
|
+
try {
|
|
80
|
+
if (interceptor.fulfilled) {
|
|
81
|
+
newConfig = interceptor.fulfilled(newConfig);
|
|
82
|
+
}
|
|
83
|
+
} catch (err) {
|
|
84
|
+
rejectReason = err;
|
|
85
|
+
isRejected = true;
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
if (interceptor.rejected) {
|
|
89
|
+
try {
|
|
90
|
+
newConfig = interceptor.rejected(rejectReason);
|
|
91
|
+
isRejected = false;
|
|
92
|
+
} catch (err) {
|
|
93
|
+
rejectReason = err;
|
|
94
|
+
isRejected = true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
73
97
|
}
|
|
74
|
-
|
|
75
|
-
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (isRejected) {
|
|
101
|
+
promise = Promise.reject(rejectReason);
|
|
102
|
+
} else {
|
|
103
|
+
promise = Promise.resolve(newConfig);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
promise = Promise.resolve(mergedConfig);
|
|
107
|
+
for (const interceptor of requestInterceptors) {
|
|
108
|
+
promise = promise.then((value: any) => {
|
|
109
|
+
if (interceptor.fulfilled) {
|
|
110
|
+
return interceptor.fulfilled(value);
|
|
111
|
+
}
|
|
112
|
+
return value;
|
|
113
|
+
}, interceptor.rejected);
|
|
114
|
+
}
|
|
76
115
|
}
|
|
77
116
|
|
|
78
117
|
promise = promise.then((cfg: any) => {
|
|
@@ -163,11 +202,12 @@ export class Accessio {
|
|
|
163
202
|
data?: any,
|
|
164
203
|
config?: AccessioRequestConfig,
|
|
165
204
|
): Promise<AccessioResponse<T>> {
|
|
205
|
+
const formData = data && !(data instanceof FormData) ? toFormData(data) : data;
|
|
166
206
|
return this.request<T>(
|
|
167
207
|
mergeConfig(config || {}, {
|
|
168
208
|
method: 'post',
|
|
169
209
|
url,
|
|
170
|
-
data,
|
|
210
|
+
data: formData,
|
|
171
211
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
172
212
|
}),
|
|
173
213
|
);
|
|
@@ -178,11 +218,12 @@ export class Accessio {
|
|
|
178
218
|
data?: any,
|
|
179
219
|
config?: AccessioRequestConfig,
|
|
180
220
|
): Promise<AccessioResponse<T>> {
|
|
221
|
+
const formData = data && !(data instanceof FormData) ? toFormData(data) : data;
|
|
181
222
|
return this.request<T>(
|
|
182
223
|
mergeConfig(config || {}, {
|
|
183
224
|
method: 'put',
|
|
184
225
|
url,
|
|
185
|
-
data,
|
|
226
|
+
data: formData,
|
|
186
227
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
187
228
|
}),
|
|
188
229
|
);
|
|
@@ -193,15 +234,90 @@ export class Accessio {
|
|
|
193
234
|
data?: any,
|
|
194
235
|
config?: AccessioRequestConfig,
|
|
195
236
|
): Promise<AccessioResponse<T>> {
|
|
237
|
+
const formData = data && !(data instanceof FormData) ? toFormData(data) : data;
|
|
196
238
|
return this.request<T>(
|
|
197
239
|
mergeConfig(config || {}, {
|
|
198
240
|
method: 'patch',
|
|
199
241
|
url,
|
|
200
|
-
data,
|
|
242
|
+
data: formData,
|
|
201
243
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
202
244
|
}),
|
|
203
245
|
);
|
|
204
246
|
}
|
|
247
|
+
|
|
248
|
+
async *stream<T = any>(
|
|
249
|
+
url: string,
|
|
250
|
+
config?: AccessioRequestConfig,
|
|
251
|
+
): AsyncGenerator<T, void, unknown> {
|
|
252
|
+
const response = await this.request<ReadableStream<Uint8Array>>(
|
|
253
|
+
mergeConfig(config || {}, { method: 'get', url, responseType: 'stream' }),
|
|
254
|
+
);
|
|
255
|
+
if (!response.data) return;
|
|
256
|
+
|
|
257
|
+
const reader = response.data.getReader();
|
|
258
|
+
const decoder = new TextDecoder();
|
|
259
|
+
let buffer = '';
|
|
260
|
+
|
|
261
|
+
while (true) {
|
|
262
|
+
const { done, value } = await reader.read();
|
|
263
|
+
if (done) break;
|
|
264
|
+
|
|
265
|
+
buffer += decoder.decode(value, { stream: true });
|
|
266
|
+
const lines = buffer.split('\n');
|
|
267
|
+
buffer = lines.pop() || '';
|
|
268
|
+
|
|
269
|
+
for (const line of lines) {
|
|
270
|
+
if (line.trim().startsWith('data:')) {
|
|
271
|
+
const dataStr = line.replace(/^data:\s*/, '');
|
|
272
|
+
if (dataStr === '[DONE]') return;
|
|
273
|
+
try {
|
|
274
|
+
yield JSON.parse(dataStr);
|
|
275
|
+
} catch (e) {
|
|
276
|
+
yield dataStr as any;
|
|
277
|
+
}
|
|
278
|
+
} else if (line.trim().startsWith('{') || line.trim().startsWith('[')) {
|
|
279
|
+
try {
|
|
280
|
+
yield JSON.parse(line);
|
|
281
|
+
} catch (e) {
|
|
282
|
+
// ignore partial json
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async *autoPaginate<T = any>(
|
|
290
|
+
url: string,
|
|
291
|
+
config?: AccessioRequestConfig,
|
|
292
|
+
): AsyncGenerator<T, void, unknown> {
|
|
293
|
+
let nextUrl: string | null = url;
|
|
294
|
+
let currentConfig = config || {};
|
|
295
|
+
|
|
296
|
+
while (nextUrl) {
|
|
297
|
+
const response: AccessioResponse<any> = await this.get(nextUrl, currentConfig);
|
|
298
|
+
|
|
299
|
+
const items = Array.isArray(response.data) ? response.data : response.data.data;
|
|
300
|
+
if (Array.isArray(items)) {
|
|
301
|
+
for (const item of items) {
|
|
302
|
+
yield item;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
nextUrl = response.data.next || response.data.links?.next || null;
|
|
307
|
+
if (nextUrl) {
|
|
308
|
+
currentConfig = mergeConfig(currentConfig, { url: nextUrl, params: {} });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
gql<T = any>(
|
|
314
|
+
url: string,
|
|
315
|
+
query: string,
|
|
316
|
+
variables?: Record<string, any>,
|
|
317
|
+
config?: AccessioRequestConfig,
|
|
318
|
+
): Promise<AccessioResponse<T>> {
|
|
319
|
+
return this.post<T>(url, { query, variables }, config);
|
|
320
|
+
}
|
|
205
321
|
}
|
|
206
322
|
|
|
207
323
|
export default Accessio;
|