@peable.to/sdk 0.2.1 → 0.2.3-oxy-one.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/dist/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WEBHOOK_SIGNATURE_HEADER = exports.PeableSignatureVerificationError = exports.PeableApiError = exports.PeablePermissionError = exports.PeableInvalidRequestError = exports.PeableAuthenticationError = exports.PeableError = exports.DEFAULT_OXY_API_URL = exports.DEFAULT_GATEWAY_BASE_URL = exports.Peable = void 0;
3
+ exports.WebhooksResource = exports.WEBHOOK_SIGNATURE_HEADER = exports.PeableSignatureVerificationError = exports.PeableApiError = exports.PeablePermissionError = exports.PeableInvalidRequestError = exports.PeableAuthenticationError = exports.PeableError = exports.DEFAULT_OXY_API_URL = exports.DEFAULT_GATEWAY_BASE_URL = exports.Peable = void 0;
4
4
  const billing_1 = require("./resources/billing");
5
5
  // Server entry (`@peable.to/sdk`) — the merchant-authed SDK. Configured with a
6
6
  // confidential `ApplicationCredential` (`{publicKey, secret}`); mints and
@@ -66,3 +66,4 @@ Object.defineProperty(exports, "PeableApiError", { enumerable: true, get: functi
66
66
  Object.defineProperty(exports, "PeableSignatureVerificationError", { enumerable: true, get: function () { return errors_1.PeableSignatureVerificationError; } });
67
67
  var webhooks_2 = require("./resources/webhooks");
68
68
  Object.defineProperty(exports, "WEBHOOK_SIGNATURE_HEADER", { enumerable: true, get: function () { return webhooks_2.WEBHOOK_SIGNATURE_HEADER; } });
69
+ Object.defineProperty(exports, "WebhooksResource", { enumerable: true, get: function () { return webhooks_2.WebhooksResource; } });
@@ -15,6 +15,9 @@ class BillingResource {
15
15
  createPortalSession(params, options) {
16
16
  return this.client.request('POST', '/v1/billing/portal_sessions', { body: params, idempotencyKey: options.idempotencyKey });
17
17
  }
18
+ retrieveCheckout(ref) { return this.client.request('GET', `/v1/billing/checkout_sessions/${encodeURIComponent(ref)}`); }
19
+ retrievePaidInvoice(subscriptionRef, invoiceRef) { return this.client.request('GET', `/v1/billing/subscriptions/${encodeURIComponent(subscriptionRef)}/paid_invoices/${encodeURIComponent(invoiceRef)}`); }
20
+ retrieveInvoiceState(subscriptionRef, invoiceRef) { return this.client.request('GET', `/v1/billing/subscriptions/${encodeURIComponent(subscriptionRef)}/invoice_states/${encodeURIComponent(invoiceRef)}`); }
18
21
  retrieveSubscription(ref) {
19
22
  return this.client.request('GET', `/v1/billing/subscriptions/${encodeURIComponent(ref)}`);
20
23
  }
@@ -7,13 +7,22 @@ const errors_1 = require("../core/errors");
7
7
  exports.WEBHOOK_SIGNATURE_HEADER = 'Peable-Signature';
8
8
  /** Default replay-tolerance window, matching the backend's own tests/usage. */
9
9
  const DEFAULT_TOLERANCE_SEC = 300;
10
- const WEBHOOK_EVENT_TYPES = [
11
- 'payment_intent.confirming',
12
- 'payment_intent.settled',
13
- 'payment_intent.failed',
14
- 'payment_intent.rejected',
15
- 'payment_intent.expired',
16
- ];
10
+ // Exhaustive against the published union: adding a backend event makes this
11
+ // fail compilation until the SDK accepts it. Own-key lookup excludes prototype
12
+ // names supplied by an untrusted, even correctly signed, payload.
13
+ const WEBHOOK_EVENT_TYPES = {
14
+ 'payment_intent.confirming': true,
15
+ 'payment_intent.settled': true,
16
+ 'payment_intent.failed': true,
17
+ 'payment_intent.rejected': true,
18
+ 'payment_intent.expired': true,
19
+ 'payment_intent.refunded': true,
20
+ 'payment_intent.partially_refunded': true,
21
+ 'payment_intent.disputed': true,
22
+ 'payment_intent.dispute_closed': true,
23
+ 'billing.observation.updated': true,
24
+ 'connected_account.updated': true,
25
+ };
17
26
  /**
18
27
  * Structural guard for the parsed payload — the signature already proves the
19
28
  * bytes were produced by `signWebhook` on the SAME secret, but a caller could
@@ -24,14 +33,24 @@ function isWebhookEventShape(value) {
24
33
  if (typeof value !== 'object' || value === null)
25
34
  return false;
26
35
  const candidate = value;
27
- return (typeof candidate.id === 'string' &&
36
+ const valid = (typeof candidate.id === 'string' &&
28
37
  candidate.object === 'event' &&
29
38
  typeof candidate.type === 'string' &&
30
- WEBHOOK_EVENT_TYPES.includes(candidate.type) &&
39
+ Object.prototype.hasOwnProperty.call(WEBHOOK_EVENT_TYPES, candidate.type) &&
31
40
  typeof candidate.created === 'string' &&
32
41
  typeof candidate.data === 'object' &&
33
42
  candidate.data !== null &&
34
43
  'object' in candidate.data);
44
+ if (!valid)
45
+ return false;
46
+ if (candidate.type === 'billing.observation.updated') {
47
+ const data = candidate.data?.object;
48
+ if (!data || typeof data !== 'object')
49
+ return false;
50
+ const v = data;
51
+ return v.object === 'billing_observation' && (v.resourceKind === 'subscription' || v.resourceKind === 'invoice') && typeof v.resourceId === 'string' && v.resourceId.length > 0 && typeof v.revision === 'number' && Number.isSafeInteger(v.revision) && v.revision > 0 && typeof v.observedAt === 'string' && Number.isFinite(Date.parse(v.observedAt)) && Object.keys(v).every(k => ['object', 'resourceKind', 'resourceId', 'revision', 'observedAt'].includes(k));
52
+ }
53
+ return true;
35
54
  }
36
55
  class WebhooksResource {
37
56
  /**
package/dist/esm/index.js CHANGED
@@ -52,4 +52,4 @@ export class Peable {
52
52
  }
53
53
  export { DEFAULT_GATEWAY_BASE_URL, DEFAULT_OXY_API_URL } from './core/config.js';
54
54
  export { PeableError, PeableAuthenticationError, PeableInvalidRequestError, PeablePermissionError, PeableApiError, PeableSignatureVerificationError, } from './core/errors.js';
55
- export { WEBHOOK_SIGNATURE_HEADER } from './resources/webhooks.js';
55
+ export { WEBHOOK_SIGNATURE_HEADER, WebhooksResource } from './resources/webhooks.js';
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -12,6 +12,9 @@ export class BillingResource {
12
12
  createPortalSession(params, options) {
13
13
  return this.client.request('POST', '/v1/billing/portal_sessions', { body: params, idempotencyKey: options.idempotencyKey });
14
14
  }
15
+ retrieveCheckout(ref) { return this.client.request('GET', `/v1/billing/checkout_sessions/${encodeURIComponent(ref)}`); }
16
+ retrievePaidInvoice(subscriptionRef, invoiceRef) { return this.client.request('GET', `/v1/billing/subscriptions/${encodeURIComponent(subscriptionRef)}/paid_invoices/${encodeURIComponent(invoiceRef)}`); }
17
+ retrieveInvoiceState(subscriptionRef, invoiceRef) { return this.client.request('GET', `/v1/billing/subscriptions/${encodeURIComponent(subscriptionRef)}/invoice_states/${encodeURIComponent(invoiceRef)}`); }
15
18
  retrieveSubscription(ref) {
16
19
  return this.client.request('GET', `/v1/billing/subscriptions/${encodeURIComponent(ref)}`);
17
20
  }
@@ -4,13 +4,22 @@ import { PeableSignatureVerificationError } from '../core/errors.js';
4
4
  export const WEBHOOK_SIGNATURE_HEADER = 'Peable-Signature';
5
5
  /** Default replay-tolerance window, matching the backend's own tests/usage. */
6
6
  const DEFAULT_TOLERANCE_SEC = 300;
7
- const WEBHOOK_EVENT_TYPES = [
8
- 'payment_intent.confirming',
9
- 'payment_intent.settled',
10
- 'payment_intent.failed',
11
- 'payment_intent.rejected',
12
- 'payment_intent.expired',
13
- ];
7
+ // Exhaustive against the published union: adding a backend event makes this
8
+ // fail compilation until the SDK accepts it. Own-key lookup excludes prototype
9
+ // names supplied by an untrusted, even correctly signed, payload.
10
+ const WEBHOOK_EVENT_TYPES = {
11
+ 'payment_intent.confirming': true,
12
+ 'payment_intent.settled': true,
13
+ 'payment_intent.failed': true,
14
+ 'payment_intent.rejected': true,
15
+ 'payment_intent.expired': true,
16
+ 'payment_intent.refunded': true,
17
+ 'payment_intent.partially_refunded': true,
18
+ 'payment_intent.disputed': true,
19
+ 'payment_intent.dispute_closed': true,
20
+ 'billing.observation.updated': true,
21
+ 'connected_account.updated': true,
22
+ };
14
23
  /**
15
24
  * Structural guard for the parsed payload — the signature already proves the
16
25
  * bytes were produced by `signWebhook` on the SAME secret, but a caller could
@@ -21,14 +30,24 @@ function isWebhookEventShape(value) {
21
30
  if (typeof value !== 'object' || value === null)
22
31
  return false;
23
32
  const candidate = value;
24
- return (typeof candidate.id === 'string' &&
33
+ const valid = (typeof candidate.id === 'string' &&
25
34
  candidate.object === 'event' &&
26
35
  typeof candidate.type === 'string' &&
27
- WEBHOOK_EVENT_TYPES.includes(candidate.type) &&
36
+ Object.prototype.hasOwnProperty.call(WEBHOOK_EVENT_TYPES, candidate.type) &&
28
37
  typeof candidate.created === 'string' &&
29
38
  typeof candidate.data === 'object' &&
30
39
  candidate.data !== null &&
31
40
  'object' in candidate.data);
41
+ if (!valid)
42
+ return false;
43
+ if (candidate.type === 'billing.observation.updated') {
44
+ const data = candidate.data?.object;
45
+ if (!data || typeof data !== 'object')
46
+ return false;
47
+ const v = data;
48
+ return v.object === 'billing_observation' && (v.resourceKind === 'subscription' || v.resourceKind === 'invoice') && typeof v.resourceId === 'string' && v.resourceId.length > 0 && typeof v.revision === 'number' && Number.isSafeInteger(v.revision) && v.revision > 0 && typeof v.observedAt === 'string' && Number.isFinite(Date.parse(v.observedAt)) && Object.keys(v).every(k => ['object', 'resourceKind', 'resourceId', 'revision', 'observedAt'].includes(k));
49
+ }
50
+ return true;
32
51
  }
33
52
  export class WebhooksResource {
34
53
  /**
@@ -1,6 +1,6 @@
1
1
  import { BillingResource } from './resources/billing';
2
2
  export type { BillingRequestOptions } from './resources/billing';
3
- export type { BillingCustomer, BillingHostedSession, BillingSubscription, CreateBillingCheckoutParams, CreateBillingPortalParams, EnsureBillingCustomerParams } from '@peable.to/shared-types';
3
+ export type { BillingObservation, BillingCustomer, BillingHostedSession, BillingCheckoutSession, BillingCheckoutObservation, BillingPaidInvoice, BillingInvoiceState, BillingSubscription, CreateBillingCheckoutParams, CreateBillingPortalParams, EnsureBillingCustomerParams } from '@peable.to/shared-types';
4
4
  import { type PeableConfig } from './core/config';
5
5
  import { PaymentIntentsResource } from './resources/paymentIntents';
6
6
  import { PaymentLinksResource } from './resources/paymentLinks';
@@ -57,5 +57,5 @@ export type { DisputeEvidenceParams, DisputeList, RegisterMerchantParams, Update
57
57
  export type { CreateRefundParams, RefundList } from './resources/refunds';
58
58
  export type { CreateTransferParams, ReverseTransferParams, TransferList, } from './resources/transfers';
59
59
  export type { PaymentLinkListParams, PaymentLinkList, UpdatePaymentLinkParams, } from './resources/paymentLinks';
60
- export { WEBHOOK_SIGNATURE_HEADER } from './resources/webhooks';
60
+ export { WEBHOOK_SIGNATURE_HEADER, WebhooksResource } from './resources/webhooks';
61
61
  export type { ConstructEventOptions } from './resources/webhooks';
@@ -1,4 +1,4 @@
1
- import type { BillingCustomer, BillingHostedSession, BillingSubscription, CreateBillingCheckoutParams, CreateBillingPortalParams, EnsureBillingCustomerParams } from '@peable.to/shared-types';
1
+ import type { BillingCustomer, BillingHostedSession, BillingCheckoutSession, BillingCheckoutObservation, BillingPaidInvoice, BillingInvoiceState, BillingSubscription, CreateBillingCheckoutParams, CreateBillingPortalParams, EnsureBillingCustomerParams } from '@peable.to/shared-types';
2
2
  import type { RestClient } from '../core/client';
3
3
  export interface BillingRequestOptions {
4
4
  idempotencyKey: string;
@@ -8,8 +8,11 @@ export declare class BillingResource {
8
8
  private readonly client;
9
9
  constructor(client: RestClient);
10
10
  ensureCustomer(params: EnsureBillingCustomerParams, options: BillingRequestOptions): Promise<BillingCustomer>;
11
- createCheckoutSession(params: CreateBillingCheckoutParams, options: BillingRequestOptions): Promise<BillingHostedSession>;
11
+ createCheckoutSession(params: CreateBillingCheckoutParams, options: BillingRequestOptions): Promise<BillingCheckoutSession>;
12
12
  createPortalSession(params: CreateBillingPortalParams, options: BillingRequestOptions): Promise<BillingHostedSession>;
13
+ retrieveCheckout(ref: string): Promise<BillingCheckoutObservation>;
14
+ retrievePaidInvoice(subscriptionRef: string, invoiceRef: string): Promise<BillingPaidInvoice>;
15
+ retrieveInvoiceState(subscriptionRef: string, invoiceRef: string): Promise<BillingInvoiceState>;
13
16
  retrieveSubscription(ref: string): Promise<BillingSubscription>;
14
17
  cancelAtPeriodEnd(ref: string, options: BillingRequestOptions): Promise<BillingSubscription>;
15
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peable.to/sdk",
3
- "version": "0.2.1",
3
+ "version": "0.2.3-oxy-one.0",
4
4
  "description": "Peable SDK — a Stripe-ergonomics TypeScript client over the Peable Gateway REST + realtime contract. Server entry (`@peable.to/sdk`) mints Oxy service tokens from an ApplicationCredential and exposes paymentIntents/paymentLinks/checkout.sessions/webhooks; browser entry (`@peable.to/sdk/checkout`) is the anonymous payer-side client core.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -8,7 +8,9 @@
8
8
  "source": "src/index.ts",
9
9
  "sideEffects": false,
10
10
  "publishConfig": {
11
- "access": "public"
11
+ "access": "public",
12
+ "registry": "https://registry.npmjs.org/",
13
+ "tag": "oxy-one"
12
14
  },
13
15
  "exports": {
14
16
  ".": {
@@ -71,7 +73,7 @@
71
73
  "prepublishOnly": "bun run clean && bun run build"
72
74
  },
73
75
  "dependencies": {
74
- "@peable.to/shared-types": "^0.3.0",
76
+ "@peable.to/shared-types": "0.3.1-oxy-one.0",
75
77
  "qrcode-generator": "^2.0.4",
76
78
  "socket.io-client": "^4.8.3"
77
79
  },