teak-sdk 1.0.85 → 1.0.87
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/sdk.js +258 -58
- package/dist/types/client/authDiscovery.d.ts +2 -2
- package/dist/types/client/sdk.d.ts +319 -4
- package/dist/types/devUrls.d.ts +0 -1
- package/dist/types/shared/constants.d.ts +13 -36
- package/dist/types/shared/fileFormats.d.ts +1 -0
- package/dist/types/shared/filesOrigins.d.ts +4 -0
- package/dist/types/shared/folders.d.ts +27 -0
- package/dist/types/shared/oauthUrl.d.ts +2 -0
- package/dist/types/shared/tags.d.ts +37 -0
- package/dist/types/shared/utils/codePoints.d.ts +2 -0
- package/dist/types/shared/utils/formatBytes.d.ts +1 -0
- package/dist/types/shared/workosResources.d.ts +7 -4
- package/package.json +2 -2
package/dist/sdk.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
// ../convex/
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
// ../convex/shared/utils/formatBytes.ts
|
|
2
|
+
var BYTE_UNITS = ["B", "KB", "MB", "GB"];
|
|
3
|
+
var formatBytes = (bytes) => {
|
|
4
|
+
if (!(bytes && Number.isFinite(bytes) && bytes > 0)) {
|
|
5
|
+
return "0 B";
|
|
6
|
+
}
|
|
7
|
+
let value = bytes;
|
|
8
|
+
let unit = 0;
|
|
9
|
+
while (value >= 1024 && unit < BYTE_UNITS.length - 1) {
|
|
10
|
+
value /= 1024;
|
|
11
|
+
unit += 1;
|
|
12
|
+
}
|
|
13
|
+
const digits = unit > 0 && value < 10 ? 1 : 0;
|
|
14
|
+
return `${value.toFixed(digits)} ${BYTE_UNITS[unit]}`;
|
|
8
15
|
};
|
|
9
|
-
|
|
10
16
|
// ../convex/shared/boundedResponse.ts
|
|
11
17
|
class ResponseSizeLimitError extends Error {
|
|
12
18
|
}
|
|
@@ -40,28 +46,17 @@ var consumeResponseWithinLimit = async (response, maxBytes, consume) => {
|
|
|
40
46
|
};
|
|
41
47
|
var readResponseTextWithinLimit = (response, maxBytes) => consumeResponseWithinLimit(response, maxBytes, (boundedResponse) => boundedResponse.text());
|
|
42
48
|
|
|
43
|
-
// ../convex/
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
// ../convex/devUrls.ts
|
|
50
|
+
var TEAK_DEV_DEPLOYMENT_NAME = "reminiscent-kangaroo-59";
|
|
51
|
+
var DEFAULT_TEAK_DEV_CONVEX_URL = `https://${TEAK_DEV_DEPLOYMENT_NAME}.convex.cloud`;
|
|
52
|
+
var DEFAULT_TEAK_DEV_CONVEX_SITE_URL = `https://${TEAK_DEV_DEPLOYMENT_NAME}.convex.site`;
|
|
53
|
+
var isLocalDevelopmentHostname = (hostname) => {
|
|
54
|
+
const normalizedHostname = hostname.trim().toLowerCase();
|
|
55
|
+
return normalizedHostname === "localhost" || normalizedHostname === "127.0.0.1" || normalizedHostname.endsWith(".localhost");
|
|
47
56
|
};
|
|
48
57
|
|
|
49
|
-
// ../convex/
|
|
50
|
-
var
|
|
51
|
-
"cli",
|
|
52
|
-
"raycast",
|
|
53
|
-
"chrome",
|
|
54
|
-
"firefox",
|
|
55
|
-
"safari"
|
|
56
|
-
];
|
|
57
|
-
var caches = new WeakMap;
|
|
58
|
-
var object = (value) => {
|
|
59
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
60
|
-
throw new Error("Invalid OAuth discovery document");
|
|
61
|
-
}
|
|
62
|
-
return value;
|
|
63
|
-
};
|
|
64
|
-
var loopback = (hostname) => isLocalDevelopmentHostname(hostname) || hostname === "[::1]";
|
|
58
|
+
// ../convex/shared/oauthUrl.ts
|
|
59
|
+
var isLoopbackHostname = (hostname) => isLocalDevelopmentHostname(hostname) || hostname === "[::1]";
|
|
65
60
|
var privateHost = (hostname) => {
|
|
66
61
|
const octets = hostname.split(".").map(Number);
|
|
67
62
|
return hostname.endsWith(".localhost") || hostname.endsWith(".local") || hostname.startsWith("[") || octets.length === 4 && octets.every((n) => Number.isInteger(n) && n >= 0 && n <= 255) && (octets[0] === 0 || octets[0] === 10 || octets[0] === 100 && octets[1] >= 64 && octets[1] <= 127 || octets[0] === 127 || octets[0] === 169 && octets[1] === 254 || octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31 || octets[0] === 192 && octets[1] === 168);
|
|
@@ -71,22 +66,40 @@ var validateOAuthUrl = (raw, local = false) => {
|
|
|
71
66
|
throw new Error("Missing OAuth discovery URL");
|
|
72
67
|
}
|
|
73
68
|
const url = new URL(raw);
|
|
74
|
-
if (url.username || url.password || url.hash || url.protocol !== "https:" && !(local && url.protocol === "http:" &&
|
|
69
|
+
if (url.username || url.password || url.hash || url.protocol !== "https:" && !(local && url.protocol === "http:" && isLoopbackHostname(url.hostname)) || !local && isLoopbackHostname(url.hostname) || privateHost(url.hostname) && !(local && isLoopbackHostname(url.hostname))) {
|
|
75
70
|
throw new Error("Unsafe OAuth discovery URL");
|
|
76
71
|
}
|
|
77
72
|
return url;
|
|
78
73
|
};
|
|
74
|
+
|
|
75
|
+
// ../convex/shared/workosResources.ts
|
|
76
|
+
var PRODUCTION_WORKOS_RESOURCE_ORIGIN = "https://teakvault.com";
|
|
77
|
+
var workosResourcesFor = (url) => {
|
|
78
|
+
const { origin } = new URL(url);
|
|
79
|
+
return Object.freeze({ api: `${origin}/api`, mcp: `${origin}/mcp` });
|
|
80
|
+
};
|
|
81
|
+
var PRODUCTION_WORKOS_RESOURCES = workosResourcesFor(PRODUCTION_WORKOS_RESOURCE_ORIGIN);
|
|
82
|
+
|
|
83
|
+
// ../convex/client/authDiscovery.ts
|
|
84
|
+
var OAUTH_SURFACES = ["cli", "raycast", "chrome", "firefox"];
|
|
85
|
+
var caches = new WeakMap;
|
|
86
|
+
var object = (value) => {
|
|
87
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
88
|
+
throw new Error("Invalid OAuth discovery document");
|
|
89
|
+
}
|
|
90
|
+
return value;
|
|
91
|
+
};
|
|
79
92
|
function discoverAuthServer(siteUrl, options = {}) {
|
|
80
93
|
const site = validateOAuthUrl(siteUrl, true);
|
|
81
|
-
const siteIsLocal =
|
|
94
|
+
const siteIsLocal = isLoopbackHostname(site.hostname);
|
|
82
95
|
const permittedLocalIssuer = options.localIssuer === undefined ? undefined : validateOAuthUrl(options.localIssuer, true);
|
|
83
|
-
if (permittedLocalIssuer && !
|
|
96
|
+
if (permittedLocalIssuer && !isLoopbackHostname(permittedLocalIssuer.hostname)) {
|
|
84
97
|
throw new Error("Development issuer must use loopback");
|
|
85
98
|
}
|
|
86
99
|
const local = siteIsLocal || permittedLocalIssuer !== undefined;
|
|
87
100
|
const validateUrl = (raw) => {
|
|
88
101
|
const url = validateOAuthUrl(raw, local);
|
|
89
|
-
if (
|
|
102
|
+
if (isLoopbackHostname(url.hostname) && !siteIsLocal && url.origin !== permittedLocalIssuer?.origin) {
|
|
90
103
|
throw new Error("Unapproved loopback OAuth server");
|
|
91
104
|
}
|
|
92
105
|
return url;
|
|
@@ -113,7 +126,7 @@ function discoverAuthServer(siteUrl, options = {}) {
|
|
|
113
126
|
const read = async (url) => {
|
|
114
127
|
const response = await fetchImpl(url, {
|
|
115
128
|
method: "GET",
|
|
116
|
-
credentials: "omit",
|
|
129
|
+
...{ credentials: "omit" },
|
|
117
130
|
redirect: "error",
|
|
118
131
|
headers: { Accept: "application/json" },
|
|
119
132
|
signal: controller.signal
|
|
@@ -158,7 +171,7 @@ function discoverAuthServer(siteUrl, options = {}) {
|
|
|
158
171
|
throw new Error("Missing OAuth client registration");
|
|
159
172
|
}
|
|
160
173
|
}
|
|
161
|
-
if (resource.resource !==
|
|
174
|
+
if (resource.resource !== PRODUCTION_WORKOS_RESOURCES.mcp && resource.resource !== workosResourcesFor(site.origin).mcp) {
|
|
162
175
|
throw new Error("OAuth resource mismatch");
|
|
163
176
|
}
|
|
164
177
|
return Object.freeze({
|
|
@@ -196,7 +209,7 @@ var base64Url = (bytes) => {
|
|
|
196
209
|
};
|
|
197
210
|
var randomBase64Url = (byteLength) => base64Url(crypto.getRandomValues(new Uint8Array(byteLength)));
|
|
198
211
|
var createPkceChallenge = async (verifier) => base64Url(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier))));
|
|
199
|
-
var apiResource = (auth) =>
|
|
212
|
+
var apiResource = (auth) => workosResourcesFor(auth.resource).api;
|
|
200
213
|
var createConnectAuthorizeUrl = (auth, params) => {
|
|
201
214
|
const url = new URL(auth.authorizationEndpoint);
|
|
202
215
|
url.searchParams.set("response_type", "code");
|
|
@@ -211,7 +224,7 @@ var createConnectAuthorizeUrl = (auth, params) => {
|
|
|
211
224
|
};
|
|
212
225
|
var send = (url, init, local) => fetch(validateOAuthUrl(url, local).href, {
|
|
213
226
|
...init,
|
|
214
|
-
credentials: "omit",
|
|
227
|
+
...{ credentials: "omit" },
|
|
215
228
|
redirect: "error",
|
|
216
229
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
217
230
|
});
|
|
@@ -304,8 +317,55 @@ var fetchConnectOwnerId = async (apiUrl, accessToken, options = {}) => {
|
|
|
304
317
|
// ../convex/shared/markdown.ts
|
|
305
318
|
var MARKDOWN_CONTENT_MAX_BYTES = 512 * 1024;
|
|
306
319
|
|
|
320
|
+
// ../files-protocol/src/decisions.ts
|
|
321
|
+
var CLEF_MODEL_ID = "@cf/cloudflare/clef";
|
|
322
|
+
var CLEF_FLASH_MODEL_ID = "@cf/cloudflare/clef-flash";
|
|
323
|
+
var CLEF_INPUT_USD_PER_MILLION = {
|
|
324
|
+
[CLEF_MODEL_ID]: 0.24,
|
|
325
|
+
[CLEF_FLASH_MODEL_ID]: 0.038
|
|
326
|
+
};
|
|
327
|
+
var RELEVANCE_LEVELS = [
|
|
328
|
+
"Not related",
|
|
329
|
+
"Loosely related",
|
|
330
|
+
"Relevant",
|
|
331
|
+
"Exactly what they are looking for"
|
|
332
|
+
];
|
|
333
|
+
var RELEVANCE_MAX_SCORE = RELEVANCE_LEVELS.length - 1;
|
|
334
|
+
// ../files-protocol/src/embeddings.ts
|
|
335
|
+
var ASCII_TOKEN_COST = 1 / 3;
|
|
336
|
+
// ../files-protocol/src/storage.ts
|
|
337
|
+
var FILES_UPLOAD_MAX_BYTES = 100 * 1024 * 1024;
|
|
338
|
+
var FILES_SIGNED_URL_MIN_VALIDITY_SECONDS = 7 * 24 * 60 * 60;
|
|
339
|
+
var FILE_CACHE_MAX_AGE_SECONDS = FILES_SIGNED_URL_MIN_VALIDITY_SECONDS - 24 * 60 * 60;
|
|
340
|
+
var FILES_PRIVATE_CACHE_CONTROL = `private, max-age=${FILE_CACHE_MAX_AGE_SECONDS}, immutable`;
|
|
341
|
+
var FILES_EDGE_CACHE_CONTROL = `public, max-age=${FILE_CACHE_MAX_AGE_SECONDS}, immutable`;
|
|
342
|
+
var FILES_DEV_KEY_PREFIX = "dev/";
|
|
343
|
+
var filesUserKeyRoot = (envPrefix) => `${envPrefix}users/`;
|
|
344
|
+
var filesExportKeyRoot = (envPrefix) => `${envPrefix}exports/`;
|
|
345
|
+
var FILES_OBJECT_KEY_ROOTS = ["", FILES_DEV_KEY_PREFIX].flatMap((envPrefix) => [filesUserKeyRoot(envPrefix), filesExportKeyRoot(envPrefix)]);
|
|
346
|
+
|
|
347
|
+
// ../files-protocol/src/inspect.ts
|
|
348
|
+
var FILES_INSPECT_MAX_ARCHIVE_BYTES = 25 * 1024 * 1024;
|
|
349
|
+
var FILES_INSPECT_MAX_SOURCE_BYTES = 2 * 1024 * 1024;
|
|
350
|
+
// ../files-protocol/src/remoteAsset.ts
|
|
351
|
+
var FILES_REMOTE_ASSET_MAX_BYTES = {
|
|
352
|
+
image: 20 * 1024 * 1024,
|
|
353
|
+
video: 50 * 1024 * 1024
|
|
354
|
+
};
|
|
355
|
+
// ../files-protocol/src/workflows.ts
|
|
356
|
+
var WORKFLOW_RPC_MAX_TTL_SECONDS = 5 * 60;
|
|
357
|
+
var WORKFLOW_RPC_MAX_BODY_BYTES = 4 * 1024 * 1024;
|
|
358
|
+
var RPC_KINDS = new Set(["action", "mutation", "query"]);
|
|
359
|
+
// ../files-protocol/src/index.ts
|
|
360
|
+
var FILES_UPLOAD_MAX_TTL_SECONDS = 15 * 60;
|
|
361
|
+
var FILES_OP_MAX_TTL_SECONDS = 15 * 60;
|
|
362
|
+
var FILES_OP_TTL_SECONDS = 10 * 60;
|
|
363
|
+
var FILES_TRANSCRIPT_MAX_BYTES = 512 * 1024;
|
|
364
|
+
var FILES_EXTRACTED_TEXT_MAX_CHARACTERS = 512 * 1024;
|
|
365
|
+
var FILES_EXTRACTED_TEXT_MAX_BYTES = 512 * 1024;
|
|
366
|
+
var FILES_IMPORT_PAGE_BYTES = 4 * 1024 * 1024;
|
|
367
|
+
|
|
307
368
|
// ../convex/shared/fileFormats.ts
|
|
308
|
-
var MAX_FILE_SIZE = 100 * 1024 * 1024;
|
|
309
369
|
var GENERIC_MIME_TYPES = new Set([
|
|
310
370
|
"",
|
|
311
371
|
"application/binary",
|
|
@@ -764,6 +824,19 @@ var FILE_FORMATS = [
|
|
|
764
824
|
preview: "audio"
|
|
765
825
|
})
|
|
766
826
|
];
|
|
827
|
+
// ../convex/shared/tags.ts
|
|
828
|
+
var MAX_TAG_NAME_LENGTH = 64;
|
|
829
|
+
var TAG_OPERATION_STALL_MS = 2 * 60000;
|
|
830
|
+
var TAG_ERROR_MESSAGES = {
|
|
831
|
+
EMPTY_NAME: "Name the tag",
|
|
832
|
+
NAME_TOO_LONG: `Tags can be at most ${MAX_TAG_NAME_LENGTH} characters`,
|
|
833
|
+
NOT_FOUND: "Tag not found",
|
|
834
|
+
SAME_TAG: "Choose a different tag to merge into",
|
|
835
|
+
OPERATION_RUNNING: "Another tag change is still running",
|
|
836
|
+
OPERATION_NOT_FOUND: "Tag operation not found"
|
|
837
|
+
};
|
|
838
|
+
var HIDDEN_TAG_KEYS = ["secret", "hidden"];
|
|
839
|
+
var hiddenTagKeys = new Set(HIDDEN_TAG_KEYS);
|
|
767
840
|
// ../convex/shared/constants.ts
|
|
768
841
|
var cardTypes = [
|
|
769
842
|
"text",
|
|
@@ -775,7 +848,9 @@ var cardTypes = [
|
|
|
775
848
|
"palette",
|
|
776
849
|
"quote"
|
|
777
850
|
];
|
|
851
|
+
var TRASH_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
|
|
778
852
|
var MULTIPART_UPLOAD_THRESHOLD = 8 * 1024 * 1024;
|
|
853
|
+
var API_IDEMPOTENCY_KEY_TTL_MS = 24 * 60 * 60 * 1000;
|
|
779
854
|
var CARD_TYPES = [...cardTypes];
|
|
780
855
|
var CARD_TYPE_REGISTRY = {
|
|
781
856
|
text: {
|
|
@@ -830,25 +905,40 @@ var RESERVED_KEYWORDS = [
|
|
|
830
905
|
|
|
831
906
|
// ../convex/client/sdk.ts
|
|
832
907
|
var CARD_TYPES2 = cardTypes;
|
|
833
|
-
var CARD_SORTS = ["newest", "oldest"];
|
|
908
|
+
var CARD_SORTS = ["newest", "oldest", "relevance", "shuffle"];
|
|
834
909
|
var ERROR_CODES = [
|
|
835
910
|
"AUTH_REQUIRED",
|
|
836
911
|
"BAD_REQUEST",
|
|
912
|
+
"CARD_LIMIT_REACHED",
|
|
837
913
|
"CONFIG_ERROR",
|
|
838
914
|
"CONFLICT",
|
|
839
915
|
"CONTENT_TOO_LARGE",
|
|
916
|
+
"FILE_TOO_LARGE",
|
|
917
|
+
"FOLDER_LIMIT",
|
|
918
|
+
"FORBIDDEN",
|
|
919
|
+
"IN_PROGRESS",
|
|
840
920
|
"INTERNAL_ERROR",
|
|
841
921
|
"INVALID_API_KEY",
|
|
842
922
|
"INVALID_INPUT",
|
|
923
|
+
"INVALID_STORAGE_KEY",
|
|
843
924
|
"INVALID_UTF8",
|
|
925
|
+
"LIMIT_REACHED",
|
|
844
926
|
"METHOD_NOT_ALLOWED",
|
|
845
927
|
"NETWORK_ERROR",
|
|
846
928
|
"NOT_FOUND",
|
|
929
|
+
"NO_CONTENT",
|
|
930
|
+
"NOT_IN_TRASH",
|
|
847
931
|
"PARSE_ERROR",
|
|
848
932
|
"RATE_LIMITED",
|
|
849
933
|
"REQUEST_FAILED",
|
|
934
|
+
"SERVICE_UNAVAILABLE",
|
|
935
|
+
"SMART_FOLDER",
|
|
936
|
+
"TAG_EXISTS",
|
|
937
|
+
"TAG_OPERATION_RUNNING",
|
|
850
938
|
"TIMEOUT",
|
|
851
|
-
"
|
|
939
|
+
"TYPE_MISMATCH",
|
|
940
|
+
"UNAUTHORIZED",
|
|
941
|
+
"UNSUPPORTED_TYPE"
|
|
852
942
|
];
|
|
853
943
|
|
|
854
944
|
class TeakApiError extends Error {
|
|
@@ -931,6 +1021,9 @@ var buildCardsSearchParams = (input) => {
|
|
|
931
1021
|
if (input.tag?.trim()) {
|
|
932
1022
|
search.set("tag", input.tag.trim());
|
|
933
1023
|
}
|
|
1024
|
+
if (input.folder?.trim()) {
|
|
1025
|
+
search.set("folder", input.folder.trim());
|
|
1026
|
+
}
|
|
934
1027
|
if (input.cursor?.trim()) {
|
|
935
1028
|
search.set("cursor", input.cursor.trim());
|
|
936
1029
|
}
|
|
@@ -943,8 +1036,20 @@ var buildCardsSearchParams = (input) => {
|
|
|
943
1036
|
if (input.trashed) {
|
|
944
1037
|
search.set("trashed", "true");
|
|
945
1038
|
}
|
|
946
|
-
if (input.
|
|
947
|
-
search.set("
|
|
1039
|
+
if (input.archived === "only" || input.archived === "include") {
|
|
1040
|
+
search.set("archived", input.archived);
|
|
1041
|
+
}
|
|
1042
|
+
if (input.similarTo?.trim()) {
|
|
1043
|
+
search.set("similarTo", input.similarTo.trim());
|
|
1044
|
+
}
|
|
1045
|
+
if (input.mode === "keyword" || input.mode === "semantic") {
|
|
1046
|
+
search.set("mode", input.mode);
|
|
1047
|
+
}
|
|
1048
|
+
if (input.sort === "oldest" || input.sort === "shuffle") {
|
|
1049
|
+
search.set("sort", input.sort);
|
|
1050
|
+
}
|
|
1051
|
+
if (input.sort === "shuffle" && typeof input.shuffleSeed === "number") {
|
|
1052
|
+
search.set("shuffleSeed", String(input.shuffleSeed));
|
|
948
1053
|
}
|
|
949
1054
|
if (typeof input.createdAfter === "number") {
|
|
950
1055
|
search.set("createdAfter", String(input.createdAfter));
|
|
@@ -983,6 +1088,35 @@ var asPage = (value) => {
|
|
|
983
1088
|
}
|
|
984
1089
|
return value;
|
|
985
1090
|
};
|
|
1091
|
+
var asFolder = (value) => {
|
|
1092
|
+
if (!isObject(value) || typeof value.id !== "string" || typeof value.name !== "string") {
|
|
1093
|
+
throw new TeakApiError("PARSE_ERROR", "Teak returned an unexpected folder payload.");
|
|
1094
|
+
}
|
|
1095
|
+
return value;
|
|
1096
|
+
};
|
|
1097
|
+
var asFolders = (value) => {
|
|
1098
|
+
if (!(isObject(value) && Array.isArray(value.items))) {
|
|
1099
|
+
throw new TeakApiError("PARSE_ERROR");
|
|
1100
|
+
}
|
|
1101
|
+
return { items: value.items.map(asFolder) };
|
|
1102
|
+
};
|
|
1103
|
+
var asFolderCards = (value) => {
|
|
1104
|
+
if (!(isObject(value) && isStringArray(value.updatedIds) && isStringArray(value.failedIds))) {
|
|
1105
|
+
throw new TeakApiError("PARSE_ERROR");
|
|
1106
|
+
}
|
|
1107
|
+
return {
|
|
1108
|
+
updatedIds: value.updatedIds,
|
|
1109
|
+
failedIds: value.failedIds,
|
|
1110
|
+
folderLimitIds: isStringArray(value.folderLimitIds) ? value.folderLimitIds : []
|
|
1111
|
+
};
|
|
1112
|
+
};
|
|
1113
|
+
var asTagOperation = (value) => {
|
|
1114
|
+
if (!isObject(value) || typeof value.id !== "string" || typeof value.status !== "string") {
|
|
1115
|
+
throw new TeakApiError("PARSE_ERROR", "Teak returned an unexpected tag operation payload.");
|
|
1116
|
+
}
|
|
1117
|
+
const { operationId: _operationId, ...operation } = value;
|
|
1118
|
+
return operation;
|
|
1119
|
+
};
|
|
986
1120
|
var asTags = (value) => {
|
|
987
1121
|
if (!(isObject(value) && Array.isArray(value.items))) {
|
|
988
1122
|
throw new TeakApiError("PARSE_ERROR");
|
|
@@ -1000,6 +1134,24 @@ var asCreate = (value) => {
|
|
|
1000
1134
|
}
|
|
1001
1135
|
return value;
|
|
1002
1136
|
};
|
|
1137
|
+
var asRefresh = (value) => {
|
|
1138
|
+
if (!isObject(value) || typeof value.cardId !== "string" || value.status !== "queued") {
|
|
1139
|
+
throw new TeakApiError("PARSE_ERROR");
|
|
1140
|
+
}
|
|
1141
|
+
return value;
|
|
1142
|
+
};
|
|
1143
|
+
var asSavedPdf = (value) => {
|
|
1144
|
+
if (!isObject(value) || typeof value.cardId !== "string" || typeof value.created !== "boolean") {
|
|
1145
|
+
throw new TeakApiError("PARSE_ERROR");
|
|
1146
|
+
}
|
|
1147
|
+
return { cardId: value.cardId, created: value.created };
|
|
1148
|
+
};
|
|
1149
|
+
var asCardContent = (value) => {
|
|
1150
|
+
if (!isObject(value) || typeof value.cardId !== "string" || typeof value.text !== "string" || typeof value.charCount !== "number" || typeof value.truncated !== "boolean" || !["document", "transcript", "content"].includes(String(value.kind))) {
|
|
1151
|
+
throw new TeakApiError("PARSE_ERROR");
|
|
1152
|
+
}
|
|
1153
|
+
return value;
|
|
1154
|
+
};
|
|
1003
1155
|
var asMe = (value) => {
|
|
1004
1156
|
if (!(isObject(value) && isObject(value.data)) || typeof value.data.id !== "string") {
|
|
1005
1157
|
throw new TeakApiError("PARSE_ERROR");
|
|
@@ -1074,6 +1226,25 @@ var createTeakClient = (options) => {
|
|
|
1074
1226
|
const qs = (params) => buildCardsSearchParams(params);
|
|
1075
1227
|
const idempotency = (requestOptions) => requestOptions?.idempotencyKey ? { "Idempotency-Key": requestOptions.idempotencyKey } : {};
|
|
1076
1228
|
const cardPath = (id) => `/v1/cards/${encodeURIComponent(id)}`;
|
|
1229
|
+
const folderPath = (id) => `/v1/folders/${encodeURIComponent(id)}`;
|
|
1230
|
+
const putFile = async (uploadUrl, bytes, mimeType) => {
|
|
1231
|
+
const headers = new Headers({ "Content-Type": mimeType });
|
|
1232
|
+
const byteLength = byteLengthForBody(bytes);
|
|
1233
|
+
if (byteLength !== null) {
|
|
1234
|
+
headers.set("Content-Length", String(byteLength));
|
|
1235
|
+
}
|
|
1236
|
+
const response = await fetchImpl(uploadUrl, {
|
|
1237
|
+
body: bytes,
|
|
1238
|
+
headers,
|
|
1239
|
+
method: "PUT"
|
|
1240
|
+
});
|
|
1241
|
+
if (!response.ok) {
|
|
1242
|
+
throw new TeakApiError("REQUEST_FAILED", `Upload failed with status ${response.status}`, { status: response.status });
|
|
1243
|
+
}
|
|
1244
|
+
return { fileEtag: response.headers.get("etag") ?? undefined };
|
|
1245
|
+
};
|
|
1246
|
+
const createThumbnailUpload = (id, input) => request(`${cardPath(id)}/thumbnail/upload`, { body: JSON.stringify(input), method: "POST" }, asUpload);
|
|
1247
|
+
const applyThumbnail = (id, fileKey) => request(`${cardPath(id)}/thumbnail`, { body: JSON.stringify({ fileKey }), method: "PUT" }, asCard);
|
|
1077
1248
|
return {
|
|
1078
1249
|
cards: {
|
|
1079
1250
|
bulk: (operation, items, requestOptions) => request("/v1/cards/bulk", {
|
|
@@ -1091,13 +1262,43 @@ var createTeakClient = (options) => {
|
|
|
1091
1262
|
headers: idempotency(requestOptions),
|
|
1092
1263
|
method: "POST"
|
|
1093
1264
|
}, asCreate),
|
|
1265
|
+
content: (id) => request(`${cardPath(id)}/content`, { method: "GET" }, asCardContent),
|
|
1094
1266
|
delete: (id, deleteOptions) => request(`${cardPath(id)}${deleteOptions?.permanent ? "?permanent=true" : ""}`, { method: "DELETE" }, () => null),
|
|
1095
1267
|
duplicate: (url) => request(`/v1/cards/duplicate?${new URLSearchParams({ url }).toString()}`, { method: "GET" }, (v) => isObject(v) && typeof v.cardId === "string" ? v.cardId : null),
|
|
1096
1268
|
favorites: (input = {}) => request(`/v1/cards?${qs({ include: "content,metadata", ...input, favorited: true })}`, { method: "GET" }, asPage),
|
|
1097
1269
|
get: (id) => request(cardPath(id), { method: "GET" }, asCard),
|
|
1270
|
+
links: (id) => request(cardPath(id), { method: "GET" }, (value) => {
|
|
1271
|
+
const card = asCard(value);
|
|
1272
|
+
return {
|
|
1273
|
+
backlinks: card.backlinks ?? [],
|
|
1274
|
+
backlinksTruncated: card.backlinksTruncated === true,
|
|
1275
|
+
links: card.links ?? [],
|
|
1276
|
+
linksTruncated: card.linksTruncated === true
|
|
1277
|
+
};
|
|
1278
|
+
}),
|
|
1098
1279
|
list: (input = {}) => request(`/v1/cards?${qs(input)}`, { method: "GET" }, asPage),
|
|
1280
|
+
createThumbnailUpload,
|
|
1281
|
+
refresh: (id) => request(`${cardPath(id)}/refresh`, { method: "POST" }, asRefresh),
|
|
1282
|
+
resetThumbnail: (id) => request(`${cardPath(id)}/thumbnail`, { method: "DELETE" }, asCard),
|
|
1099
1283
|
restore: (id) => request(`${cardPath(id)}/restore`, { method: "POST" }, () => null),
|
|
1284
|
+
similar: (id, input = {}) => request(`/v1/cards?${qs({ include: "content,metadata", ...input, similarTo: id })}`, { method: "GET" }, asPage),
|
|
1100
1285
|
search: (input = {}) => request(`/v1/cards?${qs({ include: "content,metadata", ...input })}`, { method: "GET" }, asPage),
|
|
1286
|
+
setArchived: (id, isArchived) => request(cardPath(id), { body: JSON.stringify({ isArchived }), method: "PATCH" }, asCard),
|
|
1287
|
+
setThumbnail: async (id, image, mimeType) => {
|
|
1288
|
+
if (isObject(image) && typeof image.fileKey === "string") {
|
|
1289
|
+
return applyThumbnail(id, image.fileKey);
|
|
1290
|
+
}
|
|
1291
|
+
const bytes = image;
|
|
1292
|
+
const fileSize = byteLengthForBody(bytes);
|
|
1293
|
+
if (fileSize === null || !mimeType) {
|
|
1294
|
+
throw new TeakApiError("INVALID_INPUT", "setThumbnail needs the image's bytes and its MIME type.");
|
|
1295
|
+
}
|
|
1296
|
+
const upload = await createThumbnailUpload(id, { fileSize, mimeType });
|
|
1297
|
+
await putFile(upload.uploadUrl, bytes, mimeType);
|
|
1298
|
+
return applyThumbnail(id, upload.fileKey);
|
|
1299
|
+
},
|
|
1300
|
+
savePdf: (id) => request(`${cardPath(id)}/save-pdf`, { method: "POST" }, asSavedPdf),
|
|
1301
|
+
setDone: (id, done) => request(`${cardPath(id)}/done`, { method: done ? "POST" : "DELETE" }, asCard),
|
|
1101
1302
|
setFavorite: (id, isFavorited) => request(`${cardPath(id)}/favorite`, { body: JSON.stringify({ isFavorited }), method: "PATCH" }, asCard),
|
|
1102
1303
|
update: (id, input) => request(cardPath(id), { body: JSON.stringify(input), method: "PATCH" }, asCard)
|
|
1103
1304
|
},
|
|
@@ -1105,28 +1306,26 @@ var createTeakClient = (options) => {
|
|
|
1105
1306
|
latest: () => request("/v1/exports/latest", { method: "GET" }, asLatestExport),
|
|
1106
1307
|
start: () => request("/v1/exports", { method: "POST" }, (v) => v.job)
|
|
1107
1308
|
},
|
|
1309
|
+
folders: {
|
|
1310
|
+
addCards: (id, cardIds) => request(`${folderPath(id)}/cards`, { body: JSON.stringify({ cardIds }), method: "POST" }, asFolderCards),
|
|
1311
|
+
create: (input) => request("/v1/folders", { body: JSON.stringify(input), method: "POST" }, asFolder),
|
|
1312
|
+
delete: (id) => request(folderPath(id), { method: "DELETE" }, () => null),
|
|
1313
|
+
get: (id) => request(folderPath(id), { method: "GET" }, asFolder),
|
|
1314
|
+
list: () => request("/v1/folders", { method: "GET" }, asFolders),
|
|
1315
|
+
removeCards: (id, cardIds) => request(`${folderPath(id)}/cards`, { body: JSON.stringify({ cardIds }), method: "DELETE" }, asFolderCards),
|
|
1316
|
+
update: (id, input) => request(folderPath(id), { body: JSON.stringify(input), method: "PATCH" }, asFolder)
|
|
1317
|
+
},
|
|
1108
1318
|
me: () => request("/v1/me", { method: "GET" }, asMe),
|
|
1109
1319
|
tags: {
|
|
1110
|
-
|
|
1320
|
+
delete: (tag) => request("/v1/tags/delete", { body: JSON.stringify({ tag }), method: "POST" }, asTagOperation),
|
|
1321
|
+
list: () => request("/v1/tags", { method: "GET" }, asTags),
|
|
1322
|
+
merge: (from, into) => request("/v1/tags/merge", { body: JSON.stringify({ from, into }), method: "POST" }, asTagOperation),
|
|
1323
|
+
operation: (id) => request(`/v1/tags/operations/${encodeURIComponent(id)}`, { method: "GET" }, asTagOperation),
|
|
1324
|
+
rename: (from, to) => request("/v1/tags/rename", { body: JSON.stringify({ from, to }), method: "POST" }, asTagOperation)
|
|
1111
1325
|
},
|
|
1112
1326
|
uploads: {
|
|
1113
1327
|
create: (input) => request("/v1/uploads", { body: JSON.stringify(input), method: "POST" }, asUpload),
|
|
1114
|
-
putFile
|
|
1115
|
-
const headers = new Headers({ "Content-Type": mimeType });
|
|
1116
|
-
const byteLength = byteLengthForBody(bytes);
|
|
1117
|
-
if (byteLength !== null) {
|
|
1118
|
-
headers.set("Content-Length", String(byteLength));
|
|
1119
|
-
}
|
|
1120
|
-
const response = await fetchImpl(uploadUrl, {
|
|
1121
|
-
body: bytes,
|
|
1122
|
-
headers,
|
|
1123
|
-
method: "PUT"
|
|
1124
|
-
});
|
|
1125
|
-
if (!response.ok) {
|
|
1126
|
-
throw new TeakApiError("REQUEST_FAILED", `Upload failed with status ${response.status}`, { status: response.status });
|
|
1127
|
-
}
|
|
1128
|
-
return { fileEtag: response.headers.get("etag") ?? undefined };
|
|
1129
|
-
}
|
|
1328
|
+
putFile
|
|
1130
1329
|
}
|
|
1131
1330
|
};
|
|
1132
1331
|
};
|
|
@@ -1146,6 +1345,7 @@ export {
|
|
|
1146
1345
|
disconnectConnectGrant,
|
|
1147
1346
|
discoverAuthServer,
|
|
1148
1347
|
fetchConnectOwnerId,
|
|
1348
|
+
formatBytes,
|
|
1149
1349
|
isCardType,
|
|
1150
1350
|
isStringList,
|
|
1151
1351
|
normalizeLimit,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { validateOAuthUrl } from "../shared/oauthUrl.js";
|
|
2
|
+
export declare const OAUTH_SURFACES: readonly ["cli", "raycast", "chrome", "firefox"];
|
|
2
3
|
export type OAuthSurface = (typeof OAUTH_SURFACES)[number];
|
|
3
4
|
export interface AuthDiscovery {
|
|
4
5
|
readonly authorizationEndpoint: string;
|
|
@@ -8,7 +9,6 @@ export interface AuthDiscovery {
|
|
|
8
9
|
readonly resource: string;
|
|
9
10
|
readonly tokenEndpoint: string;
|
|
10
11
|
}
|
|
11
|
-
export declare const validateOAuthUrl: (raw: unknown, local?: boolean) => URL;
|
|
12
12
|
export declare function discoverAuthServer(siteUrl: string, options?: {
|
|
13
13
|
fetch?: typeof fetch;
|
|
14
14
|
forceRefresh?: boolean;
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
export { formatBytes } from "../shared/utils/formatBytes.js";
|
|
1
2
|
export { type AuthDiscovery, discoverAuthServer, type OAuthSurface, validateOAuthUrl, } from "./authDiscovery.js";
|
|
2
3
|
export { type ConnectTokenResult, type ConnectTokens, createConnectAuthorizeUrl, createPkceChallenge, disconnectConnectGrant, fetchConnectOwnerId, randomBase64Url, requestConnectTokens, WORKOS_CONNECT_SCOPE, } from "./workosConnect.js";
|
|
3
4
|
import { type CardType } from "../shared/constants.js";
|
|
4
5
|
import type { FileKind, FilePreviewFacts } from "../shared/fileFormats.js";
|
|
6
|
+
import type { FOLDER_COLORS } from "../shared/folders.js";
|
|
5
7
|
export type { CardType } from "../shared/constants.js";
|
|
6
8
|
export declare const CARD_TYPES: readonly ["text", "link", "image", "video", "audio", "document", "palette", "quote"];
|
|
7
|
-
export declare const CARD_SORTS: readonly ["newest", "oldest"];
|
|
8
|
-
export declare const ERROR_CODES: readonly ["AUTH_REQUIRED", "BAD_REQUEST", "CONFIG_ERROR", "CONFLICT", "CONTENT_TOO_LARGE", "INTERNAL_ERROR", "INVALID_API_KEY", "INVALID_INPUT", "INVALID_UTF8", "METHOD_NOT_ALLOWED", "NETWORK_ERROR", "NOT_FOUND", "PARSE_ERROR", "RATE_LIMITED", "REQUEST_FAILED", "TIMEOUT", "UNAUTHORIZED"];
|
|
9
|
+
export declare const CARD_SORTS: readonly ["newest", "oldest", "relevance", "shuffle"];
|
|
10
|
+
export declare const ERROR_CODES: readonly ["AUTH_REQUIRED", "BAD_REQUEST", "CARD_LIMIT_REACHED", "CONFIG_ERROR", "CONFLICT", "CONTENT_TOO_LARGE", "FILE_TOO_LARGE", "FOLDER_LIMIT", "FORBIDDEN", "IN_PROGRESS", "INTERNAL_ERROR", "INVALID_API_KEY", "INVALID_INPUT", "INVALID_STORAGE_KEY", "INVALID_UTF8", "LIMIT_REACHED", "METHOD_NOT_ALLOWED", "NETWORK_ERROR", "NOT_FOUND", "NO_CONTENT", "NOT_IN_TRASH", "PARSE_ERROR", "RATE_LIMITED", "REQUEST_FAILED", "SERVICE_UNAVAILABLE", "SMART_FOLDER", "TAG_EXISTS", "TAG_OPERATION_RUNNING", "TIMEOUT", "TYPE_MISMATCH", "UNAUTHORIZED", "UNSUPPORTED_TYPE"];
|
|
9
11
|
export type CardSort = (typeof CARD_SORTS)[number];
|
|
12
|
+
/**
|
|
13
|
+
* How a search finds cards: `hybrid` (the API's default) matches words and
|
|
14
|
+
* meaning, `keyword` words only, `semantic` meaning only.
|
|
15
|
+
*/
|
|
16
|
+
export type SearchMode = "hybrid" | "keyword" | "semantic";
|
|
10
17
|
export type TeakApiErrorCode = (typeof ERROR_CODES)[number];
|
|
11
18
|
export type FetchLike = typeof fetch;
|
|
12
19
|
export interface TokenProvider {
|
|
@@ -18,11 +25,26 @@ export interface Card {
|
|
|
18
25
|
aiTags: string[];
|
|
19
26
|
aiTranscript: string | null;
|
|
20
27
|
appUrl: string;
|
|
28
|
+
/** When the card was archived, or null. */
|
|
29
|
+
archivedAt: number | null;
|
|
30
|
+
/** Bar heights 0-100: 45 for a grid card, 200 for a player. */
|
|
31
|
+
audioWaveform: {
|
|
32
|
+
detail: number[];
|
|
33
|
+
grid: number[];
|
|
34
|
+
} | null;
|
|
35
|
+
/** Your cards that link to this one, most recently updated first. */
|
|
36
|
+
backlinks?: CardLinkRef[];
|
|
37
|
+
backlinksTruncated?: boolean;
|
|
21
38
|
colors: Array<{
|
|
22
39
|
hex: string;
|
|
23
40
|
name?: string;
|
|
24
41
|
}>;
|
|
25
42
|
compactUrl: string | null;
|
|
43
|
+
/**
|
|
44
|
+
* When the link was marked read, watched, bought or done, or null.
|
|
45
|
+
* Servers that predate done states leave it out.
|
|
46
|
+
*/
|
|
47
|
+
completedAt?: number | null;
|
|
26
48
|
content: string;
|
|
27
49
|
createdAt: number;
|
|
28
50
|
detailUrl: string | null;
|
|
@@ -33,10 +55,25 @@ export interface Card {
|
|
|
33
55
|
filePreview: FilePreviewFacts | null;
|
|
34
56
|
fileSize: number | null;
|
|
35
57
|
fileUrl: string | null;
|
|
58
|
+
/** Ids of the folders the card is in. */
|
|
59
|
+
folderIds: string[];
|
|
36
60
|
id: string;
|
|
61
|
+
/** Archived cards are hidden from the library but still count. */
|
|
62
|
+
isArchived: boolean;
|
|
37
63
|
isDeleted: boolean;
|
|
38
64
|
isFavorited: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Tagged `secret` or `hidden`: left out of lists and searches unless the
|
|
67
|
+
* search names one of those tags (`#secret`). Servers that
|
|
68
|
+
* predate hidden cards leave it out.
|
|
69
|
+
*/
|
|
70
|
+
isHidden?: boolean;
|
|
39
71
|
linkAuthor: string | null;
|
|
72
|
+
/**
|
|
73
|
+
* What a link is (`article`, `movie`, `product`…), or null. A plain
|
|
74
|
+
* string: new categories are added over time.
|
|
75
|
+
*/
|
|
76
|
+
linkCategory?: string | null;
|
|
40
77
|
linkFacts: Array<{
|
|
41
78
|
label: string;
|
|
42
79
|
value: string;
|
|
@@ -53,9 +90,23 @@ export interface Card {
|
|
|
53
90
|
posterWidth?: number;
|
|
54
91
|
posterHeight?: number;
|
|
55
92
|
}>;
|
|
93
|
+
/**
|
|
94
|
+
* A product link's price: `amount` in the page's currency, `currency` an
|
|
95
|
+
* ISO 4217 code or null. Null for cards without a price.
|
|
96
|
+
*/
|
|
97
|
+
linkPrice: {
|
|
98
|
+
amount: number;
|
|
99
|
+
currency: string | null;
|
|
100
|
+
} | null;
|
|
56
101
|
linkPublishedAt: string | null;
|
|
57
102
|
linkPublisher: string | null;
|
|
58
103
|
linkSiteName: string | null;
|
|
104
|
+
/**
|
|
105
|
+
* Cards this card links to with `[[Title|teak:<id>]]`, in order. Only on
|
|
106
|
+
* single-card responses (`cards.get`, update, favorite, done, create).
|
|
107
|
+
*/
|
|
108
|
+
links?: CardLinkRef[];
|
|
109
|
+
linksTruncated?: boolean;
|
|
59
110
|
metadataDescription: string | null;
|
|
60
111
|
metadataStatus: string | null;
|
|
61
112
|
metadataTitle: string | null;
|
|
@@ -64,11 +115,43 @@ export interface Card {
|
|
|
64
115
|
placeholderUrl: string | null;
|
|
65
116
|
processingStatus: Record<string, unknown> | null;
|
|
66
117
|
screenshotUrl: string | null;
|
|
118
|
+
/**
|
|
119
|
+
* The title of the page in `sourceUrl`. Servers that predate sources
|
|
120
|
+
* leave it out.
|
|
121
|
+
*/
|
|
122
|
+
sourceTitle?: string | null;
|
|
123
|
+
/**
|
|
124
|
+
* The page the card was saved from, such as the page a quote was selected
|
|
125
|
+
* on. Servers that predate sources leave it out.
|
|
126
|
+
*/
|
|
127
|
+
sourceUrl?: string | null;
|
|
67
128
|
tags: string[];
|
|
129
|
+
/** True when linkPreviewImageUrl is an image chosen for the link. */
|
|
130
|
+
thumbnailOverridden: boolean;
|
|
68
131
|
thumbnailUrl: string | null;
|
|
69
132
|
type: CardType | string;
|
|
70
133
|
updatedAt: number;
|
|
71
134
|
url: string | null;
|
|
135
|
+
/** Hover preview strip, `frames * frameWidth` wide; the URL expires. */
|
|
136
|
+
videoScrub: {
|
|
137
|
+
frameHeight: number;
|
|
138
|
+
frameWidth: number;
|
|
139
|
+
frames: number;
|
|
140
|
+
url: string;
|
|
141
|
+
} | null;
|
|
142
|
+
}
|
|
143
|
+
/** A linked card; `missing` when it's in Trash, deleted or not yours. */
|
|
144
|
+
export interface CardLinkRef {
|
|
145
|
+
id: string;
|
|
146
|
+
missing: boolean;
|
|
147
|
+
title: string | null;
|
|
148
|
+
type: CardType | string | null;
|
|
149
|
+
}
|
|
150
|
+
export interface CardLinks {
|
|
151
|
+
backlinks: CardLinkRef[];
|
|
152
|
+
backlinksTruncated: boolean;
|
|
153
|
+
links: CardLinkRef[];
|
|
154
|
+
linksTruncated: boolean;
|
|
72
155
|
}
|
|
73
156
|
export type CardListItem = Partial<Card> & Pick<Card, "aiTags" | "appUrl" | "createdAt" | "id" | "isFavorited" | "tags" | "type" | "updatedAt">;
|
|
74
157
|
export interface PageInfo {
|
|
@@ -78,6 +161,15 @@ export interface PageInfo {
|
|
|
78
161
|
export interface CardsPage {
|
|
79
162
|
items: CardListItem[];
|
|
80
163
|
pageInfo: PageInfo;
|
|
164
|
+
/** With a query and `sort: "relevance"`: whether the top results were scored. */
|
|
165
|
+
relevanceRanked?: boolean;
|
|
166
|
+
/** With a query: the mode that ran (`keyword` when meaning search could not). */
|
|
167
|
+
searchMode?: SearchMode;
|
|
168
|
+
/**
|
|
169
|
+
* For similar cards: `pending` while the card is still being read, and
|
|
170
|
+
* `unavailable` for a card in Trash or not found.
|
|
171
|
+
*/
|
|
172
|
+
similarity?: "ok" | "pending" | "unavailable";
|
|
81
173
|
}
|
|
82
174
|
export interface CardChangesResponse {
|
|
83
175
|
deletedIds: string[];
|
|
@@ -88,21 +180,102 @@ export interface TagSummary {
|
|
|
88
180
|
count: number;
|
|
89
181
|
name: string;
|
|
90
182
|
}
|
|
183
|
+
export type FolderColor = (typeof FOLDER_COLORS)[number];
|
|
184
|
+
export interface Folder {
|
|
185
|
+
/**
|
|
186
|
+
* Cards in a manual folder that are not archived or in Trash; null for a
|
|
187
|
+
* smart folder, whose cards are found when listed.
|
|
188
|
+
*/
|
|
189
|
+
cardCount: number | null;
|
|
190
|
+
color: FolderColor | null;
|
|
191
|
+
createdAt: number;
|
|
192
|
+
id: string;
|
|
193
|
+
/** Manual folders hold the cards put in them; smart ones save a search. */
|
|
194
|
+
kind: "manual" | "smart";
|
|
195
|
+
name: string;
|
|
196
|
+
/** A smart folder's search; null for a manual folder. */
|
|
197
|
+
query: string | null;
|
|
198
|
+
updatedAt: number;
|
|
199
|
+
}
|
|
200
|
+
export type TagOperationKind = "rename" | "merge" | "delete";
|
|
201
|
+
export type TagOperationStatus = "running" | "completed" | "failed";
|
|
202
|
+
/** A library-wide tag rename, merge or delete, finished in the background. */
|
|
203
|
+
export interface TagOperation {
|
|
204
|
+
/** Cards rewritten so far. */
|
|
205
|
+
changed: number;
|
|
206
|
+
completedAt: number | null;
|
|
207
|
+
createdAt: number;
|
|
208
|
+
error: string | null;
|
|
209
|
+
/** The tag being changed, lowercased. */
|
|
210
|
+
from: string;
|
|
211
|
+
id: string;
|
|
212
|
+
kind: TagOperationKind;
|
|
213
|
+
/** Cards looked at so far. */
|
|
214
|
+
processed: number;
|
|
215
|
+
status: TagOperationStatus;
|
|
216
|
+
/** The new name (rename) or the tag merged into (merge). */
|
|
217
|
+
to: string | null;
|
|
218
|
+
/** Cards carrying the tag when the change started. */
|
|
219
|
+
total: number;
|
|
220
|
+
updatedAt: number;
|
|
221
|
+
}
|
|
222
|
+
export interface FolderCardsResult {
|
|
223
|
+
failedIds: string[];
|
|
224
|
+
/** Failed cards that are already in the most folders a card can be in. */
|
|
225
|
+
folderLimitIds: string[];
|
|
226
|
+
updatedIds: string[];
|
|
227
|
+
}
|
|
91
228
|
export interface CreateCardInput {
|
|
229
|
+
/**
|
|
230
|
+
* Optional card type: `text`, `link`, `image`, `video`, `audio`,
|
|
231
|
+
* `document`, `palette` or `quote`. Set it to `text` to store raw Markdown
|
|
232
|
+
* exactly; omit it to keep automatic URL, quote, and palette detection.
|
|
233
|
+
* @default inferred
|
|
234
|
+
*/
|
|
92
235
|
cardType?: CardType;
|
|
236
|
+
/**
|
|
237
|
+
* Markdown or plain text body for the card. Prefer this for notes; use `url`
|
|
238
|
+
* when saving a link.
|
|
239
|
+
*/
|
|
93
240
|
content?: string;
|
|
241
|
+
/** The `ETag` the upload `PUT` returned, for a file card. */
|
|
94
242
|
fileEtag?: string;
|
|
243
|
+
/** The `fileKey` from `uploads.create`, for a file card. */
|
|
95
244
|
fileKey?: string;
|
|
245
|
+
/** The uploaded file's name, for a file card. */
|
|
96
246
|
fileName?: string;
|
|
247
|
+
/** The uploaded file's size in bytes, for a file card. */
|
|
97
248
|
fileSize?: number;
|
|
249
|
+
/** The uploaded file's MIME type, for a file card. */
|
|
98
250
|
mimeType?: string;
|
|
251
|
+
/** Free-form notes attached to the card. */
|
|
99
252
|
notes?: string | null;
|
|
253
|
+
/**
|
|
254
|
+
* A free label for what saved the card (extension, CLI, API, and so on),
|
|
255
|
+
* kept in its metadata. For the page the card came from, use `sourceUrl`.
|
|
256
|
+
*/
|
|
100
257
|
source?: string;
|
|
258
|
+
/** The page's title, beside `sourceUrl`; cut to 300 characters. */
|
|
259
|
+
sourceTitle?: string;
|
|
260
|
+
/**
|
|
261
|
+
* The page the card came from, such as the page a quote was selected on:
|
|
262
|
+
* an http or https URL of at most 2,048 characters. Unlike `url`, it never
|
|
263
|
+
* makes the card a link.
|
|
264
|
+
*/
|
|
265
|
+
sourceUrl?: string;
|
|
266
|
+
/** Tags to apply on create. */
|
|
101
267
|
tags?: string[];
|
|
268
|
+
/**
|
|
269
|
+
* URL to save as a link card. Teak may classify the type automatically when
|
|
270
|
+
* `cardType` is omitted.
|
|
271
|
+
*/
|
|
102
272
|
url?: string;
|
|
103
273
|
}
|
|
104
274
|
export interface UpdateCardInput {
|
|
105
275
|
content?: string;
|
|
276
|
+
/** Replaces the card's folders; an empty list takes it out of every folder. */
|
|
277
|
+
folderIds?: string[];
|
|
278
|
+
isArchived?: boolean;
|
|
106
279
|
metadataTitle?: string | null;
|
|
107
280
|
notes?: string | null;
|
|
108
281
|
/** AI tags to drop. `tags` replaces only the card's own tags. */
|
|
@@ -150,6 +323,11 @@ export interface CreateUploadInput {
|
|
|
150
323
|
fileSize: number;
|
|
151
324
|
mimeType: string;
|
|
152
325
|
}
|
|
326
|
+
/** A link image upload: JPEG, PNG, WebP, GIF or AVIF, under 20 MB. */
|
|
327
|
+
export interface CreateThumbnailUploadInput {
|
|
328
|
+
fileSize: number;
|
|
329
|
+
mimeType: string;
|
|
330
|
+
}
|
|
153
331
|
export interface CreateUploadResponse {
|
|
154
332
|
expiresIn: number;
|
|
155
333
|
fileKey: string;
|
|
@@ -163,8 +341,37 @@ export interface CreateCardResponse {
|
|
|
163
341
|
cardId: string;
|
|
164
342
|
status: "created";
|
|
165
343
|
}
|
|
344
|
+
export interface RefreshCardResponse {
|
|
345
|
+
cardId: string;
|
|
346
|
+
requestedAt: number;
|
|
347
|
+
status: "queued";
|
|
348
|
+
}
|
|
349
|
+
/** An arXiv link's PDF saved as a document card (POST /v1/cards/:id/save-pdf). */
|
|
350
|
+
export interface SavedPdf {
|
|
351
|
+
/** The document card holding the PDF. */
|
|
352
|
+
cardId: string;
|
|
353
|
+
/** False when an earlier save already made that card. */
|
|
354
|
+
created: boolean;
|
|
355
|
+
}
|
|
356
|
+
/** A card's full stored text (GET /v1/cards/:id/content). */
|
|
357
|
+
export interface CardContent {
|
|
358
|
+
cardId: string;
|
|
359
|
+
/** Characters in the full stored text. */
|
|
360
|
+
charCount: number;
|
|
361
|
+
/**
|
|
362
|
+
* document: extracted from the card's file; transcript: its speech;
|
|
363
|
+
* content: a text or quote card's written text.
|
|
364
|
+
*/
|
|
365
|
+
kind: "document" | "transcript" | "content";
|
|
366
|
+
text: string;
|
|
367
|
+
/** The document is longer than Teak keeps. */
|
|
368
|
+
truncated: boolean;
|
|
369
|
+
}
|
|
370
|
+
export type BulkCardsOperation = "create" | "update" | "favorite" | "delete" | "archive" | "unarchive" | "addTags" | "removeTags" | "restore";
|
|
166
371
|
export interface BulkCardsResponse {
|
|
167
|
-
|
|
372
|
+
/** The `cardId` of every item that failed, to retry just those. */
|
|
373
|
+
failedIds: string[];
|
|
374
|
+
operation: BulkCardsOperation;
|
|
168
375
|
results: unknown[];
|
|
169
376
|
summary: {
|
|
170
377
|
failed: number;
|
|
@@ -172,6 +379,8 @@ export interface BulkCardsResponse {
|
|
|
172
379
|
total: number;
|
|
173
380
|
};
|
|
174
381
|
}
|
|
382
|
+
/** Archived cards outside Trash: left out by default. */
|
|
383
|
+
export type ArchivedFilter = "exclude" | "only" | "include";
|
|
175
384
|
export declare class TeakApiError extends Error {
|
|
176
385
|
code: TeakApiErrorCode;
|
|
177
386
|
requestId?: string;
|
|
@@ -186,6 +395,9 @@ export declare class TeakApiError extends Error {
|
|
|
186
395
|
export declare const staticTokenProvider: (token: string) => TokenProvider;
|
|
187
396
|
export declare const normalizeLimit: (limit?: number) => number;
|
|
188
397
|
export declare const buildCardsSearchParams: (input: {
|
|
398
|
+
archived?: ArchivedFilter;
|
|
399
|
+
/** Only cards in this folder id. */
|
|
400
|
+
folder?: string;
|
|
189
401
|
createdAfter?: number;
|
|
190
402
|
createdBefore?: number;
|
|
191
403
|
cursor?: string;
|
|
@@ -194,7 +406,20 @@ export declare const buildCardsSearchParams: (input: {
|
|
|
194
406
|
hue?: string | readonly string[];
|
|
195
407
|
include?: string;
|
|
196
408
|
limit?: number;
|
|
409
|
+
/** How `query` finds cards; the API defaults to `hybrid`. */
|
|
410
|
+
mode?: SearchMode;
|
|
411
|
+
/**
|
|
412
|
+
* Search text. Accepts qualifiers: `tag:design` or `#design`, `type:link`,
|
|
413
|
+
* `is:fav`, `is:archived`, `site:github.com`, `folder:"Reading list"`,
|
|
414
|
+
* `price:<100` (also `>`, `<=`, `>=` and `=`), `text:"total due"` (only
|
|
415
|
+
* the words Teak read in images, video thumbnails, link previews and scanned
|
|
416
|
+
* PDFs) and `"quoted phrases"`.
|
|
417
|
+
*/
|
|
197
418
|
query?: string;
|
|
419
|
+
/** Required with `sort: "shuffle"`: the same seed gives the same order. */
|
|
420
|
+
shuffleSeed?: number;
|
|
421
|
+
/** A card id: only the cards closest to it in meaning. */
|
|
422
|
+
similarTo?: string;
|
|
198
423
|
sort?: CardSort;
|
|
199
424
|
style?: string | readonly string[];
|
|
200
425
|
tag?: string;
|
|
@@ -209,13 +434,18 @@ export declare const createTeakClient: (options: {
|
|
|
209
434
|
userAgent?: string;
|
|
210
435
|
}) => {
|
|
211
436
|
cards: {
|
|
212
|
-
bulk: (operation:
|
|
437
|
+
bulk: (operation: BulkCardsOperation, items: unknown[], requestOptions?: RequestOptions) => Promise<BulkCardsResponse>;
|
|
213
438
|
changes: (input: {
|
|
214
439
|
cursor?: string;
|
|
215
440
|
limit?: number;
|
|
216
441
|
since: number;
|
|
217
442
|
}) => Promise<CardChangesResponse>;
|
|
218
443
|
create: (input: CreateCardInput, requestOptions?: RequestOptions) => Promise<CreateCardResponse>;
|
|
444
|
+
/**
|
|
445
|
+
* The card's full stored text: document text, transcript, or a text
|
|
446
|
+
* card's content. Throws NO_CONTENT when the card has none.
|
|
447
|
+
*/
|
|
448
|
+
content: (id: string) => Promise<CardContent>;
|
|
219
449
|
/** Moves the card to Trash, or deletes it for good with `permanent`. */
|
|
220
450
|
delete: (id: string, deleteOptions?: {
|
|
221
451
|
permanent?: boolean;
|
|
@@ -224,9 +454,45 @@ export declare const createTeakClient: (options: {
|
|
|
224
454
|
duplicate: (url: string) => Promise<string | null>;
|
|
225
455
|
favorites: (input?: Parameters<(params: Parameters<typeof buildCardsSearchParams>[0]) => string>[0]) => Promise<CardsPage>;
|
|
226
456
|
get: (id: string) => Promise<Card>;
|
|
457
|
+
/** Cards this card links to with `[[…]]`, and cards linking to it. */
|
|
458
|
+
links: (id: string) => Promise<CardLinks>;
|
|
227
459
|
list: (input?: Parameters<(params: Parameters<typeof buildCardsSearchParams>[0]) => string>[0]) => Promise<CardsPage>;
|
|
460
|
+
/**
|
|
461
|
+
* A signed URL for a link card's new image; `setThumbnail` with bytes
|
|
462
|
+
* does this for you.
|
|
463
|
+
*/
|
|
464
|
+
createThumbnailUpload: (id: string, input: CreateThumbnailUploadInput) => Promise<CreateUploadResponse>;
|
|
465
|
+
/** Refreshes summary, tags and link preview; it finishes in the background. */
|
|
466
|
+
refresh: (id: string) => Promise<RefreshCardResponse>;
|
|
467
|
+
/**
|
|
468
|
+
* Goes back to the image Teak found for a link card and deletes the one
|
|
469
|
+
* that replaced it. Changes nothing when the card has its own image.
|
|
470
|
+
*/
|
|
471
|
+
resetThumbnail: (id: string) => Promise<Card>;
|
|
228
472
|
restore: (id: string) => Promise<null>;
|
|
473
|
+
/** The cards closest in meaning to one card; never the card itself. */
|
|
474
|
+
similar: (id: string, input?: Parameters<(params: Parameters<typeof buildCardsSearchParams>[0]) => string>[0]) => Promise<CardsPage>;
|
|
229
475
|
search: (input?: Parameters<(params: Parameters<typeof buildCardsSearchParams>[0]) => string>[0]) => Promise<CardsPage>;
|
|
476
|
+
/** Archives the card (hidden from the library, not deleted) or returns it. */
|
|
477
|
+
setArchived: (id: string, isArchived: boolean) => Promise<Card>;
|
|
478
|
+
/**
|
|
479
|
+
* Replaces a link card's image: uploads `bytes` (JPEG, PNG, WebP, GIF or
|
|
480
|
+
* AVIF, under 20 MB) and applies them. Pass `{ fileKey }` instead to
|
|
481
|
+
* apply an upload made with `createThumbnailUpload`.
|
|
482
|
+
*/
|
|
483
|
+
setThumbnail: (id: string, image: BodyInit | {
|
|
484
|
+
fileKey: string;
|
|
485
|
+
}, mimeType?: string) => Promise<Card>;
|
|
486
|
+
/**
|
|
487
|
+
* Saves an arXiv link's paper as its own document card. Saving the same
|
|
488
|
+
* link again returns that card with `created: false`.
|
|
489
|
+
*/
|
|
490
|
+
savePdf: (id: string) => Promise<SavedPdf>;
|
|
491
|
+
/**
|
|
492
|
+
* Marks a link card read, watched, bought or done (`done: true`), or
|
|
493
|
+
* not; repeating a call changes nothing. Only link cards can be marked.
|
|
494
|
+
*/
|
|
495
|
+
setDone: (id: string, done: boolean) => Promise<Card>;
|
|
230
496
|
setFavorite: (id: string, isFavorited: boolean) => Promise<Card>;
|
|
231
497
|
update: (id: string, input: UpdateCardInput) => Promise<Card>;
|
|
232
498
|
};
|
|
@@ -234,11 +500,60 @@ export declare const createTeakClient: (options: {
|
|
|
234
500
|
latest: () => Promise<LatestExport>;
|
|
235
501
|
start: () => Promise<ExportJob>;
|
|
236
502
|
};
|
|
503
|
+
folders: {
|
|
504
|
+
/**
|
|
505
|
+
* Adds up to 100 cards; cards already in the folder are left as they
|
|
506
|
+
* are. A smart folder refuses cards (409 SMART_FOLDER).
|
|
507
|
+
*/
|
|
508
|
+
addCards: (id: string, cardIds: string[]) => Promise<FolderCardsResult>;
|
|
509
|
+
/**
|
|
510
|
+
* Creates a folder; `{ kind: "smart", query }` saves a search, whose
|
|
511
|
+
* cards are whatever matches it when listed.
|
|
512
|
+
*/
|
|
513
|
+
create: (input: {
|
|
514
|
+
color?: FolderColor;
|
|
515
|
+
kind?: "manual";
|
|
516
|
+
name: string;
|
|
517
|
+
} | {
|
|
518
|
+
color?: FolderColor;
|
|
519
|
+
kind: "smart";
|
|
520
|
+
name: string;
|
|
521
|
+
query: string;
|
|
522
|
+
}) => Promise<Folder>;
|
|
523
|
+
/** Deletes the folder; its cards are kept. */
|
|
524
|
+
delete: (id: string) => Promise<null>;
|
|
525
|
+
get: (id: string) => Promise<Folder>;
|
|
526
|
+
/** Every folder, sorted by name. */
|
|
527
|
+
list: () => Promise<{
|
|
528
|
+
items: Folder[];
|
|
529
|
+
}>;
|
|
530
|
+
removeCards: (id: string, cardIds: string[]) => Promise<FolderCardsResult>;
|
|
531
|
+
/**
|
|
532
|
+
* Renames or recolors; `color: null` clears the color. `query` changes
|
|
533
|
+
* a smart folder's search.
|
|
534
|
+
*/
|
|
535
|
+
update: (id: string, input: {
|
|
536
|
+
color?: FolderColor | null;
|
|
537
|
+
name?: string;
|
|
538
|
+
query?: string;
|
|
539
|
+
}) => Promise<Folder>;
|
|
540
|
+
};
|
|
237
541
|
me: () => Promise<Me>;
|
|
238
542
|
tags: {
|
|
543
|
+
/**
|
|
544
|
+
* Deletes a tag from every card, including cards in Trash and Archive.
|
|
545
|
+
* It finishes in the background; poll with `operation`.
|
|
546
|
+
*/
|
|
547
|
+
delete: (tag: string) => Promise<TagOperation>;
|
|
239
548
|
list: () => Promise<{
|
|
240
549
|
items: TagSummary[];
|
|
241
550
|
}>;
|
|
551
|
+
/** Replaces `from` with `into` on every card; it finishes in the background. */
|
|
552
|
+
merge: (from: string, into: string) => Promise<TagOperation>;
|
|
553
|
+
/** A tag change's progress. */
|
|
554
|
+
operation: (id: string) => Promise<TagOperation>;
|
|
555
|
+
/** Renames a tag on every card; it finishes in the background. */
|
|
556
|
+
rename: (from: string, to: string) => Promise<TagOperation>;
|
|
242
557
|
};
|
|
243
558
|
uploads: {
|
|
244
559
|
create: (input: CreateUploadInput) => Promise<CreateUploadResponse>;
|
package/dist/types/devUrls.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** The shared cloud dev deployment every checkout and cloud session uses. */
|
|
2
1
|
export declare const TEAK_DEV_DEPLOYMENT_NAME = "reminiscent-kangaroo-59";
|
|
3
2
|
export declare const DEFAULT_TEAK_DEV_APP_URL = "http://localhost:3000";
|
|
4
3
|
export declare const DEFAULT_TEAK_DEV_CONVEX_URL = "https://reminiscent-kangaroo-59.convex.cloud";
|
|
@@ -1,31 +1,30 @@
|
|
|
1
1
|
export declare const SIGNUPS_PAUSED_MESSAGE = "New sign-ups are paused right now. Please try again later.";
|
|
2
|
-
export declare const ACCOUNT_CHANGES_PAUSED_MESSAGE = "Account changes are paused right now. Please try again later.";
|
|
3
2
|
export declare const cardTypes: readonly ["text", "link", "image", "video", "audio", "document", "palette", "quote"];
|
|
4
3
|
export type CardType = (typeof cardTypes)[number];
|
|
5
|
-
export declare const VISUAL_STYLE_TAXONOMY: readonly ["abstract", "cinematic", "dark", "illustrative", "minimal", "monochrome", "moody", "pastel", "photographic", "retro", "surreal", "vintage", "vibrant"];
|
|
4
|
+
export declare const VISUAL_STYLE_TAXONOMY: readonly ["abstract", "cinematic", "dark", "illustrative", "minimal", "monochrome", "moody", "pastel", "photographic", "retro", "surreal", "vintage", "vibrant", "typographic", "3d", "flat", "geometric", "hand-drawn", "futuristic"];
|
|
6
5
|
export type VisualStyle = (typeof VISUAL_STYLE_TAXONOMY)[number];
|
|
7
6
|
export declare const VISUAL_STYLE_LABELS: Record<VisualStyle, string>;
|
|
7
|
+
export declare const VISUAL_STYLE_ALIAS_MAP: Record<string, VisualStyle>;
|
|
8
8
|
export declare function normalizeVisualStyle(value: string): VisualStyle | null;
|
|
9
9
|
export declare function normalizeVisualStyleFilters(values?: string[]): VisualStyle[];
|
|
10
10
|
export declare function extractVisualStylesFromTags(tags?: string[]): VisualStyle[] | undefined;
|
|
11
|
+
export declare const COLOR_CARD_TYPES: readonly CardType[];
|
|
12
|
+
export declare const isColorCardType: (type: string) => boolean;
|
|
13
|
+
export declare const VISUAL_STYLE_CARD_TYPES: readonly CardType[];
|
|
14
|
+
export declare const isVisualStyleCardType: (type: string) => boolean;
|
|
15
|
+
export declare const isVisualStyle: (value: string) => value is VisualStyle;
|
|
11
16
|
export declare const COLOR_HUE_BUCKETS: readonly ["red", "orange", "yellow", "green", "teal", "cyan", "blue", "purple", "pink", "brown", "neutral"];
|
|
12
17
|
export type ColorHueBucket = (typeof COLOR_HUE_BUCKETS)[number];
|
|
13
18
|
export declare const COLOR_HUE_LABELS: Record<ColorHueBucket, string>;
|
|
19
|
+
export declare const COLOR_HUE_ALIAS_MAP: Record<string, ColorHueBucket>;
|
|
14
20
|
export declare function normalizeColorHueBucket(value: string): ColorHueBucket | null;
|
|
15
21
|
export declare function normalizeHueFilters(values?: string[]): ColorHueBucket[];
|
|
16
|
-
/**
|
|
17
|
-
* Maximum number of cards allowed for free tier users
|
|
18
|
-
*/
|
|
19
22
|
export declare const FREE_TIER_LIMIT = 200;
|
|
20
|
-
|
|
21
|
-
* Maximum file size for uploads (100MB in bytes)
|
|
22
|
-
*/
|
|
23
|
+
export declare const TRASH_RETENTION_MS: number;
|
|
23
24
|
export { MAX_FILE_SIZE } from "./fileFormats.js";
|
|
24
|
-
|
|
25
|
-
* Maximum number of files that can be uploaded at once
|
|
26
|
-
*/
|
|
27
|
-
export declare const MAX_FILES_PER_UPLOAD = 5;
|
|
25
|
+
export declare const MAX_FILES_PER_UPLOAD = 20;
|
|
28
26
|
export declare const MULTIPART_UPLOAD_THRESHOLD: number;
|
|
27
|
+
export declare const API_IDEMPOTENCY_KEY_TTL_MS: number;
|
|
29
28
|
export declare const CARD_ERROR_CODES: {
|
|
30
29
|
readonly CARD_LIMIT_REACHED: "CARD_LIMIT_REACHED";
|
|
31
30
|
readonly CONTENT_TOO_LARGE: "CONTENT_TOO_LARGE";
|
|
@@ -38,45 +37,23 @@ export declare const CARD_ERROR_CODES: {
|
|
|
38
37
|
};
|
|
39
38
|
export type CardErrorCode = (typeof CARD_ERROR_CODES)[keyof typeof CARD_ERROR_CODES];
|
|
40
39
|
export declare const CARD_ERROR_MESSAGES: Record<CardErrorCode, string>;
|
|
41
|
-
/**
|
|
42
|
-
* All card types as readonly array
|
|
43
|
-
*/
|
|
44
40
|
export declare const CARD_TYPES: readonly CardType[];
|
|
45
|
-
/**
|
|
46
|
-
* Card type labels for UI display
|
|
47
|
-
*/
|
|
48
41
|
export declare const CARD_TYPE_LABELS: Record<CardType, string>;
|
|
49
|
-
/**
|
|
50
|
-
* Card type icons mapping (for UI components)
|
|
51
|
-
*/
|
|
52
42
|
export declare const CARD_TYPE_ICONS: Record<CardType, string>;
|
|
53
|
-
/**
|
|
54
|
-
* Card type configuration registry for centralized management
|
|
55
|
-
*/
|
|
56
43
|
export interface CardTypeConfig {
|
|
57
44
|
icon: string;
|
|
58
45
|
label: string;
|
|
59
46
|
searchLabel: string;
|
|
60
47
|
}
|
|
61
48
|
export declare const CARD_TYPE_REGISTRY: Record<CardType, CardTypeConfig>;
|
|
62
|
-
/**
|
|
63
|
-
* Helper functions for card type configuration
|
|
64
|
-
*/
|
|
65
49
|
export declare function getCardTypeConfig(cardType: CardType): CardTypeConfig;
|
|
66
50
|
export declare function getCardTypeIcon(cardType: CardType): string;
|
|
67
51
|
export declare function getCardTypeLabel(cardType: CardType): string;
|
|
68
|
-
/**
|
|
69
|
-
* Typeahead option for search/filter dropdowns
|
|
70
|
-
*/
|
|
71
52
|
export interface TypeaheadOption {
|
|
72
53
|
label: string;
|
|
73
54
|
value: CardType | "favorites" | "trash";
|
|
74
55
|
}
|
|
75
|
-
/**
|
|
76
|
-
* Reserved keywords for search functionality
|
|
77
|
-
*/
|
|
78
56
|
export declare const RESERVED_KEYWORDS: TypeaheadOption[];
|
|
79
|
-
/**
|
|
80
|
-
* Type guard to check if a value is a valid CardType
|
|
81
|
-
*/
|
|
82
57
|
export declare function isCardType(value: unknown): value is CardType;
|
|
58
|
+
export { TEAK_FILES_ORIGINS } from "./filesOrigins.js";
|
|
59
|
+
export { HIDDEN_TAG_KEYS, isCardHidden, isHiddenTagList } from "./tags.js";
|
|
@@ -33,6 +33,7 @@ export interface FilePreviewFacts {
|
|
|
33
33
|
}
|
|
34
34
|
export declare const MAX_FILE_NAME_LENGTH = 240;
|
|
35
35
|
export declare const MAX_FILE_SIZE: number;
|
|
36
|
+
export declare const GENERIC_MIME_TYPES: Set<string>;
|
|
36
37
|
export declare const isGenericMimeType: (mimeType: string | null | undefined) => boolean;
|
|
37
38
|
export declare const FILE_FORMATS: readonly [FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition, FileFormatDefinition];
|
|
38
39
|
export type FileFormatId = (typeof FILE_FORMATS)[number]["id"];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const MAX_FOLDERS_PER_USER = 500;
|
|
2
|
+
export declare const MAX_FOLDERS_PER_CARD = 50;
|
|
3
|
+
export declare const MAX_FOLDER_NAME_LENGTH = 300;
|
|
4
|
+
export declare const MAX_FOLDER_CARD_IDS = 100;
|
|
5
|
+
export declare const MAX_SMART_FOLDER_QUERY_LENGTH = 500;
|
|
6
|
+
export type FolderKind = "manual" | "smart";
|
|
7
|
+
export declare const FOLDER_COLORS: readonly ["gray", "red", "orange", "amber", "green", "teal", "blue", "violet", "pink"];
|
|
8
|
+
export type FolderColor = (typeof FOLDER_COLORS)[number];
|
|
9
|
+
export declare const isFolderColor: (value: unknown) => value is FolderColor;
|
|
10
|
+
export declare const FOLDER_ERROR_MESSAGES: {
|
|
11
|
+
readonly DUPLICATE_NAME: "A folder with this name already exists";
|
|
12
|
+
readonly EMPTY_NAME: "Name the folder";
|
|
13
|
+
readonly NAME_TOO_LONG: "Folder names can be at most 300 characters";
|
|
14
|
+
readonly TOO_MANY_FOLDERS: "You can have up to 500 folders";
|
|
15
|
+
readonly TOO_MANY_FOLDERS_ON_CARD: "A card can be in up to 50 folders";
|
|
16
|
+
readonly NOT_FOUND: "Folder not found";
|
|
17
|
+
readonly EMPTY_QUERY: "Add a search for the smart folder";
|
|
18
|
+
readonly QUERY_TOO_LONG: "Smart folder searches can be at most 500 characters";
|
|
19
|
+
readonly SMART_FOLDER_IN_QUERY: "A smart folder's search can't use another smart folder";
|
|
20
|
+
readonly SMART_FOLDER_MEMBERSHIP: "Cards can't be added to a smart folder; it shows the cards that match its search";
|
|
21
|
+
readonly QUERY_ON_MANUAL_FOLDER: "Only smart folders have a search";
|
|
22
|
+
readonly SMART_FOLDER_TRASH: "Smart folders don't show Trash. To search for the word, put it in quotes";
|
|
23
|
+
};
|
|
24
|
+
export declare const normalizeFolderName: (name: string) => string;
|
|
25
|
+
export declare const folderNameKey: (name: string) => string;
|
|
26
|
+
export declare const explainInvalidFolderName: (name: string) => string | null;
|
|
27
|
+
export declare const explainInvalidSmartFolderQuery: (canonical: string) => string | null;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const MAX_TAG_NAME_LENGTH = 64;
|
|
2
|
+
export declare const TAG_OPERATION_COUNT_LIMIT = 10000;
|
|
3
|
+
export declare const TAG_OPERATION_STALL_MS: number;
|
|
4
|
+
export type TagOperationKind = "rename" | "merge" | "delete";
|
|
5
|
+
export type TagOperationStatus = "running" | "completed" | "failed";
|
|
6
|
+
export declare const TAG_ERROR_MESSAGES: {
|
|
7
|
+
readonly EMPTY_NAME: "Name the tag";
|
|
8
|
+
readonly NAME_TOO_LONG: "Tags can be at most 64 characters";
|
|
9
|
+
readonly NOT_FOUND: "Tag not found";
|
|
10
|
+
readonly SAME_TAG: "Choose a different tag to merge into";
|
|
11
|
+
readonly OPERATION_RUNNING: "Another tag change is still running";
|
|
12
|
+
readonly OPERATION_NOT_FOUND: "Tag operation not found";
|
|
13
|
+
};
|
|
14
|
+
export declare const tagKey: (tag: string) => string;
|
|
15
|
+
export declare const HIDDEN_TAG_KEYS: readonly ["secret", "hidden"];
|
|
16
|
+
export declare const isHiddenTagList: (tags: readonly string[] | null | undefined) => boolean;
|
|
17
|
+
export declare const isCardHidden: (card: {
|
|
18
|
+
isHidden?: true;
|
|
19
|
+
tags?: readonly string[];
|
|
20
|
+
}) => boolean;
|
|
21
|
+
export declare const explainInvalidTagName: (name: string) => string | null;
|
|
22
|
+
export declare const MAX_TAG_KEY_LENGTH = 256;
|
|
23
|
+
export declare const explainInvalidTagSource: (name: string) => string | null;
|
|
24
|
+
export declare const tagExistsMessage: (name: string) => string;
|
|
25
|
+
export type TagRewrite = {
|
|
26
|
+
kind: "delete";
|
|
27
|
+
from: string;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "rename";
|
|
30
|
+
from: string;
|
|
31
|
+
to: string;
|
|
32
|
+
} | {
|
|
33
|
+
kind: "merge";
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
};
|
|
37
|
+
export declare const rewriteTagList: (tags: readonly string[] | undefined, rewrite: TagRewrite) => string[] | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const formatBytes: (bytes?: number | null) => string;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export
|
|
2
|
-
readonly api:
|
|
3
|
-
readonly mcp:
|
|
4
|
-
}
|
|
1
|
+
export interface WorkosResources {
|
|
2
|
+
readonly api: string;
|
|
3
|
+
readonly mcp: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const PRODUCTION_WORKOS_RESOURCE_ORIGIN = "https://teakvault.com";
|
|
6
|
+
export declare const workosResourcesFor: (url: string) => WorkosResources;
|
|
7
|
+
export declare const PRODUCTION_WORKOS_RESOURCES: WorkosResources;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teak-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.87",
|
|
4
4
|
"description": "Teak API client and OAuth discovery for browser and Node applications.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@teak/convex": "workspace:*",
|
|
29
29
|
"@types/bun": "^1.4.0",
|
|
30
|
-
"@types/node": "^26.
|
|
30
|
+
"@types/node": "^26.6.5",
|
|
31
31
|
"typescript": "^6.0.3"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|