@jammysunshine/astrology-api-client 1.0.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.
@@ -0,0 +1,28 @@
1
+ const { v4: uuid } = require('uuid');
2
+
3
+ /**
4
+ * Request Batcher for aggregating independent calls (SDK Sec 9.B)
5
+ */
6
+ class RequestBatcher {
7
+ constructor(apiClient) {
8
+ this.apiClient = apiClient;
9
+ }
10
+
11
+ async batch(calls) {
12
+ const payload = {
13
+ requestId: uuid(),
14
+ timestamp: new Date().toISOString(),
15
+ isBatch: true,
16
+ requests: calls.map(c => ({
17
+ service: c.service,
18
+ method: c.method,
19
+ params: c.params
20
+ }))
21
+ };
22
+
23
+ const result = await this.apiClient._executeRequest('gateway', 'batch', payload);
24
+ return result.results;
25
+ }
26
+ }
27
+
28
+ module.exports = RequestBatcher;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Detects response types: JSON, Text (AI), or Binary (Charts/PDFs)
3
+ */
4
+ class ResponseDetective {
5
+ static detect(response) {
6
+ const contentType = response.headers['content-type'] || '';
7
+
8
+ if (contentType.includes('application/json')) {
9
+ return 'JSON';
10
+ }
11
+
12
+ if (contentType.includes('image/') || contentType.includes('application/pdf')) {
13
+ return 'BINARY';
14
+ }
15
+
16
+ if (contentType.includes('text/plain')) {
17
+ return 'TEXT';
18
+ }
19
+
20
+ return 'UNKNOWN';
21
+ }
22
+ }
23
+
24
+ module.exports = ResponseDetective;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Shared SDK Formatter for consistent cross-platform data structures (SDK Sec 11.C)
3
+ */
4
+ class SDKFormatter {
5
+ /**
6
+ * Structures chat responses consistently across WhatsApp and Mobile UIs
7
+ */
8
+ static formatChatResponse(data) {
9
+ return {
10
+ text: data.summary || data.text || data.interpretation || '',
11
+ buttons: (data.suggestions || []).map(s => ({
12
+ id: s.id || s.action,
13
+ title: s.label || s.title || s.text
14
+ })).slice(0, 3), // Standard Meta Button Limit
15
+ list: (data.options || []).map(o => ({
16
+ id: o.id || o.value,
17
+ title: o.label || o.title,
18
+ description: o.description || o.desc
19
+ })).slice(0, 10), // Standard Meta List Limit
20
+ metadata: data.metadata || {}
21
+ };
22
+ }
23
+
24
+ static formatMessage(data) {
25
+ // Shared structure for chat-like responses
26
+ return {
27
+ text: data.summary || data.text || '',
28
+ metadata: data.metadata || {},
29
+ actions: data.suggestions || []
30
+ };
31
+ }
32
+
33
+ static wrapBinary(buffer, type) {
34
+ return {
35
+ type: 'BINARY',
36
+ buffer,
37
+ contentType: type,
38
+ length: buffer.byteLength
39
+ };
40
+ }
41
+ }
42
+
43
+ module.exports = SDKFormatter;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Exponential Backoff Retry Utility
3
+ */
4
+ async function retry(fn, options = {}) {
5
+ const {
6
+ maxAttempts = 3,
7
+ initialDelay = 500,
8
+ maxDelay = 2000,
9
+ shouldRetry = (err) => !err.code || err.code === 'TIMEOUT' || err.code === 'ECONNRESET'
10
+ } = options;
11
+
12
+ let attempt = 1;
13
+ let delay = initialDelay;
14
+
15
+ while (attempt <= maxAttempts) {
16
+ try {
17
+ return await fn();
18
+ } catch (error) {
19
+ if (attempt >= maxAttempts || !shouldRetry(error)) {
20
+ throw error;
21
+ }
22
+
23
+ console.warn(`Attempt ${attempt} failed. Retrying in ${delay}ms...`);
24
+ await new Promise(resolve => setTimeout(resolve, delay));
25
+
26
+ attempt++;
27
+ // SDK Sec 7.B: Exponential backoff (500ms -> 1s -> 2s)
28
+ delay = Math.pow(2, attempt - 1) * initialDelay;
29
+ delay = Math.min(delay, maxDelay);
30
+ }
31
+ }
32
+ }
33
+
34
+ module.exports = retry;