@calmlens/sdk 0.12.0 → 0.14.0
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 +54 -37
- package/cjs/CalmLensConnection-Bth5fJyp.js +234 -0
- package/cjs/CalmLensUtils-DNdmYeX6.js +699 -0
- package/cjs/{CalmLensError-CKwMKV0S.js → CalmLensVersion-Bs0DreBV.js} +114 -1
- package/cjs/{CalmLensWebhooks-BTPxKvcD.js → CalmLensWebhooks-6thkvr_F.js} +9 -9
- package/cjs/WebhookPayload-vy8HNMaK.d.ts +15834 -0
- package/cjs/app.d.ts +3 -3
- package/cjs/app.js +10 -10
- package/cjs/{index-BgmWj3KL.d.ts → index-Dz340UQ9.d.ts} +29 -1
- package/cjs/index.d.ts +3 -3
- package/cjs/index.js +4 -5
- package/cjs/server.d.ts +16 -7
- package/cjs/server.js +35 -21
- package/cjs/testing.d.ts +21 -42
- package/cjs/testing.js +181 -94
- package/esm/CalmLensConnection-DrCOL9h9.js +193 -0
- package/esm/{CalmLensUtils-Cx32j2zt.js → CalmLensUtils-BQo79TA1.js} +316 -2
- package/esm/{CalmLensError-CihGG26K.js → CalmLensVersion-DPnL_Ebv.js} +91 -2
- package/esm/{CalmLensWebhooks-DShmAal4.js → CalmLensWebhooks-CWlD-f_P.js} +2 -2
- package/esm/WebhookPayload-vy8HNMaK.d.ts +15834 -0
- package/esm/app.d.ts +3 -3
- package/esm/app.js +4 -4
- package/esm/{index-BgmWj3KL.d.ts → index-Dz340UQ9.d.ts} +29 -1
- package/esm/index.d.ts +3 -3
- package/esm/index.js +1 -3
- package/esm/server.d.ts +16 -7
- package/esm/server.js +24 -10
- package/esm/testing.d.ts +21 -42
- package/esm/testing.js +152 -65
- package/package.json +1 -1
- package/cjs/CalmLensConnection-CYtBP-vu.js +0 -516
- package/cjs/CalmLensUtils-Dg3s4loH.js +0 -367
- package/cjs/WebhookPayload-Cgb32aSH.d.ts +0 -10187
- package/cjs/src-Dsc8Pn6v.js +0 -45
- package/esm/CalmLensConnection-wLNy0OIP.js +0 -475
- package/esm/WebhookPayload-Cgb32aSH.d.ts +0 -10187
- package/esm/src-CJhrILvM.js +0 -22
package/esm/testing.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as hmacSha256Hex, i as WEBHOOK_TIMESTAMP_HEADER, l as stringifyJsonCanonical, n as WEBHOOK_SIGNATURE_HEADER, s as signUploadTokenWithApiKey, t as WEBHOOK_DELIVERY_HEADER } from "./CalmLensWebhooks-
|
|
3
|
-
import {
|
|
1
|
+
import { c as invalidArgument, d as API_ERROR_DEFINITIONS, o as CalmLensError, s as SDK_ERROR_CODES, u as API_ERROR_CODES } from "./CalmLensVersion-DPnL_Ebv.js";
|
|
2
|
+
import { c as hmacSha256Hex, i as WEBHOOK_TIMESTAMP_HEADER, l as stringifyJsonCanonical, n as WEBHOOK_SIGNATURE_HEADER, s as signUploadTokenWithApiKey, t as WEBHOOK_DELIVERY_HEADER } from "./CalmLensWebhooks-CWlD-f_P.js";
|
|
3
|
+
import { b as getRejectedUploadMimeTypeError, f as sleep, g as validateAssetPayload, h as getAssetPayloadByteLength, m as assetToData, n as encodePathSegment, o as toTextAssetOptions, p as assetDataToUint8Array, r as pollForDecision, s as transformSelector, t as appendCdnSelector, u as validateServerClientOptions, x as isRejectedUploadMimeType } from "./CalmLensUtils-BQo79TA1.js";
|
|
4
4
|
import * as zod from "zod";
|
|
5
5
|
import "zod/v4";
|
|
6
6
|
//#region ../shared/src/ModerationCategoryDefinitions.ts
|
|
@@ -36,58 +36,63 @@ const MODERATION_CATEGORY_DEFINITIONS = {
|
|
|
36
36
|
docsHref: "/docs/guides/moderation-categories#hate-and-identity-abuse"
|
|
37
37
|
},
|
|
38
38
|
"criminal-activity": {
|
|
39
|
-
summary: "Planning, assistance, instructions, encouragement or facilitation of a concrete criminal or seriously dangerous act.",
|
|
40
|
-
definition: "covers planning, requests for assistance, instructions, encouragement or facilitation of a concrete criminal or seriously dangerous act. A request can qualify even when no act occurs and a later reply refuses it. Dangerous activity requires a concrete serious risk of physical harm.",
|
|
41
|
-
exclusions: "Neutral reporting, prevention, lawful safety advice, fiction without criminal assistance, and vague dangerous references do not qualify. Masks, computers, payment cards, detention or ordinary tools do not establish criminal facilitation by themselves. A clear visual demonstration of how to carry out a crime can qualify.",
|
|
39
|
+
summary: "Planning, assistance, instructions, encouragement or facilitation of a concrete criminal or seriously dangerous act, and illegal drugs or contraband.",
|
|
40
|
+
definition: "covers planning, requests for assistance, instructions, encouragement or facilitation of a concrete criminal or seriously dangerous act. A request can qualify even when no act occurs and a later reply refuses it. Dangerous activity requires a concrete serious risk of physical harm. It also covers illegal drug use, dealing, production or trafficking, and contraband such as stolen goods, counterfeit money or documents and smuggled or illegally traded weapons.",
|
|
41
|
+
exclusions: "Neutral reporting, prevention, lawful safety advice, fiction without criminal assistance, and vague dangerous references do not qualify. Medical, pharmaceutical, clinical, research and educational content does not qualify, including prescriptions, dosages, side effects, controlled medicines used as prescribed, pharmacies, hospitals and drug manufacturing by pharmaceutical companies. Lawful alcohol and tobacco, harm reduction, addiction recovery and drug-policy discussion do not qualify either. Masks, computers, payment cards, detention or ordinary tools do not establish criminal facilitation by themselves. A clear visual demonstration of how to carry out a crime can qualify.",
|
|
42
42
|
docsHref: "/docs/guides/moderation-categories#criminal-and-dangerous-activity"
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
45
|
//#endregion
|
|
46
46
|
//#region ../shared/src/ModerationPolicyDimensions.ts
|
|
47
47
|
const MODERATION_QUALIFIERS = [
|
|
48
|
-
"nudity",
|
|
48
|
+
"sexual-nudity",
|
|
49
49
|
"sexual-activity",
|
|
50
|
-
"explicit-
|
|
50
|
+
"sexual-explicit-language",
|
|
51
51
|
"sexual-solicitation",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
52
|
+
"sexual-historical",
|
|
53
|
+
"sexual-documentary",
|
|
54
|
+
"sexual-fictional",
|
|
55
|
+
"sexual-support-prevention",
|
|
56
|
+
"violence-attack",
|
|
57
|
+
"violence-threat",
|
|
58
|
+
"violence-preparation",
|
|
59
|
+
"violence-encouragement",
|
|
60
|
+
"violence-injury",
|
|
61
|
+
"violence-death",
|
|
62
|
+
"violence-graphic",
|
|
63
|
+
"violence-historical",
|
|
64
|
+
"violence-documentary",
|
|
65
|
+
"violence-fictional",
|
|
66
|
+
"violence-support-prevention",
|
|
59
67
|
"self-harm-thoughts",
|
|
60
68
|
"self-harm-preparation",
|
|
61
69
|
"self-harm-act",
|
|
62
70
|
"self-harm-methods",
|
|
63
71
|
"self-harm-encouragement",
|
|
64
|
-
"
|
|
65
|
-
"
|
|
72
|
+
"self-harm-documentary",
|
|
73
|
+
"self-harm-fictional",
|
|
74
|
+
"self-harm-support-prevention",
|
|
75
|
+
"harassment-abuse",
|
|
76
|
+
"harassment-intimidation",
|
|
66
77
|
"harassment-threat",
|
|
67
|
-
"sexual
|
|
78
|
+
"harassment-sexual",
|
|
68
79
|
"harassment-encouragement",
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
80
|
+
"harassment-fictional",
|
|
81
|
+
"hate-abuse",
|
|
82
|
+
"hate-dehumanization",
|
|
83
|
+
"hate-inferiority",
|
|
84
|
+
"hate-exclusion",
|
|
73
85
|
"hate-threat",
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"criminal-
|
|
77
|
-
"criminal-
|
|
78
|
-
"criminal-
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
86
|
+
"hate-historical",
|
|
87
|
+
"hate-fictional",
|
|
88
|
+
"criminal-activity-demonstration",
|
|
89
|
+
"criminal-activity-preparation",
|
|
90
|
+
"criminal-activity-request",
|
|
91
|
+
"criminal-activity-instructions",
|
|
92
|
+
"criminal-activity-promotion",
|
|
93
|
+
"criminal-activity-substances",
|
|
94
|
+
"criminal-activity-fictional"
|
|
83
95
|
];
|
|
84
|
-
const SHARED_QUALIFIERS = [
|
|
85
|
-
"historical",
|
|
86
|
-
"documentary",
|
|
87
|
-
"fictional",
|
|
88
|
-
"support-prevention"
|
|
89
|
-
];
|
|
90
|
-
[...SHARED_QUALIFIERS], [...SHARED_QUALIFIERS], [...SHARED_QUALIFIERS], [...SHARED_QUALIFIERS], [...SHARED_QUALIFIERS], [...SHARED_QUALIFIERS];
|
|
91
96
|
//#endregion
|
|
92
97
|
//#region ../../node_modules/zod-meta/esm/index.js
|
|
93
98
|
const ZOD_META_KEY = "__zod_meta__";
|
|
@@ -252,7 +257,11 @@ const LIKELIHOOD_SCHEMA = zod.enum([
|
|
|
252
257
|
"likely",
|
|
253
258
|
"very-likely"
|
|
254
259
|
]);
|
|
255
|
-
const CLASSIFICATION_NOT_EVALUATED_REASON_SCHEMA = zod.enum([
|
|
260
|
+
const CLASSIFICATION_NOT_EVALUATED_REASON_SCHEMA = zod.enum([
|
|
261
|
+
"not-supported",
|
|
262
|
+
"unavailable",
|
|
263
|
+
"not-requested"
|
|
264
|
+
]);
|
|
256
265
|
const CLASSIFICATION_QUALIFIER_RESULTS_SCHEMA = zod.partialRecord(zod.enum(MODERATION_QUALIFIERS), zod.discriminatedUnion("status", [zod.object({
|
|
257
266
|
status: zod.literal("evaluated"),
|
|
258
267
|
score: zod.number().min(0).max(1),
|
|
@@ -302,7 +311,6 @@ const CLASSIFICATION_LABEL_SCHEMA = zod.object({
|
|
|
302
311
|
zod.object({
|
|
303
312
|
processedAt: zod.number(),
|
|
304
313
|
categories: CATEGORIES_SCHEMA,
|
|
305
|
-
flagged: zod.boolean(),
|
|
306
314
|
score: zod.number(),
|
|
307
315
|
notes: saneStringField().nullish(),
|
|
308
316
|
media: zod.object({
|
|
@@ -380,6 +388,8 @@ const ACTION_SCHEMA = zod.enum([
|
|
|
380
388
|
"lenses:write",
|
|
381
389
|
"upload-presets:read",
|
|
382
390
|
"upload-presets:write",
|
|
391
|
+
"reviews:read",
|
|
392
|
+
"reviews:write",
|
|
383
393
|
"project:manage"
|
|
384
394
|
]);
|
|
385
395
|
const PROJECT_ACTIONS = [...[
|
|
@@ -389,7 +399,8 @@ const PROJECT_ACTIONS = [...[
|
|
|
389
399
|
"connectors",
|
|
390
400
|
"metadata",
|
|
391
401
|
"lenses",
|
|
392
|
-
"upload-presets"
|
|
402
|
+
"upload-presets",
|
|
403
|
+
"reviews"
|
|
393
404
|
].flatMap((feature) => [`${feature}:read`, `${feature}:write`]), "project:manage"];
|
|
394
405
|
const isProjectAction = (action) => PROJECT_ACTIONS.includes(action);
|
|
395
406
|
/** The actions that include `action`: its feature's write action and project:manage. */
|
|
@@ -402,7 +413,7 @@ const GRANT_SCHEMA = zod.object({
|
|
|
402
413
|
const GRANTS_SCHEMA = zod.array(GRANT_SCHEMA).max(100);
|
|
403
414
|
zod.enum([
|
|
404
415
|
"admin",
|
|
405
|
-
"
|
|
416
|
+
"editor",
|
|
406
417
|
"viewer",
|
|
407
418
|
"custom"
|
|
408
419
|
]);
|
|
@@ -696,8 +707,8 @@ var MockCalmLensServerClient = class {
|
|
|
696
707
|
this.imageStorage = options.mockOptions?.imageStorage ?? new InMemoryMockImageStorage();
|
|
697
708
|
this.createId = options.mockOptions?.createId ?? crypto.randomUUID.bind(crypto);
|
|
698
709
|
this.now = options.mockOptions?.now ?? Date.now;
|
|
699
|
-
this.
|
|
700
|
-
this.
|
|
710
|
+
this.queuedOutcome = options.mockOptions?.queuedOutcome ?? "pending";
|
|
711
|
+
this.analyzedOutcome = options.mockOptions?.analyzedOutcome ?? "approved";
|
|
701
712
|
this.apiKeyGrants = getMockApiKeyGrants(options.apiKey);
|
|
702
713
|
this.signedUrlBaseUrl = options.mockOptions?.signedUrlBaseUrl ?? "mock://calmlens";
|
|
703
714
|
this.cdnBaseUrl = (options.cdnBaseUrl ?? "mock://calmlens/v1").replace(/\/+$/, "");
|
|
@@ -1009,18 +1020,22 @@ var MockCalmLensServerClient = class {
|
|
|
1009
1020
|
isFinal: part.isFinal
|
|
1010
1021
|
});
|
|
1011
1022
|
if (!validation.ok) throw this.invalidPayload(validation.error);
|
|
1012
|
-
if (asset.status !== "uploading") throw this.apiError(API_ERROR_CODES.UPLOAD_NOT_OPEN);
|
|
1013
|
-
const expectedPartNumber = (asset.uploadPartsReceived ?? 1) + 1;
|
|
1023
|
+
if (asset.processing.status !== "uploading") throw this.apiError(API_ERROR_CODES.UPLOAD_NOT_OPEN);
|
|
1024
|
+
const expectedPartNumber = (asset.processing.uploadPartsReceived ?? 1) + 1;
|
|
1014
1025
|
if (part.partNumber !== expectedPartNumber) throw this.apiError(API_ERROR_CODES.INVALID_UPLOAD_PART_NUMBER, { details: { expectedPartNumber } });
|
|
1015
1026
|
await this.imageStorage.putPart(assetId, part);
|
|
1016
1027
|
const queue = options.queue ?? this.uploadQueues.get(assetId) ?? false;
|
|
1017
1028
|
if (part.isFinal) this.uploadQueues.delete(assetId);
|
|
1018
|
-
|
|
1029
|
+
const now = this.now();
|
|
1030
|
+
const received = {
|
|
1019
1031
|
...asset,
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1032
|
+
processing: {
|
|
1033
|
+
...asset.processing,
|
|
1034
|
+
uploadPartsReceived: part.partNumber
|
|
1035
|
+
},
|
|
1036
|
+
updatedAt: now
|
|
1037
|
+
};
|
|
1038
|
+
return this.databaseStorage.updateAsset(part.isFinal ? await this.applyOutcome(received, queue ? this.queuedOutcome : this.analyzedOutcome) : received);
|
|
1024
1039
|
});
|
|
1025
1040
|
},
|
|
1026
1041
|
createSignedUrl: async (signedUrlOptions) => {
|
|
@@ -1053,23 +1068,31 @@ var MockCalmLensServerClient = class {
|
|
|
1053
1068
|
retry: async (options) => {
|
|
1054
1069
|
this.begin("assets.retry", options);
|
|
1055
1070
|
const asset = await this.findOwnAsset(options?.assetId);
|
|
1056
|
-
if (asset.status !== "
|
|
1057
|
-
if (asset.
|
|
1058
|
-
return this.databaseStorage.updateAsset(
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1071
|
+
if (asset.processing.status !== "failed") throw this.apiError(API_ERROR_CODES.ASSET_NOT_RETRYABLE);
|
|
1072
|
+
if (asset.content.status === "removed") throw this.apiError(API_ERROR_CODES.ASSET_CONTENT_UNAVAILABLE);
|
|
1073
|
+
return this.databaseStorage.updateAsset(await this.applyOutcome(asset, "pending"));
|
|
1074
|
+
},
|
|
1075
|
+
/** Waits like the real client, checking the mock's storage for a decision. */
|
|
1076
|
+
waitForDecision: async (options) => {
|
|
1077
|
+
this.begin("assets.waitForDecision", options);
|
|
1078
|
+
const { assetId, ...waitOptions } = options;
|
|
1079
|
+
return pollForDecision(() => this.findOwnAsset(assetId), waitOptions, sleep);
|
|
1063
1080
|
},
|
|
1064
1081
|
deleteContent: async (options) => {
|
|
1065
1082
|
this.begin("assets.deleteContent", options);
|
|
1066
1083
|
const asset = await this.findOwnAsset(options?.assetId);
|
|
1067
1084
|
await this.imageStorage.deleteContent(asset.id);
|
|
1085
|
+
const now = this.now();
|
|
1068
1086
|
return this.databaseStorage.updateAsset({
|
|
1069
1087
|
...asset,
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1088
|
+
content: asset.content.status === "removed" ? asset.content : {
|
|
1089
|
+
...asset.content,
|
|
1090
|
+
status: "removed",
|
|
1091
|
+
removalReason: "requested",
|
|
1092
|
+
updatedAt: now,
|
|
1093
|
+
extractedText: null
|
|
1094
|
+
},
|
|
1095
|
+
updatedAt: now
|
|
1073
1096
|
});
|
|
1074
1097
|
},
|
|
1075
1098
|
delete: async (options) => {
|
|
@@ -1253,6 +1276,7 @@ var MockCalmLensServerClient = class {
|
|
|
1253
1276
|
const id = this.createId();
|
|
1254
1277
|
const now = this.now();
|
|
1255
1278
|
const isOpenUpload = "part" in options && !options.part.isFinal;
|
|
1279
|
+
const keepContent = options.processingOptions?.keepContentAfterProcessing === true;
|
|
1256
1280
|
const asset = {
|
|
1257
1281
|
id,
|
|
1258
1282
|
projectId: this.projectId,
|
|
@@ -1265,11 +1289,37 @@ var MockCalmLensServerClient = class {
|
|
|
1265
1289
|
externalUrl: "url" in options ? options.url : "content" in options ? options.externalUrl : void 0,
|
|
1266
1290
|
type: inferAssetType(options),
|
|
1267
1291
|
metadata: options.metadata,
|
|
1268
|
-
status: isOpenUpload ? "uploading" : queue ? this.queuedStatus : this.analyzedStatus,
|
|
1269
1292
|
processingOptions: options.processingOptions,
|
|
1270
1293
|
visibility: options.visibility ?? "private",
|
|
1271
|
-
|
|
1272
|
-
|
|
1294
|
+
processing: {
|
|
1295
|
+
status: isOpenUpload ? "uploading" : "processing",
|
|
1296
|
+
updatedAt: now,
|
|
1297
|
+
uploadPartsReceived: "part" in options ? options.part.partNumber ?? 1 : null
|
|
1298
|
+
},
|
|
1299
|
+
moderation: {
|
|
1300
|
+
status: "pending",
|
|
1301
|
+
action: null,
|
|
1302
|
+
note: null,
|
|
1303
|
+
reviewerAction: null,
|
|
1304
|
+
reviewerNote: null,
|
|
1305
|
+
reviewerUserId: null,
|
|
1306
|
+
reviewedAt: null,
|
|
1307
|
+
decidedAt: null,
|
|
1308
|
+
report: null
|
|
1309
|
+
},
|
|
1310
|
+
content: {
|
|
1311
|
+
status: keepContent ? "stored" : "temporary",
|
|
1312
|
+
removalReason: null,
|
|
1313
|
+
updatedAt: now,
|
|
1314
|
+
safetyHold: null,
|
|
1315
|
+
format: this.getContentFormat(options),
|
|
1316
|
+
extension: null,
|
|
1317
|
+
sizeInBytes: this.getSizeInBytes(options) ?? null,
|
|
1318
|
+
checksums: null,
|
|
1319
|
+
image: null,
|
|
1320
|
+
previewImage: null,
|
|
1321
|
+
extractedText: null
|
|
1322
|
+
}
|
|
1273
1323
|
};
|
|
1274
1324
|
if ("content" in options) {
|
|
1275
1325
|
if (!("plainText" in options.content)) await this.imageStorage.putContent(id, options.content);
|
|
@@ -1277,7 +1327,39 @@ var MockCalmLensServerClient = class {
|
|
|
1277
1327
|
await this.imageStorage.putPart(id, options.part);
|
|
1278
1328
|
if (isOpenUpload) this.uploadQueues.set(id, queue);
|
|
1279
1329
|
}
|
|
1280
|
-
return this.databaseStorage.createAsset(asset);
|
|
1330
|
+
return this.databaseStorage.createAsset(isOpenUpload ? asset : await this.applyOutcome(asset, queue ? this.queuedOutcome : this.analyzedOutcome));
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Moves an asset to `outcome` like the pipeline would: a decision finishes processing, and
|
|
1334
|
+
* finished processing removes content kept only temporarily (`keepContentAfterProcessing` off).
|
|
1335
|
+
*/
|
|
1336
|
+
async applyOutcome(asset, outcome) {
|
|
1337
|
+
const now = this.now();
|
|
1338
|
+
const decided = outcome === "approved" || outcome === "rejected";
|
|
1339
|
+
const processingStatus = decided ? "done" : outcome === "failed" ? "failed" : "processing";
|
|
1340
|
+
const removeContent = processingStatus === "done" && asset.content.status === "temporary";
|
|
1341
|
+
if (removeContent) await this.imageStorage.deleteContent(asset.id);
|
|
1342
|
+
return {
|
|
1343
|
+
...asset,
|
|
1344
|
+
updatedAt: now,
|
|
1345
|
+
processing: {
|
|
1346
|
+
...asset.processing,
|
|
1347
|
+
status: processingStatus,
|
|
1348
|
+
updatedAt: now
|
|
1349
|
+
},
|
|
1350
|
+
moderation: {
|
|
1351
|
+
...asset.moderation,
|
|
1352
|
+
status: decided ? outcome : "pending",
|
|
1353
|
+
decidedAt: decided ? now : null
|
|
1354
|
+
},
|
|
1355
|
+
content: removeContent ? {
|
|
1356
|
+
...asset.content,
|
|
1357
|
+
status: "removed",
|
|
1358
|
+
removalReason: "retention",
|
|
1359
|
+
updatedAt: now,
|
|
1360
|
+
extractedText: null
|
|
1361
|
+
} : asset.content
|
|
1362
|
+
};
|
|
1281
1363
|
}
|
|
1282
1364
|
async resolveFolder(folderId) {
|
|
1283
1365
|
if (!this.databaseStorage.getFolder) return void 0;
|
|
@@ -1294,6 +1376,11 @@ var MockCalmLensServerClient = class {
|
|
|
1294
1376
|
async assertUniqueFolderName(name, parentId, excludeFolderId) {
|
|
1295
1377
|
if ((this.databaseStorage.listFolders ? await this.databaseStorage.listFolders(this.projectId) : []).find((f) => f.id !== excludeFolderId && f.parentId === (parentId ?? null) && f.name === name)) throw this.apiError(API_ERROR_CODES.DUPLICATE_FOLDER_NAME, { message: `A folder named "${name}" already exists in this location.` });
|
|
1296
1378
|
}
|
|
1379
|
+
getContentFormat(options) {
|
|
1380
|
+
if ("content" in options) return options.content.type;
|
|
1381
|
+
if ("part" in options) return options.part.type;
|
|
1382
|
+
return null;
|
|
1383
|
+
}
|
|
1297
1384
|
getSizeInBytes(options) {
|
|
1298
1385
|
if ("content" in options) {
|
|
1299
1386
|
if ("plainText" in options.content) return new TextEncoder().encode(options.content.plainText).byteLength;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calmlens/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Official CalmLens SDK for JavaScript and TypeScript: content moderation, asset storage and CDN delivery.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://calmlens.com/docs/sdk/javascript",
|