@zappyquote/sdk 0.1.0 → 0.1.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
@@ -4,7 +4,7 @@ The official JavaScript/TypeScript client for the Zappy API v1 - a thin wrapper
4
4
  (https://zappyquote.com/developers/). The server stays authoritative for pricing, caps, idempotency and ownership;
5
5
  this package only carries requests and maps the public error envelope into typed errors.
6
6
 
7
- Version 0.1.0 · contract `openapi-1.0.0@9dff9fdfbcd8c1bd` · Node 18+ · zero dependencies · types included · MIT
7
+ Version 0.1.1 · contract `openapi-1.0.0@9dff9fdfbcd8c1bd` · Node 18+ · zero dependencies · types included · MIT
8
8
 
9
9
  ```bash
10
10
  # official download (always available):
package/index.d.ts CHANGED
@@ -55,6 +55,8 @@ export class Zappy {
55
55
  export default Zappy;
56
56
 
57
57
  export function redact(s: string): string;
58
+ /** redact() applied to every string inside a value (objects, arrays). */
59
+ export declare function redactDeep<T = unknown>(v: T): T;
58
60
  export function newIdempotencyKey(prefix?: string): string;
59
61
  export function verifyWebhookSignature(secret: string, header: string, rawBody: string | Uint8Array, opts?: { now?: number; windowSeconds?: number }): boolean;
60
62
  export function pkcePair(): { verifier: string; challenge: string; method: 'S256' };
package/index.mjs CHANGED
@@ -14,14 +14,21 @@
14
14
  */
15
15
  import { createHash, randomBytes, timingSafeEqual, createHmac } from 'node:crypto';
16
16
 
17
- export const SDK_VERSION = '0.1.0';
17
+ export const SDK_VERSION = '0.1.1';
18
18
  /** sha256 prefix of the public_html/api/openapi.json this client was written against (see DEVELOPER_DISTRIBUTION.md). */
19
19
  export const CONTRACT = 'openapi-1.0.0@9dff9fdfbcd8c1bd';
20
20
  export const DEFAULT_BASE_URL = 'https://zappyquote.com/api/v1';
21
21
 
22
- const KEY_RE = /(zp_live_|zat_|zrt_|zcs_)[A-Za-z0-9_-]+/g; // no leading boundary: an embedded credential is still a credential
22
+ const KEY_RE = /(zp_live_|zat_|zrt_|zcs_|whsec_)[A-Za-z0-9_-]+/g; // no leading boundary: an embedded credential is still a credential
23
23
  /** Replace any Zappy credential shape in a string with a redacted marker. Used on every error message and log line. */
24
24
  export function redact(s) { return String(s).replace(KEY_RE, (m, p) => p + '…redacted'); }
25
+ /** redact() applied to every string inside a value (objects, arrays), depth-bounded - for error bodies and metadata (F6-SEC-001). */
26
+ export function redactDeep(v, depth = 0) {
27
+ if (typeof v === 'string') return redact(v);
28
+ if (v === null || typeof v !== 'object' || depth > 8) return (v !== null && typeof v === 'object') ? null : v;
29
+ if (Array.isArray(v)) return v.map(x => redactDeep(x, depth + 1));
30
+ const o = {}; for (const [k, x] of Object.entries(v)) o[redact(k)] = redactDeep(x, depth + 1); return o;
31
+ }
25
32
 
26
33
  /** A stable idempotency key for ONE intended operation. Keep it with the operation and reuse it to replay safely. */
27
34
  export function newIdempotencyKey(prefix = 'zq') {
@@ -32,8 +39,8 @@ export function newIdempotencyKey(prefix = 'zq') {
32
39
  export class ZappyError extends Error {
33
40
  constructor(message, { code = 'error', status = 0, requestId = null, rateLimit = null, retryAfter = null, body = null } = {}) {
34
41
  super(redact(message));
35
- this.name = 'ZappyError'; this.code = code; this.status = status; this.requestId = requestId;
36
- this.rateLimit = rateLimit; this.retryAfter = retryAfter; this.body = body;
42
+ this.name = 'ZappyError'; this.code = redact(code); this.status = status; this.requestId = requestId == null ? null : redact(requestId);
43
+ this.rateLimit = rateLimit; this.retryAfter = retryAfter; this.body = redactDeep(body); // F6-SEC-001: no credential survives in a serialized error
37
44
  }
38
45
  }
39
46
  export class ZappyAuthError extends ZappyError { constructor(m, o) { super(m, o); this.name = 'ZappyAuthError'; } }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zappyquote/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Official Zappy API client for JavaScript/TypeScript - a thin wrapper over the documented Zappy API v1.",
5
5
  "keywords": ["zappy", "ai", "image-generation", "api", "sdk"],
6
6
  "homepage": "https://zappyquote.com/developers/",