@moveris/shared 3.4.0 → 3.6.1

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 CHANGED
@@ -550,7 +550,7 @@ const status = getStatusMessage('capturing', DEFAULT_LOCALE);
550
550
  | `camera_angle_low` | "Raise camera to eye level" | Camera below face (Y < 0.3) |
551
551
  | `camera_angle_high` | "Lower camera to eye level" | Camera above face (Y > 0.7) |
552
552
  | `camera_tilted` | "Hold camera level" | Device tilt > 15° (via transformation matrix, falls back to eye-corner landmarks) |
553
- | `flat_lighting` | "Find better lighting" | Face-region dynamic range < 180 L-units — soft warning, capture continues |
553
+ | `flat_lighting` | "Find better lighting" | Face-region dynamic range < 60 L-units — soft warning, capture continues |
554
554
 
555
555
  ---
556
556
 
@@ -683,7 +683,7 @@ const angleResult = detectCameraAngle(landmarks); // requires ≥153 landmarks
683
683
  // Pass pre-sampled face-region pixels — use sampleFaceRegionPixels() in @moveris/react
684
684
  import { analyzeDynamicRange } from '@moveris/shared';
685
685
  const drResult = analyzeDynamicRange(rgbaPixels);
686
- // { range: number (max L* − min L*), isLow: boolean (< 180) }
686
+ // { range: number (max L* − min L*), isLow: boolean (< 60) }
687
687
  // Soft warning — do not use as a hard capture gate
688
688
  ```
689
689
 
package/dist/index.d.mts CHANGED
@@ -161,8 +161,11 @@ interface HealthResponse {
161
161
  dependencies?: Record<string, unknown>;
162
162
  }
163
163
  interface ErrorResponse {
164
- error: string;
164
+ errors?: Array<Record<string, string[]>>;
165
165
  message: string;
166
+ success?: false;
167
+ data?: null;
168
+ error?: string;
166
169
  required?: number;
167
170
  received?: number;
168
171
  }
@@ -341,7 +344,7 @@ declare const MAX_FACE_RATIO = 0.7;
341
344
  declare const FACE_CROP_OUTPUT_SIZE = 224;
342
345
  declare const MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
343
346
  declare const TARGET_FACE_PERCENTAGE_IN_CROP = 0.33;
344
- declare const DYNAMIC_RANGE_WARNING_THRESHOLD = 180;
347
+ declare const DYNAMIC_RANGE_WARNING_THRESHOLD = 60;
345
348
  interface DynamicRangeAnalysis {
346
349
  range: number;
347
350
  isLow: boolean;
package/dist/index.d.ts CHANGED
@@ -161,8 +161,11 @@ interface HealthResponse {
161
161
  dependencies?: Record<string, unknown>;
162
162
  }
163
163
  interface ErrorResponse {
164
- error: string;
164
+ errors?: Array<Record<string, string[]>>;
165
165
  message: string;
166
+ success?: false;
167
+ data?: null;
168
+ error?: string;
166
169
  required?: number;
167
170
  received?: number;
168
171
  }
@@ -341,7 +344,7 @@ declare const MAX_FACE_RATIO = 0.7;
341
344
  declare const FACE_CROP_OUTPUT_SIZE = 224;
342
345
  declare const MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
343
346
  declare const TARGET_FACE_PERCENTAGE_IN_CROP = 0.33;
344
- declare const DYNAMIC_RANGE_WARNING_THRESHOLD = 180;
347
+ declare const DYNAMIC_RANGE_WARNING_THRESHOLD = 60;
345
348
  interface DynamicRangeAnalysis {
346
349
  range: number;
347
350
  isLow: boolean;
package/dist/index.js CHANGED
@@ -342,7 +342,8 @@ var LivenessClient = class _LivenessClient {
342
342
  if (!response.ok) {
343
343
  throw await this.parseErrorResponse(response);
344
344
  }
345
- const data = await response.json();
345
+ const json = await response.json();
346
+ const data = "data" in json && "success" in json ? json.data : json;
346
347
  return { data, headers: response.headers };
347
348
  } catch (error) {
348
349
  clearTimeout(timeoutId);
@@ -362,11 +363,14 @@ var LivenessClient = class _LivenessClient {
362
363
  /**
363
364
  * Parse an error response body, handling both JSON and non-JSON bodies.
364
365
  *
365
- * The backend sometimes wraps the real error in a generic envelope:
366
+ * Handles the new v2 envelope error format:
367
+ * ```json
368
+ * { "data": null, "success": false, "message": "...", "errors": [{ "error_code": ["detail"] }] }
369
+ * ```
370
+ * Falls back to the legacy format:
366
371
  * ```json
367
372
  * { "error": "http_error", "message": "{'error': 'session_expired', ...}" }
