@puzzle-section/sdk-typescript 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 +294 -0
- package/dist/index.d.mts +1019 -0
- package/dist/index.d.ts +1019 -0
- package/dist/index.js +990 -0
- package/dist/index.mjs +957 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# @puzzle-section/sdk-typescript
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for the Puzzle Section Platform API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @puzzle-section/sdk-typescript
|
|
9
|
+
# or
|
|
10
|
+
yarn add @puzzle-section/sdk-typescript
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @puzzle-section/sdk-typescript
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { PuzzleSectionClient } from '@puzzle-section/sdk-typescript';
|
|
19
|
+
|
|
20
|
+
// Initialize the client
|
|
21
|
+
const client = new PuzzleSectionClient({
|
|
22
|
+
apiKey: 'ps_live_xxxxxxxxxxxx',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Get today's puzzles
|
|
26
|
+
const response = await client.puzzles.getDaily();
|
|
27
|
+
console.log(response.data);
|
|
28
|
+
|
|
29
|
+
// Get a specific puzzle
|
|
30
|
+
const puzzle = await client.puzzles.getById('puzzle-id');
|
|
31
|
+
console.log(puzzle.data);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
const client = new PuzzleSectionClient({
|
|
38
|
+
// Required: Your API key
|
|
39
|
+
apiKey: 'ps_live_xxxxxxxxxxxx',
|
|
40
|
+
|
|
41
|
+
// Optional: Override base URL (for sandbox or self-hosted)
|
|
42
|
+
baseUrl: 'https://sandbox.puzzlesection.app',
|
|
43
|
+
|
|
44
|
+
// Optional: Request timeout in milliseconds
|
|
45
|
+
timeout: 30000,
|
|
46
|
+
|
|
47
|
+
// Optional: Number of retry attempts for failed requests
|
|
48
|
+
retryCount: 3,
|
|
49
|
+
|
|
50
|
+
// Optional: End-user token for user-specific operations
|
|
51
|
+
userToken: 'usr_xxxxxxxxxxxx',
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API Reference
|
|
56
|
+
|
|
57
|
+
### Puzzles
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Get daily puzzles
|
|
61
|
+
const dailyPuzzles = await client.puzzles.getDaily();
|
|
62
|
+
|
|
63
|
+
// Get daily puzzles for a specific date
|
|
64
|
+
const puzzles = await client.puzzles.getDaily({ date: '2026-01-15' });
|
|
65
|
+
|
|
66
|
+
// Get daily puzzles filtered by type and difficulty
|
|
67
|
+
const filtered = await client.puzzles.getDaily({
|
|
68
|
+
date: '2026-01-15',
|
|
69
|
+
types: ['sudoku', 'kakuro'],
|
|
70
|
+
difficulties: ['medium', 'hard'],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Get puzzle by ID
|
|
74
|
+
const puzzle = await client.puzzles.getById('puzzle-id');
|
|
75
|
+
|
|
76
|
+
// Get puzzles by type with pagination
|
|
77
|
+
const sudokus = await client.puzzles.getByType('sudoku', {
|
|
78
|
+
difficulty: 'medium',
|
|
79
|
+
limit: 10,
|
|
80
|
+
page: 1,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Get puzzle by date and type
|
|
84
|
+
const datePuzzle = await client.puzzles.getByDate('2026-01-15', 'sudoku', 'medium');
|
|
85
|
+
|
|
86
|
+
// Get available puzzle types
|
|
87
|
+
const types = await client.puzzles.getTypes();
|
|
88
|
+
|
|
89
|
+
// Validate a solution before submitting
|
|
90
|
+
const validation = await client.puzzles.validateSolution('puzzle-id', {
|
|
91
|
+
grid: [[5, 3, 4, ...], ...],
|
|
92
|
+
});
|
|
93
|
+
if (validation.data.valid) {
|
|
94
|
+
// Solution is correct
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Users
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Get current user profile (requires user token)
|
|
102
|
+
const user = await client.users.getCurrent();
|
|
103
|
+
|
|
104
|
+
// Get user statistics
|
|
105
|
+
const stats = await client.users.getStats();
|
|
106
|
+
|
|
107
|
+
// Get another user by ID (public fields only)
|
|
108
|
+
const otherUser = await client.users.getById('user-id');
|
|
109
|
+
|
|
110
|
+
// Update current user profile
|
|
111
|
+
const updated = await client.users.update({
|
|
112
|
+
username: 'NewUsername',
|
|
113
|
+
avatar: 'https://example.com/avatar.png',
|
|
114
|
+
preferred_locale: 'en',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Get user achievements
|
|
118
|
+
const achievements = await client.users.getAchievements();
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Progress
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// Save puzzle progress (auto-save)
|
|
125
|
+
await client.progress.save({
|
|
126
|
+
puzzleId: 'puzzle-id',
|
|
127
|
+
elapsedTime: 120000, // milliseconds
|
|
128
|
+
state: {
|
|
129
|
+
grid: [[5, 3, 0, ...], ...],
|
|
130
|
+
notes: [[[], [], [1, 2], ...], ...],
|
|
131
|
+
},
|
|
132
|
+
isPaused: false,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Get saved progress for a puzzle
|
|
136
|
+
const progress = await client.progress.get('puzzle-id');
|
|
137
|
+
if (progress.data) {
|
|
138
|
+
console.log(`Elapsed time: ${progress.data.elapsedTime}ms`);
|
|
139
|
+
console.log(`Last saved: ${progress.data.lastSavedAt}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Get all in-progress puzzles
|
|
143
|
+
const allProgress = await client.progress.getAll();
|
|
144
|
+
|
|
145
|
+
// Complete a puzzle
|
|
146
|
+
const completion = await client.progress.complete({
|
|
147
|
+
puzzleId: 'puzzle-id',
|
|
148
|
+
elapsedTime: 300000, // milliseconds
|
|
149
|
+
hintsUsed: 0,
|
|
150
|
+
});
|
|
151
|
+
console.log(`Score: ${completion.data.score}`);
|
|
152
|
+
console.log(`Rank: ${completion.data.rank}`);
|
|
153
|
+
|
|
154
|
+
// Get completion history
|
|
155
|
+
const completions = await client.progress.getCompletions({
|
|
156
|
+
limit: 20,
|
|
157
|
+
page: 1,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Delete saved progress (start fresh)
|
|
161
|
+
await client.progress.delete('puzzle-id');
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Health
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Check API health
|
|
168
|
+
const health = await client.health.check();
|
|
169
|
+
console.log(health.data.status); // 'healthy' | 'degraded' | 'unhealthy'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Response Format
|
|
173
|
+
|
|
174
|
+
All API methods return a response object with `data` and `rateLimit`:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const response = await client.puzzles.getById('puzzle-id');
|
|
178
|
+
|
|
179
|
+
// The actual data
|
|
180
|
+
const puzzle = response.data;
|
|
181
|
+
console.log(puzzle.type); // 'sudoku'
|
|
182
|
+
console.log(puzzle.difficulty); // 'medium'
|
|
183
|
+
console.log(puzzle.data); // Puzzle-specific data (grid, clues, etc.)
|
|
184
|
+
|
|
185
|
+
// Rate limit information
|
|
186
|
+
console.log(response.rateLimit.limit); // Max requests per window
|
|
187
|
+
console.log(response.rateLimit.remaining); // Remaining requests
|
|
188
|
+
console.log(response.rateLimit.reset); // Unix timestamp when window resets
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Puzzle Object
|
|
192
|
+
|
|
193
|
+
The `Puzzle` object contains:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
interface Puzzle {
|
|
197
|
+
id: string; // UUID
|
|
198
|
+
type: PuzzleType; // 'sudoku', 'kakuro', 'crossword', etc.
|
|
199
|
+
difficulty: PuzzleDifficulty; // 'easy', 'medium', 'hard', 'expert'
|
|
200
|
+
date: string; // 'YYYY-MM-DD'
|
|
201
|
+
estimatedTime: number; // Estimated completion time in seconds
|
|
202
|
+
isPremium: boolean; // Whether premium access is required
|
|
203
|
+
data: PuzzleData; // Type-specific puzzle data
|
|
204
|
+
createdAt: string; // ISO timestamp
|
|
205
|
+
updatedAt: string; // ISO timestamp
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Available Puzzle Types
|
|
210
|
+
|
|
211
|
+
- `sudoku` - Classic 9x9 Sudoku
|
|
212
|
+
- `kakuro` - Cross-sum puzzles
|
|
213
|
+
- `crossmath` - Arithmetic crossword
|
|
214
|
+
- `slitherlink` - Loop-drawing puzzle
|
|
215
|
+
- `hashi` - Bridge-building puzzle
|
|
216
|
+
- `breadcrumb` - Path-following puzzle
|
|
217
|
+
- `crossword` - Word crossword
|
|
218
|
+
- `wordsearch` - Find hidden words
|
|
219
|
+
- `wordladder` - Transform words
|
|
220
|
+
- `wordpath` - Connect letters
|
|
221
|
+
- `nonogram` - Picture logic (black/white)
|
|
222
|
+
- `colornonogram` - Picture logic (color)
|
|
223
|
+
- `mosaic` - Fill-in picture puzzle
|
|
224
|
+
- `picturepath` - Draw path puzzle
|
|
225
|
+
|
|
226
|
+
## Error Handling
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
import {
|
|
230
|
+
PuzzleSectionClient,
|
|
231
|
+
ApiError,
|
|
232
|
+
AuthenticationError,
|
|
233
|
+
RateLimitError,
|
|
234
|
+
NotFoundError,
|
|
235
|
+
ValidationError,
|
|
236
|
+
} from '@puzzle-section/sdk-typescript';
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const puzzle = await client.puzzles.getById('invalid-id');
|
|
240
|
+
} catch (error) {
|
|
241
|
+
if (error instanceof NotFoundError) {
|
|
242
|
+
console.log('Puzzle not found');
|
|
243
|
+
} else if (error instanceof RateLimitError) {
|
|
244
|
+
console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
|
|
245
|
+
} else if (error instanceof AuthenticationError) {
|
|
246
|
+
console.log('Invalid API key');
|
|
247
|
+
} else if (error instanceof ValidationError) {
|
|
248
|
+
console.log(`Validation error: ${error.message}`);
|
|
249
|
+
} else if (error instanceof ApiError) {
|
|
250
|
+
console.log(`API error: ${error.code} - ${error.message}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## TypeScript Support
|
|
256
|
+
|
|
257
|
+
This SDK is written in TypeScript and provides full type definitions:
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import type {
|
|
261
|
+
Puzzle,
|
|
262
|
+
PuzzleType,
|
|
263
|
+
PuzzleDifficulty,
|
|
264
|
+
User,
|
|
265
|
+
UserStats,
|
|
266
|
+
PuzzleProgress,
|
|
267
|
+
PuzzleCompletion,
|
|
268
|
+
} from '@puzzle-section/sdk-typescript';
|
|
269
|
+
|
|
270
|
+
// Type-safe puzzle handling
|
|
271
|
+
const response = await client.puzzles.getById('id');
|
|
272
|
+
const puzzle: Puzzle = response.data;
|
|
273
|
+
|
|
274
|
+
if (puzzle.type === 'sudoku') {
|
|
275
|
+
// Access puzzle-specific data
|
|
276
|
+
const grid = puzzle.data.grid as number[][];
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Browser Support
|
|
281
|
+
|
|
282
|
+
The SDK works in both Node.js and browser environments:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// ES Modules (Browser/Node.js)
|
|
286
|
+
import { PuzzleSectionClient } from '@puzzle-section/sdk-typescript';
|
|
287
|
+
|
|
288
|
+
// CommonJS (Node.js)
|
|
289
|
+
const { PuzzleSectionClient } = require('@puzzle-section/sdk-typescript');
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## License
|
|
293
|
+
|
|
294
|
+
MIT
|