@skyporch/daykeeper-react-native 0.1.0 → 0.2.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/index.d.cts CHANGED
@@ -10,7 +10,12 @@ interface paths {
10
10
  path?: never;
11
11
  cookie?: never;
12
12
  };
13
- /** Get widget-safe customer identity */
13
+ /**
14
+ * Get widget-safe customer identity
15
+ * @description API-only inbox gateways authenticate the customer token and return `409`
16
+ * `{ "error": "widget_unavailable" }` before calling the conversation
17
+ * provider. Use a widget-enabled tenant gateway for this operation.
18
+ */
14
19
  get: operations["getCustomerIdentity"];
15
20
  put?: never;
16
21
  post?: never;
@@ -113,6 +118,10 @@ interface paths {
113
118
  * Claim a signed-out widget conversation after sign-in
114
119
  * @description The widget token proves possession of the anonymous thread. The gateway
115
120
  * refuses identified, foreign-tenant, or email-mismatched contacts.
121
+ *
122
+ * API-only inbox gateways authenticate the token and return `409`
123
+ * `{ "error": "widget_unavailable" }` before calling the conversation
124
+ * provider. Use a widget-enabled tenant gateway for this operation.
116
125
  */
117
126
  post: operations["claimAnonymousConversation"];
118
127
  delete?: never;
@@ -190,7 +199,7 @@ interface components {
190
199
  status: "open" | "pending" | "resolved" | "snoozed";
191
200
  createdAt: number | string | null;
192
201
  updatedAt: number | string | null;
193
- /** @description Chatwoot agent-side unread count; do not use for a customer badge. */
202
+ /** @description Agent-side unread count reported by the conversation provider; do not use for a customer badge. */
194
203
  unreadCount: number;
195
204
  /** @description Customer-side unread count used for product badges. */
196
205
  unreadForContact: number;
@@ -304,7 +313,24 @@ interface components {
304
313
  [key: string]: unknown;
305
314
  };
306
315
  CustomerError: {
316
+ /** @description Stable error code. Codes are extensible; handle unknown values safely. */
307
317
  error: string;
318
+ /** @description Optional customer-safe explanation, never infrastructure diagnostics. */
319
+ message?: string;
320
+ /**
321
+ * @description Optional server retry advice. False means do not automatically replay
322
+ * this request, including a 429 usage ceiling. Absence preserves older
323
+ * status-based handling. True does not guarantee a write is idempotent.
324
+ */
325
+ retryable?: boolean;
326
+ /**
327
+ * @description Optional next step. Known values are review_usage, review_setup and
328
+ * refresh_conversation. Values are extensible and grant no authority
329
+ * to change billing, budgets or account configuration.
330
+ */
331
+ nextAction?: string;
332
+ } & {
333
+ [key: string]: unknown;
308
334
  };
309
335
  };
310
336
  responses: {
@@ -317,6 +343,15 @@ interface components {
317
343
  "application/json": components["schemas"]["CustomerError"];
318
344
  };
319
345
  };
346
+ /** @description API-only inbox gateways do not support widget identity or anonymous-conversation claims. */
347
+ WidgetUnavailable: {
348
+ headers: {
349
+ [name: string]: unknown;
350
+ };
351
+ content: {
352
+ "application/json": components["schemas"]["CustomerError"];
353
+ };
354
+ };
320
355
  };
321
356
  parameters: {
322
357
  ConversationId: number;
@@ -345,6 +380,7 @@ interface operations {
345
380
  };
346
381
  };
347
382
  401: components["responses"]["Error"];
383
+ 409: components["responses"]["WidgetUnavailable"];
348
384
  default: components["responses"]["Error"];
349
385
  };
350
386
  };
@@ -516,6 +552,7 @@ interface operations {
516
552
  };
517
553
  };
518
554
  401: components["responses"]["Error"];
555
+ 409: components["responses"]["WidgetUnavailable"];
519
556
  default: components["responses"]["Error"];
520
557
  };
521
558
  };
@@ -615,15 +652,19 @@ type DaykeeperClaimConversationResult = Schemas["ClaimConversationResult"];
615
652
 
