@rooguys/sdk 0.1.0 → 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.
- package/README.md +478 -113
- package/dist/__tests__/utils/mockClient.d.ts +65 -3
- package/dist/__tests__/utils/mockClient.js +144 -5
- package/dist/errors.d.ts +123 -0
- package/dist/errors.js +163 -0
- package/dist/http-client.d.ts +167 -0
- package/dist/http-client.js +250 -0
- package/dist/index.d.ts +160 -10
- package/dist/index.js +585 -146
- package/dist/types.d.ts +372 -50
- package/dist/types.js +21 -0
- package/package.json +1 -1
- package/src/__tests__/property/request-construction.property.test.ts +142 -91
- package/src/__tests__/property/response-parsing.property.test.ts +118 -67
- package/src/__tests__/property/sdk-modules.property.test.ts +450 -0
- package/src/__tests__/unit/aha.test.ts +61 -50
- package/src/__tests__/unit/badges.test.ts +27 -33
- package/src/__tests__/unit/config.test.ts +94 -126
- package/src/__tests__/unit/errors.test.ts +106 -150
- package/src/__tests__/unit/events.test.ts +119 -144
- package/src/__tests__/unit/leaderboards.test.ts +173 -40
- package/src/__tests__/unit/levels.test.ts +25 -33
- package/src/__tests__/unit/questionnaires.test.ts +33 -42
- package/src/__tests__/unit/users.test.ts +214 -99
- package/src/__tests__/utils/mockClient.ts +193 -6
- package/src/errors.ts +255 -0
- package/src/http-client.ts +433 -0
- package/src/index.ts +742 -150
- package/src/types.ts +429 -51
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rooguys Node.js SDK HTTP Client
|
|
4
|
+
* Handles standardized response format, rate limit headers, and error mapping
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.HttpClient = void 0;
|
|
11
|
+
exports.extractRateLimitInfo = extractRateLimitInfo;
|
|
12
|
+
exports.extractRequestId = extractRequestId;
|
|
13
|
+
exports.parseResponseBody = parseResponseBody;
|
|
14
|
+
const axios_1 = __importDefault(require("axios"));
|
|
15
|
+
const errors_1 = require("./errors");
|
|
16
|
+
/**
|
|
17
|
+
* Extract rate limit information from response headers
|
|
18
|
+
* @param headers - Response headers (axios format)
|
|
19
|
+
* @returns Rate limit info
|
|
20
|
+
*/
|
|
21
|
+
function extractRateLimitInfo(headers) {
|
|
22
|
+
const getHeader = (name) => {
|
|
23
|
+
return headers[name] || headers[name.toLowerCase()];
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
limit: parseInt(getHeader('X-RateLimit-Limit') || getHeader('x-ratelimit-limit') || '1000', 10),
|
|
27
|
+
remaining: parseInt(getHeader('X-RateLimit-Remaining') || getHeader('x-ratelimit-remaining') || '1000', 10),
|
|
28
|
+
reset: parseInt(getHeader('X-RateLimit-Reset') || getHeader('x-ratelimit-reset') || '0', 10),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extract request ID from response headers or body
|
|
33
|
+
* @param headers - Response headers
|
|
34
|
+
* @param body - Response body
|
|
35
|
+
* @returns Request ID or null
|
|
36
|
+
*/
|
|
37
|
+
function extractRequestId(headers, body) {
|
|
38
|
+
// Try headers first
|
|
39
|
+
const getHeader = (name) => {
|
|
40
|
+
return headers[name] || headers[name.toLowerCase()];
|
|
41
|
+
};
|
|
42
|
+
const headerRequestId = getHeader('X-Request-Id') || getHeader('x-request-id');
|
|
43
|
+
if (headerRequestId) {
|
|
44
|
+
return headerRequestId;
|
|
45
|
+
}
|
|
46
|
+
// Fall back to body
|
|
47
|
+
if (body && typeof body === 'object') {
|
|
48
|
+
const bodyObj = body;
|
|
49
|
+
return bodyObj.request_id || bodyObj.requestId || null;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parse standardized API response format
|
|
55
|
+
* Handles both new format { success: true, data: {...} } and legacy format
|
|
56
|
+
* @param body - Response body
|
|
57
|
+
* @returns Parsed response with data and metadata
|
|
58
|
+
*/
|
|
59
|
+
function parseResponseBody(body) {
|
|
60
|
+
if (!body || typeof body !== 'object') {
|
|
61
|
+
return {
|
|
62
|
+
data: body,
|
|
63
|
+
pagination: null,
|
|
64
|
+
requestId: null,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const bodyObj = body;
|
|
68
|
+
// New standardized format with { success: true, data: {...} }
|
|
69
|
+
if (typeof bodyObj.success === 'boolean') {
|
|
70
|
+
if (bodyObj.success) {
|
|
71
|
+
// If there's a data field, unwrap it; otherwise return the whole body
|
|
72
|
+
// This handles both { success: true, data: {...} } and { success: true, message: "..." }
|
|
73
|
+
const data = 'data' in bodyObj ? bodyObj.data : body;
|
|
74
|
+
return {
|
|
75
|
+
data: data,
|
|
76
|
+
pagination: bodyObj.pagination || null,
|
|
77
|
+
requestId: bodyObj.request_id || null,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// Error response in standardized format
|
|
81
|
+
return {
|
|
82
|
+
error: bodyObj.error,
|
|
83
|
+
requestId: bodyObj.request_id || null,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Legacy format - return as-is
|
|
87
|
+
return {
|
|
88
|
+
data: body,
|
|
89
|
+
pagination: bodyObj.pagination || null,
|
|
90
|
+
requestId: null,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* HTTP Client class for making API requests
|
|
95
|
+
*/
|
|
96
|
+
class HttpClient {
|
|
97
|
+
constructor(apiKey, options = {}) {
|
|
98
|
+
this.apiKey = apiKey;
|
|
99
|
+
this.baseUrl = options.baseUrl || 'https://api.rooguys.com/v1';
|
|
100
|
+
this.timeout = options.timeout || 10000;
|
|
101
|
+
this.onRateLimitWarning = options.onRateLimitWarning || null;
|
|
102
|
+
this.autoRetry = options.autoRetry || false;
|
|
103
|
+
this.maxRetries = options.maxRetries || 3;
|
|
104
|
+
this.retryDelay = options.retryDelay || 1000;
|
|
105
|
+
this.client = axios_1.default.create({
|
|
106
|
+
baseURL: this.baseUrl,
|
|
107
|
+
timeout: this.timeout,
|
|
108
|
+
headers: {
|
|
109
|
+
'x-api-key': this.apiKey,
|
|
110
|
+
'Content-Type': 'application/json',
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sleep for a specified duration
|
|
116
|
+
* @param ms - Milliseconds to sleep
|
|
117
|
+
*/
|
|
118
|
+
sleep(ms) {
|
|
119
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Build query string from params object
|
|
123
|
+
* @param params - Query parameters
|
|
124
|
+
* @returns Cleaned params object
|
|
125
|
+
*/
|
|
126
|
+
buildParams(params) {
|
|
127
|
+
const cleaned = {};
|
|
128
|
+
for (const [key, value] of Object.entries(params)) {
|
|
129
|
+
if (value !== undefined && value !== null) {
|
|
130
|
+
cleaned[key] = value;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return cleaned;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Make an HTTP request with optional auto-retry for rate limits
|
|
137
|
+
* @param config - Request configuration
|
|
138
|
+
* @param retryCount - Current retry attempt (internal use)
|
|
139
|
+
* @returns API response with data and metadata
|
|
140
|
+
*/
|
|
141
|
+
async request(config, retryCount = 0) {
|
|
142
|
+
var _a, _b, _c;
|
|
143
|
+
const { method = 'GET', path, params = {}, body = null, headers = {}, idempotencyKey = undefined, timeout, } = config;
|
|
144
|
+
// Build request config
|
|
145
|
+
const requestConfig = {
|
|
146
|
+
method,
|
|
147
|
+
url: path,
|
|
148
|
+
params: this.buildParams(params),
|
|
149
|
+
headers: { ...headers },
|
|
150
|
+
};
|
|
151
|
+
if (body !== null) {
|
|
152
|
+
requestConfig.data = body;
|
|
153
|
+
}
|
|
154
|
+
if (timeout) {
|
|
155
|
+
requestConfig.timeout = timeout;
|
|
156
|
+
}
|
|
157
|
+
// Add idempotency key if provided
|
|
158
|
+
if (idempotencyKey) {
|
|
159
|
+
requestConfig.headers = {
|
|
160
|
+
...requestConfig.headers,
|
|
161
|
+
'X-Idempotency-Key': idempotencyKey,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const response = await this.client.request(requestConfig);
|
|
166
|
+
// Extract headers info
|
|
167
|
+
const rateLimit = extractRateLimitInfo(response.headers);
|
|
168
|
+
// Check for rate limit warning (80% consumed)
|
|
169
|
+
if (rateLimit.remaining < rateLimit.limit * 0.2 && this.onRateLimitWarning) {
|
|
170
|
+
this.onRateLimitWarning(rateLimit);
|
|
171
|
+
}
|
|
172
|
+
// Extract request ID
|
|
173
|
+
const requestId = extractRequestId(response.headers, response.data);
|
|
174
|
+
// Parse response body
|
|
175
|
+
const parsed = parseResponseBody(response.data);
|
|
176
|
+
// Check for error in standardized format
|
|
177
|
+
if (parsed.error) {
|
|
178
|
+
throw (0, errors_1.mapStatusToError)(400, { error: parsed.error }, requestId, {});
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
data: parsed.data,
|
|
182
|
+
requestId: requestId || parsed.requestId || null,
|
|
183
|
+
rateLimit,
|
|
184
|
+
pagination: parsed.pagination,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
// Re-throw RooguysError instances
|
|
189
|
+
if (error instanceof errors_1.RooguysError) {
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
// Handle Axios errors
|
|
193
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
194
|
+
const axiosError = error;
|
|
195
|
+
const status = ((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.status) || 0;
|
|
196
|
+
const responseData = ((_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.data) || null;
|
|
197
|
+
const responseHeaders = (((_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.headers) || {});
|
|
198
|
+
const requestId = extractRequestId(responseHeaders, responseData);
|
|
199
|
+
const mappedError = (0, errors_1.mapStatusToError)(status, responseData, requestId, {
|
|
200
|
+
'retry-after': responseHeaders['retry-after'],
|
|
201
|
+
'Retry-After': responseHeaders['Retry-After'],
|
|
202
|
+
});
|
|
203
|
+
// Auto-retry for rate limit errors if enabled
|
|
204
|
+
if (this.autoRetry && mappedError instanceof errors_1.RateLimitError && retryCount < this.maxRetries) {
|
|
205
|
+
const retryAfterMs = mappedError.retryAfter * 1000;
|
|
206
|
+
await this.sleep(retryAfterMs);
|
|
207
|
+
return this.request(config, retryCount + 1);
|
|
208
|
+
}
|
|
209
|
+
throw mappedError;
|
|
210
|
+
}
|
|
211
|
+
// Handle timeout
|
|
212
|
+
if (error instanceof Error && error.message.includes('timeout')) {
|
|
213
|
+
throw new errors_1.RooguysError('Request timeout', { code: 'TIMEOUT', statusCode: 408 });
|
|
214
|
+
}
|
|
215
|
+
// Handle other errors
|
|
216
|
+
throw new errors_1.RooguysError(error instanceof Error ? error.message : 'Network error', { code: 'NETWORK_ERROR', statusCode: 0 });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Convenience method for GET requests
|
|
221
|
+
*/
|
|
222
|
+
get(path, params = {}, options = {}) {
|
|
223
|
+
return this.request({ method: 'GET', path, params, ...options });
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Convenience method for POST requests
|
|
227
|
+
*/
|
|
228
|
+
post(path, body = null, options = {}) {
|
|
229
|
+
return this.request({ method: 'POST', path, body, ...options });
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Convenience method for PUT requests
|
|
233
|
+
*/
|
|
234
|
+
put(path, body = null, options = {}) {
|
|
235
|
+
return this.request({ method: 'PUT', path, body, ...options });
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Convenience method for PATCH requests
|
|
239
|
+
*/
|
|
240
|
+
patch(path, body = null, options = {}) {
|
|
241
|
+
return this.request({ method: 'PATCH', path, body, ...options });
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Convenience method for DELETE requests
|
|
245
|
+
*/
|
|
246
|
+
delete(path, options = {}) {
|
|
247
|
+
return this.request({ method: 'DELETE', path, ...options });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.HttpClient = HttpClient;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,47 +1,197 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Rooguys Node.js SDK
|
|
3
|
+
* Official TypeScript SDK for the Rooguys Gamification Platform
|
|
4
|
+
*/
|
|
5
|
+
import { RooguysOptions, UserProfile, UserBadge, UserRank, LeaderboardResult, LeaderboardFilterOptions, AroundUserResponse, TrackEventResponse, TrackOptions, BatchEvent, BatchTrackResponse, BatchOptions, CreateUserData, UpdateUserData, BatchCreateResponse, GetUserOptions, SearchOptions, PaginatedResponse, AnswerSubmission, AhaDeclarationResult, AhaScoreResult, BadgeListResult, LevelListResult, Questionnaire, LeaderboardListResult, HealthCheckResponse, Timeframe } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Main Rooguys SDK class
|
|
8
|
+
*/
|
|
2
9
|
export declare class Rooguys {
|
|
3
|
-
private
|
|
4
|
-
|
|
10
|
+
private _httpClient;
|
|
11
|
+
readonly apiKey: string;
|
|
12
|
+
readonly baseUrl: string;
|
|
13
|
+
readonly timeout: number;
|
|
14
|
+
/**
|
|
15
|
+
* Create a new Rooguys SDK instance
|
|
16
|
+
* @param apiKey - API key for authentication
|
|
17
|
+
* @param options - Configuration options
|
|
18
|
+
*/
|
|
5
19
|
constructor(apiKey: string, options?: RooguysOptions);
|
|
20
|
+
/**
|
|
21
|
+
* Validate email format client-side
|
|
22
|
+
*/
|
|
23
|
+
private isValidEmail;
|
|
24
|
+
/**
|
|
25
|
+
* Build request body with only provided fields (partial update support)
|
|
26
|
+
*/
|
|
27
|
+
private buildUserRequestBody;
|
|
28
|
+
/**
|
|
29
|
+
* Parse user profile to include activity summary, streak, and inventory
|
|
30
|
+
*/
|
|
31
|
+
private parseUserProfile;
|
|
32
|
+
/**
|
|
33
|
+
* Build filter query parameters from options
|
|
34
|
+
*/
|
|
35
|
+
private buildFilterParams;
|
|
36
|
+
/**
|
|
37
|
+
* Parse leaderboard response to include cache metadata and percentile ranks
|
|
38
|
+
*/
|
|
39
|
+
private parseLeaderboardResponse;
|
|
40
|
+
/**
|
|
41
|
+
* Events module for tracking user events
|
|
42
|
+
*/
|
|
6
43
|
events: {
|
|
7
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Track a single event
|
|
46
|
+
*/
|
|
47
|
+
track: (eventName: string, userId: string, properties?: Record<string, unknown>, options?: TrackOptions) => Promise<TrackEventResponse>;
|
|
48
|
+
/**
|
|
49
|
+
* Track multiple events in a single request (batch operation)
|
|
50
|
+
*/
|
|
51
|
+
trackBatch: (events: BatchEvent[], options?: BatchOptions) => Promise<BatchTrackResponse>;
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated Use track() instead. The /v1/event endpoint is deprecated.
|
|
54
|
+
*/
|
|
55
|
+
trackLegacy: (eventName: string, userId: string, properties?: Record<string, unknown>, options?: {
|
|
8
56
|
includeProfile?: boolean;
|
|
9
57
|
}) => Promise<TrackEventResponse>;
|
|
10
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* Users module for user management and queries
|
|
61
|
+
*/
|
|
11
62
|
users: {
|
|
12
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Create a new user
|
|
65
|
+
*/
|
|
66
|
+
create: (userData: CreateUserData) => Promise<UserProfile>;
|
|
67
|
+
/**
|
|
68
|
+
* Update an existing user
|
|
69
|
+
*/
|
|
70
|
+
update: (userId: string, userData: UpdateUserData) => Promise<UserProfile>;
|
|
71
|
+
/**
|
|
72
|
+
* Create multiple users in a single request (batch operation)
|
|
73
|
+
*/
|
|
74
|
+
createBatch: (users: CreateUserData[]) => Promise<BatchCreateResponse>;
|
|
75
|
+
/**
|
|
76
|
+
* Get user profile with optional field selection
|
|
77
|
+
*/
|
|
78
|
+
get: (userId: string, options?: GetUserOptions) => Promise<UserProfile>;
|
|
79
|
+
/**
|
|
80
|
+
* Search users with pagination
|
|
81
|
+
*/
|
|
82
|
+
search: (query: string, options?: SearchOptions) => Promise<PaginatedResponse<UserProfile>>;
|
|
83
|
+
/**
|
|
84
|
+
* Get multiple user profiles
|
|
85
|
+
*/
|
|
13
86
|
getBulk: (userIds: string[]) => Promise<{
|
|
14
87
|
users: UserProfile[];
|
|
15
88
|
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Get user badges
|
|
91
|
+
*/
|
|
16
92
|
getBadges: (userId: string) => Promise<{
|
|
17
93
|
badges: UserBadge[];
|
|
18
94
|
}>;
|
|
19
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Get user rank
|
|
97
|
+
*/
|
|
98
|
+
getRank: (userId: string, timeframe?: Timeframe) => Promise<UserRank>;
|
|
99
|
+
/**
|
|
100
|
+
* Submit questionnaire answers
|
|
101
|
+
*/
|
|
20
102
|
submitAnswers: (userId: string, questionnaireId: string, answers: AnswerSubmission[]) => Promise<{
|
|
21
103
|
status: string;
|
|
22
104
|
message: string;
|
|
23
105
|
}>;
|
|
24
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* Leaderboards module for ranking queries
|
|
109
|
+
*/
|
|
25
110
|
leaderboards: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Get global leaderboard with optional filters
|
|
113
|
+
*/
|
|
114
|
+
getGlobal: (timeframeOrOptions?: Timeframe | LeaderboardFilterOptions, page?: number, limit?: number, options?: LeaderboardFilterOptions) => Promise<LeaderboardResult>;
|
|
115
|
+
/**
|
|
116
|
+
* List all leaderboards
|
|
117
|
+
*/
|
|
118
|
+
list: (pageOrOptions?: number | {
|
|
119
|
+
page?: number;
|
|
120
|
+
limit?: number;
|
|
121
|
+
search?: string;
|
|
122
|
+
}, limit?: number, search?: string | null) => Promise<LeaderboardListResult>;
|
|
123
|
+
/**
|
|
124
|
+
* Get custom leaderboard with optional filters
|
|
125
|
+
*/
|
|
126
|
+
getCustom: (leaderboardId: string, pageOrOptions?: number | LeaderboardFilterOptions, limit?: number, search?: string | null, options?: LeaderboardFilterOptions) => Promise<LeaderboardResult>;
|
|
127
|
+
/**
|
|
128
|
+
* Get user rank in leaderboard
|
|
129
|
+
*/
|
|
29
130
|
getUserRank: (leaderboardId: string, userId: string) => Promise<UserRank>;
|
|
131
|
+
/**
|
|
132
|
+
* Get leaderboard entries around a specific user ("around me" view)
|
|
133
|
+
*/
|
|
134
|
+
getAroundUser: (leaderboardId: string, userId: string, range?: number) => Promise<AroundUserResponse>;
|
|
30
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* Badges module for badge queries
|
|
138
|
+
*/
|
|
31
139
|
badges: {
|
|
140
|
+
/**
|
|
141
|
+
* List all badges
|
|
142
|
+
*/
|
|
32
143
|
list: (page?: number, limit?: number, activeOnly?: boolean) => Promise<BadgeListResult>;
|
|
33
144
|
};
|
|
145
|
+
/**
|
|
146
|
+
* Levels module for level queries
|
|
147
|
+
*/
|
|
34
148
|
levels: {
|
|
149
|
+
/**
|
|
150
|
+
* List all levels
|
|
151
|
+
*/
|
|
35
152
|
list: (page?: number, limit?: number) => Promise<LevelListResult>;
|
|
36
153
|
};
|
|
154
|
+
/**
|
|
155
|
+
* Questionnaires module for questionnaire queries
|
|
156
|
+
*/
|
|
37
157
|
questionnaires: {
|
|
158
|
+
/**
|
|
159
|
+
* Get questionnaire by slug
|
|
160
|
+
*/
|
|
38
161
|
get: (slug: string) => Promise<Questionnaire>;
|
|
162
|
+
/**
|
|
163
|
+
* Get active questionnaire
|
|
164
|
+
*/
|
|
39
165
|
getActive: () => Promise<Questionnaire>;
|
|
40
166
|
};
|
|
167
|
+
/**
|
|
168
|
+
* Aha moment module for engagement tracking
|
|
169
|
+
*/
|
|
41
170
|
aha: {
|
|
171
|
+
/**
|
|
172
|
+
* Declare aha moment score
|
|
173
|
+
*/
|
|
42
174
|
declare: (userId: string, value: number) => Promise<AhaDeclarationResult>;
|
|
175
|
+
/**
|
|
176
|
+
* Get user aha score
|
|
177
|
+
*/
|
|
43
178
|
getUserScore: (userId: string) => Promise<AhaScoreResult>;
|
|
44
179
|
};
|
|
45
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Health module for API health checks
|
|
182
|
+
*/
|
|
183
|
+
health: {
|
|
184
|
+
/**
|
|
185
|
+
* Check API health status
|
|
186
|
+
*/
|
|
187
|
+
check: () => Promise<HealthCheckResponse>;
|
|
188
|
+
/**
|
|
189
|
+
* Quick availability check
|
|
190
|
+
*/
|
|
191
|
+
isReady: () => Promise<boolean>;
|
|
192
|
+
};
|
|
46
193
|
}
|
|
194
|
+
export { RooguysError, ValidationError, AuthenticationError, ForbiddenError, NotFoundError, ConflictError, RateLimitError, ServerError, mapStatusToError, } from './errors';
|
|
195
|
+
export { HttpClient, extractRateLimitInfo, extractRequestId, parseResponseBody, } from './http-client';
|
|
196
|
+
export * from './types';
|
|
47
197
|
export default Rooguys;
|