teak-sdk 1.0.84 → 1.0.86

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 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
- let types = [];
916
- if (Array.isArray(input.type)) {
917
- types = input.type;
918
- } else if (typeof input.type === "string") {
919
- types = [input.type];
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: typeof object.requestId === "string" ? object.requestId : undefined,
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", { body: JSON.stringify({ items, operation }), method: "POST" }, (v) => v),
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", { body: JSON.stringify(input), method: "POST" }, asCreate),
1064
- delete: (id) => request(`/v1/cards/${encodeURIComponent(id)}`, { method: "DELETE" }, () => null),
1065
- favorites: (input = {}) => request(`/v1/cards?${qs({ ...input, favorited: true, include: "content,metadata" })}`, { method: "GET" }, asPage),
1066
- get: (id) => request(`/v1/cards/${encodeURIComponent(id)}`, { method: "GET" }, asCard),
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
- search: (input = {}) => request(`/v1/cards?${qs({ ...input, include: "content,metadata" })}`, { method: "GET" }, asPage),
1069
- setFavorite: (id, isFavorited) => request(`/v1/cards/${encodeURIComponent(id)}/favorite`, { body: JSON.stringify({ isFavorited }), method: "PATCH" }, asCard),
1070
- update: (id, input) => request(`/v1/cards/${encodeURIComponent(id)}`, { body: JSON.stringify(input), method: "PATCH" }, asCard)
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
- delete: (id: string) => Promise<null>;
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[];
@@ -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";
@@ -5,12 +5,14 @@ export type CardType = (typeof cardTypes)[number];
5
5
  export declare const VISUAL_STYLE_TAXONOMY: readonly ["abstract", "cinematic", "dark", "illustrative", "minimal", "monochrome", "moody", "pastel", "photographic", "retro", "surreal", "vintage", "vibrant"];
6
6
  export type VisualStyle = (typeof VISUAL_STYLE_TAXONOMY)[number];
7
7
  export declare const VISUAL_STYLE_LABELS: Record<VisualStyle, string>;
8
+ export declare const VISUAL_STYLE_ALIAS_MAP: Record<string, VisualStyle>;
8
9
  export declare function normalizeVisualStyle(value: string): VisualStyle | null;
9
10
  export declare function normalizeVisualStyleFilters(values?: string[]): VisualStyle[];
10
11
  export declare function extractVisualStylesFromTags(tags?: string[]): VisualStyle[] | undefined;
11
12
  export declare const COLOR_HUE_BUCKETS: readonly ["red", "orange", "yellow", "green", "teal", "cyan", "blue", "purple", "pink", "brown", "neutral"];
12
13
  export type ColorHueBucket = (typeof COLOR_HUE_BUCKETS)[number];
13
14
  export declare const COLOR_HUE_LABELS: Record<ColorHueBucket, string>;
15
+ export declare const COLOR_HUE_ALIAS_MAP: Record<string, ColorHueBucket>;
14
16
  export declare function normalizeColorHueBucket(value: string): ColorHueBucket | null;
15
17
  export declare function normalizeHueFilters(values?: string[]): ColorHueBucket[];
16
18
  /**
@@ -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"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teak-sdk",
3
- "version": "1.0.84",
3
+ "version": "1.0.86",
4
4
  "description": "Teak API client and OAuth discovery for browser and Node applications.",
5
5
  "repository": {
6
6
  "type": "git",