@harkenapp/sdk-react-native 0.0.1-alpha.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.
Files changed (235) hide show
  1. package/README.md +67 -0
  2. package/app.plugin.cjs +135 -0
  3. package/app.plugin.js +1 -0
  4. package/dist/api/client.d.ts +67 -0
  5. package/dist/api/client.d.ts.map +1 -0
  6. package/dist/api/client.js +163 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/api/errors.d.ts +46 -0
  9. package/dist/api/errors.d.ts.map +1 -0
  10. package/dist/api/errors.js +72 -0
  11. package/dist/api/errors.js.map +1 -0
  12. package/dist/api/index.d.ts +7 -0
  13. package/dist/api/index.d.ts.map +1 -0
  14. package/dist/api/index.js +20 -0
  15. package/dist/api/index.js.map +1 -0
  16. package/dist/api/retry.d.ts +29 -0
  17. package/dist/api/retry.d.ts.map +1 -0
  18. package/dist/api/retry.js +74 -0
  19. package/dist/api/retry.js.map +1 -0
  20. package/dist/attachments/FeedbackSheet.d.ts +88 -0
  21. package/dist/attachments/FeedbackSheet.d.ts.map +1 -0
  22. package/dist/attachments/FeedbackSheet.js +250 -0
  23. package/dist/attachments/FeedbackSheet.js.map +1 -0
  24. package/dist/attachments/index.d.ts +20 -0
  25. package/dist/attachments/index.d.ts.map +1 -0
  26. package/dist/attachments/index.js +40 -0
  27. package/dist/attachments/index.js.map +1 -0
  28. package/dist/components/AttachmentGrid.d.ts +94 -0
  29. package/dist/components/AttachmentGrid.d.ts.map +1 -0
  30. package/dist/components/AttachmentGrid.js +132 -0
  31. package/dist/components/AttachmentGrid.js.map +1 -0
  32. package/dist/components/AttachmentPicker.d.ts +98 -0
  33. package/dist/components/AttachmentPicker.d.ts.map +1 -0
  34. package/dist/components/AttachmentPicker.js +297 -0
  35. package/dist/components/AttachmentPicker.js.map +1 -0
  36. package/dist/components/AttachmentPreview.d.ts +78 -0
  37. package/dist/components/AttachmentPreview.d.ts.map +1 -0
  38. package/dist/components/AttachmentPreview.js +133 -0
  39. package/dist/components/AttachmentPreview.js.map +1 -0
  40. package/dist/components/CategorySelector.d.ts +77 -0
  41. package/dist/components/CategorySelector.d.ts.map +1 -0
  42. package/dist/components/CategorySelector.js +117 -0
  43. package/dist/components/CategorySelector.js.map +1 -0
  44. package/dist/components/FeedbackForm.d.ts +50 -0
  45. package/dist/components/FeedbackForm.d.ts.map +1 -0
  46. package/dist/components/FeedbackForm.js +141 -0
  47. package/dist/components/FeedbackForm.js.map +1 -0
  48. package/dist/components/FeedbackSheet.d.ts +75 -0
  49. package/dist/components/FeedbackSheet.d.ts.map +1 -0
  50. package/dist/components/FeedbackSheet.js +215 -0
  51. package/dist/components/FeedbackSheet.js.map +1 -0
  52. package/dist/components/ThemedButton.d.ts +23 -0
  53. package/dist/components/ThemedButton.d.ts.map +1 -0
  54. package/dist/components/ThemedButton.js +77 -0
  55. package/dist/components/ThemedButton.js.map +1 -0
  56. package/dist/components/ThemedText.d.ts +16 -0
  57. package/dist/components/ThemedText.d.ts.map +1 -0
  58. package/dist/components/ThemedText.js +44 -0
  59. package/dist/components/ThemedText.js.map +1 -0
  60. package/dist/components/ThemedTextInput.d.ts +13 -0
  61. package/dist/components/ThemedTextInput.d.ts.map +1 -0
  62. package/dist/components/ThemedTextInput.js +76 -0
  63. package/dist/components/ThemedTextInput.js.map +1 -0
  64. package/dist/components/UploadStatusOverlay.d.ts +82 -0
  65. package/dist/components/UploadStatusOverlay.d.ts.map +1 -0
  66. package/dist/components/UploadStatusOverlay.js +319 -0
  67. package/dist/components/UploadStatusOverlay.js.map +1 -0
  68. package/dist/components/index.d.ts +19 -0
  69. package/dist/components/index.d.ts.map +1 -0
  70. package/dist/components/index.js +28 -0
  71. package/dist/components/index.js.map +1 -0
  72. package/dist/context/HarkenContext.d.ts +62 -0
  73. package/dist/context/HarkenContext.d.ts.map +1 -0
  74. package/dist/context/HarkenContext.js +128 -0
  75. package/dist/context/HarkenContext.js.map +1 -0
  76. package/dist/context/index.d.ts +3 -0
  77. package/dist/context/index.d.ts.map +1 -0
  78. package/dist/context/index.js +7 -0
  79. package/dist/context/index.js.map +1 -0
  80. package/dist/domain/index.d.ts +3 -0
  81. package/dist/domain/index.d.ts.map +1 -0
  82. package/dist/domain/index.js +7 -0
  83. package/dist/domain/index.js.map +1 -0
  84. package/dist/domain/upload-queue.d.ts +116 -0
  85. package/dist/domain/upload-queue.d.ts.map +1 -0
  86. package/dist/domain/upload-queue.js +34 -0
  87. package/dist/domain/upload-queue.js.map +1 -0
  88. package/dist/hooks/index.d.ts +6 -0
  89. package/dist/hooks/index.d.ts.map +1 -0
  90. package/dist/hooks/index.js +16 -0
  91. package/dist/hooks/index.js.map +1 -0
  92. package/dist/hooks/useAnonymousId.d.ts +28 -0
  93. package/dist/hooks/useAnonymousId.d.ts.map +1 -0
  94. package/dist/hooks/useAnonymousId.js +59 -0
  95. package/dist/hooks/useAnonymousId.js.map +1 -0
  96. package/dist/hooks/useAttachmentPicker.d.ts +84 -0
  97. package/dist/hooks/useAttachmentPicker.d.ts.map +1 -0
  98. package/dist/hooks/useAttachmentPicker.js +181 -0
  99. package/dist/hooks/useAttachmentPicker.js.map +1 -0
  100. package/dist/hooks/useAttachmentStatus.d.ts +51 -0
  101. package/dist/hooks/useAttachmentStatus.d.ts.map +1 -0
  102. package/dist/hooks/useAttachmentStatus.js +69 -0
  103. package/dist/hooks/useAttachmentStatus.js.map +1 -0
  104. package/dist/hooks/useAttachmentUpload.d.ts +101 -0
  105. package/dist/hooks/useAttachmentUpload.d.ts.map +1 -0
  106. package/dist/hooks/useAttachmentUpload.js +293 -0
  107. package/dist/hooks/useAttachmentUpload.js.map +1 -0
  108. package/dist/hooks/useFeedback.d.ts +55 -0
  109. package/dist/hooks/useFeedback.d.ts.map +1 -0
  110. package/dist/hooks/useFeedback.js +96 -0
  111. package/dist/hooks/useFeedback.js.map +1 -0
  112. package/dist/hooks/useHarkenContext.d.ts +25 -0
  113. package/dist/hooks/useHarkenContext.d.ts.map +1 -0
  114. package/dist/hooks/useHarkenContext.js +35 -0
  115. package/dist/hooks/useHarkenContext.js.map +1 -0
  116. package/dist/hooks/useHarkenTheme.d.ts +26 -0
  117. package/dist/hooks/useHarkenTheme.d.ts.map +1 -0
  118. package/dist/hooks/useHarkenTheme.js +36 -0
  119. package/dist/hooks/useHarkenTheme.js.map +1 -0
  120. package/dist/index.d.ts +49 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +91 -0
  123. package/dist/index.js.map +1 -0
  124. package/dist/services/index.d.ts +4 -0
  125. package/dist/services/index.d.ts.map +1 -0
  126. package/dist/services/index.js +9 -0
  127. package/dist/services/index.js.map +1 -0
  128. package/dist/services/uploadQueueService.d.ts +193 -0
  129. package/dist/services/uploadQueueService.d.ts.map +1 -0
  130. package/dist/services/uploadQueueService.js +623 -0
  131. package/dist/services/uploadQueueService.js.map +1 -0
  132. package/dist/services/uploadQueueStorage.d.ts +30 -0
  133. package/dist/services/uploadQueueStorage.d.ts.map +1 -0
  134. package/dist/services/uploadQueueStorage.js +77 -0
  135. package/dist/services/uploadQueueStorage.js.map +1 -0
  136. package/dist/storage/IdentityStore.d.ts +38 -0
  137. package/dist/storage/IdentityStore.d.ts.map +1 -0
  138. package/dist/storage/IdentityStore.js +83 -0
  139. package/dist/storage/IdentityStore.js.map +1 -0
  140. package/dist/storage/SecureStoreAdapter.d.ts +28 -0
  141. package/dist/storage/SecureStoreAdapter.d.ts.map +1 -0
  142. package/dist/storage/SecureStoreAdapter.js +52 -0
  143. package/dist/storage/SecureStoreAdapter.js.map +1 -0
  144. package/dist/storage/defaultStorage.d.ts +20 -0
  145. package/dist/storage/defaultStorage.d.ts.map +1 -0
  146. package/dist/storage/defaultStorage.js +131 -0
  147. package/dist/storage/defaultStorage.js.map +1 -0
  148. package/dist/storage/index.d.ts +6 -0
  149. package/dist/storage/index.d.ts.map +1 -0
  150. package/dist/storage/index.js +13 -0
  151. package/dist/storage/index.js.map +1 -0
  152. package/dist/storage/types.d.ts +32 -0
  153. package/dist/storage/types.d.ts.map +1 -0
  154. package/dist/storage/types.js +11 -0
  155. package/dist/storage/types.js.map +1 -0
  156. package/dist/theme/defaults.d.ts +43 -0
  157. package/dist/theme/defaults.d.ts.map +1 -0
  158. package/dist/theme/defaults.js +128 -0
  159. package/dist/theme/defaults.js.map +1 -0
  160. package/dist/theme/index.d.ts +3 -0
  161. package/dist/theme/index.d.ts.map +1 -0
  162. package/dist/theme/index.js +14 -0
  163. package/dist/theme/index.js.map +1 -0
  164. package/dist/theme/types.d.ts +136 -0
  165. package/dist/theme/types.d.ts.map +1 -0
  166. package/dist/theme/types.js +3 -0
  167. package/dist/theme/types.js.map +1 -0
  168. package/dist/types/config.d.ts +100 -0
  169. package/dist/types/config.d.ts.map +1 -0
  170. package/dist/types/config.js +3 -0
  171. package/dist/types/config.js.map +1 -0
  172. package/dist/types/index.d.ts +3 -0
  173. package/dist/types/index.d.ts.map +1 -0
  174. package/dist/types/index.js +3 -0
  175. package/dist/types/index.js.map +1 -0
  176. package/dist/types/openapi.d.ts +601 -0
  177. package/dist/types/openapi.d.ts.map +1 -0
  178. package/dist/types/openapi.js +7 -0
  179. package/dist/types/openapi.js.map +1 -0
  180. package/dist/utils/index.d.ts +2 -0
  181. package/dist/utils/index.d.ts.map +1 -0
  182. package/dist/utils/index.js +6 -0
  183. package/dist/utils/index.js.map +1 -0
  184. package/dist/utils/uuid.d.ts +10 -0
  185. package/dist/utils/uuid.d.ts.map +1 -0
  186. package/dist/utils/uuid.js +60 -0
  187. package/dist/utils/uuid.js.map +1 -0
  188. package/package.json +124 -0
  189. package/src/@types/expo-file-system-legacy.d.ts +13 -0
  190. package/src/api/client.ts +250 -0
  191. package/src/api/errors.ts +84 -0
  192. package/src/api/index.ts +15 -0
  193. package/src/api/retry.ts +99 -0
  194. package/src/attachments/FeedbackSheet.tsx +400 -0
  195. package/src/attachments/index.ts +70 -0
  196. package/src/components/AttachmentGrid.tsx +247 -0
  197. package/src/components/AttachmentPicker.tsx +391 -0
  198. package/src/components/AttachmentPreview.tsx +210 -0
  199. package/src/components/CategorySelector.tsx +174 -0
  200. package/src/components/FeedbackForm.tsx +216 -0
  201. package/src/components/FeedbackSheet.tsx +321 -0
  202. package/src/components/ThemedButton.tsx +127 -0
  203. package/src/components/ThemedText.tsx +65 -0
  204. package/src/components/ThemedTextInput.tsx +65 -0
  205. package/src/components/UploadStatusOverlay.tsx +440 -0
  206. package/src/components/index.ts +39 -0
  207. package/src/context/HarkenContext.tsx +129 -0
  208. package/src/context/index.ts +2 -0
  209. package/src/domain/index.ts +12 -0
  210. package/src/domain/upload-queue.ts +131 -0
  211. package/src/hooks/index.ts +10 -0
  212. package/src/hooks/useAnonymousId.ts +68 -0
  213. package/src/hooks/useAttachmentPicker.ts +243 -0
  214. package/src/hooks/useAttachmentStatus.ts +86 -0
  215. package/src/hooks/useAttachmentUpload.ts +370 -0
  216. package/src/hooks/useFeedback.ts +139 -0
  217. package/src/hooks/useHarkenContext.ts +35 -0
  218. package/src/hooks/useHarkenTheme.ts +36 -0
  219. package/src/index.ts +168 -0
  220. package/src/services/index.ts +11 -0
  221. package/src/services/uploadQueueService.ts +727 -0
  222. package/src/services/uploadQueueStorage.ts +78 -0
  223. package/src/storage/IdentityStore.ts +89 -0
  224. package/src/storage/SecureStoreAdapter.ts +59 -0
  225. package/src/storage/defaultStorage.ts +109 -0
  226. package/src/storage/index.ts +5 -0
  227. package/src/storage/types.ts +34 -0
  228. package/src/theme/defaults.ts +151 -0
  229. package/src/theme/index.ts +23 -0
  230. package/src/theme/types.ts +157 -0
  231. package/src/types/config.ts +112 -0
  232. package/src/types/index.ts +10 -0
  233. package/src/types/openapi.ts +601 -0
  234. package/src/utils/index.ts +1 -0
  235. package/src/utils/uuid.ts +77 -0
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Harken React Native SDK
2
+
3
+ React Native / Expo SDK for submitting in-app feedback.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npx expo install @harkenapp/sdk-react-native
9
+ ```
10
+
11
+ ## Permissions
12
+
13
+ The SDK requires camera and photo library permissions to support attachment features. The SDK includes an Expo config plugin that automatically configures these permissions.
14
+
15
+ ### Automatic Configuration (Recommended)
16
+
17
+ Add the SDK to your `app.json` or `app.config.js` plugins:
18
+
19
+ ```json
20
+ {
21
+ "expo": {
22
+ "plugins": [
23
+ "@harkenapp/sdk-react-native"
24
+ ]
25
+ }
26
+ }
27
+ ```
28
+
29
+ This automatically configures:
30
+
31
+ **iOS (Info.plist):**
32
+ - `NSCameraUsageDescription` - Camera access for taking photos
33
+ - `NSPhotoLibraryUsageDescription` - Photo library access for selecting images
34
+
35
+ > **Note:** `NSDocumentsFolderUsageDescription` is not required. The SDK uses `expo-document-picker` which presents the system document picker UI, handling file access permissions automatically without needing an Info.plist entry.
36
+
37
+ **Android (AndroidManifest.xml):**
38
+ - `android.permission.CAMERA` - Camera access
39
+ - `android.permission.READ_MEDIA_IMAGES` - Photo library access (Android 13+)
40
+ - `android.permission.READ_EXTERNAL_STORAGE` - Photo library access (Android 12 and below)
41
+
42
+ ### Custom Permission Strings
43
+
44
+ You can customize the iOS permission dialog strings:
45
+
46
+ ```json
47
+ {
48
+ "expo": {
49
+ "plugins": [
50
+ ["@harkenapp/sdk-react-native", {
51
+ "cameraPermission": "Take photos to include with your feedback",
52
+ "photoLibraryPermission": "Select photos to include with your feedback"
53
+ }]
54
+ ]
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### After Configuration
60
+
61
+ Run prebuild to apply the permissions:
62
+
63
+ ```bash
64
+ npx expo prebuild
65
+ ```
66
+
67
+ Or if using EAS Build, permissions are applied automatically during the build process.
package/app.plugin.cjs ADDED
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Expo config plugin for @harkenapp/sdk-react-native
3
+ *
4
+ * Automatically configures iOS and Android permissions required for
5
+ * camera, photo library, and document picker functionality.
6
+ *
7
+ * @example
8
+ * // app.json or app.config.js
9
+ * {
10
+ * "expo": {
11
+ * "plugins": [
12
+ * "@harkenapp/sdk-react-native"
13
+ * ]
14
+ * }
15
+ * }
16
+ *
17
+ * @example
18
+ * // With custom permission strings
19
+ * {
20
+ * "expo": {
21
+ * "plugins": [
22
+ * ["@harkenapp/sdk-react-native", {
23
+ * "cameraPermission": "Take photos to include with your feedback",
24
+ * "photoLibraryPermission": "Select photos to include with your feedback"
25
+ * }]
26
+ * ]
27
+ * }
28
+ * }
29
+ */
30
+
31
+ const {
32
+ withInfoPlist,
33
+ withAndroidManifest,
34
+ } = require('@expo/config-plugins');
35
+
36
+ /**
37
+ * Default permission strings for iOS
38
+ */
39
+ const DEFAULT_PERMISSIONS = {
40
+ cameraPermission: 'Allow $(PRODUCT_NAME) to access your camera to take photos for feedback',
41
+ photoLibraryPermission: 'Allow $(PRODUCT_NAME) to access your photos to include with feedback',
42
+ };
43
+
44
+ /**
45
+ * Configure iOS Info.plist permissions
46
+ */
47
+ function withIosPermissions(config, options) {
48
+ return withInfoPlist(config, (config) => {
49
+ // Camera permission
50
+ // Custom option overrides existing; default only sets if missing
51
+ if (options.cameraPermission) {
52
+ config.modResults.NSCameraUsageDescription = options.cameraPermission;
53
+ } else if (!config.modResults.NSCameraUsageDescription) {
54
+ config.modResults.NSCameraUsageDescription = DEFAULT_PERMISSIONS.cameraPermission;
55
+ }
56
+
57
+ // Photo library permission
58
+ // Custom option overrides existing; default only sets if missing
59
+ if (options.photoLibraryPermission) {
60
+ config.modResults.NSPhotoLibraryUsageDescription = options.photoLibraryPermission;
61
+ } else if (!config.modResults.NSPhotoLibraryUsageDescription) {
62
+ config.modResults.NSPhotoLibraryUsageDescription = DEFAULT_PERMISSIONS.photoLibraryPermission;
63
+ }
64
+
65
+ return config;
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Configure Android AndroidManifest.xml permissions
71
+ */
72
+ function withAndroidPermissions(config) {
73
+ return withAndroidManifest(config, (config) => {
74
+ const manifest = config.modResults.manifest;
75
+
76
+ // Ensure uses-permission array exists
77
+ if (!manifest['uses-permission']) {
78
+ manifest['uses-permission'] = [];
79
+ }
80
+
81
+ const permissions = manifest['uses-permission'];
82
+
83
+ /**
84
+ * Add a permission if it doesn't already exist
85
+ */
86
+ function addPermission(name, attributes = {}) {
87
+ const exists = permissions.some(
88
+ (p) => p.$?.['android:name'] === name
89
+ );
90
+ if (!exists) {
91
+ permissions.push({
92
+ $: {
93
+ 'android:name': name,
94
+ ...attributes,
95
+ },
96
+ });
97
+ }
98
+ }
99
+
100
+ // Camera permission
101
+ addPermission('android.permission.CAMERA');
102
+
103
+ // Photo library permissions
104
+ // READ_MEDIA_IMAGES for Android 13+ (API 33+)
105
+ addPermission('android.permission.READ_MEDIA_IMAGES');
106
+
107
+ // READ_EXTERNAL_STORAGE for Android 12 and below
108
+ // Use maxSdkVersion to limit to older APIs
109
+ addPermission('android.permission.READ_EXTERNAL_STORAGE', {
110
+ 'android:maxSdkVersion': '32',
111
+ });
112
+
113
+ return config;
114
+ });
115
+ }
116
+
117
+ /**
118
+ * Main plugin function
119
+ *
120
+ * @param {import('@expo/config-plugins').ExpoConfig} config - Expo config
121
+ * @param {Object} options - Plugin options
122
+ * @param {string} [options.cameraPermission] - Custom iOS camera permission string
123
+ * @param {string} [options.photoLibraryPermission] - Custom iOS photo library permission string
124
+ */
125
+ function withHarkenPermissions(config, options = {}) {
126
+ // Apply iOS permissions
127
+ config = withIosPermissions(config, options);
128
+
129
+ // Apply Android permissions
130
+ config = withAndroidPermissions(config);
131
+
132
+ return config;
133
+ }
134
+
135
+ module.exports = withHarkenPermissions;
package/app.plugin.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require("./app.plugin.cjs");
@@ -0,0 +1,67 @@
1
+ import type { components } from '../types/index.js';
2
+ import type { RetryConfig } from './retry';
3
+ type FeedbackSubmission = components['schemas']['FeedbackSubmission'];
4
+ type FeedbackSubmissionResponse = components['schemas']['FeedbackSubmissionResponse'];
5
+ type AttachmentPresignRequest = components['schemas']['AttachmentPresignRequest'];
6
+ type AttachmentPresignResponse = components['schemas']['AttachmentPresignResponse'];
7
+ type AttachmentConfirmRequest = components['schemas']['AttachmentConfirmRequest'];
8
+ type AttachmentStatusResponse = components['schemas']['AttachmentStatusResponse'];
9
+ export interface HarkenClientConfig {
10
+ /** Publishable API key */
11
+ publishableKey: string;
12
+ /** Optional user token for verified identity */
13
+ userToken?: string;
14
+ /** Base URL for API (defaults to production) */
15
+ baseUrl?: string;
16
+ /** Retry configuration */
17
+ retry?: Partial<RetryConfig>;
18
+ /** Request timeout in ms (default: 30000) */
19
+ timeout?: number;
20
+ }
21
+ /**
22
+ * Low-level API client for Harken.
23
+ */
24
+ export declare class HarkenClient {
25
+ private readonly config;
26
+ constructor(config: HarkenClientConfig);
27
+ /**
28
+ * Submit feedback to the API.
29
+ */
30
+ submitFeedback(submission: FeedbackSubmission): Promise<FeedbackSubmissionResponse>;
31
+ /**
32
+ * Create a presigned URL for attachment upload.
33
+ */
34
+ createAttachmentUpload(request: AttachmentPresignRequest): Promise<AttachmentPresignResponse>;
35
+ /**
36
+ * Confirm successful attachment upload.
37
+ */
38
+ confirmAttachment(attachmentId: string, request?: AttachmentConfirmRequest): Promise<AttachmentStatusResponse>;
39
+ /**
40
+ * Report attachment upload failure.
41
+ * This is a terminal state, so no retry is applied.
42
+ */
43
+ reportAttachmentFailure(attachmentId: string, error?: string): Promise<AttachmentStatusResponse>;
44
+ /**
45
+ * Get attachment status and download URLs.
46
+ */
47
+ getAttachmentStatus(attachmentId: string): Promise<AttachmentStatusResponse>;
48
+ /**
49
+ * Make an authenticated request to the API.
50
+ */
51
+ private request;
52
+ /**
53
+ * Parse error response body, with fallback for non-JSON responses.
54
+ */
55
+ private parseErrorResponse;
56
+ /**
57
+ * Parse Retry-After header value in seconds.
58
+ * Supports both delta-seconds and HTTP-date formats.
59
+ */
60
+ private parseRetryAfter;
61
+ }
62
+ /**
63
+ * Create a configured Harken client.
64
+ */
65
+ export declare function createHarkenClient(config: HarkenClientConfig): HarkenClient;
66
+ export {};
67
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C,KAAK,kBAAkB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,oBAAoB,CAAC,CAAC;AACtE,KAAK,0BAA0B,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,4BAA4B,CAAC,CAAC;AAItF,KAAK,wBAAwB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,0BAA0B,CAAC,CAAC;AAClF,KAAK,yBAAyB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,2BAA2B,CAAC,CAAC;AACpF,KAAK,wBAAwB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,0BAA0B,CAAC,CAAC;AAClF,KAAK,wBAAwB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,0BAA0B,CAAC,CAAC;AAIlF,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7B,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAG2B;gBAEtC,MAAM,EAAE,kBAAkB;IAUtC;;OAEG;IACG,cAAc,CAClB,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,0BAA0B,CAAC;IAUtC;;OAEG;IACG,sBAAsB,CAC1B,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,yBAAyB,CAAC;IAcrC;;OAEG;IACG,iBAAiB,CACrB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,wBAAwB,CAAC;IAcpC;;;OAGG;IACG,uBAAuB,CAC3B,YAAY,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,wBAAwB,CAAC;IAUpC;;OAEG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,wBAAwB,CAAC;IAMpC;;OAEG;YACW,OAAO;IAiErB;;OAEG;YACW,kBAAkB;IAchC;;;OAGG;IACH,OAAO,CAAC,eAAe;CAqBxB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAE3E"}
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HarkenClient = void 0;
4
+ exports.createHarkenClient = createHarkenClient;
5
+ const errors_1 = require("./errors");
6
+ const retry_1 = require("./retry");
7
+ const DEFAULT_API_BASE_URL = 'https://api.harken.app';
8
+ /**
9
+ * Low-level API client for Harken.
10
+ */
11
+ class HarkenClient {
12
+ config;
13
+ constructor(config) {
14
+ this.config = {
15
+ publishableKey: config.publishableKey,
16
+ userToken: config.userToken,
17
+ baseUrl: config.baseUrl ?? DEFAULT_API_BASE_URL,
18
+ retry: config.retry,
19
+ timeout: config.timeout ?? 30000,
20
+ };
21
+ }
22
+ /**
23
+ * Submit feedback to the API.
24
+ */
25
+ async submitFeedback(submission) {
26
+ return (0, retry_1.withRetry)(() => this.request('/v1/feedback', {
27
+ method: 'POST',
28
+ body: JSON.stringify(submission),
29
+ }), this.config.retry);
30
+ }
31
+ /**
32
+ * Create a presigned URL for attachment upload.
33
+ */
34
+ async createAttachmentUpload(request) {
35
+ return (0, retry_1.withRetry)(() => this.request('/v1/feedback/attachments/presign', {
36
+ method: 'POST',
37
+ body: JSON.stringify(request),
38
+ }), this.config.retry);
39
+ }
40
+ /**
41
+ * Confirm successful attachment upload.
42
+ */
43
+ async confirmAttachment(attachmentId, request) {
44
+ return (0, retry_1.withRetry)(() => this.request(`/v1/feedback/attachments/${attachmentId}/confirm`, {
45
+ method: 'POST',
46
+ body: request ? JSON.stringify(request) : undefined,
47
+ }), this.config.retry);
48
+ }
49
+ /**
50
+ * Report attachment upload failure.
51
+ * This is a terminal state, so no retry is applied.
52
+ */
53
+ async reportAttachmentFailure(attachmentId, error) {
54
+ return this.request(`/v1/feedback/attachments/${attachmentId}/fail`, {
55
+ method: 'POST',
56
+ body: error ? JSON.stringify({ error }) : undefined,
57
+ });
58
+ }
59
+ /**
60
+ * Get attachment status and download URLs.
61
+ */
62
+ async getAttachmentStatus(attachmentId) {
63
+ return this.request(`/v1/feedback/attachments/${attachmentId}`);
64
+ }
65
+ /**
66
+ * Make an authenticated request to the API.
67
+ */
68
+ async request(path, options = {}) {
69
+ const url = `${this.config.baseUrl}${path}`;
70
+ const headers = {
71
+ 'Content-Type': 'application/json',
72
+ 'X-Publishable-Key': this.config.publishableKey,
73
+ ...options.headers,
74
+ };
75
+ if (this.config.userToken) {
76
+ headers['X-User-Token'] = this.config.userToken;
77
+ }
78
+ // Create abort controller for timeout
79
+ const controller = new AbortController();
80
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
81
+ try {
82
+ const response = await fetch(url, {
83
+ ...options,
84
+ headers,
85
+ signal: controller.signal,
86
+ });
87
+ clearTimeout(timeoutId);
88
+ if (!response.ok) {
89
+ const errorBody = await this.parseErrorResponse(response);
90
+ // Only parse Retry-After for 429 responses
91
+ const retryAfter = response.status === 429
92
+ ? this.parseRetryAfter(response)
93
+ : undefined;
94
+ throw new errors_1.HarkenApiError(response.status, errorBody, { retryAfter });
95
+ }
96
+ return (await response.json());
97
+ }
98
+ catch (error) {
99
+ clearTimeout(timeoutId);
100
+ // Re-throw HarkenApiError as-is
101
+ if (error instanceof errors_1.HarkenApiError) {
102
+ throw error;
103
+ }
104
+ // Handle abort (timeout)
105
+ if (error instanceof Error && error.name === 'AbortError') {
106
+ throw new errors_1.HarkenNetworkError('Request timed out', error);
107
+ }
108
+ // Handle other fetch errors (network issues)
109
+ if (error instanceof TypeError) {
110
+ throw new errors_1.HarkenNetworkError('Network request failed', error);
111
+ }
112
+ // Unknown error
113
+ throw new errors_1.HarkenNetworkError(error instanceof Error ? error.message : 'Unknown error', error instanceof Error ? error : undefined);
114
+ }
115
+ }
116
+ /**
117
+ * Parse error response body, with fallback for non-JSON responses.
118
+ */
119
+ async parseErrorResponse(response) {
120
+ try {
121
+ return (await response.json());
122
+ }
123
+ catch {
124
+ // Fallback for non-JSON error responses
125
+ return {
126
+ error: {
127
+ code: `http_${response.status}`,
128
+ message: response.statusText || 'Request failed',
129
+ },
130
+ };
131
+ }
132
+ }
133
+ /**
134
+ * Parse Retry-After header value in seconds.
135
+ * Supports both delta-seconds and HTTP-date formats.
136
+ */
137
+ parseRetryAfter(response) {
138
+ const retryAfter = response.headers.get('Retry-After');
139
+ if (!retryAfter) {
140
+ return undefined;
141
+ }
142
+ // Try parsing as integer (delta-seconds)
143
+ const seconds = parseInt(retryAfter, 10);
144
+ if (!isNaN(seconds) && seconds >= 0) {
145
+ return seconds;
146
+ }
147
+ // Try parsing as HTTP-date
148
+ const date = Date.parse(retryAfter);
149
+ if (!isNaN(date)) {
150
+ const delayMs = date - Date.now();
151
+ return delayMs > 0 ? Math.ceil(delayMs / 1000) : 0;
152
+ }
153
+ return undefined;
154
+ }
155
+ }
156
+ exports.HarkenClient = HarkenClient;
157
+ /**
158
+ * Create a configured Harken client.
159
+ */
160
+ function createHarkenClient(config) {
161
+ return new HarkenClient(config);
162
+ }
163
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { components } from '../types/index.js';
2
+ type ErrorResponse = components['schemas']['ErrorResponse'];
3
+ type ErrorDetail = components['schemas']['ErrorDetail'];
4
+ /**
5
+ * Base error class for Harken API errors.
6
+ */
7
+ export declare class HarkenError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ /**
11
+ * Error thrown when the API returns an error response.
12
+ */
13
+ export declare class HarkenApiError extends HarkenError {
14
+ /** HTTP status code */
15
+ readonly status: number;
16
+ /** Machine-readable error code */
17
+ readonly code: string;
18
+ /** Validation error details (if present) */
19
+ readonly details?: ErrorDetail[];
20
+ /** Retry-After value in seconds (from 429 responses) */
21
+ readonly retryAfter?: number;
22
+ constructor(status: number, response: ErrorResponse, options?: {
23
+ retryAfter?: number;
24
+ });
25
+ /** True if this is a validation error (400) */
26
+ get isValidationError(): boolean;
27
+ /** True if this is an auth error (401) */
28
+ get isUnauthorized(): boolean;
29
+ /** True if this is a rate limit error (429) */
30
+ get isRateLimited(): boolean;
31
+ /** True if this is a server error (5xx) */
32
+ get isServerError(): boolean;
33
+ /** True if this error is retryable */
34
+ get isRetryable(): boolean;
35
+ }
36
+ /**
37
+ * Error thrown when a network request fails.
38
+ */
39
+ export declare class HarkenNetworkError extends HarkenError {
40
+ readonly cause?: Error;
41
+ constructor(message: string, cause?: Error);
42
+ /** Network errors are always retryable */
43
+ get isRetryable(): boolean;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,KAAK,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC;AAC5D,KAAK,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC;AAExD;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAC7C,uBAAuB;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACjC,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAG3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAUnC,+CAA+C;IAC/C,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,0CAA0C;IAC1C,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,+CAA+C;IAC/C,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,2CAA2C;IAC3C,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,sCAAsC;IACtC,IAAI,WAAW,IAAI,OAAO,CAEzB;CACF;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;gBAEX,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;IAM1C,0CAA0C;IAC1C,IAAI,WAAW,IAAI,OAAO,CAEzB;CACF"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HarkenNetworkError = exports.HarkenApiError = exports.HarkenError = void 0;
4
+ /**
5
+ * Base error class for Harken API errors.
6
+ */
7
+ class HarkenError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = 'HarkenError';
11
+ }
12
+ }
13
+ exports.HarkenError = HarkenError;
14
+ /**
15
+ * Error thrown when the API returns an error response.
16
+ */
17
+ class HarkenApiError extends HarkenError {
18
+ /** HTTP status code */
19
+ status;
20
+ /** Machine-readable error code */
21
+ code;
22
+ /** Validation error details (if present) */
23
+ details;
24
+ /** Retry-After value in seconds (from 429 responses) */
25
+ retryAfter;
26
+ constructor(status, response, options) {
27
+ super(response.error.message);
28
+ this.name = 'HarkenApiError';
29
+ this.status = status;
30
+ this.code = response.error.code;
31
+ this.details = response.error.details;
32
+ this.retryAfter = options?.retryAfter;
33
+ }
34
+ /** True if this is a validation error (400) */
35
+ get isValidationError() {
36
+ return this.status === 400;
37
+ }
38
+ /** True if this is an auth error (401) */
39
+ get isUnauthorized() {
40
+ return this.status === 401;
41
+ }
42
+ /** True if this is a rate limit error (429) */
43
+ get isRateLimited() {
44
+ return this.status === 429;
45
+ }
46
+ /** True if this is a server error (5xx) */
47
+ get isServerError() {
48
+ return this.status >= 500;
49
+ }
50
+ /** True if this error is retryable */
51
+ get isRetryable() {
52
+ return this.isRateLimited || this.isServerError;
53
+ }
54
+ }
55
+ exports.HarkenApiError = HarkenApiError;
56
+ /**
57
+ * Error thrown when a network request fails.
58
+ */
59
+ class HarkenNetworkError extends HarkenError {
60
+ cause;
61
+ constructor(message, cause) {
62
+ super(message);
63
+ this.name = 'HarkenNetworkError';
64
+ this.cause = cause;
65
+ }
66
+ /** Network errors are always retryable */
67
+ get isRetryable() {
68
+ return true;
69
+ }
70
+ }
71
+ exports.HarkenNetworkError = HarkenNetworkError;
72
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":";;;AAKA;;GAEG;AACH,MAAa,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AALD,kCAKC;AAED;;GAEG;AACH,MAAa,cAAe,SAAQ,WAAW;IAC7C,uBAAuB;IACd,MAAM,CAAS;IACxB,kCAAkC;IACzB,IAAI,CAAS;IACtB,4CAA4C;IACnC,OAAO,CAAiB;IACjC,wDAAwD;IAC/C,UAAU,CAAU;IAE7B,YACE,MAAc,EACd,QAAuB,EACvB,OAAiC;QAEjC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;IACxC,CAAC;IAED,+CAA+C;IAC/C,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IAC7B,CAAC;IAED,0CAA0C;IAC1C,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IAC7B,CAAC;IAED,+CAA+C;IAC/C,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IAC7B,CAAC;IAED,2CAA2C;IAC3C,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC;IAC5B,CAAC;IAED,sCAAsC;IACtC,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC;IAClD,CAAC;CACF;AA/CD,wCA+CC;AAED;;GAEG;AACH,MAAa,kBAAmB,SAAQ,WAAW;IACxC,KAAK,CAAS;IAEvB,YAAY,OAAe,EAAE,KAAa;QACxC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,0CAA0C;IAC1C,IAAI,WAAW;QACb,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAbD,gDAaC"}
@@ -0,0 +1,7 @@
1
+ export { HarkenClient, createHarkenClient } from './client';
2
+ export type { HarkenClientConfig } from './client';
3
+ export { HarkenError, HarkenApiError, HarkenNetworkError, } from './errors';
4
+ export { withRetry, calculateRetryDelay, isRetryableError } from './retry';
5
+ export type { RetryConfig } from './retry';
6
+ export { DEFAULT_RETRY_CONFIG } from './retry';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EACL,WAAW,EACX,cAAc,EACd,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_RETRY_CONFIG = exports.isRetryableError = exports.calculateRetryDelay = exports.withRetry = exports.HarkenNetworkError = exports.HarkenApiError = exports.HarkenError = exports.createHarkenClient = exports.HarkenClient = void 0;
4
+ // Client
5
+ var client_1 = require("./client");
6
+ Object.defineProperty(exports, "HarkenClient", { enumerable: true, get: function () { return client_1.HarkenClient; } });
7
+ Object.defineProperty(exports, "createHarkenClient", { enumerable: true, get: function () { return client_1.createHarkenClient; } });
8
+ // Errors
9
+ var errors_1 = require("./errors");
10
+ Object.defineProperty(exports, "HarkenError", { enumerable: true, get: function () { return errors_1.HarkenError; } });
11
+ Object.defineProperty(exports, "HarkenApiError", { enumerable: true, get: function () { return errors_1.HarkenApiError; } });
12
+ Object.defineProperty(exports, "HarkenNetworkError", { enumerable: true, get: function () { return errors_1.HarkenNetworkError; } });
13
+ // Retry utilities
14
+ var retry_1 = require("./retry");
15
+ Object.defineProperty(exports, "withRetry", { enumerable: true, get: function () { return retry_1.withRetry; } });
16
+ Object.defineProperty(exports, "calculateRetryDelay", { enumerable: true, get: function () { return retry_1.calculateRetryDelay; } });
17
+ Object.defineProperty(exports, "isRetryableError", { enumerable: true, get: function () { return retry_1.isRetryableError; } });
18
+ var retry_2 = require("./retry");
19
+ Object.defineProperty(exports, "DEFAULT_RETRY_CONFIG", { enumerable: true, get: function () { return retry_2.DEFAULT_RETRY_CONFIG; } });
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":";;;AAAA,SAAS;AACT,mCAA4D;AAAnD,sGAAA,YAAY,OAAA;AAAE,4GAAA,kBAAkB,OAAA;AAGzC,SAAS;AACT,mCAIkB;AAHhB,qGAAA,WAAW,OAAA;AACX,wGAAA,cAAc,OAAA;AACd,4GAAA,kBAAkB,OAAA;AAGpB,kBAAkB;AAClB,iCAA2E;AAAlE,kGAAA,SAAS,OAAA;AAAE,4GAAA,mBAAmB,OAAA;AAAE,yGAAA,gBAAgB,OAAA;AAEzD,iCAA+C;AAAtC,6GAAA,oBAAoB,OAAA"}
@@ -0,0 +1,29 @@
1
+ import { HarkenApiError, HarkenNetworkError } from './errors';
2
+ export interface RetryConfig {
3
+ /** Maximum number of retry attempts (default: 3) */
4
+ maxRetries: number;
5
+ /** Base delay in ms for exponential backoff (default: 1000) */
6
+ baseDelay: number;
7
+ /** Maximum delay in ms (default: 30000) */
8
+ maxDelay: number;
9
+ /** Jitter factor 0-1 to randomize delays (default: 0.1) */
10
+ jitter: number;
11
+ }
12
+ export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
13
+ /**
14
+ * Calculate delay for a retry attempt with exponential backoff and jitter.
15
+ */
16
+ export declare function calculateRetryDelay(attempt: number, config: RetryConfig, retryAfter?: number): number;
17
+ /**
18
+ * Check if an error is retryable.
19
+ */
20
+ export declare function isRetryableError(error: unknown): error is HarkenApiError | HarkenNetworkError;
21
+ /**
22
+ * Sleep for a given number of milliseconds.
23
+ */
24
+ export declare function sleep(ms: number): Promise<void>;
25
+ /**
26
+ * Execute a function with retry logic.
27
+ */
28
+ export declare function withRetry<T>(fn: () => Promise<T>, config?: Partial<RetryConfig>): Promise<T>;
29
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/api/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,EAAE,WAKlC,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAeR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,cAAc,GAAG,kBAAkB,CAQ9C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC,OAAO,CAAC,CAAC,CAAC,CA0BZ"}