616
653
  interface DaykeeperReactNativeTokenProviderContext {
617
654
  /**
618
- * True only after Daykeeper rejected the first token with HTTP 401. The
655
+ * True only after a GET rejected the first token with HTTP 401 and did not
656
+ * explicitly forbid replay with retryable: false. The
619
657
  * provider should bypass any token cache and exchange the app session again.
620
658
  */
621
659
  forceRefresh: boolean;
660
+ /** Cancel credential exchange when the request is aborted or expires. */
661
+ signal?: AbortSignal;
622
662
  }
623
663
  type DaykeeperReactNativeTokenProvider = (context: DaykeeperReactNativeTokenProviderContext) => string | Promise<string>;
624
664
  interface DaykeeperReactNativeClientOptions {
625
665
  baseUrl: string;
626
666
  getAccessToken: DaykeeperReactNativeTokenProvider;
667
+ /** Must reject redirects, omit ambient cookies, and honor cache policy. */
627
668
  fetch?: typeof globalThis.fetch;
628
669
  timeoutMs?: number;
629
670
  }
@@ -646,37 +687,57 @@ declare class DaykeeperReactNativeClient {
646
687
  }
647
688
  declare function createDaykeeperReactNativeClient(options: DaykeeperReactNativeClientOptions): DaykeeperReactNativeClient;
648
689
 
649
- type DaykeeperReactNativeTransportErrorCode = "INVALID_CONFIGURATION" | "NETWORK_ERROR" | "REQUEST_ABORTED" | "REQUEST_TIMEOUT" | "INVALID_RESPONSE" | "RESPONSE_TOO_LARGE";
690
+ type DaykeeperReactNativeTransportErrorCode = "INVALID_CONFIGURATION" | "TOKEN_PROVIDER_ERROR" | "NETWORK_ERROR" | "REQUEST_ABORTED" | "REQUEST_TIMEOUT" | "INVALID_RESPONSE" | "RESPONSE_TOO_LARGE";
691
+ /**
692
+ * Contract-documented next steps. The envelope is open and its values are
693
+ * extensible, so an unrecognized hint is dropped rather than surfaced: a
694
+ * gateway string is untrusted and none of these grant account authority.
695
+ *
696
+ * This is deliberately narrower than the error-code rule above. A code is only
697
+ * ever compared by the app, so an unknown one is inert; a next action is a UI
698
+ * instruction the app acts on, so only the three the contract defines are
699
+ * allowed through.
700
+ */
701
+ type DaykeeperReactNativeNextAction = "review_usage" | "review_setup" | "refresh_conversation";
650
702
  declare class DaykeeperReactNativeApiError extends Error {
651
703
  readonly status: number;
652
704
  readonly code: string;
653
705
  readonly retryable: boolean;
706
+ readonly outcomeUnknown: boolean;
707
+ readonly nextAction?: DaykeeperReactNativeNextAction;
654
708
  constructor(options: {
655
709
  status: number;
656
- code: string;
657
- retryable: boolean;
710
+ code?: unknown;
711
+ nextAction?: unknown;
712
+ retryable?: boolean;
713
+ outcomeUnknown?: boolean;
658
714
  });
659
715
  toJSON(): {
660
716
  name: string;
661
717
  status: number;
662
718
  code: string;
663
719
  retryable: boolean;
720
+ outcomeUnknown: boolean;
721
+ nextAction?: DaykeeperReactNativeNextAction;
664
722
  };
665
723
  }
666
724
  declare class DaykeeperReactNativeTransportError extends Error {
667
725
  readonly code: DaykeeperReactNativeTransportErrorCode;
668
726
  readonly retryable: boolean;
727
+ readonly outcomeUnknown: boolean;
669
728
  constructor(options: {
670
729
  code: DaykeeperReactNativeTransportErrorCode;
671
730
  message: string;
672
731
  retryable?: boolean;
732
+ outcomeUnknown?: boolean;
673
733
  });
674
734
  toJSON(): {
675
735
  name: string;
676
736
  code: DaykeeperReactNativeTransportErrorCode;
677
737
  message: string;
678
738
  retryable: boolean;
739
+ outcomeUnknown: boolean;
679
740
  };
680
741
  }
