@fabriktor/client 0.0.62 → 0.0.63
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/dist/src/core/http.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { HTTPMethodDelete, HTTPMethodGet, HTTPMethodPatch, HTTPMethodPost } from
|
|
|
2
2
|
import type { IdempotencyStore } from "./idempotency.js";
|
|
3
3
|
export declare const headerAuthorization = "authorization";
|
|
4
4
|
export declare const headerContentType = "content-type";
|
|
5
|
+
export declare const headerContentDisposition = "content-disposition";
|
|
5
6
|
export declare const prefixBearer = "Bearer";
|
|
6
7
|
export type Method = typeof HTTPMethodGet | typeof HTTPMethodPost | typeof HTTPMethodPatch | typeof HTTPMethodDelete;
|
|
7
8
|
export type HTTPOptions<T> = {
|
|
@@ -17,8 +18,13 @@ export type HTTPOptions<T> = {
|
|
|
17
18
|
export interface Fetcher {
|
|
18
19
|
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
19
20
|
}
|
|
21
|
+
export type HTTPFile = {
|
|
22
|
+
readonly blob: Blob;
|
|
23
|
+
readonly file_name: string;
|
|
24
|
+
};
|
|
20
25
|
export interface HTTPDoer {
|
|
21
26
|
do<T, R>(opts: HTTPOptions<T>): Promise<R>;
|
|
27
|
+
doFile<T>(opts: HTTPOptions<T>): Promise<HTTPFile>;
|
|
22
28
|
}
|
|
23
29
|
export type HTTPClientOptions = {
|
|
24
30
|
fetcher: Fetcher;
|
|
@@ -32,5 +38,7 @@ export declare class HTTPClient implements HTTPDoer {
|
|
|
32
38
|
private idempotency;
|
|
33
39
|
constructor(opts: HTTPClientOptions);
|
|
34
40
|
do<T, R>(opts: HTTPOptions<T>): Promise<R>;
|
|
41
|
+
doFile<T>(opts: HTTPOptions<T>): Promise<HTTPFile>;
|
|
42
|
+
private response;
|
|
35
43
|
}
|
|
36
44
|
export declare function newHTTPClient(opts?: Partial<HTTPClientOptions>): HTTPClient;
|
package/dist/src/core/http.js
CHANGED
|
@@ -8,6 +8,7 @@ import { errFromHTTP, errHTTPRequestFailed, errHTTPResponseInvalid, } from "./er
|
|
|
8
8
|
import { applyIdempotencyHeader, DefaultIdempotencyStore, } from "./idempotency.js";
|
|
9
9
|
export const headerAuthorization = "authorization";
|
|
10
10
|
export const headerContentType = "content-type";
|
|
11
|
+
export const headerContentDisposition = "content-disposition";
|
|
11
12
|
export const prefixBearer = "Bearer";
|
|
12
13
|
export class WebFetcher {
|
|
13
14
|
async fetch(input, init) {
|
|
@@ -25,6 +26,31 @@ export class HTTPClient {
|
|
|
25
26
|
this.idempotency = opts.idempotency;
|
|
26
27
|
}
|
|
27
28
|
async do(opts) {
|
|
29
|
+
const res = await this.response(opts);
|
|
30
|
+
if (noContent(res)) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
return (await res.json());
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
throw errHTTPResponseInvalid(err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async doFile(opts) {
|
|
41
|
+
const res = await this.response(opts);
|
|
42
|
+
if (noContent(res)) {
|
|
43
|
+
throw errHTTPResponseInvalid();
|
|
44
|
+
}
|
|
45
|
+
const file_name = responseFileName(res);
|
|
46
|
+
try {
|
|
47
|
+
return { blob: await res.blob(), file_name };
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
throw errHTTPResponseInvalid(err);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async response(opts) {
|
|
28
54
|
const h = headers(opts);
|
|
29
55
|
const requestBody = body(opts.body);
|
|
30
56
|
const idempotencyPath = idempotencyRequestPath(opts.path, requestBody);
|
|
@@ -51,15 +77,7 @@ export class HTTPClient {
|
|
|
51
77
|
if (!res.ok) {
|
|
52
78
|
return await fail(res);
|
|
53
79
|
}
|
|
54
|
-
|
|
55
|
-
return undefined;
|
|
56
|
-
}
|
|
57
|
-
try {
|
|
58
|
-
return (await res.json());
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
throw errHTTPResponseInvalid(err);
|
|
62
|
-
}
|
|
80
|
+
return res;
|
|
63
81
|
}
|
|
64
82
|
}
|
|
65
83
|
export function newHTTPClient(opts) {
|
|
@@ -84,6 +102,15 @@ function headers(opts) {
|
|
|
84
102
|
function body(v) {
|
|
85
103
|
return v === undefined ? undefined : JSON.stringify(v);
|
|
86
104
|
}
|
|
105
|
+
function responseFileName(res) {
|
|
106
|
+
const disposition = res.headers.get(headerContentDisposition)?.trim() ?? "";
|
|
107
|
+
const match = /(?:^|;)\s*filename=(?:"([^"]+)"|([^;]+))/i.exec(disposition);
|
|
108
|
+
const fileName = (match?.[1] ?? match?.[2] ?? "").trim();
|
|
109
|
+
if (fileName === "") {
|
|
110
|
+
throw errHTTPResponseInvalid();
|
|
111
|
+
}
|
|
112
|
+
return fileName;
|
|
113
|
+
}
|
|
87
114
|
function idempotencyRequestPath(path, body) {
|
|
88
115
|
return typeof body === "string" ? `${path}\n${body}` : path;
|
|
89
116
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type AccountLock, type DeletionRequest, type InAccountLock, type InDeletionRequest, type OperationResult } from "@fabriktor/schema";
|
|
2
2
|
import type { TokenProvider } from "../core/auth.js";
|
|
3
3
|
import type { DeleteOneOptionsCRUD, FindOneOptionsCRUD, InsertOneOptionsCRUD, OperationResultOf, QueryOptionsCRUD, ReplaceOneOptionsCRUD } from "../core/crud.js";
|
|
4
|
-
import type { HTTPDoer } from "../core/http.js";
|
|
5
|
-
export type PrivacyExport =
|
|
4
|
+
import type { HTTPDoer, HTTPFile } from "../core/http.js";
|
|
5
|
+
export type PrivacyExport = HTTPFile;
|
|
6
6
|
export type PrivacyClientOptions = {
|
|
7
7
|
http: HTTPDoer;
|
|
8
8
|
base_url: string;
|
|
@@ -64,7 +64,7 @@ export class PrivacyClient {
|
|
|
64
64
|
}
|
|
65
65
|
async exportData() {
|
|
66
66
|
const token = await requiredToken(this.get_token);
|
|
67
|
-
return await this.http.
|
|
67
|
+
return await this.http.doFile({
|
|
68
68
|
base_url: this.base_url,
|
|
69
69
|
path: deletionRequestPath(PathPrivacyExport),
|
|
70
70
|
method: HTTPMethodPost,
|