368
373
  * ```
369
- * This method unwraps such envelopes to extract the real error code.
370
374
  */
371
375
  async parseErrorResponse(response) {
372
376
  const status = response.status;
@@ -377,16 +381,29 @@ var LivenessClient = class _LivenessClient {
377
381
  return new LivenessApiError(`Request failed with status ${status}`, "server_error", status);
378
382
  }
379
383
  try {
380
- const data = JSON.parse(body);
381
- if (data.error) {
382
- const realCode = _LivenessClient.unwrapErrorCode(data.error, data.message);
383
- const realMessage = _LivenessClient.unwrapErrorMessage(data.message);
384
+ const json = JSON.parse(body);
385
+ if (Array.isArray(json.errors) && json.errors.length > 0) {
386
+ const errorEntry = json.errors[0];
387
+ if (errorEntry) {
388
+ const errorCode = Object.keys(errorEntry)[0] ?? "server_error";
389
+ const msgs = errorEntry[errorCode];
390
+ const errorMessage = Array.isArray(msgs) && msgs.length > 0 ? msgs[0] : void 0;
391
+ return new LivenessApiError(
392
+ errorMessage ?? json.message ?? `Request failed (${errorCode})`,
393
+ errorCode,
394
+ status
395
+ );
396
+ }
397
+ }
398
+ if (json.error) {
399
+ const realCode = _LivenessClient.unwrapErrorCode(json.error, json.message);
400
+ const realMessage = _LivenessClient.unwrapErrorMessage(json.message);
384
401
  return new LivenessApiError(
385
402
  realMessage ?? `Request failed (${realCode})`,
386
403
  realCode,
387
404
  status,
388
- data.required,
389
- data.received
405
+ json.required,
406
+ json.received
390
407
  );
391
408
  }
392
409
  } catch {
@@ -1657,7 +1674,7 @@ var MAX_FACE_RATIO = 0.7;
1657
1674
  var FACE_CROP_OUTPUT_SIZE = 224;
1658
1675
  var MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
1659
1676
  var TARGET_FACE_PERCENTAGE_IN_CROP = 0.33;
1660
- var DYNAMIC_RANGE_WARNING_THRESHOLD = 180;
1677
+ var DYNAMIC_RANGE_WARNING_THRESHOLD = 60;
1661
1678
  function srgbToLinear(c) {
1662
1679
  const n = c / 255;
1663
1680
  return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
package/dist/index.mjs CHANGED
@@ -198,7 +198,8 @@ var LivenessClient = class _LivenessClient {
198
198
  if (!response.ok) {
199
199
  throw await this.parseErrorResponse(response);
200
200
  }
201
- const data = await response.json();
201
+ const json = await response.json();
202
+ const data = "data" in json && "success" in json ? json.data : json;
202
203
  return { data, headers: response.headers };
203
204
  } catch (error) {
204
205
  clearTimeout(timeoutId);
@@ -218,11 +219,14 @@ var LivenessClient = class _LivenessClient {
218
219
  /**
219
220
  * Parse an error response body, handling both JSON and non-JSON bodies.
220
221
  *
221
- * The backend sometimes wraps the real error in a generic envelope:
222
+ * Handles the new v2 envelope error format:
223
+ * ```json
224
+ * { "data": null, "success": false, "message": "...", "errors": [{ "error_code": ["detail"] }] }
225
+ * ```
226
+ * Falls back to the legacy format:
222
227
  * ```json
223
228
  * { "error": "http_error", "message": "{'error': 'session_expired', ...}" }
224
229
  * ```
225
- * This method unwraps such envelopes to extract the real error code.
226
230
  */
227
231
  async parseErrorResponse(response) {
228
232
  const status = response.status;
@@ -233,16 +237,29 @@ var LivenessClient = class _LivenessClient {
233
237
  return new LivenessApiError(`Request failed with status ${status}`, "server_error", status);
234
238
  }
235
239
  try {
236
- const data = JSON.parse(body);
237
- if (data.error) {
238
- const realCode = _LivenessClient.unwrapErrorCode(data.error, data.message);
239
- const realMessage = _LivenessClient.unwrapErrorMessage(data.message);
240
+ const json = JSON.parse(body);
241
+ if (Array.isArray(json.errors) && json.errors.length > 0) {
242
+ const errorEntry = json.errors[0];
243
+ if (errorEntry) {
244
+ const errorCode = Object.keys(errorEntry)[0] ?? "server_error";
245
+ const msgs = errorEntry[errorCode];
246
+ const errorMessage = Array.isArray(msgs) && msgs.length > 0 ? msgs[0] : void 0;
247
+ return new LivenessApiError(
248
+ errorMessage ?? json.message ?? `Request failed (${errorCode})`,
249
+ errorCode,
250
+ status
251
+ );
252
+ }
253
+ }
254
+ if (json.error) {
255
+ const realCode = _LivenessClient.unwrapErrorCode(json.error, json.message);
256
+ const realMessage = _LivenessClient.unwrapErrorMessage(json.message);
240
257
  return new LivenessApiError(
241
258
  realMessage ?? `Request failed (${realCode})`,
242
259
  realCode,
243
260
  status,
244
- data.required,
245
- data.received
261
+ json.required,
262
+ json.received
246
263
  );
247
264
  }
248
265
  } catch {
@@ -1513,7 +1530,7 @@ var MAX_FACE_RATIO = 0.7;
1513
1530
  var FACE_CROP_OUTPUT_SIZE = 224;
1514
1531
  var MAX_FACE_PERCENTAGE_IN_CROP = 0.45;
1515
1532
  var TARGET_FACE_PERCENTAGE_IN_CROP = 0.33;
1516
- var DYNAMIC_RANGE_WARNING_THRESHOLD = 180;
1533
+ var DYNAMIC_RANGE_WARNING_THRESHOLD = 60;
1517
1534
  function srgbToLinear(c) {
1518
1535
  const n = c / 255;
1519
1536
  return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moveris/shared",
3
- "version": "3.4.0",
3
+ "version": "3.6.1",
4
4
  "description": "Core business logic for Moveris Live SDK",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",