681
742
 
682
- export { type DaykeeperAttachment, type DaykeeperClaimConversationResult, type DaykeeperConversation, type DaykeeperConversationList, type DaykeeperConversationResult, type DaykeeperCustomerIdentity, type components as DaykeeperCustomerOpenApiComponents, type operations as DaykeeperCustomerOpenApiOperations, type paths as DaykeeperCustomerOpenApiPaths, type DaykeeperMessage, type DaykeeperMessageList, type DaykeeperMessageResult, type DaykeeperMessageSender, DaykeeperReactNativeApiError, DaykeeperReactNativeClient, type DaykeeperReactNativeClientOptions, type DaykeeperReactNativeRequestOptions, type DaykeeperReactNativeTokenProvider, type DaykeeperReactNativeTokenProviderContext, DaykeeperReactNativeTransportError, type DaykeeperReactNativeTransportErrorCode, type DaykeeperSeenResult, type DaykeeperUnreadSummary, createDaykeeperReactNativeClient };
743
+ export { type DaykeeperAttachment, type DaykeeperClaimConversationResult, type DaykeeperConversation, type DaykeeperConversationList, type DaykeeperConversationResult, type DaykeeperCustomerIdentity, type components as DaykeeperCustomerOpenApiComponents, type operations as DaykeeperCustomerOpenApiOperations, type paths as DaykeeperCustomerOpenApiPaths, type DaykeeperMessage, type DaykeeperMessageList, type DaykeeperMessageResult, type DaykeeperMessageSender, DaykeeperReactNativeApiError, DaykeeperReactNativeClient, type DaykeeperReactNativeClientOptions, type DaykeeperReactNativeNextAction, type DaykeeperReactNativeRequestOptions, type DaykeeperReactNativeTokenProvider, type DaykeeperReactNativeTokenProviderContext, DaykeeperReactNativeTransportError, type DaykeeperReactNativeTransportErrorCode, type DaykeeperSeenResult, type DaykeeperUnreadSummary, createDaykeeperReactNativeClient };
package/dist/index.d.ts CHANGED
@@ -10,7 +10,12 @@ interface paths {
10
10
  path?: never;
11
11
  cookie?: never;
12
12
  };
13
- /** Get widget-safe customer identity */
13
+ /**
14
+ * Get widget-safe customer identity
15
+ * @description API-only inbox gateways authenticate the customer token and return `409`
16
+ * `{ "error": "widget_unavailable" }` before calling the conversation
17
+ * provider. Use a widget-enabled tenant gateway for this operation.
18
+ */
14
19
  get: operations["getCustomerIdentity"];
15
20
  put?: never;
16
21
  post?: never;
@@ -113,6 +118,10 @@ interface paths {
113
118
  * Claim a signed-out widget conversation after sign-in
114
119
  * @description The widget token proves possession of the anonymous thread. The gateway
115
120
  * refuses identified, foreign-tenant, or email-mismatched contacts.
121
+ *
122
+ * API-only inbox gateways authenticate the token and return `409`
123
+ * `{ "error": "widget_unavailable" }` before calling the conversation
124
+ * provider. Use a widget-enabled tenant gateway for this operation.
116
125
  */
117
126
  post: operations["claimAnonymousConversation"];
118
127
  delete?: never;
@@ -190,7 +199,7 @@ interface components {
190
199
  status: "open" | "pending" | "resolved" | "snoozed";
191
200
  createdAt: number | string | null;
192
201
  updatedAt: number | string | null;
193
- /** @description Chatwoot agent-side unread count; do not use for a customer badge. */
202
+ /** @description Agent-side unread count reported by the conversation provider; do not use for a customer badge. */
194
203
  unreadCount: number;
195
204
  /** @description Customer-side unread count used for product badges. */
196
205
  unreadForContact: number;
@@ -304,7 +313,24 @@ interface components {
304
313
  [key: string]: unknown;
305
314
  };
306
315
  CustomerError: {
316
+ /** @description Stable error code. Codes are extensible; handle unknown values safely. */
307
317
  error: string;
318
+ /** @description Optional customer-safe explanation, never infrastructure diagnostics. */
319
+ message?: string;
320
+ /**
321
+ * @description Optional server retry advice. False means do not automatically replay
322
+ * this request, including a 429 usage ceiling. Absence preserves older
323
+ * status-based handling. True does not guarantee a write is idempotent.
324
+ */
325
+ retryable?: boolean;
326
+ /**
327
+ * @description Optional next step. Known values are review_usage, review_setup and
328
+ * refresh_conversation. Values are extensible and grant no authority
329
+ * to change billing, budgets or account configuration.
330
+ */
331
+ nextAction?: string;
332
+ } & {
333
+ [key: string]: unknown;
308
334
  };
309
335
  };
310
336
  responses: {
@@ -317,6 +343,15 @@ interface components {
317
343
  "application/json": components["schemas"]["CustomerError"];
318
344
  };
319
345
  };
346
+ /** @description API-only inbox gateways do not support widget identity or anonymous-conversation claims. */
347
+ WidgetUnavailable: {
348
+ headers: {
349
+ [name: string]: unknown;
350
+ };
351
+ content: {
352
+ "application/json": components["schemas"]["CustomerError"];
353
+ };
354
+ };
320
355
  };
