teak-sdk 1.0.83 → 1.0.85
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 +2 -2
- package/dist/sdk.js +55 -18
- package/dist/types/client/sdk.d.ts +62 -3
- package/dist/types/devUrls.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,5 +26,5 @@ the token used by a retry-eligible 401 response. Return a new or already-refresh
|
|
|
26
26
|
token to retry once, or `null` to stop. Check the rejected token against the current
|
|
27
27
|
session before refreshing so an older response cannot invalidate newer credentials.
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
Install it from npm as `teak-sdk`. Each release shares the lockstep version of
|
|
30
|
+
the other Teak products and is published by the `SDK Release` workflow.
|
package/dist/sdk.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// ../convex/devUrls.ts
|
|
2
|
+
var TEAK_DEV_DEPLOYMENT_NAME = "reminiscent-kangaroo-59";
|
|
3
|
+
var DEFAULT_TEAK_DEV_CONVEX_URL = `https://${TEAK_DEV_DEPLOYMENT_NAME}.convex.cloud`;
|
|
4
|
+
var DEFAULT_TEAK_DEV_CONVEX_SITE_URL = `https://${TEAK_DEV_DEPLOYMENT_NAME}.convex.site`;
|
|
2
5
|
var isLocalDevelopmentHostname = (hostname) => {
|
|
3
6
|
const normalizedHostname = hostname.trim().toLowerCase();
|
|
4
7
|
return normalizedHostname === "localhost" || normalizedHostname === "127.0.0.1" || normalizedHostname.endsWith(".localhost");
|
|
@@ -907,20 +910,22 @@ var byteLengthForBody = (bytes) => {
|
|
|
907
910
|
}
|
|
908
911
|
return null;
|
|
909
912
|
};
|
|
913
|
+
var asList = (value) => {
|
|
914
|
+
if (Array.isArray(value)) {
|
|
915
|
+
return value;
|
|
916
|
+
}
|
|
917
|
+
return typeof value === "string" ? [value] : [];
|
|
918
|
+
};
|
|
910
919
|
var buildCardsSearchParams = (input) => {
|
|
911
920
|
const search = new URLSearchParams;
|
|
912
921
|
if (input.query?.trim()) {
|
|
913
922
|
search.set("q", input.query.trim());
|
|
914
923
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
}
|
|
921
|
-
for (const type of types) {
|
|
922
|
-
if (type.trim()) {
|
|
923
|
-
search.append("type", type.trim());
|
|
924
|
+
for (const name of ["type", "style", "hue", "hex"]) {
|
|
925
|
+
for (const value of asList(input[name])) {
|
|
926
|
+
if (value.trim()) {
|
|
927
|
+
search.append(name, value.trim());
|
|
928
|
+
}
|
|
924
929
|
}
|
|
925
930
|
}
|
|
926
931
|
if (input.tag?.trim()) {
|
|
@@ -935,6 +940,9 @@ var buildCardsSearchParams = (input) => {
|
|
|
935
940
|
if (input.favorited) {
|
|
936
941
|
search.set("favorited", "true");
|
|
937
942
|
}
|
|
943
|
+
if (input.trashed) {
|
|
944
|
+
search.set("trashed", "true");
|
|
945
|
+
}
|
|
938
946
|
if (input.sort === "oldest") {
|
|
939
947
|
search.set("sort", "oldest");
|
|
940
948
|
}
|
|
@@ -992,6 +1000,18 @@ var asCreate = (value) => {
|
|
|
992
1000
|
}
|
|
993
1001
|
return value;
|
|
994
1002
|
};
|
|
1003
|
+
var asMe = (value) => {
|
|
1004
|
+
if (!(isObject(value) && isObject(value.data)) || typeof value.data.id !== "string") {
|
|
1005
|
+
throw new TeakApiError("PARSE_ERROR");
|
|
1006
|
+
}
|
|
1007
|
+
return value.data;
|
|
1008
|
+
};
|
|
1009
|
+
var asLatestExport = (value) => {
|
|
1010
|
+
if (!isObject(value) || typeof value.canStartNew !== "boolean") {
|
|
1011
|
+
throw new TeakApiError("PARSE_ERROR");
|
|
1012
|
+
}
|
|
1013
|
+
return value;
|
|
1014
|
+
};
|
|
995
1015
|
var asUpload = (value) => {
|
|
996
1016
|
if (!isObject(value) || typeof value.uploadUrl !== "string" || typeof value.fileKey !== "string" || value.method !== "PUT" || typeof value.maxFileSize !== "number" || typeof value.expiresIn !== "number") {
|
|
997
1017
|
throw new TeakApiError("PARSE_ERROR");
|
|
@@ -1044,7 +1064,7 @@ var createTeakClient = (options) => {
|
|
|
1044
1064
|
if (!response.ok) {
|
|
1045
1065
|
const object = isObject(payload) ? payload : {};
|
|
1046
1066
|
throw new TeakApiError(codeFrom(object.code, response.status === 404 ? "NOT_FOUND" : "REQUEST_FAILED"), String(object.error || response.statusText), {
|
|
1047
|
-
requestId:
|
|
1067
|
+
requestId: response.headers.get("x-request-id") ?? undefined,
|
|
1048
1068
|
retryAt: typeof object.retryAt === "number" ? object.retryAt : undefined,
|
|
1049
1069
|
status: response.status
|
|
1050
1070
|
});
|
|
@@ -1052,23 +1072,40 @@ var createTeakClient = (options) => {
|
|
|
1052
1072
|
return parser(payload);
|
|
1053
1073
|
};
|
|
1054
1074
|
const qs = (params) => buildCardsSearchParams(params);
|
|
1075
|
+
const idempotency = (requestOptions) => requestOptions?.idempotencyKey ? { "Idempotency-Key": requestOptions.idempotencyKey } : {};
|
|
1076
|
+
const cardPath = (id) => `/v1/cards/${encodeURIComponent(id)}`;
|
|
1055
1077
|
return {
|
|
1056
1078
|
cards: {
|
|
1057
|
-
bulk: (operation, items) => request("/v1/cards/bulk", {
|
|
1079
|
+
bulk: (operation, items, requestOptions) => request("/v1/cards/bulk", {
|
|
1080
|
+
body: JSON.stringify({ items, operation }),
|
|
1081
|
+
headers: idempotency(requestOptions),
|
|
1082
|
+
method: "POST"
|
|
1083
|
+
}, (v) => v),
|
|
1058
1084
|
changes: (input) => {
|
|
1059
1085
|
const search = new URLSearchParams(qs(input));
|
|
1060
1086
|
search.set("since", String(input.since));
|
|
1061
1087
|
return request(`/v1/cards/changes?${search.toString()}`, { method: "GET" }, (v) => v);
|
|
1062
1088
|
},
|
|
1063
|
-
create: (input) => request("/v1/cards", {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1089
|
+
create: (input, requestOptions) => request("/v1/cards", {
|
|
1090
|
+
body: JSON.stringify(input),
|
|
1091
|
+
headers: idempotency(requestOptions),
|
|
1092
|
+
method: "POST"
|
|
1093
|
+
}, asCreate),
|
|
1094
|
+
delete: (id, deleteOptions) => request(`${cardPath(id)}${deleteOptions?.permanent ? "?permanent=true" : ""}`, { method: "DELETE" }, () => null),
|
|
1095
|
+
duplicate: (url) => request(`/v1/cards/duplicate?${new URLSearchParams({ url }).toString()}`, { method: "GET" }, (v) => isObject(v) && typeof v.cardId === "string" ? v.cardId : null),
|
|
1096
|
+
favorites: (input = {}) => request(`/v1/cards?${qs({ include: "content,metadata", ...input, favorited: true })}`, { method: "GET" }, asPage),
|
|
1097
|
+
get: (id) => request(cardPath(id), { method: "GET" }, asCard),
|
|
1067
1098
|
list: (input = {}) => request(`/v1/cards?${qs(input)}`, { method: "GET" }, asPage),
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1099
|
+
restore: (id) => request(`${cardPath(id)}/restore`, { method: "POST" }, () => null),
|
|
1100
|
+
search: (input = {}) => request(`/v1/cards?${qs({ include: "content,metadata", ...input })}`, { method: "GET" }, asPage),
|
|
1101
|
+
setFavorite: (id, isFavorited) => request(`${cardPath(id)}/favorite`, { body: JSON.stringify({ isFavorited }), method: "PATCH" }, asCard),
|
|
1102
|
+
update: (id, input) => request(cardPath(id), { body: JSON.stringify(input), method: "PATCH" }, asCard)
|
|
1103
|
+
},
|
|
1104
|
+
exports: {
|
|
1105
|
+
latest: () => request("/v1/exports/latest", { method: "GET" }, asLatestExport),
|
|
1106
|
+
start: () => request("/v1/exports", { method: "POST" }, (v) => v.job)
|
|
1071
1107
|
},
|
|
1108
|
+
me: () => request("/v1/me", { method: "GET" }, asMe),
|
|
1072
1109
|
tags: {
|
|
1073
1110
|
list: () => request("/v1/tags", { method: "GET" }, asTags)
|
|
1074
1111
|
},
|
|
@@ -34,8 +34,13 @@ export interface Card {
|
|
|
34
34
|
fileSize: number | null;
|
|
35
35
|
fileUrl: string | null;
|
|
36
36
|
id: string;
|
|
37
|
+
isDeleted: boolean;
|
|
37
38
|
isFavorited: boolean;
|
|
38
39
|
linkAuthor: string | null;
|
|
40
|
+
linkFacts: Array<{
|
|
41
|
+
label: string;
|
|
42
|
+
value: string;
|
|
43
|
+
}>;
|
|
39
44
|
linkPreviewImageUrl: string | null;
|
|
40
45
|
linkPreviewMedia: Array<{
|
|
41
46
|
type: "image" | "video";
|
|
@@ -52,10 +57,12 @@ export interface Card {
|
|
|
52
57
|
linkPublisher: string | null;
|
|
53
58
|
linkSiteName: string | null;
|
|
54
59
|
metadataDescription: string | null;
|
|
60
|
+
metadataStatus: string | null;
|
|
55
61
|
metadataTitle: string | null;
|
|
56
62
|
mimeType: string | null;
|
|
57
63
|
notes: string | null;
|
|
58
64
|
placeholderUrl: string | null;
|
|
65
|
+
processingStatus: Record<string, unknown> | null;
|
|
59
66
|
screenshotUrl: string | null;
|
|
60
67
|
tags: string[];
|
|
61
68
|
thumbnailUrl: string | null;
|
|
@@ -98,9 +105,46 @@ export interface UpdateCardInput {
|
|
|
98
105
|
content?: string;
|
|
99
106
|
metadataTitle?: string | null;
|
|
100
107
|
notes?: string | null;
|
|
108
|
+
/** AI tags to drop. `tags` replaces only the card's own tags. */
|
|
109
|
+
removeAiTags?: string[];
|
|
101
110
|
tags?: string[];
|
|
102
111
|
url?: string;
|
|
103
112
|
}
|
|
113
|
+
export interface Me {
|
|
114
|
+
cardCount: number;
|
|
115
|
+
/** Null on Pro, which has no card limit. */
|
|
116
|
+
cardLimit: number | null;
|
|
117
|
+
email: string;
|
|
118
|
+
id: string;
|
|
119
|
+
name?: string;
|
|
120
|
+
plan: "free" | "pro";
|
|
121
|
+
settingsUrl: string;
|
|
122
|
+
}
|
|
123
|
+
export interface ExportJob {
|
|
124
|
+
cardCount: number | null;
|
|
125
|
+
completedAt: number | null;
|
|
126
|
+
createdAt: number;
|
|
127
|
+
downloadUrl: string | null;
|
|
128
|
+
expiresAt: number | null;
|
|
129
|
+
failureClass: string | null;
|
|
130
|
+
filesIncluded: number | null;
|
|
131
|
+
filesOmitted: number | null;
|
|
132
|
+
id: string;
|
|
133
|
+
processedCount: number | null;
|
|
134
|
+
sizeBytes: number | null;
|
|
135
|
+
stage: "snapshotting" | "archiving" | null;
|
|
136
|
+
status: "pending" | "running" | "ready" | "failed" | "canceled" | "expired";
|
|
137
|
+
updatedAt: number;
|
|
138
|
+
}
|
|
139
|
+
export interface LatestExport {
|
|
140
|
+
canStartNew: boolean;
|
|
141
|
+
job: ExportJob | null;
|
|
142
|
+
nextAvailableAt: number | null;
|
|
143
|
+
}
|
|
144
|
+
export interface RequestOptions {
|
|
145
|
+
/** Makes a retried create or bulk request safe to repeat. */
|
|
146
|
+
idempotencyKey?: string;
|
|
147
|
+
}
|
|
104
148
|
export interface CreateUploadInput {
|
|
105
149
|
fileName: string;
|
|
106
150
|
fileSize: number;
|
|
@@ -146,11 +190,15 @@ export declare const buildCardsSearchParams: (input: {
|
|
|
146
190
|
createdBefore?: number;
|
|
147
191
|
cursor?: string;
|
|
148
192
|
favorited?: boolean;
|
|
193
|
+
hex?: string | readonly string[];
|
|
194
|
+
hue?: string | readonly string[];
|
|
149
195
|
include?: string;
|
|
150
196
|
limit?: number;
|
|
151
197
|
query?: string;
|
|
152
198
|
sort?: CardSort;
|
|
199
|
+
style?: string | readonly string[];
|
|
153
200
|
tag?: string;
|
|
201
|
+
trashed?: boolean;
|
|
154
202
|
type?: CardType | string | readonly (CardType | string)[];
|
|
155
203
|
}) => string;
|
|
156
204
|
export declare const createTeakClient: (options: {
|
|
@@ -161,21 +209,32 @@ export declare const createTeakClient: (options: {
|
|
|
161
209
|
userAgent?: string;
|
|
162
210
|
}) => {
|
|
163
211
|
cards: {
|
|
164
|
-
bulk: (operation: BulkCardsResponse["operation"], items: unknown[]) => Promise<BulkCardsResponse>;
|
|
212
|
+
bulk: (operation: BulkCardsResponse["operation"], items: unknown[], requestOptions?: RequestOptions) => Promise<BulkCardsResponse>;
|
|
165
213
|
changes: (input: {
|
|
166
214
|
cursor?: string;
|
|
167
215
|
limit?: number;
|
|
168
216
|
since: number;
|
|
169
217
|
}) => Promise<CardChangesResponse>;
|
|
170
|
-
create: (input: CreateCardInput) => Promise<CreateCardResponse>;
|
|
171
|
-
|
|
218
|
+
create: (input: CreateCardInput, requestOptions?: RequestOptions) => Promise<CreateCardResponse>;
|
|
219
|
+
/** Moves the card to Trash, or deletes it for good with `permanent`. */
|
|
220
|
+
delete: (id: string, deleteOptions?: {
|
|
221
|
+
permanent?: boolean;
|
|
222
|
+
}) => Promise<null>;
|
|
223
|
+
/** The ID of a saved card with exactly this URL, or null. */
|
|
224
|
+
duplicate: (url: string) => Promise<string | null>;
|
|
172
225
|
favorites: (input?: Parameters<(params: Parameters<typeof buildCardsSearchParams>[0]) => string>[0]) => Promise<CardsPage>;
|
|
173
226
|
get: (id: string) => Promise<Card>;
|
|
174
227
|
list: (input?: Parameters<(params: Parameters<typeof buildCardsSearchParams>[0]) => string>[0]) => Promise<CardsPage>;
|
|
228
|
+
restore: (id: string) => Promise<null>;
|
|
175
229
|
search: (input?: Parameters<(params: Parameters<typeof buildCardsSearchParams>[0]) => string>[0]) => Promise<CardsPage>;
|
|
176
230
|
setFavorite: (id: string, isFavorited: boolean) => Promise<Card>;
|
|
177
231
|
update: (id: string, input: UpdateCardInput) => Promise<Card>;
|
|
178
232
|
};
|
|
233
|
+
exports: {
|
|
234
|
+
latest: () => Promise<LatestExport>;
|
|
235
|
+
start: () => Promise<ExportJob>;
|
|
236
|
+
};
|
|
237
|
+
me: () => Promise<Me>;
|
|
179
238
|
tags: {
|
|
180
239
|
list: () => Promise<{
|
|
181
240
|
items: TagSummary[];
|
package/dist/types/devUrls.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
/** The shared cloud dev deployment every checkout and cloud session uses. */
|
|
2
|
+
export declare const TEAK_DEV_DEPLOYMENT_NAME = "reminiscent-kangaroo-59";
|
|
1
3
|
export declare const DEFAULT_TEAK_DEV_APP_URL = "http://localhost:3000";
|
|
4
|
+
export declare const DEFAULT_TEAK_DEV_CONVEX_URL = "https://reminiscent-kangaroo-59.convex.cloud";
|
|
2
5
|
export declare const DEFAULT_TEAK_DEV_CONVEX_SITE_URL = "https://reminiscent-kangaroo-59.convex.site";
|
|
3
6
|
export declare const DEFAULT_TEAK_DEV_API_URL = "https://reminiscent-kangaroo-59.convex.site";
|
|
4
7
|
export declare const DEFAULT_TEAK_DEV_DOCS_URL = "http://localhost:3001";
|