@doist/todoist-sdk 10.1.4 → 10.1.5
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/cjs/clients/backup-client.js +3 -21
- package/dist/cjs/clients/upload-client.js +3 -22
- package/dist/cjs/test-utils/obsidian-fetch-adapter.js +1 -0
- package/dist/cjs/transport/fetch-with-retry.js +1 -0
- package/dist/cjs/utils/file-response.js +32 -0
- package/dist/esm/clients/backup-client.js +3 -21
- package/dist/esm/clients/upload-client.js +3 -22
- package/dist/esm/test-utils/obsidian-fetch-adapter.js +1 -0
- package/dist/esm/transport/fetch-with-retry.js +1 -0
- package/dist/esm/utils/file-response.js +29 -0
- package/dist/types/types/http.d.ts +7 -1
- package/dist/types/utils/file-response.d.ts +15 -0
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BackupClient = void 0;
|
|
4
4
|
const endpoints_1 = require("../consts/endpoints");
|
|
5
5
|
const http_client_1 = require("../transport/http-client");
|
|
6
|
-
const
|
|
6
|
+
const file_response_1 = require("../utils/file-response");
|
|
7
7
|
const validators_1 = require("../utils/validators");
|
|
8
8
|
const base_client_1 = require("./base-client");
|
|
9
9
|
/**
|
|
@@ -35,31 +35,13 @@ class BackupClient extends base_client_1.BaseClient {
|
|
|
35
35
|
if (!response.ok) {
|
|
36
36
|
throw new Error(`Failed to download backup: ${response.status} ${response.statusText}`);
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
const buffer = new TextEncoder().encode(text).buffer;
|
|
40
|
-
return {
|
|
41
|
-
ok: response.ok,
|
|
42
|
-
status: response.status,
|
|
43
|
-
statusText: response.statusText,
|
|
44
|
-
headers: response.headers,
|
|
45
|
-
text: () => Promise.resolve(text),
|
|
46
|
-
json: () => response.json(),
|
|
47
|
-
arrayBuffer: () => Promise.resolve(buffer),
|
|
48
|
-
};
|
|
38
|
+
return (0, file_response_1.wrapAsFileResponse)(response, 'downloadBackup');
|
|
49
39
|
}
|
|
50
40
|
const response = await fetch(url, fetchOptions);
|
|
51
41
|
if (!response.ok) {
|
|
52
42
|
throw new Error(`Failed to download backup: ${response.status} ${response.statusText}`);
|
|
53
43
|
}
|
|
54
|
-
return
|
|
55
|
-
ok: response.ok,
|
|
56
|
-
status: response.status,
|
|
57
|
-
statusText: response.statusText,
|
|
58
|
-
headers: (0, headers_1.headersToRecord)(response.headers),
|
|
59
|
-
text: () => response.text(),
|
|
60
|
-
json: () => response.json(),
|
|
61
|
-
arrayBuffer: () => response.arrayBuffer(),
|
|
62
|
-
};
|
|
44
|
+
return (0, file_response_1.wrapAsFileResponse)(response, 'downloadBackup');
|
|
63
45
|
}
|
|
64
46
|
}
|
|
65
47
|
exports.BackupClient = BackupClient;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.UploadClient = void 0;
|
|
4
4
|
const endpoints_1 = require("../consts/endpoints");
|
|
5
5
|
const http_client_1 = require("../transport/http-client");
|
|
6
|
-
const
|
|
6
|
+
const file_response_1 = require("../utils/file-response");
|
|
7
7
|
const multipart_upload_1 = require("../utils/multipart-upload");
|
|
8
8
|
const validators_1 = require("../utils/validators");
|
|
9
9
|
const base_client_1 = require("./base-client");
|
|
@@ -71,32 +71,13 @@ class UploadClient extends base_client_1.BaseClient {
|
|
|
71
71
|
if (!response.ok) {
|
|
72
72
|
throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
const text = await response.text();
|
|
76
|
-
const buffer = new TextEncoder().encode(text).buffer;
|
|
77
|
-
return {
|
|
78
|
-
ok: response.ok,
|
|
79
|
-
status: response.status,
|
|
80
|
-
statusText: response.statusText,
|
|
81
|
-
headers: response.headers,
|
|
82
|
-
text: () => Promise.resolve(text),
|
|
83
|
-
json: () => response.json(),
|
|
84
|
-
arrayBuffer: () => Promise.resolve(buffer),
|
|
85
|
-
};
|
|
74
|
+
return (0, file_response_1.wrapAsFileResponse)(response, 'viewAttachment');
|
|
86
75
|
}
|
|
87
76
|
const response = await fetch(fileUrl, fetchOptions);
|
|
88
77
|
if (!response.ok) {
|
|
89
78
|
throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
|
|
90
79
|
}
|
|
91
|
-
return
|
|
92
|
-
ok: response.ok,
|
|
93
|
-
status: response.status,
|
|
94
|
-
statusText: response.statusText,
|
|
95
|
-
headers: (0, headers_1.headersToRecord)(response.headers),
|
|
96
|
-
text: () => response.text(),
|
|
97
|
-
json: () => response.json(),
|
|
98
|
-
arrayBuffer: () => response.arrayBuffer(),
|
|
99
|
-
};
|
|
80
|
+
return (0, file_response_1.wrapAsFileResponse)(response, 'viewAttachment');
|
|
100
81
|
}
|
|
101
82
|
}
|
|
102
83
|
exports.UploadClient = UploadClient;
|
|
@@ -48,6 +48,7 @@ function createObsidianFetchAdapter(requestUrl) {
|
|
|
48
48
|
// Wrap Obsidian's direct properties as methods returning promises
|
|
49
49
|
text: () => Promise.resolve(response.text),
|
|
50
50
|
json: () => Promise.resolve(response.json),
|
|
51
|
+
arrayBuffer: () => Promise.resolve(response.arrayBuffer),
|
|
51
52
|
};
|
|
52
53
|
};
|
|
53
54
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapAsFileResponse = wrapAsFileResponse;
|
|
4
|
+
const headers_1 = require("./headers");
|
|
5
|
+
/**
|
|
6
|
+
* Wraps either a native `Response` or a `CustomFetchResponse` into the SDK's
|
|
7
|
+
* `FileResponse` shape (binary endpoints: `viewAttachment`, `downloadBackup`).
|
|
8
|
+
*
|
|
9
|
+
* `arrayBuffer()` is resolved lazily. A customFetch implementation that omits
|
|
10
|
+
* `arrayBuffer()` is still valid for callers that only read `text()`/`json()`;
|
|
11
|
+
* the descriptive error is thrown only if the caller actually requests binary
|
|
12
|
+
* bytes. This avoids the lossy `text()` → `TextEncoder` round-trip that
|
|
13
|
+
* corrupts non-UTF-8 bytes (every `0x80`-`0xFF` byte not part of a valid UTF-8
|
|
14
|
+
* sequence is replaced with `U+FFFD`).
|
|
15
|
+
*/
|
|
16
|
+
function wrapAsFileResponse(response, context) {
|
|
17
|
+
const headers = response.headers instanceof Headers ? (0, headers_1.headersToRecord)(response.headers) : response.headers;
|
|
18
|
+
return {
|
|
19
|
+
ok: response.ok,
|
|
20
|
+
status: response.status,
|
|
21
|
+
statusText: response.statusText,
|
|
22
|
+
headers,
|
|
23
|
+
text: () => response.text(),
|
|
24
|
+
json: () => response.json(),
|
|
25
|
+
arrayBuffer: () => {
|
|
26
|
+
if (typeof response.arrayBuffer !== 'function') {
|
|
27
|
+
throw new Error(`customFetch response must implement arrayBuffer() for ${context} (binary endpoint); reading the body via text() corrupts non-UTF-8 bytes`);
|
|
28
|
+
}
|
|
29
|
+
return response.arrayBuffer();
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ENDPOINT_REST_BACKUPS, ENDPOINT_REST_BACKUPS_DOWNLOAD } from '../consts/endpoints.js';
|
|
2
2
|
import { request } from '../transport/http-client.js';
|
|
3
|
-
import {
|
|
3
|
+
import { wrapAsFileResponse } from '../utils/file-response.js';
|
|
4
4
|
import { validateBackupArray } from '../utils/validators.js';
|
|
5
5
|
import { BaseClient } from './base-client.js';
|
|
6
6
|
/**
|
|
@@ -32,30 +32,12 @@ export class BackupClient extends BaseClient {
|
|
|
32
32
|
if (!response.ok) {
|
|
33
33
|
throw new Error(`Failed to download backup: ${response.status} ${response.statusText}`);
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
const buffer = new TextEncoder().encode(text).buffer;
|
|
37
|
-
return {
|
|
38
|
-
ok: response.ok,
|
|
39
|
-
status: response.status,
|
|
40
|
-
statusText: response.statusText,
|
|
41
|
-
headers: response.headers,
|
|
42
|
-
text: () => Promise.resolve(text),
|
|
43
|
-
json: () => response.json(),
|
|
44
|
-
arrayBuffer: () => Promise.resolve(buffer),
|
|
45
|
-
};
|
|
35
|
+
return wrapAsFileResponse(response, 'downloadBackup');
|
|
46
36
|
}
|
|
47
37
|
const response = await fetch(url, fetchOptions);
|
|
48
38
|
if (!response.ok) {
|
|
49
39
|
throw new Error(`Failed to download backup: ${response.status} ${response.statusText}`);
|
|
50
40
|
}
|
|
51
|
-
return
|
|
52
|
-
ok: response.ok,
|
|
53
|
-
status: response.status,
|
|
54
|
-
statusText: response.statusText,
|
|
55
|
-
headers: headersToRecord(response.headers),
|
|
56
|
-
text: () => response.text(),
|
|
57
|
-
json: () => response.json(),
|
|
58
|
-
arrayBuffer: () => response.arrayBuffer(),
|
|
59
|
-
};
|
|
41
|
+
return wrapAsFileResponse(response, 'downloadBackup');
|
|
60
42
|
}
|
|
61
43
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ENDPOINT_REST_UPLOADS } from '../consts/endpoints.js';
|
|
2
2
|
import { isSuccess, request } from '../transport/http-client.js';
|
|
3
|
-
import {
|
|
3
|
+
import { wrapAsFileResponse } from '../utils/file-response.js';
|
|
4
4
|
import { uploadMultipartFile } from '../utils/multipart-upload.js';
|
|
5
5
|
import { validateAttachment } from '../utils/validators.js';
|
|
6
6
|
import { BaseClient } from './base-client.js';
|
|
@@ -68,31 +68,12 @@ export class UploadClient extends BaseClient {
|
|
|
68
68
|
if (!response.ok) {
|
|
69
69
|
throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
const text = await response.text();
|
|
73
|
-
const buffer = new TextEncoder().encode(text).buffer;
|
|
74
|
-
return {
|
|
75
|
-
ok: response.ok,
|
|
76
|
-
status: response.status,
|
|
77
|
-
statusText: response.statusText,
|
|
78
|
-
headers: response.headers,
|
|
79
|
-
text: () => Promise.resolve(text),
|
|
80
|
-
json: () => response.json(),
|
|
81
|
-
arrayBuffer: () => Promise.resolve(buffer),
|
|
82
|
-
};
|
|
71
|
+
return wrapAsFileResponse(response, 'viewAttachment');
|
|
83
72
|
}
|
|
84
73
|
const response = await fetch(fileUrl, fetchOptions);
|
|
85
74
|
if (!response.ok) {
|
|
86
75
|
throw new Error(`Failed to fetch attachment: ${response.status} ${response.statusText}`);
|
|
87
76
|
}
|
|
88
|
-
return
|
|
89
|
-
ok: response.ok,
|
|
90
|
-
status: response.status,
|
|
91
|
-
statusText: response.statusText,
|
|
92
|
-
headers: headersToRecord(response.headers),
|
|
93
|
-
text: () => response.text(),
|
|
94
|
-
json: () => response.json(),
|
|
95
|
-
arrayBuffer: () => response.arrayBuffer(),
|
|
96
|
-
};
|
|
77
|
+
return wrapAsFileResponse(response, 'viewAttachment');
|
|
97
78
|
}
|
|
98
79
|
}
|
|
@@ -45,6 +45,7 @@ export function createObsidianFetchAdapter(requestUrl) {
|
|
|
45
45
|
// Wrap Obsidian's direct properties as methods returning promises
|
|
46
46
|
text: () => Promise.resolve(response.text),
|
|
47
47
|
json: () => Promise.resolve(response.json),
|
|
48
|
+
arrayBuffer: () => Promise.resolve(response.arrayBuffer),
|
|
48
49
|
};
|
|
49
50
|
};
|
|
50
51
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { headersToRecord } from './headers.js';
|
|
2
|
+
/**
|
|
3
|
+
* Wraps either a native `Response` or a `CustomFetchResponse` into the SDK's
|
|
4
|
+
* `FileResponse` shape (binary endpoints: `viewAttachment`, `downloadBackup`).
|
|
5
|
+
*
|
|
6
|
+
* `arrayBuffer()` is resolved lazily. A customFetch implementation that omits
|
|
7
|
+
* `arrayBuffer()` is still valid for callers that only read `text()`/`json()`;
|
|
8
|
+
* the descriptive error is thrown only if the caller actually requests binary
|
|
9
|
+
* bytes. This avoids the lossy `text()` → `TextEncoder` round-trip that
|
|
10
|
+
* corrupts non-UTF-8 bytes (every `0x80`-`0xFF` byte not part of a valid UTF-8
|
|
11
|
+
* sequence is replaced with `U+FFFD`).
|
|
12
|
+
*/
|
|
13
|
+
export function wrapAsFileResponse(response, context) {
|
|
14
|
+
const headers = response.headers instanceof Headers ? headersToRecord(response.headers) : response.headers;
|
|
15
|
+
return {
|
|
16
|
+
ok: response.ok,
|
|
17
|
+
status: response.status,
|
|
18
|
+
statusText: response.statusText,
|
|
19
|
+
headers,
|
|
20
|
+
text: () => response.text(),
|
|
21
|
+
json: () => response.json(),
|
|
22
|
+
arrayBuffer: () => {
|
|
23
|
+
if (typeof response.arrayBuffer !== 'function') {
|
|
24
|
+
throw new Error(`customFetch response must implement arrayBuffer() for ${context} (binary endpoint); reading the body via text() corrupts non-UTF-8 bytes`);
|
|
25
|
+
}
|
|
26
|
+
return response.arrayBuffer();
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -67,7 +67,12 @@ export declare function isNetworkError(error: Error): error is NetworkError;
|
|
|
67
67
|
*/
|
|
68
68
|
export declare function isHttpError(error: Error): error is HttpError;
|
|
69
69
|
/**
|
|
70
|
-
* Custom fetch response interface that custom HTTP clients must implement
|
|
70
|
+
* Custom fetch response interface that custom HTTP clients must implement.
|
|
71
|
+
*
|
|
72
|
+
* `arrayBuffer()` is optional for back-compat with existing implementations,
|
|
73
|
+
* but must be provided when the fetch is used with binary endpoints
|
|
74
|
+
* (`viewAttachment`, `downloadBackup`) — those endpoints throw at runtime if
|
|
75
|
+
* it is missing rather than fall back to a lossy `text()` round-trip.
|
|
71
76
|
*/
|
|
72
77
|
export type CustomFetchResponse = {
|
|
73
78
|
ok: boolean;
|
|
@@ -76,6 +81,7 @@ export type CustomFetchResponse = {
|
|
|
76
81
|
headers: Record<string, string>;
|
|
77
82
|
text(): Promise<string>;
|
|
78
83
|
json(): Promise<unknown>;
|
|
84
|
+
arrayBuffer?: () => Promise<ArrayBuffer>;
|
|
79
85
|
};
|
|
80
86
|
/**
|
|
81
87
|
* Custom fetch function type for alternative HTTP clients
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CustomFetchResponse, FileResponse } from '../types/http.js';
|
|
2
|
+
type AnyResponse = CustomFetchResponse | Response;
|
|
3
|
+
/**
|
|
4
|
+
* Wraps either a native `Response` or a `CustomFetchResponse` into the SDK's
|
|
5
|
+
* `FileResponse` shape (binary endpoints: `viewAttachment`, `downloadBackup`).
|
|
6
|
+
*
|
|
7
|
+
* `arrayBuffer()` is resolved lazily. A customFetch implementation that omits
|
|
8
|
+
* `arrayBuffer()` is still valid for callers that only read `text()`/`json()`;
|
|
9
|
+
* the descriptive error is thrown only if the caller actually requests binary
|
|
10
|
+
* bytes. This avoids the lossy `text()` → `TextEncoder` round-trip that
|
|
11
|
+
* corrupts non-UTF-8 bytes (every `0x80`-`0xFF` byte not part of a valid UTF-8
|
|
12
|
+
* sequence is replaced with `U+FFFD`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function wrapAsFileResponse(response: AnyResponse, context: 'viewAttachment' | 'downloadBackup'): FileResponse;
|
|
15
|
+
export {};
|
package/package.json
CHANGED