@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.
@@ -0,0 +1,1019 @@
1
+ /**
2
+ * SDK Type Definitions
3
+ *
4
+ * These types mirror the API response types and provide TypeScript support.
5
+ * Types are manually maintained to ensure a clean SDK interface.
6
+ */
7
+ type PuzzleType = 'sudoku' | 'wordsearch' | 'crossword' | 'nonogram' | 'colornonogram' | 'picturepath' | 'crossmath' | 'kakuro' | 'slitherlink' | 'mosaic' | 'wordpath' | 'wordladder' | 'breadcrumb' | 'hashi';
8
+ type PuzzleDifficulty = 'easy' | 'medium' | 'hard' | 'expert';
9
+ interface SudokuData {
10
+ grid: number[][];
11
+ given: boolean[][];
12
+ difficulty: PuzzleDifficulty;
13
+ }
14
+ interface WordsearchData {
15
+ grid: string[][];
16
+ words: string[];
17
+ theme?: string;
18
+ difficulty: PuzzleDifficulty;
19
+ }
20
+ interface CrosswordData {
21
+ grid: (string | null)[][];
22
+ clues: {
23
+ across: Record<string, string>;
24
+ down: Record<string, string>;
25
+ };
26
+ numbering: (number | null)[][];
27
+ difficulty: PuzzleDifficulty;
28
+ }
29
+ interface NonogramData {
30
+ rows: number[][];
31
+ cols: number[][];
32
+ size: {
33
+ width: number;
34
+ height: number;
35
+ };
36
+ difficulty: PuzzleDifficulty;
37
+ }
38
+ type PuzzleData = SudokuData | WordsearchData | CrosswordData | NonogramData | Record<string, unknown>;
39
+ type PuzzleSolution = Record<string, unknown>;
40
+ interface Puzzle {
41
+ id: string;
42
+ type: PuzzleType;
43
+ difficulty: PuzzleDifficulty;
44
+ date: string;
45
+ estimatedTime: number;
46
+ isPremium: boolean;
47
+ data: PuzzleData;
48
+ createdAt: string;
49
+ updatedAt: string;
50
+ }
51
+ /** @deprecated Implement your own user types */
52
+ interface UserPublic {
53
+ id: string;
54
+ username: string;
55
+ avatar: string | null;
56
+ puzzlesCompleted: number;
57
+ totalScore: number;
58
+ achievementCount: number;
59
+ joinDate: string;
60
+ }
61
+ /** @deprecated Implement your own user types */
62
+ interface User extends UserPublic {
63
+ email?: string;
64
+ isVerified: boolean;
65
+ isPremium: boolean;
66
+ isBetaTester: boolean;
67
+ preferredLocale: 'en' | 'es' | null;
68
+ tokens?: number;
69
+ lastActiveAt: string | null;
70
+ }
71
+ /** @deprecated Implement your own user statistics */
72
+ interface UserStats {
73
+ totalPuzzlesCompleted: number;
74
+ totalScore: number;
75
+ currentStreak: number;
76
+ longestStreak: number;
77
+ byPuzzleType: Record<string, {
78
+ completed: number;
79
+ totalScore: number;
80
+ averageTime: number | null;
81
+ bestTime: number | null;
82
+ }>;
83
+ recentActivity: Array<{
84
+ date: string;
85
+ puzzlesCompleted: number;
86
+ scoreEarned: number;
87
+ }>;
88
+ }
89
+ /** @deprecated Implement your own progress types */
90
+ interface PuzzleProgress {
91
+ puzzleId: string;
92
+ userId: string;
93
+ stateData: Record<string, unknown>;
94
+ elapsedTime: number;
95
+ isPaused: boolean;
96
+ lastSavedAt: string;
97
+ }
98
+ /** @deprecated Implement your own completion types */
99
+ interface PuzzleCompletion {
100
+ puzzleId: string;
101
+ userId: string;
102
+ completionTime: number;
103
+ score: number;
104
+ hintsUsed: number;
105
+ completedAt: string;
106
+ rank?: number;
107
+ achievementsUnlocked?: string[];
108
+ }
109
+ /** @deprecated Implement your own progress types */
110
+ interface SaveProgressInput {
111
+ puzzleId: string;
112
+ elapsedTime: number;
113
+ state: Record<string, unknown>;
114
+ isPaused?: boolean;
115
+ }
116
+ /** @deprecated Implement your own completion types */
117
+ interface CompleteProgressInput {
118
+ puzzleId: string;
119
+ elapsedTime: number;
120
+ hintsUsed?: number;
121
+ }
122
+ interface RateLimitInfo {
123
+ limit: number;
124
+ remaining: number;
125
+ reset: number;
126
+ }
127
+ interface PaginatedResponse<T> {
128
+ data: T[];
129
+ pagination: {
130
+ page: number;
131
+ limit: number;
132
+ total: number;
133
+ totalPages: number;
134
+ };
135
+ rateLimit?: RateLimitInfo;
136
+ }
137
+ interface HealthStatus {
138
+ status: 'healthy' | 'degraded' | 'unhealthy';
139
+ version: string;
140
+ timestamp: string;
141
+ checks?: {
142
+ database: 'up' | 'down';
143
+ redis: 'up' | 'down';
144
+ };
145
+ }
146
+ interface GetDailyPuzzlesParams {
147
+ date?: string;
148
+ types?: PuzzleType[];
149
+ difficulties?: PuzzleDifficulty[];
150
+ }
151
+ interface GetPuzzlesByTypeParams {
152
+ difficulty?: PuzzleDifficulty;
153
+ limit?: number;
154
+ page?: number;
155
+ }
156
+ type AdminPuzzleType = 'nonogram' | 'colornonogram' | 'picturepath';
157
+ type AdminPuzzleStatus = 'draft' | 'published';
158
+ interface AdminPuzzle {
159
+ id: string;
160
+ title: string;
161
+ type: AdminPuzzleType;
162
+ status: AdminPuzzleStatus;
163
+ eventTags?: string[];
164
+ tenantId?: string | null;
165
+ createdById?: string | null;
166
+ createdAt: string;
167
+ updatedAt: string;
168
+ deletedAt?: string | null;
169
+ variants?: AdminPuzzleVariant[];
170
+ createdBy?: {
171
+ id: string;
172
+ username: string;
173
+ };
174
+ }
175
+ interface AdminPuzzleVariant {
176
+ id: string;
177
+ puzzleId: string;
178
+ difficulty: PuzzleDifficulty;
179
+ enabled: boolean;
180
+ width: number;
181
+ height: number;
182
+ gridData: number[][];
183
+ colorGrid?: number[][];
184
+ palette?: string[];
185
+ createdAt: string;
186
+ updatedAt: string;
187
+ }
188
+ interface CreateAdminPuzzleRequest {
189
+ title: string;
190
+ type: AdminPuzzleType;
191
+ }
192
+ interface UpdateAdminPuzzleRequest {
193
+ title?: string;
194
+ status?: AdminPuzzleStatus;
195
+ event_tags?: string[];
196
+ }
197
+ interface UpsertPuzzleVariantRequest {
198
+ difficulty: PuzzleDifficulty;
199
+ enabled?: boolean;
200
+ width: number;
201
+ height: number;
202
+ grid_data: number[][];
203
+ color_grid?: number[][];
204
+ palette?: string[];
205
+ }
206
+ interface FilterWordRequest {
207
+ word: string;
208
+ reason?: string;
209
+ addedByName?: string;
210
+ addedByEmail?: string;
211
+ }
212
+ interface FilterWordResult {
213
+ word: string;
214
+ puzzleId: string;
215
+ updatedPuzzleData: Record<string, unknown>;
216
+ updatedSolutionData: Record<string, unknown>;
217
+ message: string;
218
+ }
219
+ interface FunFactorResult {
220
+ funScore: number;
221
+ meetsThreshold: boolean;
222
+ recommendation: 'accept' | 'regenerate' | 'adjust_difficulty';
223
+ estimatedDifficulty: string;
224
+ components: {
225
+ techniqueDiversity: number;
226
+ logicalFlow: number;
227
+ noGuessingBonus: number;
228
+ gridEngagement: number;
229
+ difficultyMatch: number;
230
+ };
231
+ notes: string[];
232
+ solveStats: {
233
+ solved: boolean;
234
+ steps: number;
235
+ techniquesUsed: string[];
236
+ guessesRequired: number;
237
+ backtrackCount: number;
238
+ maxTechniqueDifficulty: number;
239
+ avgTechniqueDifficulty: number;
240
+ solveTimeMs: number;
241
+ guessLocations: Array<{
242
+ row: number;
243
+ col: number;
244
+ description: string;
245
+ isBacktrack: boolean;
246
+ }>;
247
+ };
248
+ report: string;
249
+ }
250
+
251
+ /**
252
+ * Puzzles API Module
253
+ */
254
+
255
+ type RequestFn$4 = <T>(options: {
256
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
257
+ path: string;
258
+ body?: unknown;
259
+ query?: Record<string, string | number | boolean | undefined>;
260
+ }) => Promise<ResponseWithRateLimit<T>>;
261
+ /**
262
+ * Puzzles API
263
+ *
264
+ * Methods for retrieving and interacting with puzzles.
265
+ */
266
+ declare class PuzzlesApi {
267
+ private request;
268
+ constructor(request: RequestFn$4);
269
+ /**
270
+ * Get daily puzzles
271
+ *
272
+ * @param params - Optional parameters
273
+ * @returns List of daily puzzles
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * // Get today's puzzles
278
+ * const puzzles = await client.puzzles.getDaily();
279
+ *
280
+ * // Get puzzles for a specific date
281
+ * const puzzles = await client.puzzles.getDaily({ date: '2024-01-15' });
282
+ * ```
283
+ */
284
+ getDaily(params?: GetDailyPuzzlesParams): Promise<ResponseWithRateLimit<Puzzle[]>>;
285
+ /**
286
+ * Get a specific puzzle by ID
287
+ *
288
+ * @param id - Puzzle ID
289
+ * @returns Puzzle details
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * const puzzle = await client.puzzles.getById('puzzle-id');
294
+ * ```
295
+ */
296
+ getById(id: string): Promise<ResponseWithRateLimit<Puzzle>>;
297
+ /**
298
+ * Get puzzles by type
299
+ *
300
+ * @param type - Puzzle type (sudoku, wordsearch, etc.)
301
+ * @param params - Optional filtering parameters
302
+ * @returns Paginated list of puzzles
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const sudokus = await client.puzzles.getByType('sudoku', {
307
+ * difficulty: 'medium',
308
+ * limit: 10,
309
+ * });
310
+ * ```
311
+ */
312
+ getByType(type: PuzzleType, params?: GetPuzzlesByTypeParams): Promise<ResponseWithRateLimit<PaginatedResponse<Puzzle>>>;
313
+ /**
314
+ * Get available puzzle types
315
+ *
316
+ * @returns List of available puzzle types
317
+ */
318
+ getTypes(): Promise<ResponseWithRateLimit<PuzzleType[]>>;
319
+ /**
320
+ * Get puzzle by date and type
321
+ *
322
+ * @param date - Date in YYYY-MM-DD format
323
+ * @param type - Puzzle type
324
+ * @param difficulty - Optional difficulty filter
325
+ * @returns Puzzle for the specified date
326
+ */
327
+ getByDate(date: string, type: PuzzleType, difficulty?: PuzzleDifficulty): Promise<ResponseWithRateLimit<Puzzle>>;
328
+ /**
329
+ * Validate puzzle solution
330
+ *
331
+ * @param id - Puzzle ID
332
+ * @param solution - User's solution
333
+ * @returns Validation result
334
+ */
335
+ validateSolution(id: string, solution: unknown): Promise<ResponseWithRateLimit<{
336
+ valid: boolean;
337
+ errors?: string[];
338
+ }>>;
339
+ }
340
+
341
+ /**
342
+ * Users API Module
343
+ *
344
+ * @deprecated This module is deprecated and will be removed in a future version.
345
+ *
346
+ * User management is now considered a Client-domain responsibility.
347
+ * Tenants should implement their own user management systems and databases.
348
+ *
349
+ * The Platform API provides:
350
+ * - Puzzle content delivery
351
+ * - Tenant authentication
352
+ * - Anonymized analytics
353
+ *
354
+ * For user-specific features (authentication, progress, achievements),
355
+ * implement your own backend or use the TenantEndUser APIs directly.
356
+ */
357
+
358
+ type RequestFn$3 = <T>(options: {
359
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
360
+ path: string;
361
+ body?: unknown;
362
+ query?: Record<string, string | number | boolean | undefined>;
363
+ }) => Promise<ResponseWithRateLimit<T>>;
364
+ /**
365
+ * Users API
366
+ *
367
+ * @deprecated User management should be handled by your own backend.
368
+ * This API will be removed in a future SDK version.
369
+ *
370
+ * Methods for user management and profile operations.
371
+ * Most methods require a user token to be set.
372
+ */
373
+ declare class UsersApi {
374
+ private request;
375
+ constructor(request: RequestFn$3);
376
+ /**
377
+ * Get current user profile
378
+ *
379
+ * Requires a user token to be set.
380
+ *
381
+ * @returns Current user profile
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * client.setUserToken('usr_xxxxxxxxxxxx');
386
+ * const user = await client.users.getCurrent();
387
+ * ```
388
+ */
389
+ getCurrent(): Promise<ResponseWithRateLimit<User>>;
390
+ /**
391
+ * Get user statistics
392
+ *
393
+ * Requires a user token to be set.
394
+ *
395
+ * @returns User statistics
396
+ */
397
+ getStats(): Promise<ResponseWithRateLimit<UserStats>>;
398
+ /**
399
+ * Get user by ID
400
+ *
401
+ * @param id - User ID
402
+ * @returns User profile (public fields only)
403
+ */
404
+ getById(id: string): Promise<ResponseWithRateLimit<User>>;
405
+ /**
406
+ * Update current user profile
407
+ *
408
+ * Requires a user token to be set.
409
+ *
410
+ * @param updates - Profile updates
411
+ * @returns Updated user profile
412
+ */
413
+ update(updates: {
414
+ username?: string;
415
+ avatar?: string;
416
+ preferred_locale?: string;
417
+ }): Promise<ResponseWithRateLimit<User>>;
418
+ /**
419
+ * Get user achievements
420
+ *
421
+ * Requires a user token to be set.
422
+ *
423
+ * @returns List of user achievements
424
+ */
425
+ getAchievements(): Promise<ResponseWithRateLimit<Array<{
426
+ id: string;
427
+ name: string;
428
+ description: string;
429
+ earned_at: string;
430
+ }>>>;
431
+ }
432
+
433
+ /**
434
+ * Progress API Module
435
+ *
436
+ * @deprecated This module is deprecated and will be removed in a future version.
437
+ *
438
+ * Progress tracking is now considered a Client-domain responsibility.
439
+ * Tenants should implement their own progress storage and management.
440
+ *
441
+ * The Platform API provides:
442
+ * - Puzzle content delivery (puzzles, solutions, hints)
443
+ * - Tenant authentication
444
+ * - Anonymized analytics
445
+ *
446
+ * For progress tracking, implement your own backend storage solution.
447
+ * This ensures you own your user data and can customize the experience.
448
+ */
449
+
450
+ type RequestFn$2 = <T>(options: {
451
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
452
+ path: string;
453
+ body?: unknown;
454
+ query?: Record<string, string | number | boolean | undefined>;
455
+ }) => Promise<ResponseWithRateLimit<T>>;
456
+ /**
457
+ * Progress API
458
+ *
459
+ * @deprecated Progress tracking should be handled by your own backend.
460
+ * This API will be removed in a future SDK version.
461
+ *
462
+ * Methods for saving and retrieving puzzle progress.
463
+ * All methods require a user token to be set.
464
+ */
465
+ declare class ProgressApi {
466
+ private request;
467
+ constructor(request: RequestFn$2);
468
+ /**
469
+ * Get saved progress for a puzzle
470
+ *
471
+ * @param puzzleId - Puzzle ID
472
+ * @returns Saved progress or null if not found
473
+ *
474
+ * @example
475
+ * ```typescript
476
+ * const progress = await client.progress.get('puzzle-id');
477
+ * if (progress.data) {
478
+ * console.log(`Elapsed time: ${progress.data.elapsed_time}s`);
479
+ * }
480
+ * ```
481
+ */
482
+ get(puzzleId: string): Promise<ResponseWithRateLimit<PuzzleProgress | null>>;
483
+ /**
484
+ * Save puzzle progress
485
+ *
486
+ * @param input - Progress data to save
487
+ * @returns Saved progress
488
+ *
489
+ * @example
490
+ * ```typescript
491
+ * await client.progress.save({
492
+ * puzzleId: 'puzzle-id',
493
+ * elapsedTime: 120,
494
+ * state: {
495
+ * grid: [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
496
+ * },
497
+ * });
498
+ * ```
499
+ */
500
+ save(input: SaveProgressInput): Promise<ResponseWithRateLimit<PuzzleProgress>>;
501
+ /**
502
+ * Mark puzzle as complete
503
+ *
504
+ * @param input - Completion data
505
+ * @returns Completion record with score
506
+ *
507
+ * @example
508
+ * ```typescript
509
+ * const completion = await client.progress.complete({
510
+ * puzzleId: 'puzzle-id',
511
+ * elapsedTime: 300,
512
+ * hintsUsed: 2,
513
+ * });
514
+ * console.log(`Score: ${completion.data.score}`);
515
+ * ```
516
+ */
517
+ complete(input: CompleteProgressInput): Promise<ResponseWithRateLimit<PuzzleCompletion>>;
518
+ /**
519
+ * Delete saved progress
520
+ *
521
+ * @param puzzleId - Puzzle ID
522
+ */
523
+ delete(puzzleId: string): Promise<ResponseWithRateLimit<void>>;
524
+ /**
525
+ * Get all active progress for current user
526
+ *
527
+ * @returns List of in-progress puzzles
528
+ */
529
+ getAll(): Promise<ResponseWithRateLimit<PuzzleProgress[]>>;
530
+ /**
531
+ * Get completion history for current user
532
+ *
533
+ * @param params - Optional pagination params
534
+ * @returns List of completed puzzles
535
+ */
536
+ getCompletions(params?: {
537
+ limit?: number;
538
+ page?: number;
539
+ }): Promise<ResponseWithRateLimit<PuzzleCompletion[]>>;
540
+ }
541
+
542
+ /**
543
+ * Health API Module
544
+ */
545
+
546
+ type RequestFn$1 = <T>(options: {
547
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
548
+ path: string;
549
+ body?: unknown;
550
+ query?: Record<string, string | number | boolean | undefined>;
551
+ }) => Promise<ResponseWithRateLimit<T>>;
552
+ /**
553
+ * Health API
554
+ *
555
+ * Methods for checking API health and status.
556
+ */
557
+ declare class HealthApi {
558
+ private request;
559
+ constructor(request: RequestFn$1);
560
+ /**
561
+ * Check API health
562
+ *
563
+ * @returns Health status
564
+ *
565
+ * @example
566
+ * ```typescript
567
+ * const health = await client.health.check();
568
+ * console.log(health.data.status); // 'healthy'
569
+ * ```
570
+ */
571
+ check(): Promise<ResponseWithRateLimit<HealthStatus>>;
572
+ /**
573
+ * Simple ping check
574
+ *
575
+ * @returns Ping response
576
+ */
577
+ ping(): Promise<ResponseWithRateLimit<{
578
+ pong: boolean;
579
+ timestamp: string;
580
+ }>>;
581
+ }
582
+
583
+ /**
584
+ * Admin API Module
585
+ *
586
+ * Methods for managing admin puzzles (nonograms, color nonograms).
587
+ * Requires tenant API key authentication.
588
+ */
589
+
590
+ type RequestFn = <T>(options: {
591
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
592
+ path: string;
593
+ body?: unknown;
594
+ query?: Record<string, string | number | boolean | undefined>;
595
+ }) => Promise<ResponseWithRateLimit<T>>;
596
+ /**
597
+ * Admin API
598
+ *
599
+ * Methods for creating and managing admin puzzles.
600
+ * These endpoints are tenant-scoped and require API key authentication.
601
+ */
602
+ declare class AdminApi {
603
+ private request;
604
+ constructor(request: RequestFn);
605
+ /**
606
+ * List admin puzzles
607
+ *
608
+ * @param params - Optional filter parameters
609
+ * @returns Paginated list of admin puzzles
610
+ *
611
+ * @example
612
+ * ```typescript
613
+ * const result = await client.admin.listPuzzles({
614
+ * type: 'nonogram',
615
+ * status: 'published',
616
+ * page: 1,
617
+ * pageSize: 20,
618
+ * });
619
+ * ```
620
+ */
621
+ listPuzzles(params?: {
622
+ type?: 'nonogram' | 'colornonogram';
623
+ status?: 'draft' | 'published';
624
+ search?: string;
625
+ page?: number;
626
+ pageSize?: number;
627
+ }): Promise<ResponseWithRateLimit<PaginatedResponse<AdminPuzzle>>>;
628
+ /**
629
+ * List deleted admin puzzles (recycle bin)
630
+ *
631
+ * @param params - Optional filter parameters
632
+ * @returns Paginated list of deleted admin puzzles
633
+ *
634
+ * @example
635
+ * ```typescript
636
+ * const result = await client.admin.listDeletedPuzzles();
637
+ * ```
638
+ */
639
+ listDeletedPuzzles(params?: {
640
+ type?: 'nonogram' | 'colornonogram';
641
+ search?: string;
642
+ page?: number;
643
+ pageSize?: number;
644
+ }): Promise<ResponseWithRateLimit<PaginatedResponse<AdminPuzzle>>>;
645
+ /**
646
+ * Get a single admin puzzle by ID
647
+ *
648
+ * @param id - Puzzle ID
649
+ * @returns Admin puzzle with variants
650
+ *
651
+ * @example
652
+ * ```typescript
653
+ * const puzzle = await client.admin.getPuzzle('puzzle-id');
654
+ * ```
655
+ */
656
+ getPuzzle(id: string): Promise<ResponseWithRateLimit<AdminPuzzle>>;
657
+ /**
658
+ * Create a new admin puzzle
659
+ *
660
+ * @param data - Puzzle creation data
661
+ * @returns Created puzzle
662
+ *
663
+ * @example
664
+ * ```typescript
665
+ * const puzzle = await client.admin.createPuzzle({
666
+ * title: 'My Nonogram',
667
+ * type: 'nonogram',
668
+ * });
669
+ * ```
670
+ */
671
+ createPuzzle(data: CreateAdminPuzzleRequest): Promise<ResponseWithRateLimit<AdminPuzzle>>;
672
+ /**
673
+ * Update an admin puzzle
674
+ *
675
+ * @param id - Puzzle ID
676
+ * @param data - Update data
677
+ * @returns Updated puzzle
678
+ *
679
+ * @example
680
+ * ```typescript
681
+ * const puzzle = await client.admin.updatePuzzle('puzzle-id', {
682
+ * title: 'Updated Title',
683
+ * status: 'published',
684
+ * });
685
+ * ```
686
+ */
687
+ updatePuzzle(id: string, data: UpdateAdminPuzzleRequest): Promise<ResponseWithRateLimit<AdminPuzzle>>;
688
+ /**
689
+ * Soft delete an admin puzzle (move to recycle bin)
690
+ *
691
+ * @param id - Puzzle ID
692
+ * @returns Success message
693
+ *
694
+ * @example
695
+ * ```typescript
696
+ * await client.admin.deletePuzzle('puzzle-id');
697
+ * ```
698
+ */
699
+ deletePuzzle(id: string): Promise<ResponseWithRateLimit<{
700
+ message: string;
701
+ }>>;
702
+ /**
703
+ * Remove a platform puzzle from the tenant's library.
704
+ * Deactivates all calendar assignments for this puzzle. Only applies to platform puzzles
705
+ * (tenantId=null). For tenant-owned puzzles, use deletePuzzle instead.
706
+ * Requires tenant API key authentication.
707
+ *
708
+ * @param id - Admin puzzle ID
709
+ * @returns Result with deactivatedCount
710
+ *
711
+ * @example
712
+ * ```typescript
713
+ * const result = await client.admin.removeFromLibrary('puzzle-id');
714
+ * console.log(`Deactivated ${result.data.deactivatedCount} calendar assignments`);
715
+ * ```
716
+ */
717
+ removeFromLibrary(id: string): Promise<ResponseWithRateLimit<{
718
+ message: string;
719
+ data: {
720
+ deactivatedCount: number;
721
+ };
722
+ }>>;
723
+ /**
724
+ * Restore a soft-deleted puzzle from recycle bin
725
+ *
726
+ * @param id - Puzzle ID
727
+ * @returns Restored puzzle
728
+ *
729
+ * @example
730
+ * ```typescript
731
+ * const puzzle = await client.admin.restorePuzzle('puzzle-id');
732
+ * ```
733
+ */
734
+ restorePuzzle(id: string): Promise<ResponseWithRateLimit<AdminPuzzle>>;
735
+ /**
736
+ * Permanently delete a puzzle (cannot be undone)
737
+ *
738
+ * @param id - Puzzle ID
739
+ * @returns Success message
740
+ *
741
+ * @example
742
+ * ```typescript
743
+ * await client.admin.permanentlyDeletePuzzle('puzzle-id');
744
+ * ```
745
+ */
746
+ permanentlyDeletePuzzle(id: string): Promise<ResponseWithRateLimit<{
747
+ message: string;
748
+ }>>;
749
+ /**
750
+ * Publish an admin puzzle
751
+ *
752
+ * @param id - Puzzle ID
753
+ * @returns Published puzzle
754
+ *
755
+ * @example
756
+ * ```typescript
757
+ * const puzzle = await client.admin.publishPuzzle('puzzle-id');
758
+ * ```
759
+ */
760
+ publishPuzzle(id: string): Promise<ResponseWithRateLimit<AdminPuzzle>>;
761
+ /**
762
+ * Unpublish an admin puzzle
763
+ *
764
+ * @param id - Puzzle ID
765
+ * @returns Unpublished puzzle
766
+ *
767
+ * @example
768
+ * ```typescript
769
+ * const puzzle = await client.admin.unpublishPuzzle('puzzle-id');
770
+ * ```
771
+ */
772
+ unpublishPuzzle(id: string): Promise<ResponseWithRateLimit<AdminPuzzle>>;
773
+ /**
774
+ * Create or update a puzzle variant
775
+ *
776
+ * @param puzzleId - Puzzle ID
777
+ * @param data - Variant data
778
+ * @returns Created/updated variant
779
+ *
780
+ * @example
781
+ * ```typescript
782
+ * const variant = await client.admin.upsertVariant('puzzle-id', {
783
+ * difficulty: 'medium',
784
+ * enabled: true,
785
+ * width: 15,
786
+ * height: 15,
787
+ * grid_data: [[0, 1, 0], ...],
788
+ * });
789
+ * ```
790
+ */
791
+ upsertVariant(puzzleId: string, data: UpsertPuzzleVariantRequest): Promise<ResponseWithRateLimit<AdminPuzzleVariant>>;
792
+ /**
793
+ * Delete a puzzle variant
794
+ *
795
+ * @param puzzleId - Puzzle ID
796
+ * @param variantId - Variant ID
797
+ * @returns Success message
798
+ *
799
+ * @example
800
+ * ```typescript
801
+ * await client.admin.deleteVariant('puzzle-id', 'variant-id');
802
+ * ```
803
+ */
804
+ deleteVariant(puzzleId: string, variantId: string): Promise<ResponseWithRateLimit<{
805
+ message: string;
806
+ }>>;
807
+ /**
808
+ * Evaluate fun factor of a nonogram puzzle
809
+ *
810
+ * @param data - Grid data and puzzle metadata
811
+ * @returns Fun factor evaluation result
812
+ *
813
+ * @example
814
+ * ```typescript
815
+ * const result = await client.admin.evaluateFunFactor({
816
+ * grid_data: [[0, 1, 0], ...],
817
+ * difficulty: 'medium',
818
+ * width: 15,
819
+ * height: 15,
820
+ * });
821
+ * ```
822
+ */
823
+ evaluateFunFactor(data: {
824
+ grid_data: number[][];
825
+ difficulty: 'easy' | 'medium' | 'hard' | 'expert';
826
+ width: number;
827
+ height: number;
828
+ }): Promise<ResponseWithRateLimit<FunFactorResult>>;
829
+ /**
830
+ * Filter a word from a wordsearch puzzle
831
+ *
832
+ * Adds the word to the tenant's filtered word list and removes it from
833
+ * the specified puzzle. The word will not appear in future puzzle generations
834
+ * and is immediately removed from the current puzzle for all users.
835
+ *
836
+ * @param puzzleId - ID of the wordsearch puzzle
837
+ * @param data - Word to filter and optional audit metadata
838
+ * @returns Updated puzzle data with the word removed
839
+ *
840
+ * @example
841
+ * ```typescript
842
+ * const result = await client.admin.filterWordFromPuzzle('puzzle-id', {
843
+ * word: 'offensive',
844
+ * reason: 'Inappropriate content',
845
+ * addedByName: 'Admin User',
846
+ * addedByEmail: 'admin@example.com',
847
+ * });
848
+ * ```
849
+ */
850
+ filterWordFromPuzzle(puzzleId: string, data: FilterWordRequest): Promise<ResponseWithRateLimit<FilterWordResult>>;
851
+ }
852
+
853
+ /**
854
+ * Puzzle Section Client
855
+ *
856
+ * Main client class for interacting with the Puzzle Section API.
857
+ */
858
+
859
+ /**
860
+ * Client configuration options
861
+ */
862
+ interface ClientConfig {
863
+ /**
864
+ * Your API key (required)
865
+ * Format: ps_live_xxxx or ps_sandbox_xxxx
866
+ */
867
+ apiKey: string;
868
+ /**
869
+ * API base URL
870
+ * @default 'https://api.puzzlesection.app'
871
+ */
872
+ baseUrl?: string;
873
+ /**
874
+ * Request timeout in milliseconds
875
+ * @default 30000
876
+ */
877
+ timeout?: number;
878
+ /**
879
+ * Number of retry attempts for failed requests
880
+ * @default 3
881
+ */
882
+ retryCount?: number;
883
+ /**
884
+ * End-user session token for user-specific operations
885
+ */
886
+ userToken?: string;
887
+ /**
888
+ * Custom fetch implementation (for testing or special environments)
889
+ */
890
+ fetch?: typeof fetch;
891
+ }
892
+ /**
893
+ * Internal request options
894
+ */
895
+ interface RequestOptions {
896
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
897
+ path: string;
898
+ body?: unknown;
899
+ query?: Record<string, string | number | boolean | undefined>;
900
+ headers?: Record<string, string>;
901
+ }
902
+ /**
903
+ * Response with rate limit info
904
+ */
905
+ interface ResponseWithRateLimit<T> {
906
+ data: T;
907
+ rateLimit: RateLimitInfo;
908
+ }
909
+ /**
910
+ * Puzzle Section API Client
911
+ *
912
+ * @example
913
+ * ```typescript
914
+ * const client = new PuzzleSectionClient({
915
+ * apiKey: 'ps_live_xxxxxxxxxxxx',
916
+ * });
917
+ *
918
+ * const puzzles = await client.puzzles.getDaily();
919
+ * ```
920
+ */
921
+ declare class PuzzleSectionClient {
922
+ private readonly config;
923
+ /**
924
+ * Puzzles API
925
+ */
926
+ readonly puzzles: PuzzlesApi;
927
+ /**
928
+ * Users API
929
+ */
930
+ readonly users: UsersApi;
931
+ /**
932
+ * Progress API
933
+ */
934
+ readonly progress: ProgressApi;
935
+ /**
936
+ * Health API
937
+ */
938
+ readonly health: HealthApi;
939
+ /**
940
+ * Admin API
941
+ */
942
+ readonly admin: AdminApi;
943
+ constructor(config: ClientConfig);
944
+ /**
945
+ * Set the user token for user-specific operations
946
+ */
947
+ setUserToken(token: string | undefined): void;
948
+ /**
949
+ * Make an API request
950
+ */
951
+ request<T>(options: RequestOptions): Promise<ResponseWithRateLimit<T>>;
952
+ /**
953
+ * Execute a single request
954
+ */
955
+ private executeRequest;
956
+ /**
957
+ * Sleep for a given duration
958
+ */
959
+ private sleep;
960
+ }
961
+
962
+ /**
963
+ * SDK Error Classes
964
+ *
965
+ * Provides typed error handling for API responses.
966
+ */
967
+ /**
968
+ * Base error class for all API errors
969
+ */
970
+ declare class ApiError extends Error {
971
+ readonly code: string;
972
+ readonly statusCode: number;
973
+ readonly details?: unknown;
974
+ constructor(message: string, code: string, statusCode: number, details?: unknown);
975
+ }
976
+ /**
977
+ * Authentication error (401)
978
+ * Thrown when API key is invalid or missing
979
+ */
980
+ declare class AuthenticationError extends ApiError {
981
+ constructor(message?: string);
982
+ }
983
+ /**
984
+ * Rate limit error (429)
985
+ * Thrown when rate limit is exceeded
986
+ */
987
+ declare class RateLimitError extends ApiError {
988
+ readonly retryAfter: number;
989
+ readonly limit: number;
990
+ readonly remaining: number;
991
+ readonly reset: number;
992
+ constructor(message: string, retryAfter: number, limit: number, remaining: number, reset: number);
993
+ }
994
+ /**
995
+ * Not found error (404)
996
+ * Thrown when requested resource doesn't exist
997
+ */
998
+ declare class NotFoundError extends ApiError {
999
+ readonly resourceType: string;
1000
+ readonly resourceId: string;
1001
+ constructor(resourceType: string, resourceId: string);
1002
+ }
1003
+ /**
1004
+ * Validation error (400)
1005
+ * Thrown when request validation fails
1006
+ */
1007
+ declare class ValidationError extends ApiError {
1008
+ readonly validationErrors: Record<string, string[]>;
1009
+ constructor(message: string, validationErrors: Record<string, string[]>);
1010
+ }
1011
+ /**
1012
+ * Server error (500)
1013
+ * Thrown when server encounters an error
1014
+ */
1015
+ declare class ServerError extends ApiError {
1016
+ constructor(message?: string);
1017
+ }
1018
+
1019
+ export { AdminApi, type AdminPuzzle, type AdminPuzzleStatus, type AdminPuzzleType, type AdminPuzzleVariant, ApiError, AuthenticationError, type ClientConfig, type CreateAdminPuzzleRequest, type FunFactorResult, HealthApi, type HealthStatus, NotFoundError, ProgressApi, type Puzzle, type PuzzleCompletion, type PuzzleData, type PuzzleDifficulty, type PuzzleProgress, PuzzleSectionClient, type PuzzleSolution, type PuzzleType, PuzzlesApi, RateLimitError, type RateLimitInfo, ServerError, type UpdateAdminPuzzleRequest, type UpsertPuzzleVariantRequest, type User, type UserStats, UsersApi, ValidationError };