@calmlens/sdk 0.5.0 → 0.7.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/cjs/testing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_CalmLensUtils = require("./CalmLensUtils-0QaxbI3A.js");
2
+ const require_CalmLensUtils = require("./CalmLensUtils-CJ6o7KRU.js");
3
3
  let zod = require("zod");
4
4
  zod = require_CalmLensUtils.__toESM(zod);
5
5
  //#region ../shared/src/Permissions.ts
@@ -14,13 +14,36 @@ const ACTION_SCHEMA = zod.enum([
14
14
  "folders:create",
15
15
  "folders:update",
16
16
  "folders:delete",
17
+ "settings:read",
18
+ "settings:write",
19
+ "members:read",
20
+ "members:write",
21
+ "api-keys:read",
22
+ "api-keys:write",
23
+ "connectors:read",
24
+ "connectors:write",
25
+ "metadata:read",
26
+ "metadata:write",
27
+ "lenses:read",
28
+ "lenses:write",
17
29
  "project:manage"
18
30
  ]);
31
+ const PROJECT_ACTIONS = [...[
32
+ "settings",
33
+ "members",
34
+ "api-keys",
35
+ "connectors",
36
+ "metadata",
37
+ "lenses"
38
+ ].flatMap((feature) => [`${feature}:read`, `${feature}:write`]), "project:manage"];
39
+ const isProjectAction = (action) => PROJECT_ACTIONS.includes(action);
40
+ /** The actions that include `action`: its feature's write action and project:manage. */
41
+ const actionsImplying = (action) => !isProjectAction(action) || action === "project:manage" ? [] : action.endsWith(":read") ? [action.replace(/:read$/, ":write"), "project:manage"] : ["project:manage"];
19
42
  const GRANT_SCHEMA = zod.object({
20
43
  actions: zod.array(ACTION_SCHEMA),
21
44
  folderId: zod.string().uuid().nullable(),
22
45
  includeSubfolders: zod.boolean()
23
- }).strict().refine((g) => g.folderId === null || !g.actions.includes("project:manage"), "Project management requires project scope");
46
+ }).strict().refine((g) => g.folderId === null || !g.actions.some(isProjectAction), "Project configuration permissions require project scope");
24
47
  const GRANTS_SCHEMA = zod.array(GRANT_SCHEMA).max(100);