321
356
  parameters: {
322
357
  ConversationId: number;
@@ -345,6 +380,7 @@ interface operations {
345
380
  };
346
381
  };
347
382
  401: components["responses"]["Error"];
383
+ 409: components["responses"]["WidgetUnavailable"];
348
384
  default: components["responses"]["Error"];
349
385
  };
350
386
  };
@@ -516,6 +552,7 @@ interface operations {
516
552
  };
517
553
  };
518
554
  401: components["responses"]["Error"];
555
+ 409: components["responses"]["WidgetUnavailable"];
519
556
  default: components["responses"]["Error"];
520
557
  };
521
558
  };
@@ -615,15 +652,19 @@ type DaykeeperClaimConversationResult = Schemas["ClaimConversationResult"];
615
652
 
616
653
  interface DaykeeperReactNativeTokenProviderContext {
617
654
  /**
618
- * True only after Daykeeper rejected the first token with HTTP 401. The
655
+ * True only after a GET rejected the first token with HTTP 401 and did not
656
+ * explicitly forbid replay with retryable: false. The
619
657
  * provider should bypass any token cache and exchange the app session again.
620
658
  */
621
659
  forceRefresh: boolean;
660
+ /** Cancel credential exchange when the request is aborted or expires. */
661
+ signal?: AbortSignal;
622
662
  }
623
663
  type DaykeeperReactNativeTokenProvider = (context: DaykeeperReactNativeTokenProviderContext) => string | Promise<string>;
624
664
  interface DaykeeperReactNativeClientOptions {
625
665
  baseUrl: string;
626
666
  getAccessToken: DaykeeperReactNativeTokenProvider;
667
+ /** Must reject redirects, omit ambient cookies, and honor cache policy. */
627
668
  fetch?: typeof globalThis.fetch;
628
669
  timeoutMs?: number;
629
670
  }
@@ -646,37 +687,57 @@ declare class DaykeeperReactNativeClient {
646
687
  }
647
688
  declare function createDaykeeperReactNativeClient(options: DaykeeperReactNativeClientOptions): DaykeeperReactNativeClient;
648
689
 
