@mediaviz/sdk 1.8.0 → 1.9.0-dev.107

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.cjs CHANGED
@@ -4,36 +4,181 @@ function getDefaultExportFromCjs (x) {
4
4
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5
5
  }
6
6
 
7
- var pkce;
8
- var hasRequiredPkce;
7
+ var base64;
8
+ var hasRequiredBase64;
9
9
 
10
- function requirePkce () {
11
- if (hasRequiredPkce) return pkce;
12
- hasRequiredPkce = 1;
10
+ function requireBase64 () {
11
+ if (hasRequiredBase64) return base64;
12
+ hasRequiredBase64 = 1;
13
+
14
+ // Base64URL codec, used by PKCE (encode) and JWT payload decoding (decode).
15
+ // Hand-rolled rather than delegating to atob/btoa, Buffer, or TextDecoder:
16
+ // none of those is present on every target runtime — React Native's Hermes has
17
+ // no Buffer and does not guarantee atob — and the alphabet here is URL-safe and
18
+ // unpadded, which the standard helpers do not produce.
13
19
 
14
- // base64url-encode a Uint8Array without padding
20
+ const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
21
+
22
+ /**
23
+ * @param {Uint8Array} bytes
24
+ * @returns {string} unpadded base64url
25
+ */
15
26
  function base64urlEncode(bytes) {
16
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
17
27
  let result = '';
18
28
  for (let i = 0; i < bytes.length; i += 3) {
19
29
  const b0 = bytes[i];
20
30
  const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
21
31
  const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
22
- result += chars[b0 >> 2];
23
- result += chars[((b0 & 3) << 4) | (b1 >> 4)];
24
- if (i + 1 < bytes.length) result += chars[((b1 & 0xf) << 2) | (b2 >> 6)];
25
- if (i + 2 < bytes.length) result += chars[b2 & 0x3f];
32
+ result += ALPHABET[b0 >> 2];
33
+ result += ALPHABET[((b0 & 3) << 4) | (b1 >> 4)];
34
+ if (i + 1 < bytes.length) result += ALPHABET[((b1 & 0xf) << 2) | (b2 >> 6)];
35
+ if (i + 2 < bytes.length) result += ALPHABET[b2 & 0x3f];
26
36
  }
27
37
  return result;
28
38
  }
29
39
 
40
+ /**
41
+ * Decodes base64url or standard base64, padded or not.
42
+ * @param {string} str
43
+ * @returns {Uint8Array}
44
+ */
45
+ function base64urlDecode(str) {
46
+ const clean = String(str).replace(/=+$/, '');
47
+ const out = new Uint8Array((clean.length * 3) >> 2);
48
+ let acc = 0;
49
+ let bits = 0;
50
+ let i = 0;
51
+ for (const ch of clean) {
52
+ const value = decodeChar(ch);
53
+ if (value < 0) throw new TypeError(`Invalid base64url character: ${JSON.stringify(ch)}`);
54
+ acc = (acc << 6) | value;
55
+ bits += 6;
56
+ if (bits >= 8) {
57
+ bits -= 8;
58
+ out[i++] = (acc >> bits) & 0xff;
59
+ }
60
+ }
61
+ return out.subarray(0, i);
62
+ }
63
+
64
+ /**
65
+ * @param {Uint8Array} bytes
66
+ * @returns {string}
67
+ */
68
+ function utf8Decode(bytes) {
69
+ let out = '';
70
+ let i = 0;
71
+ while (i < bytes.length) {
72
+ const b0 = bytes[i++];
73
+ let codePoint;
74
+ if (b0 < 0x80) codePoint = b0;
75
+ else if ((b0 & 0xe0) === 0xc0) codePoint = ((b0 & 0x1f) << 6) | (bytes[i++] & 0x3f);
76
+ else if ((b0 & 0xf0) === 0xe0)
77
+ codePoint = ((b0 & 0x0f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f);
78
+ else
79
+ codePoint =
80
+ ((b0 & 0x07) << 18) | ((bytes[i++] & 0x3f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f);
81
+ out += String.fromCodePoint(codePoint);
82
+ }
83
+ return out;
84
+ }
85
+
86
+ // helpers
87
+ function decodeChar(ch) {
88
+ // '+' and '/' map onto the URL-safe alphabet's '-' and '_' slots, so standard
89
+ // base64 decodes through the same table.
90
+ if (ch === '+') return 62;
91
+ if (ch === '/') return 63;
92
+ return ALPHABET.indexOf(ch);
93
+ }
94
+
95
+ base64 = { base64urlEncode, base64urlDecode, utf8Decode };
96
+ return base64;
97
+ }
98
+
99
+ var crypto;
100
+ var hasRequiredCrypto;
101
+
102
+ function requireCrypto () {
103
+ if (hasRequiredCrypto) return crypto;
104
+ hasRequiredCrypto = 1;
105
+
106
+ // Crypto seam for PKCE.
107
+ //
108
+ // Defaults to WebCrypto, which covers browsers and Node >= 18. React Native's
109
+ // Hermes runtime provides neither half of what PKCE needs: there is no
110
+ // SubtleCrypto at all (so no SHA-256), and no crypto.getRandomValues without a
111
+ // polyfill. Hosts on such runtimes call configureCrypto() once at startup with
112
+ // native-backed equivalents (expo-crypto, react-native-quick-crypto).
113
+
114
+ /** @typedef {{getRandomValues: (bytes: Uint8Array) => Uint8Array, sha256: (bytes: Uint8Array) => Promise<Uint8Array>}} CryptoProvider */
115
+
116
+ let _provider = null;
117
+
118
+ /**
119
+ * Installs a crypto provider, replacing the WebCrypto default.
120
+ * @param {CryptoProvider} provider
121
+ */
122
+ function configureCrypto(provider) {
123
+ if (!provider || typeof provider.getRandomValues !== 'function' || typeof provider.sha256 !== 'function') {
124
+ throw new TypeError(
125
+ 'configureCrypto requires { getRandomValues(bytes) => bytes, sha256(bytes) => Promise<Uint8Array> }'
126
+ );
127
+ }
128
+ _provider = provider;
129
+ }
130
+
131
+ /** Restores the WebCrypto default. Primarily for tests. */
132
+ function resetCrypto() {
133
+ _provider = null;
134
+ }
135
+
136
+ /**
137
+ * @returns {CryptoProvider}
138
+ */
139
+ function getCrypto() {
140
+ return _provider ?? webCryptoProvider();
141
+ }
142
+
143
+ // helpers
144
+ function webCryptoProvider() {
145
+ const wc = globalThis.crypto;
146
+ // Named explicitly rather than letting a property access blow up deep inside
147
+ // PKCE: on React Native the failure is a missing polyfill, and the message
148
+ // has to say so.
149
+ if (!wc || typeof wc.getRandomValues !== 'function' || !wc.subtle) {
150
+ throw new Error(
151
+ 'No WebCrypto available in this runtime. On React Native (or any host without ' +
152
+ 'SubtleCrypto), call configureCrypto({ getRandomValues, sha256 }) before using PKCE.'
153
+ );
154
+ }
155
+ return {
156
+ getRandomValues: (bytes) => wc.getRandomValues(bytes),
157
+ sha256: async (bytes) => new Uint8Array(await wc.subtle.digest('SHA-256', bytes)),
158
+ };
159
+ }
160
+
161
+ crypto = { configureCrypto, resetCrypto, getCrypto };
162
+ return crypto;
163
+ }
164
+
165
+ var pkce;
166
+ var hasRequiredPkce;
167
+
168
+ function requirePkce () {
169
+ if (hasRequiredPkce) return pkce;
170
+ hasRequiredPkce = 1;
171
+
172
+ const { base64urlEncode } = requireBase64();
173
+ const { getCrypto } = requireCrypto();
174
+
30
175
  /**
31
176
  * Generates a 64-character PKCE code verifier from [A-Za-z0-9-._~].
32
177
  * @returns {string}
33
178
  */
34
179
  function generateCodeVerifier() {
35
180
  const bytes = new Uint8Array(48);
36
- globalThis.crypto.getRandomValues(bytes);
181
+ getCrypto().getRandomValues(bytes);
37
182
  return base64urlEncode(bytes).slice(0, 64);
38
183
  }
39
184
 
@@ -43,9 +188,8 @@ function requirePkce () {
43
188
  * @returns {Promise<string>}
44
189
  */
45
190
  async function generateCodeChallenge(verifier) {
46
- const encoded = new TextEncoder().encode(verifier);
47
- const hashBuf = await globalThis.crypto.subtle.digest('SHA-256', encoded);
48
- return base64urlEncode(new Uint8Array(hashBuf));
191
+ const hash = await getCrypto().sha256(asciiEncode(verifier));
192
+ return base64urlEncode(hash);
49
193
  }
50
194
 
51
195
  /**
@@ -54,8 +198,24 @@ function requirePkce () {
54
198
  */
55
199
  function generateState() {
56
200
  const bytes = new Uint8Array(16);
57
- globalThis.crypto.getRandomValues(bytes);
58
- return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
201
+ getCrypto().getRandomValues(bytes);
202
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
203
+ }
204
+
205
+ // helpers
206
+
207
+ // The RFC 7636 §4.1 verifier alphabet is ASCII-only, so a byte-per-char encode
208
+ // is exact and keeps TextEncoder — absent on some React Native versions — off
209
+ // the PKCE path entirely. A non-ASCII verifier is invalid input, not something
210
+ // to silently re-encode.
211
+ function asciiEncode(str) {
212
+ const out = new Uint8Array(str.length);
213
+ for (let i = 0; i < str.length; i++) {
214
+ const code = str.charCodeAt(i);
215
+ if (code > 0x7f) throw new TypeError('PKCE code_verifier must be ASCII (RFC 7636 §4.1)');
216
+ out[i] = code;
217
+ }
218
+ return out;
59
219
  }
60
220
 
61
221
  pkce = { generateCodeVerifier, generateCodeChallenge, generateState };
@@ -178,6 +338,7 @@ function requireClient () {
178
338
 
179
339
  const { generateCodeVerifier, generateCodeChallenge, generateState } = requirePkce();
180
340
  const { postForm, postJson } = requireHttp();
341
+ const { base64urlDecode, utf8Decode } = requireBase64();
181
342
  const { OAuthError } = requireErrors();
182
343
 
183
344
  // In-flight dedup key for client_credentials re-mints (no refresh_token to key on).
@@ -253,8 +414,7 @@ function requireClient () {
253
414
  code,
254
415
  code_verifier: codeVerifier,
255
416
  redirect_uri: redirectUri ?? this._config.redirectUri,
256
- client_id: this._config.clientId,
257
- client_secret: this._config.clientSecret,
417
+ ...this._clientAuth(),
258
418
  });
259
419
  }
260
420
 
@@ -266,8 +426,7 @@ function requireClient () {
266
426
  async getClientCredentialsToken() {
267
427
  return postForm(`${this._config.baseUrl}/oauth/token`, {
268
428
  grant_type: 'client_credentials',
269
- client_id: this._config.clientId,
270
- client_secret: this._config.clientSecret,
429
+ ...this._clientAuth(),
271
430
  });
272
431
  }
273
432
 
@@ -279,8 +438,7 @@ function requireClient () {
279
438
  return postForm(`${this._config.baseUrl}/oauth/token`, {
280
439
  grant_type: 'refresh_token',
281
440
  refresh_token: refreshToken,
282
- client_id: this._config.clientId,
283
- client_secret: this._config.clientSecret,
441
+ ...this._clientAuth(),
284
442
  });
285
443
  }
286
444
 
@@ -290,7 +448,7 @@ function requireClient () {
290
448
  * @returns {Promise<void>}
291
449
  */
292
450
  async revokeToken(token, tokenTypeHint) {
293
- const params = { token, client_id: this._config.clientId, client_secret: this._config.clientSecret };
451
+ const params = { token, ...this._clientAuth() };
294
452
  if (tokenTypeHint) params.token_type_hint = tokenTypeHint;
295
453
  await postForm(`${this._config.baseUrl}/oauth/revoke`, params);
296
454
  }
@@ -371,10 +529,22 @@ function requireClient () {
371
529
  decodeAccessToken(accessToken) {
372
530
  const segment = accessToken.split('.')[1];
373
531
  if (!segment) throw new OAuthError('invalid_token', 'Malformed JWT', 400);
374
- const b64 = segment.replace(/-/g, '+').replace(/_/g, '/').padEnd(Math.ceil(segment.length / 4) * 4, '=');
375
- const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
376
- const payload = JSON.parse(new TextDecoder().decode(bytes));
377
- return payload;
532
+ return JSON.parse(utf8Decode(base64urlDecode(segment)));
533
+ }
534
+
535
+ /**
536
+ * Client-authentication params for a token-endpoint request.
537
+ *
538
+ * A public client (mobile, SPA) holds no secret, and the authorization server
539
+ * rejects the request outright if one is present, so the key is omitted
540
+ * entirely rather than sent empty. Passing it through unconditionally
541
+ * serializes `undefined` into the form body as that literal string.
542
+ * @returns {Record<string, string>}
543
+ */
544
+ _clientAuth() {
545
+ const params = { client_id: this._config.clientId };
546
+ if (this._config.clientSecret) params.client_secret = this._config.clientSecret;
547
+ return params;
378
548
  }
379
549
  }
380
550
 
@@ -471,8 +641,9 @@ function requireSrc$1 () {
471
641
  const { OAuthClient } = requireClient();
472
642
  const { OAuthError } = requireErrors();
473
643
  const { OAuthErrorCode } = requireTypes();
644
+ const { configureCrypto } = requireCrypto();
474
645
 
475
- src$1 = { OAuthClient, OAuthError, OAuthErrorCode };
646
+ src$1 = { OAuthClient, OAuthError, OAuthErrorCode, configureCrypto };
476
647
  return src$1;
477
648
  }
478
649
 
@@ -480,7 +651,7 @@ var srcExports$1 = requireSrc$1();
480
651
  var _oauth = /*@__PURE__*/getDefaultExportFromCjs(srcExports$1);
481
652
 
482
653
  // Auto-generated — do not edit
483
- const { OAuthClient, OAuthError, OAuthErrorCode } = _oauth;
654
+ const { OAuthClient, OAuthError, OAuthErrorCode, configureCrypto } = _oauth;
484
655
 
485
656
  var signing;
486
657
  var hasRequiredSigning;
@@ -497,12 +668,21 @@ function requireSigning () {
497
668
  // constant time. Web Crypto only, so the same code runs in Node >= 18 and
498
669
  // browsers.
499
670
 
500
- const _encoder = new TextEncoder();
671
+ // Built on first use, not at import. These functions are a server-side concern
672
+ // (only the endpoint receiving a push verifies a signature), but the module is
673
+ // bundled into every SDK including React Native — and constructing this at
674
+ // module scope made merely importing the SDK crash on any runtime without a
675
+ // TextEncoder global.
676
+ let _encoderInstance = null;
677
+ function _encode(text) {
678
+ if (!_encoderInstance) _encoderInstance = new TextEncoder();
679
+ return _encoderInstance.encode(text);
680
+ }
501
681
 
502
682
  async function signWebhookPayload(secret, timestamp, rawBody) {
503
683
  const key = await globalThis.crypto.subtle.importKey(
504
- 'raw', _encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
505
- const payload = _concat(_encoder.encode(`${timestamp}.`), toBytes(rawBody));
684
+ 'raw', _encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
685
+ const payload = _concat(_encode(`${timestamp}.`), toBytes(rawBody));
506
686
  const digest = await globalThis.crypto.subtle.sign('HMAC', key, payload);
507
687
  return 'sha256=' + _hex(new Uint8Array(digest));
508
688
  }
@@ -526,7 +706,7 @@ function requireSigning () {
526
706
 
527
707
  // helpers
528
708
  function toBytes(rawBody) {
529
- if (typeof rawBody === 'string') return _encoder.encode(rawBody);
709
+ if (typeof rawBody === 'string') return _encode(rawBody);
530
710
  if (rawBody instanceof Uint8Array) return rawBody;
531
711
  if (rawBody instanceof ArrayBuffer) return new Uint8Array(rawBody);
532
712
  throw new TypeError('rawBody must be a string, Uint8Array, or ArrayBuffer');
@@ -969,7 +1149,7 @@ class Company {
969
1149
  }
970
1150
  }
971
1151
 
972
- function stripUndef$7(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1152
+ function stripUndef$8(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
973
1153
 
974
1154
  class CuratedAlbums {
975
1155
  constructor(ctx) { this._ctx = ctx; }
@@ -977,7 +1157,7 @@ class CuratedAlbums {
977
1157
  async createCuratedAlbum(projectTableName, name, description = undefined, confidenceValue = undefined) {
978
1158
  this._ctx.requireTokens();
979
1159
  const path = `/api/v1/curated_album/project/${encodeURIComponent(projectTableName)}`;
980
- const body = stripUndef$7({
1160
+ const body = stripUndef$8({
981
1161
  name: name,
982
1162
  description: description,
983
1163
  confidence_value: confidenceValue,
@@ -1031,7 +1211,7 @@ class CuratedAlbums {
1031
1211
  async updateCuratedAlbum(albumId, { name, description, confidenceValue } = {}) {
1032
1212
  this._ctx.requireTokens();
1033
1213
  const path = `/api/v1/curated_album/${encodeURIComponent(albumId)}`;
1034
- const body = stripUndef$7({
1214
+ const body = stripUndef$8({
1035
1215
  name: name,
1036
1216
  description: description,
1037
1217
  confidence_value: confidenceValue,
@@ -1055,7 +1235,7 @@ class CuratedAlbums {
1055
1235
  }
1056
1236
  }
1057
1237
 
1058
- function stripUndef$6(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1238
+ function stripUndef$7(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1059
1239
 
1060
1240
  class CustomAlbums {
1061
1241
  constructor(ctx) { this._ctx = ctx; }
@@ -1103,7 +1283,7 @@ class CustomAlbums {
1103
1283
  async createProjectCustomAlbum(projectTableName, { name, description, photoIdInclusionList, photoIdRemovalList } = {}) {
1104
1284
  this._ctx.requireTokens();
1105
1285
  const path = `/api/v1/custom_album/project/${encodeURIComponent(projectTableName)}`;
1106
- const body = stripUndef$6({
1286
+ const body = stripUndef$7({
1107
1287
  name: name,
1108
1288
  description: description,
1109
1289
  photo_id_inclusion_list: photoIdInclusionList,
@@ -1116,7 +1296,7 @@ class CustomAlbums {
1116
1296
  async updateCustomAlbum(albumId, { name, description, photoIdInclusionList, photoIdRemovalList } = {}) {
1117
1297
  this._ctx.requireTokens();
1118
1298
  const path = `/api/v1/custom_album/${encodeURIComponent(albumId)}`;
1119
- const body = stripUndef$6({
1299
+ const body = stripUndef$7({
1120
1300
  name: name,
1121
1301
  description: description,
1122
1302
  photo_id_inclusion_list: photoIdInclusionList,
@@ -1216,7 +1396,7 @@ async function handleResponse(response) {
1216
1396
  }
1217
1397
  }
1218
1398
 
1219
- function stripUndef$5(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1399
+ function stripUndef$6(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1220
1400
 
1221
1401
  class EmailTokens {
1222
1402
  constructor(ctx) { this._ctx = ctx; }
@@ -1247,7 +1427,7 @@ class EmailTokens {
1247
1427
  }
1248
1428
 
1249
1429
  async validateToken(token) {
1250
- const body = stripUndef$5({
1430
+ const body = stripUndef$6({
1251
1431
  token: token,
1252
1432
  });
1253
1433
  const resp = await fetch(this._ctx.baseUrl + `/api/v1/validate-token`, {
@@ -1259,7 +1439,7 @@ class EmailTokens {
1259
1439
  }
1260
1440
 
1261
1441
  async resetPassword(token, newPassword) {
1262
- const body = stripUndef$5({
1442
+ const body = stripUndef$6({
1263
1443
  token: token,
1264
1444
  new_password: newPassword,
1265
1445
  });
@@ -1298,7 +1478,7 @@ class Health {
1298
1478
  }
1299
1479
  }
1300
1480
 
1301
- function stripUndef$4(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1481
+ function stripUndef$5(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1302
1482
 
1303
1483
  class Keywords {
1304
1484
  constructor(ctx) { this._ctx = ctx; }
@@ -1306,7 +1486,7 @@ class Keywords {
1306
1486
  async createKeywordFilteringList(name, projectList = undefined) {
1307
1487
  this._ctx.requireTokens();
1308
1488
  const path = `/api/v1/keyword/`;
1309
- const body = stripUndef$4({
1489
+ const body = stripUndef$5({
1310
1490
  name: name,
1311
1491
  project_list: projectList,
1312
1492
  });
@@ -1359,7 +1539,7 @@ class Keywords {
1359
1539
  async updateKeywordFilteringListLabels(keywordListId, listKeywordsToInclude, listKeywordsToExclude) {
1360
1540
  this._ctx.requireTokens();
1361
1541
  const path = `/api/v1/keyword/${encodeURIComponent(keywordListId)}`;
1362
- const body = stripUndef$4({
1542
+ const body = stripUndef$5({
1363
1543
  list_keywords_to_include: listKeywordsToInclude,
1364
1544
  list_keywords_to_exclude: listKeywordsToExclude,
1365
1545
  });
@@ -1370,7 +1550,7 @@ class Keywords {
1370
1550
  async updateKeywordFilteringListDetails(keywordListId, { name, projectList } = {}) {
1371
1551
  this._ctx.requireTokens();
1372
1552
  const path = `/api/v1/keyword/details/${encodeURIComponent(keywordListId)}`;
1373
- const body = stripUndef$4({
1553
+ const body = stripUndef$5({
1374
1554
  name: name,
1375
1555
  project_list: projectList,
1376
1556
  });
@@ -1635,7 +1815,7 @@ class Person {
1635
1815
  }
1636
1816
  }
1637
1817
 
1638
- function stripUndef$3(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1818
+ function stripUndef$4(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
1639
1819
 
1640
1820
  class Projects {
1641
1821
  constructor(ctx) { this._ctx = ctx; }
@@ -1648,7 +1828,7 @@ class Projects {
1648
1828
  if (models !== undefined) (Array.isArray(models) ? models : [models]).forEach(v => query.append('models', v));
1649
1829
  const qs = query.toString();
1650
1830
  if (qs) path += '?' + qs;
1651
- const body = stripUndef$3({
1831
+ const body = stripUndef$4({
1652
1832
  name: name,
1653
1833
  private: private_,
1654
1834
  type: type,
@@ -1718,7 +1898,7 @@ class Projects {
1718
1898
  async updateProject(projectId, { private: private_, type, description, directory, name, thumbnail } = {}) {
1719
1899
  this._ctx.requireTokens();
1720
1900
  const path = `/api/v1/projects/${encodeURIComponent(projectId)}`;
1721
- const body = stripUndef$3({
1901
+ const body = stripUndef$4({
1722
1902
  private: private_,
1723
1903
  type: type,
1724
1904
  description: description,
@@ -1797,7 +1977,7 @@ class Projects {
1797
1977
  async addProjectEvent(projectTableName, event, detail = undefined) {
1798
1978
  this._ctx.requireTokens();
1799
1979
  const path = `/api/v1/projects/${encodeURIComponent(projectTableName)}/event`;
1800
- const body = stripUndef$3({
1980
+ const body = stripUndef$4({
1801
1981
  event: event,
1802
1982
  detail: detail,
1803
1983
  });
@@ -1816,7 +1996,7 @@ class Projects {
1816
1996
  class Photoupload {
1817
1997
  constructor(ctx) { this._ctx = ctx; this._caches = {}; }
1818
1998
 
1819
- async uploadPhotoToMediaviz(fileContent, filePath, mimetype, companyId, userId, projectTableName, blur, colors, faceRecognition, imageClassification, imageComparison, imageDescribe, ocr, { clientSideId, format, size, sourceResolutionX, sourceResolutionY, dateTaken, latitude, longitude } = {}) {
1999
+ async uploadPhotoToMediaviz(fileContent, filePath, mimetype, companyId, userId, projectTableName, blur, colors, faceRecognition, imageClassification, imageComparison, imageDescribe, ocr, judgment, { clientSideId, format, size, sourceResolutionX, sourceResolutionY, dateTaken, latitude, longitude } = {}) {
1820
2000
  this._ctx.requireTokens();
1821
2001
  const baseUrl = this._ctx.requireHost('photoUpload');
1822
2002
  const headers = {
@@ -1826,7 +2006,7 @@ class Photoupload {
1826
2006
  const resp = await fetch(baseUrl + `/photo_upload`, {
1827
2007
  method: 'POST',
1828
2008
  headers,
1829
- body: JSON.stringify({ file_content: fileContent, file_path: filePath, mimetype, company_id: companyId, user_id: userId, project_table_name: projectTableName, blur, colors, face_recognition: faceRecognition, image_classification: imageClassification, image_comparison: imageComparison, image_describe: imageDescribe, ocr, client_side_id: clientSideId, format, size, source_resolution_x: sourceResolutionX, source_resolution_y: sourceResolutionY, date_taken: dateTaken, latitude, longitude }),
2009
+ body: JSON.stringify({ file_content: fileContent, file_path: filePath, mimetype, company_id: companyId, user_id: userId, project_table_name: projectTableName, blur, colors, face_recognition: faceRecognition, image_classification: imageClassification, image_comparison: imageComparison, image_describe: imageDescribe, ocr, judgment, client_side_id: clientSideId, format, size, source_resolution_x: sourceResolutionX, source_resolution_y: sourceResolutionY, date_taken: dateTaken, latitude, longitude }),
1830
2010
  });
1831
2011
  return handleResponse(resp);
1832
2012
  }
@@ -1842,12 +2022,14 @@ class Photoupload {
1842
2022
  this._caches['_get_template'].set(_cacheKey_get_template, template);
1843
2023
  }
1844
2024
 
1845
- const upload_result = await this.uploadPhotoToMediaviz(photo.fileContent, photo.filePath, photo.mimetype, companyId, userId, projectTableName, (((template?.body?.['blur'] ?? template?.headers?.['x-blur']) === true || (template?.body?.['blur'] ?? template?.headers?.['x-blur']) === 'true') ? 'true' : undefined), (((template?.body?.['colors'] ?? template?.headers?.['x-colors']) === true || (template?.body?.['colors'] ?? template?.headers?.['x-colors']) === 'true') ? 'true' : undefined), (((template?.body?.['face_recognition'] ?? template?.headers?.['x-face-recognition']) === true || (template?.body?.['face_recognition'] ?? template?.headers?.['x-face-recognition']) === 'true') ? 'true' : undefined), (((template?.body?.['image_classification'] ?? template?.headers?.['x-image-classification']) === true || (template?.body?.['image_classification'] ?? template?.headers?.['x-image-classification']) === 'true') ? 'true' : undefined), (((template?.body?.['image_comparison'] ?? template?.headers?.['x-image-comparison']) === true || (template?.body?.['image_comparison'] ?? template?.headers?.['x-image-comparison']) === 'true') ? 'true' : undefined), (((template?.body?.['image_describe'] ?? template?.headers?.['x-image-describe']) === true || (template?.body?.['image_describe'] ?? template?.headers?.['x-image-describe']) === 'true') ? 'true' : undefined), (((template?.body?.['ocr'] ?? template?.headers?.['x-ocr']) === true || (template?.body?.['ocr'] ?? template?.headers?.['x-ocr']) === 'true') ? 'true' : undefined), { clientSideId: photo.clientSideId, format: photo.format, size: photo.size, sourceResolutionX: photo.sourceResolutionX, sourceResolutionY: photo.sourceResolutionY, dateTaken: photo.dateTaken, latitude: photo.latitude, longitude: photo.longitude });
2025
+ const upload_result = await this.uploadPhotoToMediaviz(photo.fileContent, photo.filePath, photo.mimetype, companyId, userId, projectTableName, (((template?.body?.['blur'] ?? template?.headers?.['x-blur']) === true || (template?.body?.['blur'] ?? template?.headers?.['x-blur']) === 'true') ? 'true' : undefined), (((template?.body?.['colors'] ?? template?.headers?.['x-colors']) === true || (template?.body?.['colors'] ?? template?.headers?.['x-colors']) === 'true') ? 'true' : undefined), (((template?.body?.['face_recognition'] ?? template?.headers?.['x-face-recognition']) === true || (template?.body?.['face_recognition'] ?? template?.headers?.['x-face-recognition']) === 'true') ? 'true' : undefined), (((template?.body?.['image_classification'] ?? template?.headers?.['x-image-classification']) === true || (template?.body?.['image_classification'] ?? template?.headers?.['x-image-classification']) === 'true') ? 'true' : undefined), (((template?.body?.['image_comparison'] ?? template?.headers?.['x-image-comparison']) === true || (template?.body?.['image_comparison'] ?? template?.headers?.['x-image-comparison']) === 'true') ? 'true' : undefined), (((template?.body?.['image_describe'] ?? template?.headers?.['x-image-describe']) === true || (template?.body?.['image_describe'] ?? template?.headers?.['x-image-describe']) === 'true') ? 'true' : undefined), (((template?.body?.['ocr'] ?? template?.headers?.['x-ocr']) === true || (template?.body?.['ocr'] ?? template?.headers?.['x-ocr']) === 'true') ? 'true' : undefined), (((template?.body?.['judgment'] ?? template?.headers?.['x-judgment']) === true || (template?.body?.['judgment'] ?? template?.headers?.['x-judgment']) === 'true') ? 'true' : undefined), { clientSideId: photo.clientSideId, format: photo.format, size: photo.size, sourceResolutionX: photo.sourceResolutionX, sourceResolutionY: photo.sourceResolutionY, dateTaken: photo.dateTaken, latitude: photo.latitude, longitude: photo.longitude });
1846
2026
 
1847
2027
  return upload_result;
1848
2028
  }
1849
2029
  }
1850
2030
 
2031
+ function stripUndef$3(o) { const r = {}; for (const k in o) if (o[k] !== undefined) r[k] = o[k]; return r; }
2032
+
1851
2033
  class Photos {
1852
2034
  constructor(ctx) { this._ctx = ctx; }
1853
2035
 
@@ -1909,16 +2091,16 @@ class Photos {
1909
2091
  return data;
1910
2092
  }
1911
2093
 
1912
- async updatePhotoInProject({ tableName, photoId, photoData } = {}) {
2094
+ async updatePhotoInProject(tableName, photoId, { filePath, title, description, tags } = {}) {
1913
2095
  this._ctx.requireTokens();
1914
- let path = `/api/v1/photos_update`;
1915
- const query = new URLSearchParams();
1916
- if (tableName !== undefined) (Array.isArray(tableName) ? tableName : [tableName]).forEach(v => query.append('table_name', v));
1917
- if (photoId !== undefined) (Array.isArray(photoId) ? photoId : [photoId]).forEach(v => query.append('photo_id', v));
1918
- if (photoData !== undefined) (Array.isArray(photoData) ? photoData : [photoData]).forEach(v => query.append('photo_data', v));
1919
- const qs = query.toString();
1920
- if (qs) path += '?' + qs;
1921
- const { data } = await this._ctx.client.request(path, 'PUT', this._ctx.accessToken, this._ctx.refreshToken);
2096
+ const path = `/api/v1/photos_update/${encodeURIComponent(tableName)}/id/${encodeURIComponent(photoId)}`;
2097
+ const body = stripUndef$3({
2098
+ file_path: filePath,
2099
+ title: title,
2100
+ description: description,
2101
+ tags: tags,
2102
+ });
2103
+ const { data } = await this._ctx.client.request(path, 'PUT', this._ctx.accessToken, this._ctx.refreshToken, body);
1922
2104
  return data;
1923
2105
  }
1924
2106
 
@@ -2394,6 +2576,7 @@ exports.ValidationError = ValidationError;
2394
2576
  exports.WEBHOOK_MODEL_COLUMNS = WEBHOOK_MODEL_COLUMNS;
2395
2577
  exports.WEBHOOK_OUTCOME_MODELS = WEBHOOK_OUTCOME_MODELS;
2396
2578
  exports.WebhookConsumer = WebhookConsumer;
2579
+ exports.configureCrypto = configureCrypto;
2397
2580
  exports.handleResponse = handleResponse;
2398
2581
  exports.selectResultColumns = selectResultColumns;
2399
2582
  exports.signWebhookPayload = signWebhookPayload;
package/dist/sdk.d.cts CHANGED
@@ -268,6 +268,15 @@ export interface PhotoDisplay {
268
268
  hue_values?: number[];
269
269
  light_values?: number[];
270
270
  saturation_values?: number[];
271
+ aesthetic_appeal?: number;
272
+ lighting?: number;
273
+ subject_significance?: number;
274
+ emotional_intensity?: number;
275
+ positive_emotion?: number;
276
+ universal_relatability?: number;
277
+ memorability?: number;
278
+ composition?: number;
279
+ judgment_overall_score?: number;
271
280
  user_id: number;
272
281
  company_id: number;
273
282
  id: number;
@@ -356,6 +365,7 @@ export interface ProjectRunDisplay {
356
365
  image_comparison_model?: boolean;
357
366
  image_describe_model?: boolean;
358
367
  ocr_model?: boolean;
368
+ judgment_model?: boolean;
359
369
  similarity_model?: boolean;
360
370
  personhood_model?: boolean;
361
371
  evidence_model?: boolean;
@@ -431,7 +441,7 @@ export class Admin {
431
441
 
432
442
  export class Company {
433
443
  getCompanyById(companyId: number): Promise<CompanyDisplay>;
434
- confirmCompanyCreditBalance(companyId: number, options?: { photoCount?: number | number[], modelsList?: string[] | string[][] }): Promise<CreditBalanceOutput>;
444
+ confirmCompanyCreditBalance(companyId: number, options?: { photoCount?: number | number[], modelsList?: any }): Promise<CreditBalanceOutput>;
435
445
  }
436
446
 
437
447
  export class CuratedAlbums {
@@ -522,7 +532,7 @@ export class Person {
522
532
  }
523
533
 
524
534
  export class Photoupload {
525
- uploadPhotoToMediaviz(fileContent: string, filePath: string, mimetype: string, companyId: string, userId: string, projectTableName: string, blur: boolean | string, colors: boolean | string, faceRecognition: boolean | string, imageClassification: boolean | string, imageComparison: boolean | string, imageDescribe: boolean | string, ocr: boolean | string, options?: { clientSideId?: string, format?: string, size?: string, sourceResolutionX?: number | string, sourceResolutionY?: number | string, dateTaken?: string, latitude?: number | string, longitude?: number | string }): Promise<any>;
535
+ uploadPhotoToMediaviz(fileContent: string, filePath: string, mimetype: string, companyId: string, userId: string, projectTableName: string, blur: boolean | string, colors: boolean | string, faceRecognition: boolean | string, imageClassification: boolean | string, imageComparison: boolean | string, imageDescribe: boolean | string, ocr: boolean | string, judgment: boolean | string, options?: { clientSideId?: string, format?: string, size?: string, sourceResolutionX?: number | string, sourceResolutionY?: number | string, dateTaken?: string, latitude?: number | string, longitude?: number | string }): Promise<any>;
526
536
  uploadPhoto(companyId: string, userId: string, projectTableName: string, photo: Record<string, any>): Promise<any>;
527
537
  }
528
538
 
@@ -532,7 +542,7 @@ export class Photos {
532
542
  getProjectPhotoIdsByTableName(tableName: string, options?: { ascOrDesc?: string | string[], lastId?: number | number[], limit?: number | number[], includeAll?: boolean | boolean[], startDate?: string | string[], endDate?: string | string[], noDateTaken?: boolean | boolean[] }): Promise<any>;
533
543
  getRankedProjectPhotoIdsByTableName(tableName: string, options?: { ascOrDesc?: string | string[], lastId?: number | number[], limit?: number | number[], startDate?: string | string[], endDate?: string | string[], noDateTaken?: boolean | boolean[] }): Promise<Record<string, any>>;
534
544
  getProjectMonthYearsWithPhotos(tableName: string): Promise<any>;
535
- updatePhotoInProject(options?: { tableName?: string | string[], photoId?: number | number[], photoData?: Record<string, any> | Record<string, any>[] }): Promise<PhotoDisplay>;
545
+ updatePhotoInProject(tableName: string, photoId: number, body?: { filePath?: string, title?: string, description?: string, tags?: string[] }): Promise<PhotoDisplay>;
536
546
  updatePhotoRanking(tableName: string, photoId: number, newCategory: string): Promise<Record<string, any>>;
537
547
  deletePhotoFromProject(tableName: string, options?: { photoIds?: any }): Promise<Record<string, any>>;
538
548
  }
@@ -547,7 +557,7 @@ export class Projects {
547
557
  getProjectById(projectId: string): Promise<ProjectRunDisplay>;
548
558
  getProjectByDirectory(directory: string): Promise<ProjectRunDisplay>;
549
559
  updateProject(projectId: string, body?: { private?: boolean, type?: number, description?: string, directory?: string, name?: string, thumbnail?: string }): Promise<ProjectRunDisplay>;
550
- updateProjectPhotoCount(tableName: string, options?: { filesFailedCount?: number | number[] }): Promise<any>;
560
+ updateProjectPhotoCount(tableName: string, options?: { filesFailedCount?: number | number[] }): Promise<Record<string, any>>;
551
561
  updateProjectCreateUploadReport(tableName: string, options?: { filesFailedCount?: number | number[] }): Promise<any>;
552
562
  requestProjectSimilarityQueue(projectTableName: string, level: string): Promise<Record<string, any>>;
553
563
  requestProjectEvidenceQueue(projectTableName: string): Promise<Record<string, any>>;