@rooguys/sdk 0.1.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.js ADDED
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Rooguys = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ class Rooguys {
9
+ constructor(apiKey, options = {}) {
10
+ this.apiKey = apiKey;
11
+ this.events = {
12
+ track: async (eventName, userId, properties = {}, options = {}) => {
13
+ try {
14
+ const response = await this.client.post('/event', {
15
+ event_name: eventName,
16
+ user_id: userId,
17
+ properties,
18
+ }, {
19
+ params: {
20
+ include_profile: options.includeProfile,
21
+ },
22
+ });
23
+ return response.data;
24
+ }
25
+ catch (error) {
26
+ throw this.handleError(error);
27
+ }
28
+ },
29
+ };
30
+ this.users = {
31
+ get: async (userId) => {
32
+ try {
33
+ const response = await this.client.get(`/user/${encodeURIComponent(userId)}`);
34
+ return response.data;
35
+ }
36
+ catch (error) {
37
+ throw this.handleError(error);
38
+ }
39
+ },
40
+ getBulk: async (userIds) => {
41
+ try {
42
+ const response = await this.client.post('/users/bulk', { user_ids: userIds });
43
+ return response.data;
44
+ }
45
+ catch (error) {
46
+ throw this.handleError(error);
47
+ }
48
+ },
49
+ getBadges: async (userId) => {
50
+ try {
51
+ const response = await this.client.get(`/user/${encodeURIComponent(userId)}/badges`);
52
+ return response.data;
53
+ }
54
+ catch (error) {
55
+ throw this.handleError(error);
56
+ }
57
+ },
58
+ getRank: async (userId, timeframe = 'all-time') => {
59
+ try {
60
+ const response = await this.client.get(`/user/${encodeURIComponent(userId)}/rank`, {
61
+ params: { timeframe },
62
+ });
63
+ return response.data;
64
+ }
65
+ catch (error) {
66
+ throw this.handleError(error);
67
+ }
68
+ },
69
+ submitAnswers: async (userId, questionnaireId, answers) => {
70
+ try {
71
+ const response = await this.client.post(`/user/${encodeURIComponent(userId)}/answers`, {
72
+ questionnaire_id: questionnaireId,
73
+ answers,
74
+ });
75
+ return response.data;
76
+ }
77
+ catch (error) {
78
+ throw this.handleError(error);
79
+ }
80
+ },
81
+ };
82
+ this.leaderboards = {
83
+ getGlobal: async (timeframe = 'all-time', page = 1, limit = 50) => {
84
+ try {
85
+ const response = await this.client.get('/leaderboard', {
86
+ params: { timeframe, page, limit },
87
+ });
88
+ return response.data;
89
+ }
90
+ catch (error) {
91
+ throw this.handleError(error);
92
+ }
93
+ },
94
+ list: async (page = 1, limit = 50, search) => {
95
+ try {
96
+ const params = { page, limit };
97
+ if (search) {
98
+ params.search = search;
99
+ }
100
+ const response = await this.client.get('/leaderboards', { params });
101
+ return response.data;
102
+ }
103
+ catch (error) {
104
+ throw this.handleError(error);
105
+ }
106
+ },
107
+ getCustom: async (leaderboardId, page = 1, limit = 50, search) => {
108
+ try {
109
+ const params = { page, limit };
110
+ if (search) {
111
+ params.search = search;
112
+ }
113
+ const response = await this.client.get(`/leaderboard/${encodeURIComponent(leaderboardId)}`, { params });
114
+ return response.data;
115
+ }
116
+ catch (error) {
117
+ throw this.handleError(error);
118
+ }
119
+ },
120
+ getUserRank: async (leaderboardId, userId) => {
121
+ try {
122
+ const response = await this.client.get(`/leaderboard/${encodeURIComponent(leaderboardId)}/user/${encodeURIComponent(userId)}/rank`);
123
+ return response.data;
124
+ }
125
+ catch (error) {
126
+ throw this.handleError(error);
127
+ }
128
+ },
129
+ };
130
+ this.badges = {
131
+ list: async (page = 1, limit = 50, activeOnly = false) => {
132
+ try {
133
+ const response = await this.client.get('/badges', {
134
+ params: { page, limit, active_only: activeOnly },
135
+ });
136
+ return response.data;
137
+ }
138
+ catch (error) {
139
+ throw this.handleError(error);
140
+ }
141
+ },
142
+ };
143
+ this.levels = {
144
+ list: async (page = 1, limit = 50) => {
145
+ try {
146
+ const response = await this.client.get('/levels', {
147
+ params: { page, limit },
148
+ });
149
+ return response.data;
150
+ }
151
+ catch (error) {
152
+ throw this.handleError(error);
153
+ }
154
+ },
155
+ };
156
+ this.questionnaires = {
157
+ get: async (slug) => {
158
+ try {
159
+ const response = await this.client.get(`/questionnaire/${slug}`);
160
+ return response.data;
161
+ }
162
+ catch (error) {
163
+ throw this.handleError(error);
164
+ }
165
+ },
166
+ getActive: async () => {
167
+ try {
168
+ const response = await this.client.get('/questionnaire/active');
169
+ return response.data;
170
+ }
171
+ catch (error) {
172
+ throw this.handleError(error);
173
+ }
174
+ },
175
+ };
176
+ this.aha = {
177
+ declare: async (userId, value) => {
178
+ // Validate value is between 1 and 5
179
+ if (!Number.isInteger(value) || value < 1 || value > 5) {
180
+ throw new Error('Aha score value must be an integer between 1 and 5');
181
+ }
182
+ try {
183
+ const response = await this.client.post('/aha/declare', {
184
+ user_id: userId,
185
+ value,
186
+ });
187
+ return response.data;
188
+ }
189
+ catch (error) {
190
+ throw this.handleError(error);
191
+ }
192
+ },
193
+ getUserScore: async (userId) => {
194
+ try {
195
+ const response = await this.client.get(`/users/${encodeURIComponent(userId)}/aha`);
196
+ return response.data;
197
+ }
198
+ catch (error) {
199
+ throw this.handleError(error);
200
+ }
201
+ },
202
+ };
203
+ this.client = axios_1.default.create({
204
+ baseURL: options.baseUrl || 'https://api.rooguys.com/v1',
205
+ timeout: options.timeout || 10000,
206
+ headers: {
207
+ 'x-api-key': this.apiKey,
208
+ 'Content-Type': 'application/json',
209
+ },
210
+ });
211
+ }
212
+ handleError(error) {
213
+ var _a, _b;
214
+ if (axios_1.default.isAxiosError(error)) {
215
+ const message = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || error.message;
216
+ return new Error(message);
217
+ }
218
+ return error;
219
+ }
220
+ }
221
+ exports.Rooguys = Rooguys;
222
+ exports.default = Rooguys;
@@ -0,0 +1,148 @@
1
+ export interface RooguysOptions {
2
+ baseUrl?: string;
3
+ timeout?: number;
4
+ }
5
+ export interface UserProfile {
6
+ user_id: string;
7
+ points: number;
8
+ persona: string | null;
9
+ level: {
10
+ id: string;
11
+ name: string;
12
+ level_number: number;
13
+ points_required: number;
14
+ } | null;
15
+ next_level: {
16
+ id: string;
17
+ name: string;
18
+ level_number: number;
19
+ points_required: number;
20
+ points_needed: number;
21
+ } | null;
22
+ metrics: Record<string, any>;
23
+ badges: UserBadge[];
24
+ }
25
+ export interface UserBadge {
26
+ id: string;
27
+ name: string;
28
+ description: string;
29
+ icon_url: string;
30
+ earned_at: string;
31
+ }
32
+ export interface UserRank {
33
+ user_id: string;
34
+ rank: number;
35
+ points: number;
36
+ total_users: number;
37
+ }
38
+ export interface LeaderboardEntry {
39
+ rank: number;
40
+ user_id: string;
41
+ points: number;
42
+ level: {
43
+ id: string;
44
+ name: string;
45
+ level_number: number;
46
+ } | null;
47
+ }
48
+ export interface LeaderboardResult {
49
+ timeframe: string;
50
+ page: number;
51
+ limit: number;
52
+ total: number;
53
+ rankings: LeaderboardEntry[];
54
+ }
55
+ export interface TrackEventResponse {
56
+ status: string;
57
+ message: string;
58
+ profile?: UserProfile;
59
+ }
60
+ export interface AnswerSubmission {
61
+ question_id: string;
62
+ answer_option_id: string;
63
+ }
64
+ export interface AhaDeclarationResult {
65
+ success: boolean;
66
+ message: string;
67
+ }
68
+ export interface AhaScoreResult {
69
+ success: boolean;
70
+ data: {
71
+ user_id: string;
72
+ current_score: number;
73
+ declarative_score: number | null;
74
+ inferred_score: number | null;
75
+ status: 'not_started' | 'progressing' | 'activated';
76
+ history: {
77
+ initial: number | null;
78
+ initial_date: string | null;
79
+ previous: number | null;
80
+ };
81
+ };
82
+ }
83
+ export interface Badge {
84
+ id: string;
85
+ name: string;
86
+ description: string;
87
+ icon_url: string;
88
+ points_required: number;
89
+ is_active: boolean;
90
+ unlock_criteria: string;
91
+ created_at: string;
92
+ }
93
+ export interface BadgeListResult {
94
+ badges: Badge[];
95
+ pagination: {
96
+ page: number;
97
+ limit: number;
98
+ total: number;
99
+ };
100
+ }
101
+ export interface Level {
102
+ id: string;
103
+ name: string;
104
+ level_number: number;
105
+ points_required: number;
106
+ description: string | null;
107
+ icon_url: string | null;
108
+ created_at: string;
109
+ }
110
+ export interface LevelListResult {
111
+ levels: Level[];
112
+ pagination: {
113
+ page: number;
114
+ limit: number;
115
+ total: number;
116
+ };
117
+ }
118
+ export interface QuestionOption {
119
+ id: string;
120
+ text: string;
121
+ persona_weight: Record<string, number>;
122
+ }
123
+ export interface Question {
124
+ id: string;
125
+ text: string;
126
+ order: number;
127
+ answer_options: QuestionOption[];
128
+ }
129
+ export interface Questionnaire {
130
+ id: string;
131
+ slug: string;
132
+ title: string;
133
+ description: string;
134
+ is_active: boolean;
135
+ questions: Question[];
136
+ created_at: string;
137
+ }
138
+ export interface LeaderboardListResult {
139
+ page: number;
140
+ limit: number;
141
+ total: number;
142
+ leaderboards: Array<{
143
+ id: string;
144
+ name: string;
145
+ description: string;
146
+ created_at: string;
147
+ }>;
148
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/jest.config.js ADDED
@@ -0,0 +1,31 @@
1
+ export default {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ roots: ['<rootDir>/src'],
5
+ testMatch: ['**/__tests__/**/*.test.ts'],
6
+ collectCoverageFrom: [
7
+ 'src/**/*.ts',
8
+ '!src/**/*.test.ts',
9
+ '!src/**/__tests__/**',
10
+ ],
11
+ coverageThreshold: {
12
+ global: {
13
+ lines: 90,
14
+ branches: 85,
15
+ functions: 90,
16
+ statements: 90,
17
+ },
18
+ },
19
+ coverageDirectory: 'coverage',
20
+ coverageReporters: ['text', 'lcov', 'html'],
21
+ moduleNameMapper: {
22
+ '^@/(.*)$': '<rootDir>/src/$1',
23
+ },
24
+ transform: {
25
+ '^.+\\.ts$': ['ts-jest', {
26
+ tsconfig: {
27
+ esModuleInterop: true,
28
+ },
29
+ }],
30
+ },
31
+ };
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@rooguys/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Official Node.js SDK for Rooguys API",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "jest",
10
+ "test:watch": "jest --watch",
11
+ "test:coverage": "jest --coverage",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "keywords": [
15
+ "rooguys",
16
+ "sdk",
17
+ "api",
18
+ "gamification"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Rooguys/rooguys-nodejs-sdk.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Rooguys/rooguys-nodejs-sdk/issues"
26
+ },
27
+ "homepage": "https://github.com/Rooguys/rooguys-nodejs-sdk#readme",
28
+ "author": "mowamed",
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "axios": "^1.6.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/jest": "^29.5.0",
35
+ "@types/node": "^20.0.0",
36
+ "fast-check": "^3.15.0",
37
+ "jest": "^29.7.0",
38
+ "ts-jest": "^29.1.0",
39
+ "typescript": "^5.0.0"
40
+ }
41
+ }