649
- type DaykeeperReactNativeTransportErrorCode = "INVALID_CONFIGURATION" | "NETWORK_ERROR" | "REQUEST_ABORTED" | "REQUEST_TIMEOUT" | "INVALID_RESPONSE" | "RESPONSE_TOO_LARGE";
690
+ type DaykeeperReactNativeTransportErrorCode = "INVALID_CONFIGURATION" | "TOKEN_PROVIDER_ERROR" | "NETWORK_ERROR" | "REQUEST_ABORTED" | "REQUEST_TIMEOUT" | "INVALID_RESPONSE" | "RESPONSE_TOO_LARGE";
691
+ /**
692
+ * Contract-documented next steps. The envelope is open and its values are
693
+ * extensible, so an unrecognized hint is dropped rather than surfaced: a
694
+ * gateway string is untrusted and none of these grant account authority.
695
+ *
696
+ * This is deliberately narrower than the error-code rule above. A code is only
697
+ * ever compared by the app, so an unknown one is inert; a next action is a UI
698
+ * instruction the app acts on, so only the three the contract defines are
699
+ * allowed through.
700
+ */
701
+ type DaykeeperReactNativeNextAction = "review_usage" | "review_setup" | "refresh_conversation";
650
702
  declare class DaykeeperReactNativeApiError extends Error {
651
703
  readonly status: number;
652
704
  readonly code: string;
653
705
  readonly retryable: boolean;
706
+ readonly outcomeUnknown: boolean;
707
+ readonly nextAction?: DaykeeperReactNativeNextAction;
654
708
  constructor(options: {
655
709
  status: number;
656
- code: string;
657
- retryable: boolean;
710
+ code?: unknown;
711
+ nextAction?: unknown;
712
+ retryable?: boolean;
713
+ outcomeUnknown?: boolean;
658
714
  });
659
715
  toJSON(): {
660
716
  name: string;
661
717
  status: number;
662
718
  code: string;
663
719
  retryable: boolean;
720
+ outcomeUnknown: boolean;
721
+ nextAction?: DaykeeperReactNativeNextAction;
664
722
  };
665
723
  }
666
724
  declare class DaykeeperReactNativeTransportError extends Error {
667
725
  readonly code: DaykeeperReactNativeTransportErrorCode;
668
726
  readonly retryable: boolean;
727
+ readonly outcomeUnknown: boolean;
669
728
  constructor(options: {
670
729
  code: DaykeeperReactNativeTransportErrorCode;
671
730
  message: string;
672
731
  retryable?: boolean;
732
+ outcomeUnknown?: boolean;
673
733
  });
674
734
  toJSON(): {
675
735
  name: string;
676
736
  code: DaykeeperReactNativeTransportErrorCode;
677
737
  message: string;
678
738
  retryable: boolean;
739
+ outcomeUnknown: boolean;
679
740
  };
680
741
  }
681
742
 
682
- export { type DaykeeperAttachment, type DaykeeperClaimConversationResult, type DaykeeperConversation, type DaykeeperConversationList, type DaykeeperConversationResult, type DaykeeperCustomerIdentity, type components as DaykeeperCustomerOpenApiComponents, type operations as DaykeeperCustomerOpenApiOperations, type paths as DaykeeperCustomerOpenApiPaths, type DaykeeperMessage, type DaykeeperMessageList, type DaykeeperMessageResult, type DaykeeperMessageSender, DaykeeperReactNativeApiError, DaykeeperReactNativeClient, type DaykeeperReactNativeClientOptions, type DaykeeperReactNativeRequestOptions, type DaykeeperReactNativeTokenProvider, type DaykeeperReactNativeTokenProviderContext, DaykeeperReactNativeTransportError, type DaykeeperReactNativeTransportErrorCode, type DaykeeperSeenResult, type DaykeeperUnreadSummary, createDaykeeperReactNativeClient };
743
+ export { type DaykeeperAttachment, type DaykeeperClaimConversationResult, type DaykeeperConversation, type DaykeeperConversationList, type DaykeeperConversationResult, type DaykeeperCustomerIdentity, type components as DaykeeperCustomerOpenApiComponents, type operations as DaykeeperCustomerOpenApiOperations, type paths as DaykeeperCustomerOpenApiPaths, type DaykeeperMessage, type DaykeeperMessageList, type DaykeeperMessageResult, type DaykeeperMessageSender, DaykeeperReactNativeApiError, DaykeeperReactNativeClient, type DaykeeperReactNativeClientOptions, type DaykeeperReactNativeNextAction, type DaykeeperReactNativeRequestOptions, type DaykeeperReactNativeTokenProvider, type DaykeeperReactNativeTokenProviderContext, DaykeeperReactNativeTransportError, type DaykeeperReactNativeTransportErrorCode, type DaykeeperSeenResult, type DaykeeperUnreadSummary, createDaykeeperReactNativeClient };