25
48
  zod.enum([
26
49
  "admin",
@@ -29,7 +52,7 @@ zod.enum([
29
52
  "custom"
30
53
  ]);
31
54
  const permits = (grants, action, folderId, folders) => grants.some((grant) => {
32
- if (!grant.actions.includes(action)) return false;
55
+ if (![action, ...actionsImplying(action)].some((held) => grant.actions.includes(held))) return false;
33
56
  if (grant.folderId === null) return true;
34
57
  let current = folderId;
35
58
  const visited = /* @__PURE__ */ new Set();
@@ -191,7 +214,7 @@ var InMemoryMockDatabaseStorage = class {
191
214
  //#endregion
192
215
  //#region src/testing/MockUtils.ts
193
216
  const appendCdnSelector = (url, options) => {
194
- if (options.lens && options.transform) throw new Error("Specify either a lens or a transform, not both");
217
+ if (options.lens && options.transform) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Specify either a lens or a transform, not both" });
195
218
  if (options.lens) return `${url}/@${encodeURIComponent(options.lens)}`;
196
219
  if (!options.transform) return url;
197
220
  return `${url}/${encodeURI(options.transform.replace(/^\/+/, ""))}`;
@@ -237,20 +260,34 @@ const _excluded = ["assetIdentifier"];
237
260
  const _excluded2 = ["assetIdentifier"];
238
261
  const _excluded3 = ["assetId"];
239
262
  const _excluded4 = ["assetId"];
240
- const _excluded5 = ["folderId"];
263
+ const _excluded5 = ["assetId"];
264
+ const _excluded6 = ["folderId"];
241
265
  const assertValidUploadMimeType = (mimeType) => {
242
266
  if (require_CalmLensUtils.isRejectedUploadMimeType(mimeType)) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_MIME_TYPE, {
243
267
  message: require_CalmLensUtils.getRejectedUploadMimeTypeError(mimeType),
244
268
  details: { mimeType }
245
269
  });
246
270
  };
271
+ const toFailureError = (failure) => {
272
+ if (failure === "transport-error") return require_CalmLensUtils.calmLensError({ id: "sdk/transport-error" }, {
273
+ message: "Request failed",
274
+ cause: /* @__PURE__ */ new TypeError("Simulated network failure")
275
+ });
276
+ if (failure === "timeout") return require_CalmLensUtils.calmLensError({ id: "sdk/timeout" }, {
277
+ message: "Request aborted",
278
+ cause: new DOMException("The operation timed out.", "TimeoutError")
279
+ });
280
+ return failure;
281
+ };
247
282
  var MockCalmLensClient = class {
283
+ /** Accepts the same options as `CalmLensClient` (validated the same way), plus `mockOptions`. */
248
284
  constructor(options) {
249
- var _options$mockOptions$, _options$mockOptions, _options$mockOptions$2, _options$mockOptions2, _options$mockOptions$3, _options$mockOptions3, _options$mockOptions$4, _options$mockOptions4, _options$mockOptions$5, _options$mockOptions5, _options$mockOptions$6, _options$mockOptions6, _options$mockOptions$7, _options$mockOptions7, _options$mockOptions$8, _options$mockOptions8;
285
+ var _options$mockOptions$, _options$mockOptions, _options$mockOptions$2, _options$mockOptions2, _options$mockOptions$3, _options$mockOptions3, _options$mockOptions$4, _options$mockOptions4, _options$mockOptions$5, _options$mockOptions5, _options$mockOptions$6, _options$mockOptions6, _options$mockOptions$7, _options$mockOptions7, _options$cdnBaseUrl;
250
286
  this.options = options;
251
287
  this.lenses = /* @__PURE__ */ new Map();
252
- if (!options.apiKey) throw new Error("API key is required");
253
- if (!options.projectId) throw new Error("Project ID is required");
288
+ this.pendingFailures = [];
289
+ this.calls = [];
290
+ require_CalmLensUtils.validateClientOptions(options);
254
291
  this.databaseStorage = (_options$mockOptions$ = (_options$mockOptions = options.mockOptions) === null || _options$mockOptions === void 0 ? void 0 : _options$mockOptions.databaseStorage) !== null && _options$mockOptions$ !== void 0 ? _options$mockOptions$ : new InMemoryMockDatabaseStorage();
255
292
  this.imageStorage = (_options$mockOptions$2 = (_options$mockOptions2 = options.mockOptions) === null || _options$mockOptions2 === void 0 ? void 0 : _options$mockOptions2.imageStorage) !== null && _options$mockOptions$2 !== void 0 ? _options$mockOptions$2 : new InMemoryMockImageStorage();
256
293
  this.createId = (_options$mockOptions$3 = (_options$mockOptions3 = options.mockOptions) === null || _options$mockOptions3 === void 0 ? void 0 : _options$mockOptions3.createId) !== null && _options$mockOptions$3 !== void 0 ? _options$mockOptions$3 : crypto.randomUUID.bind(crypto);
@@ -259,7 +296,32 @@ var MockCalmLensClient = class {
259
296
  this.analyzedStatus = (_options$mockOptions$6 = (_options$mockOptions6 = options.mockOptions) === null || _options$mockOptions6 === void 0 ? void 0 : _options$mockOptions6.analyzedStatus) !== null && _options$mockOptions$6 !== void 0 ? _options$mockOptions$6 : "approved";
260
297
  this.apiKeyGrants = getMockApiKeyGrants(options.apiKey);
261
298
  this.signedUrlBaseUrl = (_options$mockOptions$7 = (_options$mockOptions7 = options.mockOptions) === null || _options$mockOptions7 === void 0 ? void 0 : _options$mockOptions7.signedUrlBaseUrl) !== null && _options$mockOptions$7 !== void 0 ? _options$mockOptions$7 : "mock://calmlens";
262
- this.cdnBaseUrl = (_options$mockOptions$8 = (_options$mockOptions8 = options.mockOptions) === null || _options$mockOptions8 === void 0 ? void 0 : _options$mockOptions8.cdnBaseUrl) !== null && _options$mockOptions$8 !== void 0 ? _options$mockOptions$8 : "mock://calmlens/v1";
299
+ this.cdnBaseUrl = (_options$cdnBaseUrl = options.cdnBaseUrl) !== null && _options$cdnBaseUrl !== void 0 ? _options$cdnBaseUrl : "mock://calmlens/v1";
300
+ }
301
+ /**
302
+ * Makes the next call (or the next call to `operation`) throw `failure` instead of running,
303
+ * as if the request never completed. Queue several to fail several calls in a row.
304
+ */
305
+ failNextRequest(failure = "transport-error", { operation } = {}) {
306
+ this.pendingFailures.push({
307
+ failure,
308
+ operation
309
+ });
310
+ }
311
+ /** Calls recorded for one operation, oldest first. */
312
+ callsTo(operation) {
313
+ return this.calls.filter((call) => call.operation === operation);
314
+ }
315
+ begin(operation, options) {
316
+ this.calls.push({
317
+ operation,
318
+ options
319
+ });
320
+ const index = this.pendingFailures.findIndex((pending) => pending.operation === void 0 || pending.operation === operation);
321
+ if (index !== -1) {
322
+ const [pending] = this.pendingFailures.splice(index, 1);
323
+ throw toFailureError(pending.failure);
324
+ }
263
325
  }
264
326
  get cdn() {
265
327
  var _this = this;
@@ -267,16 +329,17 @@ var MockCalmLensClient = class {
267
329
  getAssetUrl: (_ref) => {
268
330
  var _options$resource;
269
331
  let { assetIdentifier } = _ref, options = require_CalmLensUtils._objectWithoutProperties(_ref, _excluded);
270
- if (!assetIdentifier) throw new Error("Asset identifier is required");
332
+ if (!assetIdentifier) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset identifier is required" });
271
333
  const resource = (_options$resource = options.resource) !== null && _options$resource !== void 0 ? _options$resource : "content";
272
334
  const url = `${this.cdnBaseUrl.replace(/\/$/, "")}/assets/${encodeURIComponent(this.options.projectId)}/${encodeURIComponent(assetIdentifier)}/${resource}`;
273
335
  return appendCdnSelector(url, options);
274
336
  },
275
337
  serve: function() {
276
- var _ref3 = require_CalmLensUtils._asyncToGenerator(function* (_ref2) {
338
+ var _ref2 = require_CalmLensUtils._asyncToGenerator(function* (serveOptions) {
277
339
  var _asset$folderId, _await$this$databaseS, _this$databaseStorage, _this$databaseStorage2, _storedContent$type;
278
- let { assetIdentifier } = _ref2, options = require_CalmLensUtils._objectWithoutProperties(_ref2, _excluded2);
279
- if (!assetIdentifier) throw new Error("Asset identifier is required");
340
+ _this.begin("cdn.serve", serveOptions);
341
+ const { assetIdentifier } = serveOptions, options = require_CalmLensUtils._objectWithoutProperties(serveOptions, _excluded2);
342
+ if (!assetIdentifier) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset identifier is required" });
280
343
  const asset = (yield _this.databaseStorage.listAssets(_this.options.projectId)).find((asset) => asset.id === assetIdentifier || asset.externalId === assetIdentifier);
281
344
  if (!asset) return new Response("Asset not found", { status: 404 });
282
345
  if (asset.visibility !== "public" && !permits(_this.apiKeyGrants, "assets:download", (_asset$folderId = asset.folderId) !== null && _asset$folderId !== void 0 ? _asset$folderId : null, (_await$this$databaseS = yield (_this$databaseStorage = (_this$databaseStorage2 = _this.databaseStorage).listFolders) === null || _this$databaseStorage === void 0 ? void 0 : _this$databaseStorage.call(_this$databaseStorage2, _this.options.projectId)) !== null && _await$this$databaseS !== void 0 ? _await$this$databaseS : [])) return new Response(JSON.stringify({
@@ -305,7 +368,7 @@ var MockCalmLensClient = class {
305
368
  });
306
369
  });
307
370
  return function serve(_x) {
308
- return _ref3.apply(this, arguments);
371
+ return _ref2.apply(this, arguments);
309
372
  };
310
373
  }()
311
374
  };
@@ -315,8 +378,9 @@ var MockCalmLensClient = class {
315
378
  return {
316
379
  /** The mock does not record events; it always returns an empty page at "now". */
317
380
  list: function() {
318
- var _ref4 = require_CalmLensUtils._asyncToGenerator(function* (options = {}) {
381
+ var _ref3 = require_CalmLensUtils._asyncToGenerator(function* (options = {}) {
319
382
  var _options$after;
383
+ _this2.begin("events.list", options);
320
384
  return {
321
385
  events: [],
322
386
  cursor: (_options$after = options.after) !== null && _options$after !== void 0 ? _options$after : `${_this2.now()}_`,
@@ -324,18 +388,19 @@ list: function() {
324
388
  };
325
389
  });
326
390
  return function list() {
327
- return _ref4.apply(this, arguments);
391
+ return _ref3.apply(this, arguments);
328
392
  };
329
393
  }() };
330
394
  }
331
395
  get text() {
332
396
  var _this3 = this;
333
397
  return { moderate: function() {
334
- var _ref5 = require_CalmLensUtils._asyncToGenerator(function* (options) {
335
- return _this3.assets.moderate(require_CalmLensUtils.toTextAssetOptions(options));
398
+ var _ref4 = require_CalmLensUtils._asyncToGenerator(function* (options) {
399
+ _this3.begin("text.moderate", options);
400
+ return _this3.moderateAsset(require_CalmLensUtils.toTextAssetOptions(options));
336
401
  });
337
402
  return function moderate(_x2) {
338
- return _ref5.apply(this, arguments);
403
+ return _ref4.apply(this, arguments);
339
404
  };
340
405
  }() };
341
406
  }
@@ -343,62 +408,83 @@ list: function() {
343
408
  var _this4 = this;
344
409
  return {
345
410
  list: function() {
346
- var _ref6 = require_CalmLensUtils._asyncToGenerator(function* (options) {
411
+ var _ref5 = require_CalmLensUtils._asyncToGenerator(function* (options) {
347
412
  var _options$pageIndex;
413
+ _this4.begin("assets.list", options);
348
414
  const assets = yield _this4.databaseStorage.listAssets(_this4.options.projectId);
349
415
  return createPage(assets, require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2({}, options), {}, { pageIndex: (_options$pageIndex = options.pageIndex) !== null && _options$pageIndex !== void 0 ? _options$pageIndex : 0 }));
350
416
  });
351
417
  return function list(_x3) {
352
- return _ref6.apply(this, arguments);
418
+ return _ref5.apply(this, arguments);
353
419
  };
354
420
  }(),
355
421
  retrieve: function() {
356
- var _ref7 = require_CalmLensUtils._asyncToGenerator(function* ({ assetId }) {
357
- if (!assetId) throw new Error("Asset ID is required");
422
+ var _ref6 = require_CalmLensUtils._asyncToGenerator(function* (options) {
423
+ _this4.begin("assets.retrieve", options);
424
+ const { assetId } = options;
425
+ if (!assetId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset ID is required" });
358
426
  const asset = yield _this4.databaseStorage.getAsset(assetId);
359
- if (!asset) throw new Error("Asset not found");
427
+ if (!asset) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.ASSET_NOT_FOUND);
360
428
  return asset;
361
429
  });
362
430
  return function retrieve(_x4) {
363
- return _ref7.apply(this, arguments);
431
+ return _ref6.apply(this, arguments);
364
432
  };
365
433
  }(),
366
434
  listChildren: function() {
367
- var _ref9 = require_CalmLensUtils._asyncToGenerator(function* (_ref8) {
435
+ var _ref7 = require_CalmLensUtils._asyncToGenerator(function* (childrenOptions) {
368
436
  var _options$pageIndex2;
369
- let { assetId } = _ref8, options = require_CalmLensUtils._objectWithoutProperties(_ref8, _excluded3);
370
- if (!assetId) throw new Error("Asset ID is required");
437
+ _this4.begin("assets.listChildren", childrenOptions);
438
+ const { assetId } = childrenOptions, options = require_CalmLensUtils._objectWithoutProperties(childrenOptions, _excluded3);
439
+ if (!assetId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset ID is required" });
371
440
  const assets = yield _this4.databaseStorage.listAssets(_this4.options.projectId);
372
441
  return createPage(assets.filter((asset) => asset.parentId === assetId), require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2({}, options), {}, { pageIndex: (_options$pageIndex2 = options.pageIndex) !== null && _options$pageIndex2 !== void 0 ? _options$pageIndex2 : 0 }));
373
442
  });
374
443
  return function listChildren(_x5) {
375
- return _ref9.apply(this, arguments);
444
+ return _ref7.apply(this, arguments);
445
+ };
446
+ }(),
447
+ update: function() {
448
+ var _ref8 = require_CalmLensUtils._asyncToGenerator(function* (options) {
449
+ _this4.begin("assets.update", options);
450
+ const { assetId } = options, body = require_CalmLensUtils._objectWithoutProperties(options, _excluded4);
451
+ if (!assetId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset ID is required" });
452
+ const asset = yield _this4.databaseStorage.getAsset(assetId);
453
+ if (!asset || asset.projectId !== _this4.options.projectId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.ASSET_NOT_FOUND);
454
+ const changes = Object.fromEntries(Object.entries(body).filter(([, value]) => value !== void 0));
455
+ return _this4.databaseStorage.updateAsset(require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2({}, asset), changes), {}, { updatedAt: _this4.now() }));
456
+ });
457
+ return function update(_x6) {
458
+ return _ref8.apply(this, arguments);
376
459
  };
377
460
  }(),
378
461
  create: function() {
379
- var _ref10 = require_CalmLensUtils._asyncToGenerator(function* (options) {
462
+ var _ref9 = require_CalmLensUtils._asyncToGenerator(function* (options) {
463
+ _this4.begin("assets.create", options);
380
464
  return _this4.createAsset(options, _this4.queuedStatus);
381
465
  });
382
- return function create(_x6) {
383
- return _ref10.apply(this, arguments);
466
+ return function create(_x7) {
467
+ return _ref9.apply(this, arguments);
384
468
  };
385
469
  }(),
386
470
  moderate: function() {
387
- var _ref11 = require_CalmLensUtils._asyncToGenerator(function* (options) {
388
- if ("content" in options && "plainText" in options.content && (typeof options.content.plainText !== "string" || !options.content.plainText.trim())) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Text to moderate must be a non-empty string" });
389
- return _this4.createAsset(options, _this4.analyzedStatus);
471
+ var _ref10 = require_CalmLensUtils._asyncToGenerator(function* (options) {
472
+ _this4.begin("assets.moderate", options);
473
+ return _this4.moderateAsset(options);
390
474
  });
391
- return function moderate(_x7) {
392
- return _ref11.apply(this, arguments);
475
+ return function moderate(_x8) {
476
+ return _ref10.apply(this, arguments);
393
477
  };
394
478
  }(),
395
479
  uploadPart: function() {
396
- var _ref12 = require_CalmLensUtils._asyncToGenerator(function* ({ assetId, part }) {
480
+ var _ref11 = require_CalmLensUtils._asyncToGenerator(function* (options) {
397
481
  var _asset$uploadPartsRec;
398
- if (!assetId) throw new Error("Asset ID is required");
399
- if (!part) throw new Error("Part options are required");
482
+ _this4.begin("assets.uploadPart", options);
483
+ const { assetId, part } = options;
484
+ if (!assetId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset ID is required" });
485
+ if (!part) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Part options are required" });
400
486
  const asset = yield _this4.databaseStorage.getAsset(assetId);
401
- if (!asset) throw new Error("Asset not found");
487
+ if (!asset) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.ASSET_NOT_FOUND);
402
488
  const validation = require_CalmLensUtils.validateAssetPayload(part, {
403
489
  multipart: true,
404
490
  isFinal: part.isFinal
@@ -412,32 +498,35 @@ list: function() {
412
498
  });
413
499
  return _this4.databaseStorage.updateAsset(updated);
414
500
  });
415
- return function uploadPart(_x8) {
416
- return _ref12.apply(this, arguments);
501
+ return function uploadPart(_x9) {
502
+ return _ref11.apply(this, arguments);
417
503
  };
418
504
  }(),
419
505
  createSignedUrl: function() {
420
- var _ref14 = require_CalmLensUtils._asyncToGenerator(function* (_ref13) {
506
+ var _ref12 = require_CalmLensUtils._asyncToGenerator(function* (signedUrlOptions) {
421
507
  var _options$expiresInSec, _options$resource2;
422
- let { assetId } = _ref13, options = require_CalmLensUtils._objectWithoutProperties(_ref13, _excluded4);
423
- if (!assetId) throw new Error("Asset ID is required");
424
- if (!(yield _this4.databaseStorage.getAsset(assetId))) throw new Error("Asset not found");
508
+ _this4.begin("assets.createSignedUrl", signedUrlOptions);
509
+ const { assetId } = signedUrlOptions, options = require_CalmLensUtils._objectWithoutProperties(signedUrlOptions, _excluded5);
510
+ if (!assetId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset ID is required" });
511
+ if (!(yield _this4.databaseStorage.getAsset(assetId))) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.ASSET_NOT_FOUND);
425
512
  const expiresInSeconds = (_options$expiresInSec = options.expiresInSeconds) !== null && _options$expiresInSec !== void 0 ? _options$expiresInSec : 900;
426
513
  const resource = (_options$resource2 = options.resource) !== null && _options$resource2 !== void 0 ? _options$resource2 : "content";
427
- if (options.lens && options.transform) throw new Error("Specify either a lens or a transform, not both");
514
+ if (options.lens && options.transform) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Specify either a lens or a transform, not both" });
428
515
  const selector = options.lens ? `&lens=${encodeURIComponent(options.lens)}` : options.transform ? `&transform=${encodeURIComponent(options.transform)}` : "";
429
516
  return {
430
517
  url: `${_this4.signedUrlBaseUrl}/assets/${assetId}/${resource}?expiresInSeconds=${expiresInSeconds}${selector}`,
431
518
  expiresAt: _this4.now() + expiresInSeconds * 1e3
432
519
  };
433
520
  });
434
- return function createSignedUrl(_x9) {
435
- return _ref14.apply(this, arguments);
521
+ return function createSignedUrl(_x10) {
522
+ return _ref12.apply(this, arguments);
436
523
  };
437
524
  }(),
438
525
  move: function() {
439
- var _ref15 = require_CalmLensUtils._asyncToGenerator(function* ({ assetId, folderId }) {
440
- if (!assetId) throw new Error("Asset ID is required");
526
+ var _ref13 = require_CalmLensUtils._asyncToGenerator(function* (options) {
527
+ _this4.begin("assets.move", options);
528
+ const { assetId, folderId } = options;
529
+ if (!assetId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset ID is required" });
441
530
  const asset = yield _this4.databaseStorage.getAsset(assetId);
442
531
  if (!asset || asset.projectId !== _this4.options.projectId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.ASSET_NOT_FOUND);
443
532
  if (folderId !== null && folderId !== void 0) {
@@ -449,13 +538,15 @@ list: function() {
449
538
  });
450
539
  return _this4.databaseStorage.updateAsset(updated);
451
540
  });
452
- return function move(_x10) {
453
- return _ref15.apply(this, arguments);
541
+ return function move(_x11) {
542
+ return _ref13.apply(this, arguments);
454
543
  };
455
544
  }(),
456
545
  retry: function() {
457
- var _ref16 = require_CalmLensUtils._asyncToGenerator(function* ({ assetId }) {
458
- if (!assetId) throw new Error("Asset ID is required");
546
+ var _ref14 = require_CalmLensUtils._asyncToGenerator(function* (options) {
547
+ _this4.begin("assets.retry", options);
548
+ const { assetId } = options;
549
+ if (!assetId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset ID is required" });
459
550
  const asset = yield _this4.databaseStorage.getAsset(assetId);
460
551
  if (!asset || asset.projectId !== _this4.options.projectId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.ASSET_NOT_FOUND);
461
552
  if (asset.status !== "error") throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.ASSET_NOT_RETRYABLE);
@@ -464,8 +555,8 @@ list: function() {
464
555
  updatedAt: _this4.now()
465
556
  }));
466
557
  });
467
- return function retry(_x11) {
468
- return _ref16.apply(this, arguments);
558
+ return function retry(_x12) {
559
+ return _ref14.apply(this, arguments);
469
560
  };
470
561
  }()
471
562
  };
@@ -474,28 +565,32 @@ list: function() {
474
565
  var _this5 = this;
475
566
  return {
476
567
  list: function() {
477
- var _ref17 = require_CalmLensUtils._asyncToGenerator(function* () {
568
+ var _ref15 = require_CalmLensUtils._asyncToGenerator(function* () {
569
+ _this5.begin("folders.list", void 0);
478
570
  return [..._this5.databaseStorage.listFolders ? yield _this5.databaseStorage.listFolders(_this5.options.projectId) : []].sort((a, b) => a.name.localeCompare(b.name));
479
571
  });
480
572
  return function list() {
481
- return _ref17.apply(this, arguments);
573
+ return _ref15.apply(this, arguments);
482
574
  };
483
575
  }(),
484
576
  retrieve: function() {
485
- var _ref18 = require_CalmLensUtils._asyncToGenerator(function* ({ folderId }) {
486
- if (!folderId) throw new Error("Folder ID is required");
577
+ var _ref16 = require_CalmLensUtils._asyncToGenerator(function* (options) {
578
+ _this5.begin("folders.retrieve", options);
579
+ const { folderId } = options;
580
+ if (!folderId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Folder ID is required" });
487
581
  const folder = yield _this5.resolveFolder(folderId);
488
582
  if (!folder) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.FOLDER_NOT_FOUND);
489
583
  return folder;
490
584
  });
491
- return function retrieve(_x12) {
492
- return _ref18.apply(this, arguments);
585
+ return function retrieve(_x13) {
586
+ return _ref16.apply(this, arguments);
493
587
  };
494
588
  }(),
495
589
  create: function() {
496
- var _ref19 = require_CalmLensUtils._asyncToGenerator(function* (options) {
590
+ var _ref17 = require_CalmLensUtils._asyncToGenerator(function* (options) {
497
591
  var _options$parentId, _options$parentId2;
498
- if (!options.name) throw new Error("Folder name is required");
592
+ _this5.begin("folders.create", options);
593
+ if (!options.name) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Folder name is required" });
499
594
  if (options.parentId) {
500
595
  if (!(yield _this5.resolveFolder(options.parentId))) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.FOLDER_NOT_FOUND);
501
596
  }
@@ -511,14 +606,15 @@ list: function() {
511
606
  if (_this5.databaseStorage.createFolder) return yield _this5.databaseStorage.createFolder(folder);
512
607
  return folder;
513
608
  });
514
- return function create(_x13) {
515
- return _ref19.apply(this, arguments);
609
+ return function create(_x14) {
610
+ return _ref17.apply(this, arguments);
516
611
  };
517
612
  }(),
518
613
  update: function() {
519
- var _ref21 = require_CalmLensUtils._asyncToGenerator(function* (_ref20) {
520
- let { folderId } = _ref20, body = require_CalmLensUtils._objectWithoutProperties(_ref20, _excluded5);
521
- if (!folderId) throw new Error("Folder ID is required");
614
+ var _ref18 = require_CalmLensUtils._asyncToGenerator(function* (options) {
615
+ _this5.begin("folders.update", options);
616
+ const { folderId } = options, body = require_CalmLensUtils._objectWithoutProperties(options, _excluded6);
617
+ if (!folderId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Folder ID is required" });
522
618
  const folder = yield _this5.resolveFolder(folderId);
523
619
  if (!folder) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.FOLDER_NOT_FOUND);
524
620
  if (body.name !== void 0 && body.name !== folder.name) {
@@ -529,13 +625,15 @@ list: function() {
529
625
  if (_this5.databaseStorage.updateFolder) return yield _this5.databaseStorage.updateFolder(updated);
530
626
  return updated;
531
627
  });
532
- return function update(_x14) {
533
- return _ref21.apply(this, arguments);
628
+ return function update(_x15) {
629
+ return _ref18.apply(this, arguments);
534
630
  };
535
631
  }(),
536
632
  delete: function() {
537
- var _ref22 = require_CalmLensUtils._asyncToGenerator(function* ({ folderId }) {
538
- if (!folderId) throw new Error("Folder ID is required");
633
+ var _ref19 = require_CalmLensUtils._asyncToGenerator(function* (options) {
634
+ _this5.begin("folders.delete", options);
635
+ const { folderId } = options;
636
+ if (!folderId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Folder ID is required" });
539
637
  if (!(yield _this5.resolveFolder(folderId))) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.FOLDER_NOT_FOUND);
540
638
  const hasAssets = (yield _this5.databaseStorage.listAssets(_this5.options.projectId)).some((asset) => asset.folderId === folderId);
541
639
  const hasChildren = (_this5.databaseStorage.listFolders ? yield _this5.databaseStorage.listFolders(_this5.options.projectId) : []).some((f) => f.parentId === folderId);
@@ -545,13 +643,15 @@ list: function() {
545
643
  } });
546
644
  if (_this5.databaseStorage.deleteFolder) yield _this5.databaseStorage.deleteFolder(folderId);
547
645
  });
548
- return function _delete(_x15) {
549
- return _ref22.apply(this, arguments);
646
+ return function _delete(_x16) {
647
+ return _ref19.apply(this, arguments);
550
648
  };
551
649
  }(),
552
650
  move: function() {
553
- var _ref23 = require_CalmLensUtils._asyncToGenerator(function* ({ folderId, parentId }) {
554
- if (!folderId) throw new Error("Folder ID is required");
651
+ var _ref20 = require_CalmLensUtils._asyncToGenerator(function* (options) {
652
+ _this5.begin("folders.move", options);
653
+ const { folderId, parentId } = options;
654
+ if (!folderId) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Folder ID is required" });
555
655
  const folder = yield _this5.resolveFolder(folderId);
556
656
  if (!folder) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.FOLDER_NOT_FOUND);
557
657
  const targetParentId = parentId !== null && parentId !== void 0 ? parentId : null;
@@ -574,8 +674,8 @@ list: function() {
574
674
  if (_this5.databaseStorage.updateFolder) return yield _this5.databaseStorage.updateFolder(updated);
575
675
  return updated;
576
676
  });
577
- return function move(_x16) {
578
- return _ref23.apply(this, arguments);
677
+ return function move(_x17) {
678
+ return _ref20.apply(this, arguments);
579
679
  };
580
680
  }()
581
681
  };
@@ -583,46 +683,58 @@ list: function() {
583
683
  ensureLens(options) {
584
684
  var _this6 = this;
585
685
  return require_CalmLensUtils._asyncToGenerator(function* () {
586
- var _existing$description, _options$description, _existing$transforms, _options$transforms;
587
- const existing = _this6.lenses.get(options.identifier);
588
- if (!existing) {
589
- const lens = require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2({
590
- id: _this6.createId(),
591
- projectId: _this6.options.projectId,
592
- userId: null
593
- }, options), {}, {
594
- createdAt: _this6.now(),
595
- updatedAt: _this6.now()
596
- });
597
- _this6.lenses.set(lens.identifier, lens);
598
- return lens;
599
- }
600
- if (existing.name === options.name && ((_existing$description = existing.description) !== null && _existing$description !== void 0 ? _existing$description : null) === ((_options$description = options.description) !== null && _options$description !== void 0 ? _options$description : null) && existing.type === options.type && existing.active === options.active && require_CalmLensUtils.stringifyJsonCanonical((_existing$transforms = existing.transforms) !== null && _existing$transforms !== void 0 ? _existing$transforms : null) === require_CalmLensUtils.stringifyJsonCanonical((_options$transforms = options.transforms) !== null && _options$transforms !== void 0 ? _options$transforms : null) && existing.version === options.version) return existing;
601
- if (options.version > existing.version) {
602
- const lens = require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2({}, existing), options), {}, { updatedAt: _this6.now() });
603
- _this6.lenses.set(lens.identifier, lens);
604
- return lens;
605
- }
606
- throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.LENS_VERSION_CONFLICT, { details: {
607
- currentVersion: existing.version,
608
- minimumVersion: existing.version + 1,
609
- requestedVersion: options.version
610
- } });
686
+ _this6.begin("ensureLens", options);
687
+ return _this6.ensureLensDefinition(options);
611
688
  })();
612
689
  }
613
- ensureLenses({ lenses }) {
690
+ ensureLensDefinition(options) {
691
+ var _existing$description, _options$description, _existing$transforms, _options$transforms;
692
+ const existing = this.lenses.get(options.identifier);
693
+ if (!existing) {
694
+ const lens = require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2({
695
+ id: this.createId(),
696
+ projectId: this.options.projectId,
697
+ userId: null
698
+ }, options), {}, {
699
+ createdAt: this.now(),
700
+ updatedAt: this.now()
701
+ });
702
+ this.lenses.set(lens.identifier, lens);
703
+ return lens;
704
+ }
705
+ if (existing.name === options.name && ((_existing$description = existing.description) !== null && _existing$description !== void 0 ? _existing$description : null) === ((_options$description = options.description) !== null && _options$description !== void 0 ? _options$description : null) && existing.type === options.type && existing.active === options.active && require_CalmLensUtils.stringifyJsonCanonical((_existing$transforms = existing.transforms) !== null && _existing$transforms !== void 0 ? _existing$transforms : null) === require_CalmLensUtils.stringifyJsonCanonical((_options$transforms = options.transforms) !== null && _options$transforms !== void 0 ? _options$transforms : null) && existing.version === options.version) return existing;
706
+ if (options.version > existing.version) {
707
+ const lens = require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2(require_CalmLensUtils._objectSpread2({}, existing), options), {}, { updatedAt: this.now() });
708
+ this.lenses.set(lens.identifier, lens);
709
+ return lens;
710
+ }
711
+ throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.LENS_VERSION_CONFLICT, { details: {
712
+ currentVersion: existing.version,
713
+ minimumVersion: existing.version + 1,
714
+ requestedVersion: options.version
715
+ } });
716
+ }
717
+ ensureLenses(options) {
614
718
  var _this7 = this;
615
719
  return require_CalmLensUtils._asyncToGenerator(function* () {
616
- if (lenses.length === 0) throw new Error("At least one lens is required");
617
- return yield Promise.all(lenses.map((option) => _this7.ensureLens(option)));
720
+ _this7.begin("ensureLenses", options);
721
+ if (options.lenses.length === 0) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "At least one lens is required" });
722
+ return options.lenses.map((option) => _this7.ensureLensDefinition(option));
618
723
  })();
619
724
  }
620
- createAsset(options, status) {
725
+ moderateAsset(options) {
621
726
  var _this8 = this;
727
+ return require_CalmLensUtils._asyncToGenerator(function* () {
728
+ if ("content" in options && "plainText" in options.content && (typeof options.content.plainText !== "string" || !options.content.plainText.trim())) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Text to moderate must be a non-empty string" });
729
+ return _this8.createAsset(options, _this8.analyzedStatus);
730
+ })();
731
+ }
732
+ createAsset(options, status) {
733
+ var _this9 = this;
622
734
  return require_CalmLensUtils._asyncToGenerator(function* () {
623
735
  var _options$folderId, _options$visibility, _options$part$partNum;
624
- if (!("content" in options) && !("url" in options) && !("part" in options)) throw new Error("Either file content, URL, or multipart part is required");
625
- if (!options.name) throw new Error("Asset name is required");
736
+ if (!("content" in options) && !("url" in options) && !("part" in options)) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Either file content, URL, or multipart part is required" });
737
+ if (!options.name) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "Asset name is required" });
626
738
  if (!("part" in options) && "isFinal" in options) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: "isFinal is only valid for multipart uploads" });
627
739
  if ("part" in options && options.part.partNumber && options.part.partNumber > 1) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.USE_UPLOAD_PART);
628
740
  if ("content" in options) {
@@ -640,13 +752,13 @@ list: function() {
640
752
  });
641
753
  if (!validation.ok) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.INVALID_UPLOAD_PAYLOAD, { message: validation.error });
642
754
  }
643
- const id = _this8.createId();
644
- const now = _this8.now();
755
+ const id = _this9.createId();
756
+ const now = _this9.now();
645
757
  const type = inferAssetType(options);
646
- const sizeInBytes = _this8.getSizeInBytes(options);
758
+ const sizeInBytes = _this9.getSizeInBytes(options);
647
759
  const asset = {
648
760
  id,
649
- projectId: _this8.options.projectId,
761
+ projectId: _this9.options.projectId,
650
762
  folderId: (_options$folderId = options.folderId) !== null && _options$folderId !== void 0 ? _options$folderId : null,
651
763
  createdAt: now,
652
764
  updatedAt: now,
@@ -663,24 +775,24 @@ list: function() {
663
775
  uploadPartsReceived: "part" in options ? (_options$part$partNum = options.part.partNumber) !== null && _options$part$partNum !== void 0 ? _options$part$partNum : 1 : void 0
664
776
  };
665
777
  if ("content" in options) {
666
- if (!("plainText" in options.content)) yield _this8.imageStorage.putContent(id, options.content);
667
- } else if ("part" in options) yield _this8.imageStorage.putPart(id, options.part);
668
- return _this8.databaseStorage.createAsset(asset);
778
+ if (!("plainText" in options.content)) yield _this9.imageStorage.putContent(id, options.content);
779
+ } else if ("part" in options) yield _this9.imageStorage.putPart(id, options.part);
780
+ return _this9.databaseStorage.createAsset(asset);
669
781
  })();
670
782
  }
671
783
  resolveFolder(folderId) {
672
- var _this9 = this;
784
+ var _this10 = this;
673
785
  return require_CalmLensUtils._asyncToGenerator(function* () {
674
- if (!_this9.databaseStorage.getFolder) return void 0;
675
- const folder = yield _this9.databaseStorage.getFolder(folderId);
676
- if (!folder || folder.projectId !== _this9.options.projectId) return;
786
+ if (!_this10.databaseStorage.getFolder) return void 0;
787
+ const folder = yield _this10.databaseStorage.getFolder(folderId);
788
+ if (!folder || folder.projectId !== _this10.options.projectId) return;
677
789
  return folder;
678
790
  })();
679
791
  }
680
792
  assertUniqueFolderName(name, parentId, excludeFolderId) {
681
- var _this10 = this;
793
+ var _this11 = this;
682
794
  return require_CalmLensUtils._asyncToGenerator(function* () {
683
- if ((_this10.databaseStorage.listFolders ? yield _this10.databaseStorage.listFolders(_this10.options.projectId) : []).find((f) => f.id !== excludeFolderId && f.parentId === (parentId !== null && parentId !== void 0 ? parentId : null) && f.name === name)) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.DUPLICATE_FOLDER_NAME, { message: `A folder named "${name}" already exists in this location.` });
795
+ if ((_this11.databaseStorage.listFolders ? yield _this11.databaseStorage.listFolders(_this11.options.projectId) : []).find((f) => f.id !== excludeFolderId && f.parentId === (parentId !== null && parentId !== void 0 ? parentId : null) && f.name === name)) throw require_CalmLensUtils.calmLensError(require_CalmLensUtils.PUBLIC_ERROR_CODES.DUPLICATE_FOLDER_NAME, { message: `A folder named "${name}" already exists in this location.` });
684
796
  })();
685
797
  }
686
798
  getSizeInBytes(options) {