@sudobility/sudojo_client 0.0.98 → 0.0.99

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.
@@ -6,7 +6,7 @@ export { useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLe
6
6
  export { useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, } from "./use-sudojo-techniques";
7
7
  export { useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, } from "./use-sudojo-learning";
8
8
  export { useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, } from "./use-sudojo-boards";
9
- export { useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoRandomDaily, useSudojoTodayDaily, useSudojoUpdateDaily, } from "./use-sudojo-dailies";
9
+ export { useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, } from "./use-sudojo-dailies";
10
10
  export { useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, } from "./use-sudojo-challenges";
11
11
  export { useSudojoUser, useSudojoUserSubscription } from "./use-sudojo-users";
12
12
  export { useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, } from "./use-sudojo-practices";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -5,7 +5,7 @@ export { useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLe
5
5
  export { useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, } from "./use-sudojo-techniques";
6
6
  export { useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, } from "./use-sudojo-learning";
7
7
  export { useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, } from "./use-sudojo-boards";
8
- export { useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoRandomDaily, useSudojoTodayDaily, useSudojoUpdateDaily, } from "./use-sudojo-dailies";
8
+ export { useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, } from "./use-sudojo-dailies";
9
9
  export { useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, } from "./use-sudojo-challenges";
10
10
  export { useSudojoUser, useSudojoUserSubscription } from "./use-sudojo-users";
11
11
  export { useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, } from "./use-sudojo-practices";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["/**\n * Sudojo API hooks for React\n */\n\n// ============================================================================\n// Query utilities\n// ============================================================================\n\nexport { createQueryKey, getServiceKeys, queryKeys } from \"./query-keys\";\nexport type { QueryKey } from \"./query-keys\";\nexport { STALE_TIMES } from \"./query-config\";\n\n// ============================================================================\n// Health hook\n// ============================================================================\n\nexport { useSudojoHealth } from \"./use-sudojo-health\";\n\n// ============================================================================\n// Level hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n} from \"./use-sudojo-levels\";\n\n// ============================================================================\n// Technique hooks\n// ============================================================================\n\nexport {\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n} from \"./use-sudojo-techniques\";\n\n// ============================================================================\n// Learning hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n} from \"./use-sudojo-learning\";\n\n// ============================================================================\n// Board hooks\n// ============================================================================\n\nexport {\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n} from \"./use-sudojo-boards\";\n\n// ============================================================================\n// Daily hooks\n// ============================================================================\n\nexport {\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoRandomDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n} from \"./use-sudojo-dailies\";\n\n// ============================================================================\n// Challenge hooks\n// ============================================================================\n\nexport {\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n} from \"./use-sudojo-challenges\";\n\n// ============================================================================\n// User hooks\n// ============================================================================\n\nexport { useSudojoUser, useSudojoUserSubscription } from \"./use-sudojo-users\";\n\n// ============================================================================\n// Practice hooks\n// ============================================================================\n\nexport {\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n} from \"./use-sudojo-practices\";\n\n// ============================================================================\n// Gamification hooks (points, badges, levels, game sessions)\n// ============================================================================\n\nexport {\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n} from \"./use-sudojo-gamification\";\n\n// ============================================================================\n// Invalidation utilities\n// ============================================================================\n\nexport { useSudojoInvalidation } from \"./use-sudojo-invalidation\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["/**\n * Sudojo API hooks for React\n */\n\n// ============================================================================\n// Query utilities\n// ============================================================================\n\nexport { createQueryKey, getServiceKeys, queryKeys } from \"./query-keys\";\nexport type { QueryKey } from \"./query-keys\";\nexport { STALE_TIMES } from \"./query-config\";\n\n// ============================================================================\n// Health hook\n// ============================================================================\n\nexport { useSudojoHealth } from \"./use-sudojo-health\";\n\n// ============================================================================\n// Level hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n} from \"./use-sudojo-levels\";\n\n// ============================================================================\n// Technique hooks\n// ============================================================================\n\nexport {\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n} from \"./use-sudojo-techniques\";\n\n// ============================================================================\n// Learning hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n} from \"./use-sudojo-learning\";\n\n// ============================================================================\n// Board hooks\n// ============================================================================\n\nexport {\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n} from \"./use-sudojo-boards\";\n\n// ============================================================================\n// Daily hooks\n// ============================================================================\n\nexport {\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n} from \"./use-sudojo-dailies\";\n\n// ============================================================================\n// Challenge hooks\n// ============================================================================\n\nexport {\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n} from \"./use-sudojo-challenges\";\n\n// ============================================================================\n// User hooks\n// ============================================================================\n\nexport { useSudojoUser, useSudojoUserSubscription } from \"./use-sudojo-users\";\n\n// ============================================================================\n// Practice hooks\n// ============================================================================\n\nexport {\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n} from \"./use-sudojo-practices\";\n\n// ============================================================================\n// Gamification hooks (points, badges, levels, game sessions)\n// ============================================================================\n\nexport {\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n} from \"./use-sudojo-gamification\";\n\n// ============================================================================\n// Invalidation utilities\n// ============================================================================\n\nexport { useSudojoInvalidation } from \"./use-sudojo-invalidation\";\n"]}
@@ -30,7 +30,6 @@ export declare const queryKeys: {
30
30
  } | undefined];
31
31
  readonly board: (uuid: string) => readonly ["sudojo", "boards", string];
32
32
  readonly dailies: () => readonly ["sudojo", "dailies"];
33
- readonly dailyRandom: () => readonly ["sudojo", "dailies", "random"];
34
33
  readonly dailyToday: () => readonly ["sudojo", "dailies", "today"];
35
34
  readonly dailyByDate: (date: string) => readonly ["sudojo", "dailies", "date", string];
36
35
  readonly daily: (uuid: string) => readonly ["sudojo", "dailies", string];
@@ -1 +1 @@
1
- {"version":3,"file":"query-keys.d.ts","sourceRoot":"","sources":["../../src/hooks/query-keys.ts"],"names":[],"mappings":"AAkCA,eAAO,MAAM,SAAS;;;;;gCAaH,MAAM;wCAIE;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE;oBAApB,MAAM,GAAG,SAAS;;wCAG5B,MAAM;sCAKR;YACnB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACpC;wBAFa,MAAM,GAAG,SAAS;4BACd,MAAM,GAAG,SAAS;;sCAGf,MAAM;oCAKR;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE;oBAApB,MAAM,GAAG,SAAS;;yCAGvB;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE;oBAApB,MAAM,GAAG,SAAS;;+BAGtC,MAAM;;;;qCAUA,MAAM;+BAGZ,MAAM;wCAIG;YACrB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACjC;oBAFS,MAAM,GAAG,SAAS;yBACb,MAAM,GAAG,SAAS;;6CAGL;YAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACjC;oBAFS,MAAM,GAAG,SAAS;yBACb,MAAM,GAAG,SAAS;;mCAGf,MAAM;gCAIT,MAAM;4CAEM,MAAM;;6CAOL,MAAM;;;iDAWF;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;oBAAzB,MAAM;qBAAW,MAAM;;;CAG3D,CAAC;AAMX,MAAM,MAAM,QAAQ,GAAG,SAAS,OAAO,EAAE,CAAC;AAgB1C,eAAO,MAAM,cAAc,GACzB,SAAS,MAAM,EACf,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,KACrC,SAAS,OAAO,EAElB,CAAC;AAcF,eAAO,MAAM,cAAc,2BAE1B,CAAC"}
1
+ {"version":3,"file":"query-keys.d.ts","sourceRoot":"","sources":["../../src/hooks/query-keys.ts"],"names":[],"mappings":"AAkCA,eAAO,MAAM,SAAS;;;;;gCAaH,MAAM;wCAIE;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE;oBAApB,MAAM,GAAG,SAAS;;wCAG5B,MAAM;sCAKR;YACnB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACpC;wBAFa,MAAM,GAAG,SAAS;4BACd,MAAM,GAAG,SAAS;;sCAGf,MAAM;oCAKR;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE;oBAApB,MAAM,GAAG,SAAS;;yCAGvB;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE;oBAApB,MAAM,GAAG,SAAS;;+BAGtC,MAAM;;;qCAQA,MAAM;+BAGZ,MAAM;wCAIG;YACrB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACjC;oBAFS,MAAM,GAAG,SAAS;yBACb,MAAM,GAAG,SAAS;;6CAGL;YAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACjC;oBAFS,MAAM,GAAG,SAAS;yBACb,MAAM,GAAG,SAAS;;mCAGf,MAAM;gCAIT,MAAM;4CAEM,MAAM;;6CAOL,MAAM;;;iDAWF;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;oBAAzB,MAAM;qBAAW,MAAM;;;CAG3D,CAAC;AAMX,MAAM,MAAM,QAAQ,GAAG,SAAS,OAAO,EAAE,CAAC;AAgB1C,eAAO,MAAM,cAAc,GACzB,SAAS,MAAM,EACf,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,KACrC,SAAS,OAAO,EAElB,CAAC;AAcF,eAAO,MAAM,cAAc,2BAE1B,CAAC"}
@@ -13,7 +13,6 @@ export const queryKeys = {
13
13
  boardRandom: (filters) => [...sudojoBase(), "boards", "random", filters],
14
14
  board: (uuid) => [...sudojoBase(), "boards", uuid],
15
15
  dailies: () => [...sudojoBase(), "dailies"],
16
- dailyRandom: () => [...sudojoBase(), "dailies", "random"],
17
16
  dailyToday: () => [...sudojoBase(), "dailies", "today"],
18
17
  dailyByDate: (date) => [...sudojoBase(), "dailies", "date", date],
19
18
  daily: (uuid) => [...sudojoBase(), "dailies", uuid],
@@ -1 +1 @@
1
- {"version":3,"file":"query-keys.js","sourceRoot":"","sources":["../../src/hooks/query-keys.ts"],"names":[],"mappings":"AAgCA,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAU,CAAC;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,MAAM,EAAE;QAEN,GAAG,EAAE,UAAU;QAIf,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,QAAQ,CAAU;QAIlD,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,QAAQ,CAAU;QAElD,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAU;QAIrE,UAAU,EAAE,CAAC,OAAwC,EAAE,EAAE,CACvD,CAAC,GAAG,UAAU,EAAE,EAAE,YAAY,EAAE,OAAO,CAAU;QAEnD,SAAS,EAAE,CAAC,SAAiB,EAAE,EAAE,CAC/B,CAAC,GAAG,UAAU,EAAE,EAAE,YAAY,EAAE,SAAS,CAAU;QAIrD,QAAQ,EAAE,CAAC,OAGV,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,UAAU,EAAE,OAAO,CAAU;QAErD,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE,CAC7B,CAAC,GAAG,UAAU,EAAE,EAAE,UAAU,EAAE,IAAI,CAAU;QAI9C,MAAM,EAAE,CAAC,OAAwC,EAAE,EAAE,CACnD,CAAC,GAAG,UAAU,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAU;QAE/C,WAAW,EAAE,CAAC,OAAwC,EAAE,EAAE,CACxD,CAAC,GAAG,UAAU,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAU;QAEzD,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAU;QAInE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,SAAS,CAAU;QAEpD,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAU;QAElE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,SAAS,EAAE,OAAO,CAAU;QAEhE,WAAW,EAAE,CAAC,IAAY,EAAE,EAAE,CAC5B,CAAC,GAAG,UAAU,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAU;QAErD,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,CAAU;QAIpE,UAAU,EAAE,CAAC,OAGZ,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,YAAY,EAAE,OAAO,CAAU;QAEvD,eAAe,EAAE,CAAC,OAGjB,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAU;QAEjE,SAAS,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,YAAY,EAAE,IAAI,CAAU;QAI3E,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,CAAU;QAErE,gBAAgB,EAAE,CAAC,MAAc,EAAE,EAAE,CACnC,CAAC,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,CAAU;QAI7D,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,WAAW,EAAE,QAAQ,CAAU;QAEvE,cAAc,EAAE,CAAC,SAAiB,EAAE,EAAE,CACpC,CAAC,GAAG,UAAU,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAU;QAI9D,iBAAiB,EAAE,GAAG,EAAE,CACtB,CAAC,GAAG,UAAU,EAAE,EAAE,cAAc,EAAE,OAAO,CAAU;QAErD,kBAAkB,EAAE,GAAG,EAAE,CACvB,CAAC,GAAG,UAAU,EAAE,EAAE,cAAc,EAAE,QAAQ,CAAU;QAEtD,mBAAmB,EAAE,CAAC,OAA6C,EAAE,EAAE,CACrE,CAAC,GAAG,UAAU,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,CAAU;KACjE;CACO,CAAC;AAsBX,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,OAAe,EACf,GAAG,KAAmC,EAClB,EAAE;IACtB,OAAO,CAAC,OAAO,EAAE,GAAG,KAAK,CAAU,CAAC;AACtC,CAAC,CAAC;AAcF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,OAAO,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;AAChC,CAAC,CAAC","sourcesContent":["/**\n * Query Key Factory for Sudojo TanStack Query\n *\n * Provides type-safe, consistent query keys for all Sudojo API endpoints.\n * Follows TanStack Query best practices for hierarchical key structure.\n *\n * ## Key Hierarchy\n *\n * All keys start with `[\"sudojo\"]` as the root, then branch by resource:\n * - `[\"sudojo\", \"levels\"]` - all levels\n * - `[\"sudojo\", \"levels\", 1]` - specific level\n * - `[\"sudojo\", \"boards\", { level: 3 }]` - boards filtered by level\n *\n * ## Invalidation Patterns\n *\n * Use the hierarchical structure for targeted invalidation:\n * - `queryKeys.sudojo.all()` invalidates ALL sudojo queries\n * - `queryKeys.sudojo.levels()` invalidates the levels list\n * - `queryKeys.sudojo.level(1)` invalidates only level 1\n *\n * For broader invalidation (e.g., all board queries including random):\n * ```ts\n * queryClient.invalidateQueries({ queryKey: [...queryKeys.sudojo.all(), \"boards\"] })\n * ```\n *\n * ## Filter Parameters\n *\n * Keys that accept filter objects (e.g., `boards`, `techniques`, `challenges`)\n * include the filter in the key so that different filter combinations produce\n * distinct cache entries.\n */\n\nconst sudojoBase = () => [\"sudojo\"] as const;\n\nexport const queryKeys = {\n sudojo: {\n /** Root key for all sudojo queries. Use for bulk invalidation. */\n all: sudojoBase,\n\n // Health\n /** Key for the server health check endpoint. */\n health: () => [...sudojoBase(), \"health\"] as const,\n\n // Levels\n /** Key for the levels list query. */\n levels: () => [...sudojoBase(), \"levels\"] as const,\n /** Key for a specific level query. @param level - Level number (1-12) */\n level: (level: number) => [...sudojoBase(), \"levels\", level] as const,\n\n // Techniques\n /** Key for the techniques list query, optionally filtered by level. */\n techniques: (filters?: { level?: number | undefined }) =>\n [...sudojoBase(), \"techniques\", filters] as const,\n /** Key for a specific technique query. @param technique - Technique number (>= 1) */\n technique: (technique: number) =>\n [...sudojoBase(), \"techniques\", technique] as const,\n\n // Learning\n /** Key for the learning entries list, optionally filtered by technique and/or language. */\n learning: (filters?: {\n technique?: number | undefined;\n language_code?: string | undefined;\n }) => [...sudojoBase(), \"learning\", filters] as const,\n /** Key for a specific learning item by UUID. */\n learningItem: (uuid: string) =>\n [...sudojoBase(), \"learning\", uuid] as const,\n\n // Boards\n /** Key for the boards list query, optionally filtered by level. */\n boards: (filters?: { level?: number | undefined }) =>\n [...sudojoBase(), \"boards\", filters] as const,\n /** Key for the random board query, optionally filtered by level. */\n boardRandom: (filters?: { level?: number | undefined }) =>\n [...sudojoBase(), \"boards\", \"random\", filters] as const,\n /** Key for a specific board by UUID. */\n board: (uuid: string) => [...sudojoBase(), \"boards\", uuid] as const,\n\n // Dailies\n /** Key for the dailies list query. */\n dailies: () => [...sudojoBase(), \"dailies\"] as const,\n /** Key for the random daily query. */\n dailyRandom: () => [...sudojoBase(), \"dailies\", \"random\"] as const,\n /** Key for today's daily puzzle query. */\n dailyToday: () => [...sudojoBase(), \"dailies\", \"today\"] as const,\n /** Key for a daily puzzle by date. @param date - Date string in YYYY-MM-DD format */\n dailyByDate: (date: string) =>\n [...sudojoBase(), \"dailies\", \"date\", date] as const,\n /** Key for a specific daily by UUID. */\n daily: (uuid: string) => [...sudojoBase(), \"dailies\", uuid] as const,\n\n // Challenges\n /** Key for the challenges list, optionally filtered by level and/or difficulty. */\n challenges: (filters?: {\n level?: number | undefined;\n difficulty?: string | undefined;\n }) => [...sudojoBase(), \"challenges\", filters] as const,\n /** Key for the random challenge query, optionally filtered. */\n challengeRandom: (filters?: {\n level?: number | undefined;\n difficulty?: string | undefined;\n }) => [...sudojoBase(), \"challenges\", \"random\", filters] as const,\n /** Key for a specific challenge by UUID. */\n challenge: (uuid: string) => [...sudojoBase(), \"challenges\", uuid] as const,\n\n // Users\n /** Key for a user info query. @param userId - Firebase UID */\n user: (userId: string) => [...sudojoBase(), \"users\", userId] as const,\n /** Key for a user's subscription status query. @param userId - Firebase UID */\n userSubscription: (userId: string) =>\n [...sudojoBase(), \"users\", userId, \"subscription\"] as const,\n\n // Practices\n /** Key for practice counts across all techniques. */\n practiceCounts: () => [...sudojoBase(), \"practices\", \"counts\"] as const,\n /** Key for a random practice for a specific technique. */\n practiceRandom: (technique: number) =>\n [...sudojoBase(), \"practices\", \"random\", technique] as const,\n\n // Gamification\n /** Key for the user's gamification stats (points, level, badges). */\n gamificationStats: () =>\n [...sudojoBase(), \"gamification\", \"stats\"] as const,\n /** Key for badge definitions (public, no auth required). */\n gamificationBadges: () =>\n [...sudojoBase(), \"gamification\", \"badges\"] as const,\n /** Key for point transaction history with optional pagination. */\n gamificationHistory: (options?: { limit?: number; offset?: number }) =>\n [...sudojoBase(), \"gamification\", \"history\", options] as const,\n },\n} as const;\n\n/**\n * Utility type to extract query key from the factory.\n * All query keys are readonly arrays of unknown values.\n */\nexport type QueryKey = readonly unknown[];\n\n/**\n * Helper function to create a query key for custom or ad-hoc endpoints\n * that are not covered by the standard `queryKeys` factory.\n *\n * @param service - The service name (e.g., \"sudojo\", \"solver\")\n * @param parts - Additional key segments (strings, numbers, or filter objects)\n * @returns A readonly query key tuple\n *\n * @example\n * ```ts\n * const key = createQueryKey(\"sudojo\", \"custom-endpoint\", { filter: \"value\" });\n * // => [\"sudojo\", \"custom-endpoint\", { filter: \"value\" }]\n * ```\n */\nexport const createQueryKey = (\n service: string,\n ...parts: (string | number | object)[]\n): readonly unknown[] => {\n return [service, ...parts] as const;\n};\n\n/**\n * Helper to get the root key for all sudojo service queries.\n * Useful for bulk invalidation of the entire sudojo cache.\n *\n * @returns The root query key `[\"sudojo\"]`\n *\n * @example\n * ```ts\n * // Invalidate all sudojo queries at once\n * queryClient.invalidateQueries({ queryKey: getServiceKeys() });\n * ```\n */\nexport const getServiceKeys = () => {\n return queryKeys.sudojo.all();\n};\n"]}
1
+ {"version":3,"file":"query-keys.js","sourceRoot":"","sources":["../../src/hooks/query-keys.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Query Key Factory for Sudojo TanStack Query\n *\n * Provides type-safe, consistent query keys for all Sudojo API endpoints.\n * Follows TanStack Query best practices for hierarchical key structure.\n *\n * ## Key Hierarchy\n *\n * All keys start with `[\"sudojo\"]` as the root, then branch by resource:\n * - `[\"sudojo\", \"levels\"]` - all levels\n * - `[\"sudojo\", \"levels\", 1]` - specific level\n * - `[\"sudojo\", \"boards\", { level: 3 }]` - boards filtered by level\n *\n * ## Invalidation Patterns\n *\n * Use the hierarchical structure for targeted invalidation:\n * - `queryKeys.sudojo.all()` invalidates ALL sudojo queries\n * - `queryKeys.sudojo.levels()` invalidates the levels list\n * - `queryKeys.sudojo.level(1)` invalidates only level 1\n *\n * For broader invalidation (e.g., all board queries including random):\n * ```ts\n * queryClient.invalidateQueries({ queryKey: [...queryKeys.sudojo.all(), \"boards\"] })\n * ```\n *\n * ## Filter Parameters\n *\n * Keys that accept filter objects (e.g., `boards`, `techniques`, `challenges`)\n * include the filter in the key so that different filter combinations produce\n * distinct cache entries.\n */\n\nconst sudojoBase = () => [\"sudojo\"] as const;\n\nexport const queryKeys = {\n sudojo: {\n /** Root key for all sudojo queries. Use for bulk invalidation. */\n all: sudojoBase,\n\n // Health\n /** Key for the server health check endpoint. */\n health: () => [...sudojoBase(), \"health\"] as const,\n\n // Levels\n /** Key for the levels list query. */\n levels: () => [...sudojoBase(), \"levels\"] as const,\n /** Key for a specific level query. @param level - Level number (1-12) */\n level: (level: number) => [...sudojoBase(), \"levels\", level] as const,\n\n // Techniques\n /** Key for the techniques list query, optionally filtered by level. */\n techniques: (filters?: { level?: number | undefined }) =>\n [...sudojoBase(), \"techniques\", filters] as const,\n /** Key for a specific technique query. @param technique - Technique number (>= 1) */\n technique: (technique: number) =>\n [...sudojoBase(), \"techniques\", technique] as const,\n\n // Learning\n /** Key for the learning entries list, optionally filtered by technique and/or language. */\n learning: (filters?: {\n technique?: number | undefined;\n language_code?: string | undefined;\n }) => [...sudojoBase(), \"learning\", filters] as const,\n /** Key for a specific learning item by UUID. */\n learningItem: (uuid: string) =>\n [...sudojoBase(), \"learning\", uuid] as const,\n\n // Boards\n /** Key for the boards list query, optionally filtered by level. */\n boards: (filters?: { level?: number | undefined }) =>\n [...sudojoBase(), \"boards\", filters] as const,\n /** Key for the random board query, optionally filtered by level. */\n boardRandom: (filters?: { level?: number | undefined }) =>\n [...sudojoBase(), \"boards\", \"random\", filters] as const,\n /** Key for a specific board by UUID. */\n board: (uuid: string) => [...sudojoBase(), \"boards\", uuid] as const,\n\n // Dailies\n /** Key for the dailies list query. */\n dailies: () => [...sudojoBase(), \"dailies\"] as const,\n /** Key for today's daily puzzle query. */\n dailyToday: () => [...sudojoBase(), \"dailies\", \"today\"] as const,\n /** Key for a daily puzzle by date. @param date - Date string in YYYY-MM-DD format */\n dailyByDate: (date: string) =>\n [...sudojoBase(), \"dailies\", \"date\", date] as const,\n /** Key for a specific daily by UUID. */\n daily: (uuid: string) => [...sudojoBase(), \"dailies\", uuid] as const,\n\n // Challenges\n /** Key for the challenges list, optionally filtered by level and/or difficulty. */\n challenges: (filters?: {\n level?: number | undefined;\n difficulty?: string | undefined;\n }) => [...sudojoBase(), \"challenges\", filters] as const,\n /** Key for the random challenge query, optionally filtered. */\n challengeRandom: (filters?: {\n level?: number | undefined;\n difficulty?: string | undefined;\n }) => [...sudojoBase(), \"challenges\", \"random\", filters] as const,\n /** Key for a specific challenge by UUID. */\n challenge: (uuid: string) => [...sudojoBase(), \"challenges\", uuid] as const,\n\n // Users\n /** Key for a user info query. @param userId - Firebase UID */\n user: (userId: string) => [...sudojoBase(), \"users\", userId] as const,\n /** Key for a user's subscription status query. @param userId - Firebase UID */\n userSubscription: (userId: string) =>\n [...sudojoBase(), \"users\", userId, \"subscription\"] as const,\n\n // Practices\n /** Key for practice counts across all techniques. */\n practiceCounts: () => [...sudojoBase(), \"practices\", \"counts\"] as const,\n /** Key for a random practice for a specific technique. */\n practiceRandom: (technique: number) =>\n [...sudojoBase(), \"practices\", \"random\", technique] as const,\n\n // Gamification\n /** Key for the user's gamification stats (points, level, badges). */\n gamificationStats: () =>\n [...sudojoBase(), \"gamification\", \"stats\"] as const,\n /** Key for badge definitions (public, no auth required). */\n gamificationBadges: () =>\n [...sudojoBase(), \"gamification\", \"badges\"] as const,\n /** Key for point transaction history with optional pagination. */\n gamificationHistory: (options?: { limit?: number; offset?: number }) =>\n [...sudojoBase(), \"gamification\", \"history\", options] as const,\n },\n} as const;\n\n/**\n * Utility type to extract query key from the factory.\n * All query keys are readonly arrays of unknown values.\n */\nexport type QueryKey = readonly unknown[];\n\n/**\n * Helper function to create a query key for custom or ad-hoc endpoints\n * that are not covered by the standard `queryKeys` factory.\n *\n * @param service - The service name (e.g., \"sudojo\", \"solver\")\n * @param parts - Additional key segments (strings, numbers, or filter objects)\n * @returns A readonly query key tuple\n *\n * @example\n * ```ts\n * const key = createQueryKey(\"sudojo\", \"custom-endpoint\", { filter: \"value\" });\n * // => [\"sudojo\", \"custom-endpoint\", { filter: \"value\" }]\n * ```\n */\nexport const createQueryKey = (\n service: string,\n ...parts: (string | number | object)[]\n): readonly unknown[] => {\n return [service, ...parts] as const;\n};\n\n/**\n * Helper to get the root key for all sudojo service queries.\n * Useful for bulk invalidation of the entire sudojo cache.\n *\n * @returns The root query key `[\"sudojo\"]`\n *\n * @example\n * ```ts\n * // Invalidate all sudojo queries at once\n * queryClient.invalidateQueries({ queryKey: getServiceKeys() });\n * ```\n */\nexport const getServiceKeys = () => {\n return queryKeys.sudojo.all();\n};\n"]}
@@ -2,7 +2,6 @@ import { UseMutationResult, UseQueryOptions, UseQueryResult } from "@tanstack/re
2
2
  import type { NetworkClient } from "@sudobility/types";
3
3
  import type { BaseResponse, Daily, DailyCreateRequest, DailyUpdateRequest } from "@sudobility/sudojo_types";
4
4
  export declare const useSudojoDailies: (networkClient: NetworkClient, baseUrl: string, token: string, options?: Omit<UseQueryOptions<BaseResponse<Daily[]>>, "queryKey" | "queryFn">) => UseQueryResult<BaseResponse<Daily[]>>;
5
- export declare const useSudojoRandomDaily: (networkClient: NetworkClient, baseUrl: string, token: string, options?: Omit<UseQueryOptions<BaseResponse<Daily>>, "queryKey" | "queryFn">) => UseQueryResult<BaseResponse<Daily>>;
6
5
  export declare const useSudojoTodayDaily: (networkClient: NetworkClient, baseUrl: string, token: string, options?: Omit<UseQueryOptions<BaseResponse<Daily>>, "queryKey" | "queryFn">) => UseQueryResult<BaseResponse<Daily>>;
7
6
  export declare const useSudojoDailyByDate: (networkClient: NetworkClient, baseUrl: string, token: string, date: string, options?: Omit<UseQueryOptions<BaseResponse<Daily>>, "queryKey" | "queryFn">) => UseQueryResult<BaseResponse<Daily>>;
8
7
  export declare const useSudojoDaily: (networkClient: NetworkClient, baseUrl: string, token: string, uuid: string, options?: Omit<UseQueryOptions<BaseResponse<Daily>>, "queryKey" | "queryFn">) => UseQueryResult<BaseResponse<Daily>>;
@@ -1 +1 @@
1
- {"version":3,"file":"use-sudojo-dailies.d.ts","sourceRoot":"","sources":["../../src/hooks/use-sudojo-dailies.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,iBAAiB,EAGjB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,KAAK,EACL,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAkBlC,eAAO,MAAM,gBAAgB,GAC3B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAU,IAAI,CACZ,eAAe,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,EACtC,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAoBtC,CAAC;AAaF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAU,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAC3E,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAoBpC,CAAC;AAgBF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAU,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAC3E,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAoBpC,CAAC;AAiBF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,UAAU,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAC3E,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAqBpC,CAAC;AAgBF,eAAO,MAAM,cAAc,GACzB,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,UAAU,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAC3E,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAqBpC,CAAC;AAWF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,KAAK,CAAC,EACnB,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAwB5C,CAAC;AAWF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,KAAK,CAAC,EACnB,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CA6B1D,CAAC;AAYF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,KAAK,CAAC,EACnB,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAqBhC,CAAC"}
1
+ {"version":3,"file":"use-sudojo-dailies.d.ts","sourceRoot":"","sources":["../../src/hooks/use-sudojo-dailies.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,iBAAiB,EAGjB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,KAAK,EACL,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAkBlC,eAAO,MAAM,gBAAgB,GAC3B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAU,IAAI,CACZ,eAAe,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,EACtC,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAoBtC,CAAC;AAgBF,eAAO,MAAM,mBAAmB,GAC9B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAU,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAC3E,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAoBpC,CAAC;AAiBF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,UAAU,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAC3E,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAqBpC,CAAC;AAgBF,eAAO,MAAM,cAAc,GACzB,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,UAAU,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAC3E,cAAc,CAAC,YAAY,CAAC,KAAK,CAAC,CAqBpC,CAAC;AAWF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,KAAK,CAAC,EACnB,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAwB5C,CAAC;AAWF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,KAAK,CAAC,EACnB,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CA6B1D,CAAC;AAYF,eAAO,MAAM,oBAAoB,GAC/B,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,KAAK,CAAC,EACnB,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAqBhC,CAAC"}
@@ -17,20 +17,6 @@ export const useSudojoDailies = (networkClient, baseUrl, token, options) => {
17
17
  enabled: isEnabled,
18
18
  });
19
19
  };
20
- export const useSudojoRandomDaily = (networkClient, baseUrl, token, options) => {
21
- const client = useMemo(() => new SudojoClient(networkClient, baseUrl), [networkClient, baseUrl]);
22
- const queryFn = useCallback(async () => {
23
- return client.getRandomDaily(token);
24
- }, [client, token]);
25
- const isEnabled = options?.enabled !== undefined ? options.enabled : true;
26
- return useQuery({
27
- queryKey: queryKeys.sudojo.dailyRandom(),
28
- queryFn,
29
- staleTime: 0,
30
- ...options,
31
- enabled: isEnabled,
32
- });
33
- };
34
20
  export const useSudojoTodayDaily = (networkClient, baseUrl, token, options) => {
35
21
  const client = useMemo(() => new SudojoClient(networkClient, baseUrl), [networkClient, baseUrl]);
36
22
  const queryFn = useCallback(async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"use-sudojo-dailies.js","sourceRoot":"","sources":["../../src/hooks/use-sudojo-dailies.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hook for Sudojo dailies endpoints\n */\n\nimport { useCallback, useMemo } from \"react\";\nimport {\n useMutation,\n UseMutationResult,\n useQuery,\n useQueryClient,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { NetworkClient } from \"@sudobility/types\";\nimport type {\n BaseResponse,\n Daily,\n DailyCreateRequest,\n DailyUpdateRequest,\n} from \"@sudobility/sudojo_types\";\nimport { queryKeys } from \"./query-keys\";\nimport { STALE_TIMES } from \"./query-config\";\nimport { SudojoClient } from \"../network/sudojo-client\";\n\n/**\n * Hook to fetch all daily puzzles.\n *\n * Daily puzzles are boards assigned to specific dates. This is a public endpoint.\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing an array of Daily objects\n */\nexport const useSudojoDailies = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options?: Omit<\n UseQueryOptions<BaseResponse<Daily[]>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<Daily[]>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily[]>> => {\n return client.getDailies(token);\n }, [client, token]);\n\n // Public endpoint - no token required\n const isEnabled = options?.enabled !== undefined ? options.enabled : true;\n\n return useQuery({\n queryKey: queryKeys.sudojo.dailies(),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch a random daily puzzle.\n *\n * Uses `staleTime: 0` to always fetch a fresh random daily on each access.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing a single Daily object\n */\nexport const useSudojoRandomDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options?: Omit<UseQueryOptions<BaseResponse<Daily>>, \"queryKey\" | \"queryFn\">,\n): UseQueryResult<BaseResponse<Daily>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily>> => {\n return client.getRandomDaily(token);\n }, [client, token]);\n\n // Public endpoint - no token required\n const isEnabled = options?.enabled !== undefined ? options.enabled : true;\n\n return useQuery({\n queryKey: queryKeys.sudojo.dailyRandom(),\n queryFn,\n staleTime: 0, // Always fetch fresh for random\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch today's daily puzzle.\n *\n * The server determines \"today\" based on its timezone configuration.\n * This is the primary hook for showing the daily puzzle to users.\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing today's Daily object\n */\nexport const useSudojoTodayDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options?: Omit<UseQueryOptions<BaseResponse<Daily>>, \"queryKey\" | \"queryFn\">,\n): UseQueryResult<BaseResponse<Daily>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily>> => {\n return client.getTodayDaily(token);\n }, [client, token]);\n\n // Public endpoint - no token required\n const isEnabled = options?.enabled !== undefined ? options.enabled : true;\n\n return useQuery({\n queryKey: queryKeys.sudojo.dailyToday(),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch a daily puzzle for a specific date.\n *\n * The query is automatically disabled when no date is provided.\n * Date must be in YYYY-MM-DD format (validated by the SudojoClient).\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param date - Date string in YYYY-MM-DD format. Query is disabled if empty.\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing the Daily object for the given date\n */\nexport const useSudojoDailyByDate = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n date: string,\n options?: Omit<UseQueryOptions<BaseResponse<Daily>>, \"queryKey\" | \"queryFn\">,\n): UseQueryResult<BaseResponse<Daily>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily>> => {\n return client.getDailyByDate(token, date);\n }, [client, token, date]);\n\n // Public endpoint - no token required, but date is required\n const isEnabled =\n !!date && (options?.enabled !== undefined ? options.enabled : true);\n\n return useQuery({\n queryKey: queryKeys.sudojo.dailyByDate(date),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch a specific daily puzzle by its UUID.\n *\n * The query is automatically disabled when no UUID is provided.\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param uuid - Daily UUID. Query is disabled if empty.\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing a single Daily object\n */\nexport const useSudojoDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n uuid: string,\n options?: Omit<UseQueryOptions<BaseResponse<Daily>>, \"queryKey\" | \"queryFn\">,\n): UseQueryResult<BaseResponse<Daily>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily>> => {\n return client.getDaily(token, uuid);\n }, [client, token, uuid]);\n\n // Public endpoint - no token required, but uuid is required\n const isEnabled =\n !!uuid && (options?.enabled !== undefined ? options.enabled : true);\n\n return useQuery({\n queryKey: queryKeys.sudojo.daily(uuid),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to create a new daily puzzle. Requires admin authentication.\n *\n * On success, invalidates all daily list queries so the UI reflects the new daily.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, data })` to execute.\n */\nexport const useSudojoCreateDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<Daily>,\n Error,\n { token: string; data: DailyCreateRequest }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({\n token,\n data,\n }: {\n token: string;\n data: DailyCreateRequest;\n }) => {\n return client.createDaily(token, data);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: [...queryKeys.sudojo.all(), \"dailies\"],\n });\n },\n });\n};\n\n/**\n * Hook to update an existing daily puzzle. Requires admin authentication.\n *\n * On success, invalidates all daily list queries and the specific daily query.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, uuid, data })` to execute.\n */\nexport const useSudojoUpdateDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<Daily>,\n Error,\n { token: string; uuid: string; data: DailyUpdateRequest }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({\n token,\n uuid,\n data,\n }: {\n token: string;\n uuid: string;\n data: DailyUpdateRequest;\n }) => {\n return client.updateDaily(token, uuid, data);\n },\n onSuccess: (_data, variables) => {\n queryClient.invalidateQueries({\n queryKey: [...queryKeys.sudojo.all(), \"dailies\"],\n });\n queryClient.invalidateQueries({\n queryKey: queryKeys.sudojo.daily(variables.uuid),\n });\n },\n });\n};\n\n/**\n * Hook to delete a daily puzzle. Requires admin authentication.\n *\n * On success, invalidates all daily list queries and removes the specific\n * daily from the query cache.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, uuid })` to execute.\n */\nexport const useSudojoDeleteDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<Daily>,\n Error,\n { token: string; uuid: string }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ token, uuid }: { token: string; uuid: string }) => {\n return client.deleteDaily(token, uuid);\n },\n onSuccess: (_data, variables) => {\n queryClient.invalidateQueries({\n queryKey: [...queryKeys.sudojo.all(), \"dailies\"],\n });\n queryClient.removeQueries({\n queryKey: queryKeys.sudojo.daily(variables.uuid),\n });\n },\n });\n};\n"]}
1
+ {"version":3,"file":"use-sudojo-dailies.js","sourceRoot":"","sources":["../../src/hooks/use-sudojo-dailies.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hook for Sudojo dailies endpoints\n */\n\nimport { useCallback, useMemo } from \"react\";\nimport {\n useMutation,\n UseMutationResult,\n useQuery,\n useQueryClient,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { NetworkClient } from \"@sudobility/types\";\nimport type {\n BaseResponse,\n Daily,\n DailyCreateRequest,\n DailyUpdateRequest,\n} from \"@sudobility/sudojo_types\";\nimport { queryKeys } from \"./query-keys\";\nimport { STALE_TIMES } from \"./query-config\";\nimport { SudojoClient } from \"../network/sudojo-client\";\n\n/**\n * Hook to fetch all daily puzzles.\n *\n * Daily puzzles are boards assigned to specific dates. This is a public endpoint.\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing an array of Daily objects\n */\nexport const useSudojoDailies = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options?: Omit<\n UseQueryOptions<BaseResponse<Daily[]>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<Daily[]>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily[]>> => {\n return client.getDailies(token);\n }, [client, token]);\n\n // Public endpoint - no token required\n const isEnabled = options?.enabled !== undefined ? options.enabled : true;\n\n return useQuery({\n queryKey: queryKeys.sudojo.dailies(),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch today's daily puzzle.\n *\n * The server determines \"today\" based on its timezone configuration.\n * This is the primary hook for showing the daily puzzle to users.\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing today's Daily object\n */\nexport const useSudojoTodayDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options?: Omit<UseQueryOptions<BaseResponse<Daily>>, \"queryKey\" | \"queryFn\">,\n): UseQueryResult<BaseResponse<Daily>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily>> => {\n return client.getTodayDaily(token);\n }, [client, token]);\n\n // Public endpoint - no token required\n const isEnabled = options?.enabled !== undefined ? options.enabled : true;\n\n return useQuery({\n queryKey: queryKeys.sudojo.dailyToday(),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch a daily puzzle for a specific date.\n *\n * The query is automatically disabled when no date is provided.\n * Date must be in YYYY-MM-DD format (validated by the SudojoClient).\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param date - Date string in YYYY-MM-DD format. Query is disabled if empty.\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing the Daily object for the given date\n */\nexport const useSudojoDailyByDate = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n date: string,\n options?: Omit<UseQueryOptions<BaseResponse<Daily>>, \"queryKey\" | \"queryFn\">,\n): UseQueryResult<BaseResponse<Daily>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily>> => {\n return client.getDailyByDate(token, date);\n }, [client, token, date]);\n\n // Public endpoint - no token required, but date is required\n const isEnabled =\n !!date && (options?.enabled !== undefined ? options.enabled : true);\n\n return useQuery({\n queryKey: queryKeys.sudojo.dailyByDate(date),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch a specific daily puzzle by its UUID.\n *\n * The query is automatically disabled when no UUID is provided.\n *\n * Stale time: {@link STALE_TIMES.DAILIES} (5 minutes).\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token (optional for this public endpoint)\n * @param uuid - Daily UUID. Query is disabled if empty.\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing a single Daily object\n */\nexport const useSudojoDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n uuid: string,\n options?: Omit<UseQueryOptions<BaseResponse<Daily>>, \"queryKey\" | \"queryFn\">,\n): UseQueryResult<BaseResponse<Daily>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<Daily>> => {\n return client.getDaily(token, uuid);\n }, [client, token, uuid]);\n\n // Public endpoint - no token required, but uuid is required\n const isEnabled =\n !!uuid && (options?.enabled !== undefined ? options.enabled : true);\n\n return useQuery({\n queryKey: queryKeys.sudojo.daily(uuid),\n queryFn,\n staleTime: STALE_TIMES.DAILIES,\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to create a new daily puzzle. Requires admin authentication.\n *\n * On success, invalidates all daily list queries so the UI reflects the new daily.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, data })` to execute.\n */\nexport const useSudojoCreateDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<Daily>,\n Error,\n { token: string; data: DailyCreateRequest }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({\n token,\n data,\n }: {\n token: string;\n data: DailyCreateRequest;\n }) => {\n return client.createDaily(token, data);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: [...queryKeys.sudojo.all(), \"dailies\"],\n });\n },\n });\n};\n\n/**\n * Hook to update an existing daily puzzle. Requires admin authentication.\n *\n * On success, invalidates all daily list queries and the specific daily query.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, uuid, data })` to execute.\n */\nexport const useSudojoUpdateDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<Daily>,\n Error,\n { token: string; uuid: string; data: DailyUpdateRequest }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({\n token,\n uuid,\n data,\n }: {\n token: string;\n uuid: string;\n data: DailyUpdateRequest;\n }) => {\n return client.updateDaily(token, uuid, data);\n },\n onSuccess: (_data, variables) => {\n queryClient.invalidateQueries({\n queryKey: [...queryKeys.sudojo.all(), \"dailies\"],\n });\n queryClient.invalidateQueries({\n queryKey: queryKeys.sudojo.daily(variables.uuid),\n });\n },\n });\n};\n\n/**\n * Hook to delete a daily puzzle. Requires admin authentication.\n *\n * On success, invalidates all daily list queries and removes the specific\n * daily from the query cache.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, uuid })` to execute.\n */\nexport const useSudojoDeleteDaily = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<Daily>,\n Error,\n { token: string; uuid: string }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ token, uuid }: { token: string; uuid: string }) => {\n return client.deleteDaily(token, uuid);\n },\n onSuccess: (_data, variables) => {\n queryClient.invalidateQueries({\n queryKey: [...queryKeys.sudojo.all(), \"dailies\"],\n });\n queryClient.removeQueries({\n queryKey: queryKeys.sudojo.daily(variables.uuid),\n });\n },\n });\n};\n"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { configureSolutionKey, createSudojoClient, isValidUUID, SudojoClient, validateUUID, } from "./network";
2
2
  export type { GenerateOptions, SolveOptions, ValidateOptions } from "./network";
3
3
  export { HintAccessDeniedError } from "./errors";
4
- export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoRandomDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
4
+ export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
5
5
  export type { QueryKey } from "./hooks";
6
6
  export { getSolverServiceKeys, solverQueryKeys, SOLVER_STALE_TIMES, useSolverGenerate, useSolverSolve, useSolverValidate, } from "./solver";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGhF,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGhF,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { configureSolutionKey, createSudojoClient, isValidUUID, SudojoClient, validateUUID, } from "./network";
2
2
  export { HintAccessDeniedError } from "./errors";
3
- export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoRandomDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
3
+ export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
4
4
  export { getSolverServiceKeys, solverQueryKeys, SOLVER_STALE_TIMES, useSolverGenerate, useSolverSolve, useSolverValidate, } from "./solver";
5
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAIjB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC","sourcesContent":["// Main library exports\nexport {\n configureSolutionKey,\n createSudojoClient,\n isValidUUID,\n SudojoClient,\n validateUUID,\n} from \"./network\";\nexport type { GenerateOptions, SolveOptions, ValidateOptions } from \"./network\";\n\n// Errors\nexport { HintAccessDeniedError } from \"./errors\";\n\n// React hooks\nexport {\n // Query utilities\n createQueryKey,\n getServiceKeys,\n queryKeys,\n STALE_TIMES,\n // Health\n useSudojoHealth,\n // Levels\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n // Techniques\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n // Learning\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n // Boards\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n // Dailies\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoRandomDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n // Challenges\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n // Users\n useSudojoUser,\n useSudojoUserSubscription,\n // Practices\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n // Gamification\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n // Invalidation utilities\n useSudojoInvalidation,\n} from \"./hooks\";\nexport type { QueryKey } from \"./hooks\";\n\n// Solver hooks\nexport {\n getSolverServiceKeys,\n solverQueryKeys,\n SOLVER_STALE_TIMES,\n useSolverGenerate,\n useSolverSolve,\n useSolverValidate,\n} from \"./solver\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAIjB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC","sourcesContent":["// Main library exports\nexport {\n configureSolutionKey,\n createSudojoClient,\n isValidUUID,\n SudojoClient,\n validateUUID,\n} from \"./network\";\nexport type { GenerateOptions, SolveOptions, ValidateOptions } from \"./network\";\n\n// Errors\nexport { HintAccessDeniedError } from \"./errors\";\n\n// React hooks\nexport {\n // Query utilities\n createQueryKey,\n getServiceKeys,\n queryKeys,\n STALE_TIMES,\n // Health\n useSudojoHealth,\n // Levels\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n // Techniques\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n // Learning\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n // Boards\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n // Dailies\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n // Challenges\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n // Users\n useSudojoUser,\n useSudojoUserSubscription,\n // Practices\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n // Gamification\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n // Invalidation utilities\n useSudojoInvalidation,\n} from \"./hooks\";\nexport type { QueryKey } from \"./hooks\";\n\n// Solver hooks\nexport {\n getSolverServiceKeys,\n solverQueryKeys,\n SOLVER_STALE_TIMES,\n useSolverGenerate,\n useSolverSolve,\n useSolverValidate,\n} from \"./solver\";\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { NetworkClient, UserInfoResponse } from "@sudobility/types";
2
- import { type BadgeDefinition, type BaseResponse, type Board, type BoardCountsData, type BoardCreateRequest, type BoardQueryParams, type BoardUpdateRequest, type Challenge, type ChallengeCreateRequest, type ChallengeQueryParams, type ChallengeUpdateRequest, type Daily, type DailyCreateRequest, type DailyUpdateRequest, type ExampleCountsData, type GameFinishRequest, type GameFinishResponse, type GameStartRequest, type GameStartResponse, type GamificationStats, type GenerateData, type GenerateOptions, type HealthCheckData, isValidUUID, type Learning, type LearningCreateRequest, type LearningQueryParams, type LearningUpdateRequest, type Level, type LevelCreateRequest, type LevelUpdateRequest, type PointTransaction, type SolveData, type SolveOptions, type SubscriptionResult, type Technique, type TechniqueCreateRequest, type TechniqueExample, type TechniqueExampleCreateRequest, type TechniqueExampleQueryParams, type TechniquePractice, type TechniquePracticeCountItem, type TechniquePracticeCreateRequest, type TechniqueQueryParams, type TechniqueUpdateRequest, type ValidateData, type ValidateOptions, validateUUID } from "@sudobility/sudojo_types";
2
+ import { type BadgeDefinition, type BaseResponse, type Board, type BoardCountsByTechniqueData, type BoardCountsData, type BoardCreateRequest, type BoardQueryParams, type BoardUpdateRequest, type Challenge, type ChallengeCreateRequest, type ChallengeQueryParams, type ChallengeUpdateRequest, type Daily, type DailyCreateRequest, type DailyUpdateRequest, type ExampleCountsData, type GameFinishRequest, type GameFinishResponse, type GameStartRequest, type GameStartResponse, type GamificationStats, type GenerateData, type GenerateOptions, type HealthCheckData, isValidUUID, type Learning, type LearningCreateRequest, type LearningQueryParams, type LearningUpdateRequest, type Level, type LevelCreateRequest, type LevelUpdateRequest, type PointTransaction, type PracticesBulkDeleteData, type SolveData, type SolveOptions, type SubscriptionResult, type Technique, type TechniqueCreateRequest, type TechniqueExample, type TechniqueExampleCreateRequest, type TechniqueExampleQueryParams, type TechniquePractice, type TechniquePracticeCountItem, type TechniquePracticeCreateRequest, type TechniqueQueryParams, type TechniqueUpdateRequest, type UpdateStatsData, type ValidateData, type ValidateOptions, validateUUID } from "@sudobility/sudojo_types";
3
3
  export type { SolveOptions, ValidateOptions, GenerateOptions };
4
4
  export declare function configureSolutionKey(keyHex: string): Promise<void>;
5
5
  export declare class SudojoClient {
@@ -32,7 +32,6 @@ export declare class SudojoClient {
32
32
  updateBoard(token: string, uuid: string, data: BoardUpdateRequest): Promise<BaseResponse<Board>>;
33
33
  deleteBoard(token: string, uuid: string): Promise<BaseResponse<Board>>;
34
34
  getDailies(token: string): Promise<BaseResponse<Daily[]>>;
35
- getRandomDaily(token: string): Promise<BaseResponse<Daily>>;
36
35
  getTodayDaily(token: string): Promise<BaseResponse<Daily>>;
37
36
  getDailyByDate(token: string, date: string): Promise<BaseResponse<Daily>>;
38
37
  getDaily(token: string, uuid: string): Promise<BaseResponse<Daily>>;
@@ -50,19 +49,13 @@ export declare class SudojoClient {
50
49
  getPracticeCounts(token: string): Promise<BaseResponse<TechniquePracticeCountItem[]>>;
51
50
  getRandomPractice(token: string, technique: number): Promise<BaseResponse<TechniquePractice>>;
52
51
  createPractice(token: string, data: TechniquePracticeCreateRequest): Promise<BaseResponse<TechniquePractice>>;
53
- deleteAllPractices(token: string): Promise<BaseResponse<{
54
- deleted: number;
55
- message: string;
56
- }>>;
52
+ deleteAllPractices(token: string): Promise<BaseResponse<PracticesBulkDeleteData>>;
57
53
  getExampleCounts(token: string): Promise<BaseResponse<ExampleCountsData>>;
58
54
  getExamples(token: string, queryParams?: TechniqueExampleQueryParams): Promise<BaseResponse<TechniqueExample[]>>;
59
55
  createExample(token: string, data: TechniqueExampleCreateRequest): Promise<BaseResponse<TechniqueExample>>;
60
56
  getBoardCounts(token: string): Promise<BaseResponse<BoardCountsData>>;
61
- getBoardCountsByTechnique(token: string): Promise<BaseResponse<Record<number, number>>>;
62
- updatePuzzleStats(token: string): Promise<BaseResponse<{
63
- levels: Record<number, number>;
64
- techniques: Record<number, number>;
65
- }>>;
57
+ getBoardCountsByTechnique(token: string): Promise<BaseResponse<BoardCountsByTechniqueData>>;
58
+ updatePuzzleStats(token: string): Promise<BaseResponse<UpdateStatsData>>;
66
59
  private buildSolverUrl;
67
60
  solverSolve(token: string, options: SolveOptions): Promise<BaseResponse<SolveData>>;
68
61
  solverValidate(token: string, options: ValidateOptions): Promise<BaseResponse<ValidateData>>;
@@ -1 +1 @@
1
- {"version":3,"file":"sudojo-client.d.ts","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sudojo-client.d.ts","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"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"}
@@ -76,7 +76,6 @@ const createApiConfig = (baseUrl) => ({
76
76
  BOARDS_RANDOM: "/api/v1/boards/random",
77
77
  BOARD: (uuid) => `/api/v1/boards/${uuid}`,
78
78
  DAILIES: "/api/v1/dailies",
79
- DAILIES_RANDOM: "/api/v1/dailies/random",
80
79
  DAILIES_TODAY: "/api/v1/dailies/today",
81
80
  DAILIES_DATE: (date) => `/api/v1/dailies/date/${date}`,
82
81
  DAILY: (uuid) => `/api/v1/dailies/${uuid}`,
@@ -324,9 +323,6 @@ export class SudojoClient {
324
323
  token,
325
324
  });
326
325
  }
327
- async getRandomDaily(token) {
328
- return this.request(this.config.ENDPOINTS.DAILIES_RANDOM, { token });
329
- }
330
326
  async getTodayDaily(token) {
331
327
  return this.request(this.config.ENDPOINTS.DAILIES_TODAY, { token });
332
328
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sudojo-client.js","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NetworkClient, UserInfoResponse } from \"@sudobility/types\";\nimport {\n type BadgeDefinition,\n type BaseResponse,\n type Board,\n type BoardCountsData,\n type BoardCreateRequest,\n type BoardQueryParams,\n type BoardUpdateRequest,\n type Challenge,\n type ChallengeCreateRequest,\n type ChallengeQueryParams,\n type ChallengeUpdateRequest,\n type Daily,\n type DailyCreateRequest,\n type DailyUpdateRequest,\n type ExampleCountsData,\n type GameFinishRequest,\n type GameFinishResponse,\n type GameStartRequest,\n type GameStartResponse,\n type GamificationStats,\n type GenerateData,\n type GenerateOptions,\n type HealthCheckData,\n type HintAccessDeniedResponse,\n isValidUUID,\n type Learning,\n type LearningCreateRequest,\n type LearningQueryParams,\n type LearningUpdateRequest,\n type Level,\n type LevelCreateRequest,\n type LevelUpdateRequest,\n type Optional,\n type PointTransaction,\n type SolveData,\n type SolveOptions,\n type SubscriptionResult,\n type Technique,\n type TechniqueCreateRequest,\n type TechniqueExample,\n type TechniqueExampleCreateRequest,\n type TechniqueExampleQueryParams,\n type TechniquePractice,\n type TechniquePracticeCountItem,\n type TechniquePracticeCreateRequest,\n type TechniqueQueryParams,\n type TechniqueUpdateRequest,\n type ValidateData,\n type ValidateOptions,\n validateUUID,\n} from \"@sudobility/sudojo_types\";\nimport { HintAccessDeniedError } from \"../errors\";\n\n// Re-export option types for convenience\nexport type { SolveOptions, ValidateOptions, GenerateOptions };\n\n// =============================================================================\n// Solution Decryption\n// =============================================================================\n\nlet _solutionKey: CryptoKey | null = null;\n\n/**\n * Configure the symmetric key used to decrypt `solution` fields in API responses.\n * Call once at app startup with the hex-encoded 256-bit key.\n * If not called (or called with empty string), encrypted solutions pass through as-is.\n */\nexport async function configureSolutionKey(keyHex: string): Promise<void> {\n if (!keyHex) return;\n const hexPairs = keyHex.match(/.{2}/g);\n if (!hexPairs) return;\n const keyBytes = new Uint8Array(hexPairs.map((byte) => parseInt(byte, 16)));\n _solutionKey = await globalThis.crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n \"AES-GCM\",\n false,\n [\"decrypt\"],\n );\n}\n\nasync function decryptSolution(encrypted: string): Promise<string> {\n if (!_solutionKey) return encrypted;\n\n const raw = globalThis.atob(encrypted.slice(4)); // strip \"enc:\" prefix\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n bytes[i] = raw.charCodeAt(i);\n }\n\n const nonce = bytes.slice(0, 12);\n const ciphertextWithTag = bytes.slice(12);\n\n const decrypted = await globalThis.crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: nonce },\n _solutionKey,\n ciphertextWithTag,\n );\n\n return new TextDecoder().decode(decrypted);\n}\n\nasync function decryptSolutionFields(data: unknown): Promise<unknown> {\n if (data === null || data === undefined) return data;\n\n if (Array.isArray(data)) {\n return Promise.all(data.map((item) => decryptSolutionFields(item)));\n }\n\n if (typeof data === \"object\") {\n const obj = data as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n if (\n key === \"solution\" &&\n typeof obj[key] === \"string\" &&\n (obj[key] as string).startsWith(\"enc:\")\n ) {\n result[key] = await decryptSolution(obj[key] as string);\n } else {\n result[key] = await decryptSolutionFields(obj[key]);\n }\n }\n return result;\n }\n\n return data;\n}\n\n// =============================================================================\n// URL Search Params Utility\n// =============================================================================\n\n/**\n * Creates a lightweight URL search params builder.\n *\n * This is a custom implementation instead of the standard `URLSearchParams`\n * because the solver API requires a special encoding behavior: **commas must\n * NOT be percent-encoded** in pencilmark values. The standard `URLSearchParams`\n * encodes commas as `%2C`, which the Kotlin-based solver backend does not decode.\n *\n * @returns An object with `append(key, value)` and `toString()` methods\n *\n * @example\n * ```ts\n * const params = createURLSearchParams();\n * params.append(\"pencilmarks\", \"1,2,3\");\n * params.toString(); // \"pencilmarks=1,2,3\" (commas preserved)\n * ```\n */\nconst createURLSearchParams = () => {\n const params: Record<string, string[]> = {};\n return {\n append: (key: string, value: string) => {\n if (!params[key]) {\n params[key] = [];\n }\n params[key]?.push(value);\n },\n toString: () => {\n return Object.entries(params)\n .flatMap(([key, values]) =>\n values.map(\n (value) =>\n // Don't encode commas - the solver API expects literal commas in pencilmarks\n `${encodeURIComponent(key)}=${encodeURIComponent(value).replace(/%2C/g, \",\")}`,\n ),\n )\n .join(\"&\");\n },\n };\n};\n\n// =============================================================================\n// API Configuration Factory\n// =============================================================================\n\nconst createApiConfig = (baseUrl: string) => ({\n BASE_URL: baseUrl,\n ENDPOINTS: {\n // Health\n HEALTH: \"/\",\n\n // Levels\n LEVELS: \"/api/v1/levels\",\n LEVEL: (level: number) => `/api/v1/levels/${level}`,\n\n // Techniques\n TECHNIQUES: \"/api/v1/techniques\",\n TECHNIQUE: (technique: number) => `/api/v1/techniques/${technique}`,\n\n // Learning\n LEARNING: \"/api/v1/learning\",\n LEARNING_ITEM: (uuid: string) => `/api/v1/learning/${uuid}`,\n\n // Boards\n BOARDS: \"/api/v1/boards\",\n BOARDS_RANDOM: \"/api/v1/boards/random\",\n BOARD: (uuid: string) => `/api/v1/boards/${uuid}`,\n\n // Dailies\n DAILIES: \"/api/v1/dailies\",\n DAILIES_RANDOM: \"/api/v1/dailies/random\",\n DAILIES_TODAY: \"/api/v1/dailies/today\",\n DAILIES_DATE: (date: string) => `/api/v1/dailies/date/${date}`,\n DAILY: (uuid: string) => `/api/v1/dailies/${uuid}`,\n\n // Challenges\n CHALLENGES: \"/api/v1/challenges\",\n CHALLENGES_RANDOM: \"/api/v1/challenges/random\",\n CHALLENGE: (uuid: string) => `/api/v1/challenges/${uuid}`,\n\n // Users\n USER: (userId: string) => `/api/v1/users/${userId}`,\n USER_SUBSCRIPTIONS: (userId: string) =>\n `/api/v1/users/${userId}/subscriptions`,\n\n // Solver\n SOLVER_SOLVE: \"/api/v1/solver/solve\",\n SOLVER_VALIDATE: \"/api/v1/solver/validate\",\n SOLVER_GENERATE: \"/api/v1/solver/generate\",\n\n // Practices\n PRACTICES: \"/api/v1/practices\",\n PRACTICES_COUNTS: \"/api/v1/practices/counts\",\n PRACTICE_RANDOM: (technique: number) =>\n `/api/v1/practices/technique/${technique}/random`,\n\n // Examples\n EXAMPLES: \"/api/v1/examples\",\n EXAMPLES_COUNTS: \"/api/v1/examples/counts\",\n\n // Boards counts\n BOARDS_COUNTS: \"/api/v1/boards/counts\",\n BOARDS_COUNTS_BY_TECHNIQUE: \"/api/v1/boards/counts/by-technique\",\n BOARDS_UPDATE_STATS: \"/api/v1/boards/update-stats\",\n\n // Play (game sessions)\n PLAY_START: \"/api/v1/play/start\",\n PLAY_FINISH: \"/api/v1/play/finish\",\n\n // Gamification\n GAMIFICATION_STATS: \"/api/v1/gamification/stats\",\n GAMIFICATION_BADGES: \"/api/v1/gamification/badges\",\n GAMIFICATION_HISTORY: \"/api/v1/gamification/history\",\n },\n DEFAULT_HEADERS: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n});\n\n// =============================================================================\n// Sudojo Client Class\n// =============================================================================\n\n/**\n * Type-safe client for the Sudojo REST API.\n *\n * Provides methods for all Sudojo API endpoints including levels, techniques,\n * boards, dailies, challenges, users, solver, practices, examples, and gamification.\n *\n * ## Error Handling\n *\n * All methods throw errors on failure:\n * - **Network errors**: Thrown by the underlying `NetworkClient` (e.g., connection refused, timeout)\n * - **Empty response**: Throws `Error(\"No data received from server\")` when the server returns no data\n * - **Validation errors**: Thrown before the request for invalid parameters (e.g., invalid UUID, level out of range)\n * - **HTTP 402**: `solverSolve()` throws {@link HintAccessDeniedError} when the hint level exceeds the user's tier\n * - **Other HTTP errors**: Depend on the `NetworkClient` implementation - typically thrown as generic `Error`\n *\n * ## Authentication\n *\n * Most methods accept a `token` parameter (Firebase ID token). The token is sent\n * as a `Bearer` token in the `Authorization` header. Public endpoints (health,\n * levels, boards, etc.) accept but do not require a token. User-specific endpoints\n * (subscriptions, gamification) require a valid token.\n *\n * ## Usage\n *\n * ```typescript\n * const client = new SudojoClient(networkClient, \"https://api.sudojo.com\");\n * const levels = await client.getLevels(token);\n * const daily = await client.getDailyByDate(token, \"2024-01-15\");\n * ```\n */\nexport class SudojoClient {\n private baseUrl: string;\n private headers: Record<string, string>;\n private networkClient: NetworkClient;\n private config: ReturnType<typeof createApiConfig>;\n\n /**\n * Create a SudojoClient instance.\n *\n * @param networkClient - Network client for making HTTP requests (from `@sudobility/types`)\n * @param baseUrl - Base URL for the Sudojo API (e.g., \"https://api.sudojo.com\")\n */\n constructor(networkClient: NetworkClient, baseUrl: string) {\n this.config = createApiConfig(baseUrl);\n this.baseUrl = this.config.BASE_URL;\n this.networkClient = networkClient;\n\n this.headers = {\n ...this.config.DEFAULT_HEADERS,\n };\n }\n\n // ===========================================================================\n // Private Request Method\n // ===========================================================================\n\n private async request<T>(\n endpoint: string,\n options: {\n method?: Optional<\"GET\" | \"POST\" | \"PUT\" | \"DELETE\">;\n body?: Optional<Record<string, unknown>>;\n headers?: Optional<Record<string, string>>;\n token?: Optional<string>;\n timeout?: Optional<number>;\n } = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n ...options.headers,\n };\n\n // Add authorization header if token is provided\n if (options.token) {\n requestHeaders[\"Authorization\"] = `Bearer ${options.token}`;\n }\n\n const requestOptions: {\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n headers: Record<string, string>;\n body?: string;\n timeout?: number;\n } = {\n method: options.method || \"GET\",\n headers: requestHeaders,\n };\n\n // Add body for POST/PUT/DELETE requests\n if (options.body && options.method !== \"GET\") {\n requestOptions.body = JSON.stringify(options.body);\n }\n\n // Add timeout if specified\n if (options.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await this.networkClient.request<T>(url, requestOptions);\n\n if (response.data === undefined) {\n throw new Error(\"No data received from server\");\n }\n\n return (await decryptSolutionFields(response.data)) as T;\n }\n\n // ===========================================================================\n // Health Check\n // ===========================================================================\n\n async getHealth(): Promise<BaseResponse<HealthCheckData>> {\n return this.request<BaseResponse<HealthCheckData>>(\n this.config.ENDPOINTS.HEALTH,\n );\n }\n\n // ===========================================================================\n // Levels\n // ===========================================================================\n\n async getLevels(token: string): Promise<BaseResponse<Level[]>> {\n return this.request<BaseResponse<Level[]>>(this.config.ENDPOINTS.LEVELS, {\n token,\n });\n }\n\n async getLevel(token: string, level: number): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n { token },\n );\n }\n\n async createLevel(\n token: string,\n data: LevelCreateRequest,\n ): Promise<BaseResponse<Level>> {\n return this.request<BaseResponse<Level>>(this.config.ENDPOINTS.LEVELS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateLevel(\n token: string,\n level: number,\n data: LevelUpdateRequest,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLevel(\n token: string,\n level: number,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Techniques\n // ===========================================================================\n\n async getTechniques(\n token: string,\n queryParams?: TechniqueQueryParams,\n ): Promise<BaseResponse<Technique[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.TECHNIQUES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Technique[]>>(endpoint, { token });\n }\n\n async getTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n { token },\n );\n }\n\n async createTechnique(\n token: string,\n data: TechniqueCreateRequest,\n ): Promise<BaseResponse<Technique>> {\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateTechnique(\n token: string,\n technique: number,\n data: TechniqueUpdateRequest,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Learning\n // ===========================================================================\n\n async getLearning(\n token: string,\n queryParams?: LearningQueryParams,\n ): Promise<BaseResponse<Learning[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n if (queryParams?.language_code) {\n params.append(\"language_code\", queryParams.language_code);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.LEARNING}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Learning[]>>(endpoint, { token });\n }\n\n async getLearningItem(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n { token },\n );\n }\n\n async createLearning(\n token: string,\n data: LearningCreateRequest,\n ): Promise<BaseResponse<Learning>> {\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateLearning(\n token: string,\n uuid: string,\n data: LearningUpdateRequest,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLearning(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Boards\n // ===========================================================================\n\n async getBoards(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.limit !== undefined) {\n params.append(\"limit\", String(queryParams.limit));\n }\n if (queryParams?.offset !== undefined) {\n params.append(\"offset\", String(queryParams.offset));\n }\n if (queryParams?.techniques !== undefined) {\n params.append(\"techniques\", String(queryParams.techniques));\n }\n if (queryParams?.technique_bit !== undefined) {\n params.append(\"technique_bit\", String(queryParams.technique_bit));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board[]>>(endpoint, { token });\n }\n\n async getRandomBoard(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n if (queryParams?.symmetrical !== undefined) {\n params.append(\"symmetrical\", String(queryParams.symmetrical));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board>>(endpoint, { token });\n }\n\n async getBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n { token },\n );\n }\n\n async createBoard(\n token: string,\n data: BoardCreateRequest,\n ): Promise<BaseResponse<Board>> {\n return this.request<BaseResponse<Board>>(this.config.ENDPOINTS.BOARDS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateBoard(\n token: string,\n uuid: string,\n data: BoardUpdateRequest,\n ): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Dailies\n // ===========================================================================\n\n async getDailies(token: string): Promise<BaseResponse<Daily[]>> {\n return this.request<BaseResponse<Daily[]>>(this.config.ENDPOINTS.DAILIES, {\n token,\n });\n }\n\n async getRandomDaily(token: string): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_RANDOM,\n { token },\n );\n }\n\n async getTodayDaily(token: string): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_TODAY,\n { token },\n );\n }\n\n async getDailyByDate(\n token: string,\n date: string,\n ): Promise<BaseResponse<Daily>> {\n // Validate date format (YYYY-MM-DD)\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n throw new Error(\n `Invalid date format: \"${date}\". Expected YYYY-MM-DD format`,\n );\n }\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_DATE(date),\n { token },\n );\n }\n\n async getDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n { token },\n );\n }\n\n async createDaily(\n token: string,\n data: DailyCreateRequest,\n ): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(this.config.ENDPOINTS.DAILIES, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateDaily(\n token: string,\n uuid: string,\n data: DailyUpdateRequest,\n ): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Challenges\n // ===========================================================================\n\n async getChallenges(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge[]>>(endpoint, { token });\n }\n\n async getRandomChallenge(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge>>(endpoint, { token });\n }\n\n async getChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n { token },\n );\n }\n\n async createChallenge(\n token: string,\n data: ChallengeCreateRequest,\n ): Promise<BaseResponse<Challenge>> {\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateChallenge(\n token: string,\n uuid: string,\n data: ChallengeUpdateRequest,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Users\n // ===========================================================================\n\n async getUser(\n token: string,\n userId: string,\n ): Promise<BaseResponse<UserInfoResponse>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n return this.request<BaseResponse<UserInfoResponse>>(\n this.config.ENDPOINTS.USER(userId),\n {\n token,\n },\n );\n }\n\n async getUserSubscription(\n token: string,\n userId: string,\n testMode?: boolean,\n ): Promise<BaseResponse<SubscriptionResult>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n const endpoint = testMode\n ? `${this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId)}?testMode=true`\n : this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId);\n return this.request<BaseResponse<SubscriptionResult>>(endpoint, {\n token,\n });\n }\n\n // ===========================================================================\n // Practices\n // ===========================================================================\n\n /**\n * Get practice counts for all techniques\n */\n async getPracticeCounts(\n token: string,\n ): Promise<BaseResponse<TechniquePracticeCountItem[]>> {\n return this.request<BaseResponse<TechniquePracticeCountItem[]>>(\n this.config.ENDPOINTS.PRACTICES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get a random practice for a specific technique\n */\n async getRandomPractice(\n token: string,\n technique: number,\n ): Promise<BaseResponse<TechniquePractice>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICE_RANDOM(technique),\n { token },\n );\n }\n\n /**\n * Create a new practice (admin only)\n */\n async createPractice(\n token: string,\n data: TechniquePracticeCreateRequest,\n ): Promise<BaseResponse<TechniquePractice>> {\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Delete all practices (admin only, requires confirm=true)\n */\n async deleteAllPractices(\n token: string,\n ): Promise<BaseResponse<{ deleted: number; message: string }>> {\n return this.request<BaseResponse<{ deleted: number; message: string }>>(\n `${this.config.ENDPOINTS.PRACTICES}?confirm=true`,\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Examples\n // ===========================================================================\n\n /**\n * Get example counts for all techniques\n */\n async getExampleCounts(\n token: string,\n ): Promise<BaseResponse<ExampleCountsData>> {\n return this.request<BaseResponse<ExampleCountsData>>(\n this.config.ENDPOINTS.EXAMPLES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get examples, optionally filtered by technique\n */\n async getExamples(\n token: string,\n queryParams?: TechniqueExampleQueryParams,\n ): Promise<BaseResponse<TechniqueExample[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.EXAMPLES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<TechniqueExample[]>>(endpoint, { token });\n }\n\n /**\n * Create a new example (admin only)\n */\n async createExample(\n token: string,\n data: TechniqueExampleCreateRequest,\n ): Promise<BaseResponse<TechniqueExample>> {\n return this.request<BaseResponse<TechniqueExample>>(\n this.config.ENDPOINTS.EXAMPLES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Board Counts\n // ===========================================================================\n\n /**\n * Get board counts (total and without techniques)\n */\n async getBoardCounts(token: string): Promise<BaseResponse<BoardCountsData>> {\n return this.request<BaseResponse<BoardCountsData>>(\n this.config.ENDPOINTS.BOARDS_COUNTS,\n { token },\n );\n }\n\n /**\n * Get board counts by technique (count of boards with each technique bit set)\n * Returns Record<number, number> where key is technique ID and value is count\n */\n async getBoardCountsByTechnique(\n token: string,\n ): Promise<BaseResponse<Record<number, number>>> {\n return this.request<BaseResponse<Record<number, number>>>(\n this.config.ENDPOINTS.BOARDS_COUNTS_BY_TECHNIQUE,\n { token },\n );\n }\n\n /**\n * Calculate and update puzzle stats (percentages) on levels and techniques.\n * Requires admin authentication.\n */\n async updatePuzzleStats(token: string): Promise<\n BaseResponse<{\n levels: Record<number, number>;\n techniques: Record<number, number>;\n }>\n > {\n return this.request<\n BaseResponse<{\n levels: Record<number, number>;\n techniques: Record<number, number>;\n }>\n >(this.config.ENDPOINTS.BOARDS_UPDATE_STATS, {\n method: \"POST\",\n token,\n });\n }\n\n // ===========================================================================\n // Solver\n // ===========================================================================\n\n /**\n * Builds an endpoint path with query parameters for solver endpoints\n */\n private buildSolverUrl(\n endpoint: string,\n params: Record<string, string | boolean | undefined>,\n ): string {\n const searchParams = createURLSearchParams();\n // Sort keys alphabetically to match Kotlin behavior\n const sortedKeys = Object.keys(params).sort();\n for (const key of sortedKeys) {\n const value = params[key];\n if (value !== undefined) {\n searchParams.append(key, String(value));\n }\n }\n const query = searchParams.toString();\n // Return endpoint + query only, baseUrl is added by request()\n return `${endpoint}${query ? `?${query}` : \"\"}`;\n }\n\n /**\n * Get hints for solving a Sudoku puzzle\n * @throws {HintAccessDeniedError} When hint level exceeds user's subscription tier\n */\n async solverSolve(\n token: string,\n options: SolveOptions,\n ): Promise<BaseResponse<SolveData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_SOLVE, {\n original: options.original,\n user: options.user,\n autopencilmarks: options.autoPencilmarks,\n pencilmarks: options.pencilmarks,\n filters: options.filters,\n techniques: options.techniques,\n });\n\n const fullUrl = `${this.baseUrl}${url}`;\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n };\n\n if (token) {\n requestHeaders[\"Authorization\"] = `Bearer ${token}`;\n }\n\n // Use 120 second timeout for solve (advanced techniques can be slow)\n const response = await this.networkClient.request<\n BaseResponse<SolveData> | HintAccessDeniedResponse\n >(fullUrl, {\n method: \"GET\",\n headers: requestHeaders,\n timeout: 120000,\n });\n\n // Check for hint access denied (402)\n if (response.status === 402 && response.data) {\n const errorResponse = response.data as HintAccessDeniedResponse;\n if (errorResponse.error?.code === \"HINT_ACCESS_DENIED\") {\n throw new HintAccessDeniedError(errorResponse.error);\n }\n }\n\n // Check for other errors\n if (!response.ok || response.data === undefined) {\n throw new Error(\"Failed to get hints from solver\");\n }\n\n return (await decryptSolutionFields(\n response.data,\n )) as BaseResponse<SolveData>;\n }\n\n /**\n * Validate that a Sudoku puzzle has a unique solution.\n * Uses a longer timeout (120s) because validation involves iterative solving.\n */\n async solverValidate(\n token: string,\n options: ValidateOptions,\n ): Promise<BaseResponse<ValidateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_VALIDATE, {\n original: options.original,\n });\n\n // Use 120 second timeout for validation (iterative solving can be slow)\n return this.request<BaseResponse<ValidateData>>(url, {\n token,\n timeout: 120000,\n });\n }\n\n /**\n * Generate a new random Sudoku puzzle\n */\n async solverGenerate(\n token: string,\n options: GenerateOptions = {},\n ): Promise<BaseResponse<GenerateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_GENERATE, {\n symmetrical: options.symmetrical,\n });\n\n return this.request<BaseResponse<GenerateData>>(url, { token });\n }\n\n // ===========================================================================\n // Play (Game Session) Endpoints\n // ===========================================================================\n\n /**\n * Start a new game session\n */\n async playStart(\n token: string,\n data: GameStartRequest,\n ): Promise<BaseResponse<GameStartResponse>> {\n return this.request<BaseResponse<GameStartResponse>>(\n this.config.ENDPOINTS.PLAY_START,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Finish the current game session and get rewards\n */\n async playFinish(\n token: string,\n data: GameFinishRequest,\n ): Promise<BaseResponse<GameFinishResponse>> {\n return this.request<BaseResponse<GameFinishResponse>>(\n this.config.ENDPOINTS.PLAY_FINISH,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Gamification Endpoints\n // ===========================================================================\n\n /**\n * Get user's gamification stats (points, level, badges)\n */\n async getGamificationStats(\n token: string,\n ): Promise<BaseResponse<GamificationStats>> {\n return this.request<BaseResponse<GamificationStats>>(\n this.config.ENDPOINTS.GAMIFICATION_STATS,\n { token },\n );\n }\n\n /**\n * Get all badge definitions (public)\n */\n async getBadgeDefinitions(): Promise<BaseResponse<BadgeDefinition[]>> {\n return this.request<BaseResponse<BadgeDefinition[]>>(\n this.config.ENDPOINTS.GAMIFICATION_BADGES,\n );\n }\n\n /**\n * Get user's point transaction history\n */\n async getPointHistory(\n token: string,\n options?: { limit?: number; offset?: number },\n ): Promise<BaseResponse<PointTransaction[]>> {\n let endpoint = this.config.ENDPOINTS.GAMIFICATION_HISTORY;\n if (options?.limit || options?.offset) {\n const params = createURLSearchParams();\n if (options.limit) params.append(\"limit\", String(options.limit));\n if (options.offset) params.append(\"offset\", String(options.offset));\n endpoint = `${endpoint}?${params.toString()}`;\n }\n return this.request<BaseResponse<PointTransaction[]>>(endpoint, { token });\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Factory function to create a new SudojoClient instance.\n *\n * Equivalent to `new SudojoClient(networkClient, baseUrl)` but useful\n * for dependency injection and functional composition patterns.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL for the Sudojo API\n * @returns A new SudojoClient instance\n */\nexport const createSudojoClient = (\n networkClient: NetworkClient,\n baseUrl: string,\n): SudojoClient => {\n return new SudojoClient(networkClient, baseUrl);\n};\n\n// =============================================================================\n// Utility Exports\n// =============================================================================\n\n/**\n * Re-exported UUID validation utilities from `@sudobility/sudojo_types`.\n *\n * These are used internally by the SudojoClient for parameter validation\n * and are also exported for consumer convenience. Use `isValidUUID` for\n * boolean checks and `validateUUID` when you want an error thrown on invalid input.\n *\n * - `isValidUUID(value)` - Returns true if the string is a valid UUID v4\n * - `validateUUID(value, label)` - Returns the UUID or throws an Error with the label\n */\nexport { isValidUUID, validateUUID };\n"]}
1
+ {"version":3,"file":"sudojo-client.js","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"AACA,OAAO,EA0BL,WAAW,EA2BX,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AASlD,IAAI,YAAY,GAAqB,IAAI,CAAC;AAO1C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAc;IACvD,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,YAAY,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CACrD,KAAK,EACL,QAAQ,EACR,SAAS,EACT,KAAK,EACL,CAAC,SAAS,CAAC,CACZ,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,SAAiB;IAC9C,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAC;IAEpC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjC,MAAM,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAE1C,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CACtD,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,EAC9B,YAAY,EACZ,iBAAiB,CAClB,CAAC;IAEF,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,IAAa;IAChD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAErD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,IACE,GAAG,KAAK,UAAU;gBAClB,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAC3B,GAAG,CAAC,GAAG,CAAY,CAAC,UAAU,CAAC,MAAM,CAAC,EACvC,CAAC;gBACD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,GAAG,CAAW,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAuBD,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,OAAO;QACL,MAAM,EAAE,CAAC,GAAW,EAAE,KAAa,EAAE,EAAE;YACrC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACnB,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,QAAQ,EAAE,GAAG,EAAE;YACb,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;iBAC1B,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CACzB,MAAM,CAAC,GAAG,CACR,CAAC,KAAK,EAAE,EAAE,CAER,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CACjF,CACF;iBACA,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAMF,MAAM,eAAe,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC;IAC5C,QAAQ,EAAE,OAAO;IACjB,SAAS,EAAE;QAET,MAAM,EAAE,GAAG;QAGX,MAAM,EAAE,gBAAgB;QACxB,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,kBAAkB,KAAK,EAAE;QAGnD,UAAU,EAAE,oBAAoB;QAChC,SAAS,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,sBAAsB,SAAS,EAAE;QAGnE,QAAQ,EAAE,kBAAkB;QAC5B,aAAa,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,oBAAoB,IAAI,EAAE;QAG3D,MAAM,EAAE,gBAAgB;QACxB,aAAa,EAAE,uBAAuB;QACtC,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,kBAAkB,IAAI,EAAE;QAGjD,OAAO,EAAE,iBAAiB;QAC1B,aAAa,EAAE,uBAAuB;QACtC,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,wBAAwB,IAAI,EAAE;QAC9D,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,mBAAmB,IAAI,EAAE;QAGlD,UAAU,EAAE,oBAAoB;QAChC,iBAAiB,EAAE,2BAA2B;QAC9C,SAAS,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,sBAAsB,IAAI,EAAE;QAGzD,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,iBAAiB,MAAM,EAAE;QACnD,kBAAkB,EAAE,CAAC,MAAc,EAAE,EAAE,CACrC,iBAAiB,MAAM,gBAAgB;QAGzC,YAAY,EAAE,sBAAsB;QACpC,eAAe,EAAE,yBAAyB;QAC1C,eAAe,EAAE,yBAAyB;QAG1C,SAAS,EAAE,mBAAmB;QAC9B,gBAAgB,EAAE,0BAA0B;QAC5C,eAAe,EAAE,CAAC,SAAiB,EAAE,EAAE,CACrC,+BAA+B,SAAS,SAAS;QAGnD,QAAQ,EAAE,kBAAkB;QAC5B,eAAe,EAAE,yBAAyB;QAG1C,aAAa,EAAE,uBAAuB;QACtC,0BAA0B,EAAE,oCAAoC;QAChE,mBAAmB,EAAE,6BAA6B;QAGlD,UAAU,EAAE,oBAAoB;QAChC,WAAW,EAAE,qBAAqB;QAGlC,kBAAkB,EAAE,4BAA4B;QAChD,mBAAmB,EAAE,6BAA6B;QAClD,oBAAoB,EAAE,8BAA8B;KACrD;IACD,eAAe,EAAE;QACf,cAAc,EAAE,kBAAkB;QAClC,MAAM,EAAE,kBAAkB;KAC3B;CACF,CAAC,CAAC;AAoCH,MAAM,OAAO,YAAY;IAYvB,YAAY,aAA4B,EAAE,OAAe;QACvD,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QACpC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QAEnC,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe;SAC/B,CAAC;IACJ,CAAC;IAMO,KAAK,CAAC,OAAO,CACnB,QAAgB,EAChB,UAMI,EAAE;QAEN,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC;QAEzC,MAAM,cAAc,GAA2B;YAC7C,GAAG,IAAI,CAAC,OAAO;YACf,GAAG,OAAO,CAAC,OAAO;SACnB,CAAC;QAGF,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,cAAc,CAAC,eAAe,CAAC,GAAG,UAAU,OAAO,CAAC,KAAK,EAAE,CAAC;QAC9D,CAAC;QAED,MAAM,cAAc,GAKhB;YACF,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;YAC/B,OAAO,EAAE,cAAc;SACxB,CAAC;QAGF,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC7C,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QAGD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,cAAc,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC3C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAI,GAAG,EAAE,cAAc,CAAC,CAAC;QAE1E,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,OAAO,CAAC,MAAM,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAM,CAAC;IAC3D,CAAC;IAMD,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAC7B,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,SAAS,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAwB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;YACvE,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,KAAa;QACzC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,iBAAiB,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAClC,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa,EACb,IAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAsB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;YACrE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa,EACb,KAAa,EACb,IAAwB;QAExB,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,iBAAiB,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAClC;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa,EACb,KAAa;QAEb,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,iBAAiB,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAClC;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,aAAa,CACjB,KAAa,EACb,WAAkC;QAElC,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAEvC,IAAI,WAAW,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAElF,OAAO,IAAI,CAAC,OAAO,CAA4B,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,KAAa,EACb,SAAiB;QAEjB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,iBAAiB,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,EAC1C,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,IAA4B;QAE5B,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAChC;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,SAAiB,EACjB,IAA4B;QAE5B,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,iBAAiB,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,EAC1C;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,SAAiB;QAEjB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,iBAAiB,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,EAC1C;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,WAAW,CACf,KAAa,EACb,WAAiC;QAEjC,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAEvC,IAAI,WAAW,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,WAAW,EAAE,aAAa,EAAE,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEhF,OAAO,IAAI,CAAC,OAAO,CAA2B,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,IAAY;QAEZ,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,aAAa,CAAC,EAClD,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,IAA2B;QAE3B,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAC9B;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,IAAY,EACZ,IAA2B;QAE3B,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,aAAa,CAAC,EAClD;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,IAAY;QAEZ,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,aAAa,CAAC,EAClD;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,SAAS,CACb,KAAa,EACb,WAA8B;QAE9B,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAEvC,IAAI,WAAW,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,WAAW,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,WAAW,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,WAAW,EAAE,UAAU,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,WAAW,EAAE,aAAa,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAE9E,OAAO,IAAI,CAAC,OAAO,CAAwB,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,WAA8B;QAE9B,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAEvC,IAAI,WAAW,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,WAAW,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAErF,OAAO,IAAI,CAAC,OAAO,CAAsB,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,IAAY;QACxC,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,EAC1C,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa,EACb,IAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAsB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;YACrE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa,EACb,IAAY,EACZ,IAAwB;QAExB,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,EAC1C;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,IAAY;QAC3C,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,EAC1C;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAwB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE;YACxE,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAa;QAC/B,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EACnC,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,IAAY;QAGZ,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CACb,yBAAyB,IAAI,+BAA+B,CAC7D,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,EACxC,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,IAAY;QACxC,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,EAC1C,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa,EACb,IAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAsB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE;YACtE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa,EACb,IAAY,EACZ,IAAwB;QAExB,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,EAC1C;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,IAAY;QAC3C,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,EAC1C;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,aAAa,CACjB,KAAa,EACb,WAAkC;QAElC,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAEvC,IAAI,WAAW,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,WAAW,EAAE,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAElF,OAAO,IAAI,CAAC,OAAO,CAA4B,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,KAAa,EACb,WAAkC;QAElC,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAEvC,IAAI,WAAW,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,WAAW,EAAE,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEzF,OAAO,IAAI,CAAC,OAAO,CAA0B,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,KAAa,EACb,IAAY;QAEZ,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,EAC9C,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,IAA4B;QAE5B,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAChC;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,IAAY,EACZ,IAA4B;QAE5B,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,EAC9C;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,IAAY;QAEZ,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,EAC9C;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,OAAO,CACX,KAAa,EACb,MAAc;QAEd,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,8BAA8B,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAClC;YACE,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,KAAa,EACb,MAAc,EACd,QAAkB;QAElB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,8BAA8B,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,QAAQ,GAAG,QAAQ;YACvB,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,gBAAgB;YACrE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,OAAO,CAAmC,QAAQ,EAAE;YAC9D,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IASD,KAAK,CAAC,iBAAiB,CACrB,KAAa;QAEb,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EACtC,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,iBAAiB,CACrB,KAAa,EACb,SAAiB;QAEjB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,iBAAiB,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,EAChD,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,IAAoC;QAEpC,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAC/B;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,kBAAkB,CACtB,KAAa;QAEb,OAAO,IAAI,CAAC,OAAO,CACjB,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,eAAe,EACjD;YACE,MAAM,EAAE,QAAQ;YAChB,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IASD,KAAK,CAAC,gBAAgB,CACpB,KAAa;QAEb,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EACrC,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,WAAW,CACf,KAAa,EACb,WAAyC;QAEzC,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAEvC,IAAI,WAAW,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEhF,OAAO,IAAI,CAAC,OAAO,CAAmC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;IAKD,KAAK,CAAC,aAAa,CACjB,KAAa,EACb,IAAmC;QAEnC,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAC9B;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IASD,KAAK,CAAC,cAAc,CAAC,KAAa;QAChC,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EACnC,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,yBAAyB,CAC7B,KAAa;QAEb,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,0BAA0B,EAChD,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,iBAAiB,CACrB,KAAa;QAEb,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,EACzC;YACE,MAAM,EAAE,MAAM;YACd,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IASO,cAAc,CACpB,QAAgB,EAChB,MAAoD;QAEpD,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC;QAE7C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;QAEtC,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAClD,CAAC;IAMD,KAAK,CAAC,WAAW,CACf,KAAa,EACb,OAAqB;QAErB,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE;YAClE,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC;QACxC,MAAM,cAAc,GAA2B;YAC7C,GAAG,IAAI,CAAC,OAAO;SAChB,CAAC;QAEF,IAAI,KAAK,EAAE,CAAC;YACV,cAAc,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;QACtD,CAAC;QAGD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAE/C,OAAO,EAAE;YACT,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,cAAc;YACvB,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QAGH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAgC,CAAC;YAChE,IAAI,aAAa,CAAC,KAAK,EAAE,IAAI,KAAK,oBAAoB,EAAE,CAAC;gBACvD,MAAM,IAAI,qBAAqB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAGD,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,CAAC,MAAM,qBAAqB,CACjC,QAAQ,CAAC,IAAI,CACd,CAA4B,CAAC;IAChC,CAAC;IAMD,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,OAAwB;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE;YACrE,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;QAGH,OAAO,IAAI,CAAC,OAAO,CAA6B,GAAG,EAAE;YACnD,KAAK;YACL,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;IACL,CAAC;IAKD,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,UAA2B,EAAE;QAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE;YACrE,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,OAAO,CAA6B,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;IASD,KAAK,CAAC,SAAS,CACb,KAAa,EACb,IAAsB;QAEtB,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAChC;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,UAAU,CACd,KAAa,EACb,IAAuB;QAEvB,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EACjC;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAA0C;YAChD,KAAK;SACN,CACF,CAAC;IACJ,CAAC;IASD,KAAK,CAAC,oBAAoB,CACxB,KAAa;QAEb,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,EACxC,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,mBAAmB;QACvB,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,CAC1C,CAAC;IACJ,CAAC;IAKD,KAAK,CAAC,eAAe,CACnB,KAAa,EACb,OAA6C;QAE7C,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC;QAC1D,IAAI,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,KAAK;gBAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YACjE,IAAI,OAAO,CAAC,MAAM;gBAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACpE,QAAQ,GAAG,GAAG,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAmC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;CACF;AAgBD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,aAA4B,EAC5B,OAAe,EACD,EAAE;IAChB,OAAO,IAAI,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC,CAAC;AAgBF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import type { NetworkClient, UserInfoResponse } from \"@sudobility/types\";\nimport {\n type BadgeDefinition,\n type BaseResponse,\n type Board,\n type BoardCountsByTechniqueData,\n type BoardCountsData,\n type BoardCreateRequest,\n type BoardQueryParams,\n type BoardUpdateRequest,\n type Challenge,\n type ChallengeCreateRequest,\n type ChallengeQueryParams,\n type ChallengeUpdateRequest,\n type Daily,\n type DailyCreateRequest,\n type DailyUpdateRequest,\n type ExampleCountsData,\n type GameFinishRequest,\n type GameFinishResponse,\n type GameStartRequest,\n type GameStartResponse,\n type GamificationStats,\n type GenerateData,\n type GenerateOptions,\n type HealthCheckData,\n type HintAccessDeniedResponse,\n isValidUUID,\n type Learning,\n type LearningCreateRequest,\n type LearningQueryParams,\n type LearningUpdateRequest,\n type Level,\n type LevelCreateRequest,\n type LevelUpdateRequest,\n type Optional,\n type PointTransaction,\n type PracticesBulkDeleteData,\n type SolveData,\n type SolveOptions,\n type SubscriptionResult,\n type Technique,\n type TechniqueCreateRequest,\n type TechniqueExample,\n type TechniqueExampleCreateRequest,\n type TechniqueExampleQueryParams,\n type TechniquePractice,\n type TechniquePracticeCountItem,\n type TechniquePracticeCreateRequest,\n type TechniqueQueryParams,\n type TechniqueUpdateRequest,\n type UpdateStatsData,\n type ValidateData,\n type ValidateOptions,\n validateUUID,\n} from \"@sudobility/sudojo_types\";\nimport { HintAccessDeniedError } from \"../errors\";\n\n// Re-export option types for convenience\nexport type { SolveOptions, ValidateOptions, GenerateOptions };\n\n// =============================================================================\n// Solution Decryption\n// =============================================================================\n\nlet _solutionKey: CryptoKey | null = null;\n\n/**\n * Configure the symmetric key used to decrypt `solution` fields in API responses.\n * Call once at app startup with the hex-encoded 256-bit key.\n * If not called (or called with empty string), encrypted solutions pass through as-is.\n */\nexport async function configureSolutionKey(keyHex: string): Promise<void> {\n if (!keyHex) return;\n const hexPairs = keyHex.match(/.{2}/g);\n if (!hexPairs) return;\n const keyBytes = new Uint8Array(hexPairs.map((byte) => parseInt(byte, 16)));\n _solutionKey = await globalThis.crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n \"AES-GCM\",\n false,\n [\"decrypt\"],\n );\n}\n\nasync function decryptSolution(encrypted: string): Promise<string> {\n if (!_solutionKey) return encrypted;\n\n const raw = globalThis.atob(encrypted.slice(4)); // strip \"enc:\" prefix\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n bytes[i] = raw.charCodeAt(i);\n }\n\n const nonce = bytes.slice(0, 12);\n const ciphertextWithTag = bytes.slice(12);\n\n const decrypted = await globalThis.crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: nonce },\n _solutionKey,\n ciphertextWithTag,\n );\n\n return new TextDecoder().decode(decrypted);\n}\n\nasync function decryptSolutionFields(data: unknown): Promise<unknown> {\n if (data === null || data === undefined) return data;\n\n if (Array.isArray(data)) {\n return Promise.all(data.map((item) => decryptSolutionFields(item)));\n }\n\n if (typeof data === \"object\") {\n const obj = data as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n if (\n key === \"solution\" &&\n typeof obj[key] === \"string\" &&\n (obj[key] as string).startsWith(\"enc:\")\n ) {\n result[key] = await decryptSolution(obj[key] as string);\n } else {\n result[key] = await decryptSolutionFields(obj[key]);\n }\n }\n return result;\n }\n\n return data;\n}\n\n// =============================================================================\n// URL Search Params Utility\n// =============================================================================\n\n/**\n * Creates a lightweight URL search params builder.\n *\n * This is a custom implementation instead of the standard `URLSearchParams`\n * because the solver API requires a special encoding behavior: **commas must\n * NOT be percent-encoded** in pencilmark values. The standard `URLSearchParams`\n * encodes commas as `%2C`, which the Kotlin-based solver backend does not decode.\n *\n * @returns An object with `append(key, value)` and `toString()` methods\n *\n * @example\n * ```ts\n * const params = createURLSearchParams();\n * params.append(\"pencilmarks\", \"1,2,3\");\n * params.toString(); // \"pencilmarks=1,2,3\" (commas preserved)\n * ```\n */\nconst createURLSearchParams = () => {\n const params: Record<string, string[]> = {};\n return {\n append: (key: string, value: string) => {\n if (!params[key]) {\n params[key] = [];\n }\n params[key]?.push(value);\n },\n toString: () => {\n return Object.entries(params)\n .flatMap(([key, values]) =>\n values.map(\n (value) =>\n // Don't encode commas - the solver API expects literal commas in pencilmarks\n `${encodeURIComponent(key)}=${encodeURIComponent(value).replace(/%2C/g, \",\")}`,\n ),\n )\n .join(\"&\");\n },\n };\n};\n\n// =============================================================================\n// API Configuration Factory\n// =============================================================================\n\nconst createApiConfig = (baseUrl: string) => ({\n BASE_URL: baseUrl,\n ENDPOINTS: {\n // Health\n HEALTH: \"/\",\n\n // Levels\n LEVELS: \"/api/v1/levels\",\n LEVEL: (level: number) => `/api/v1/levels/${level}`,\n\n // Techniques\n TECHNIQUES: \"/api/v1/techniques\",\n TECHNIQUE: (technique: number) => `/api/v1/techniques/${technique}`,\n\n // Learning\n LEARNING: \"/api/v1/learning\",\n LEARNING_ITEM: (uuid: string) => `/api/v1/learning/${uuid}`,\n\n // Boards\n BOARDS: \"/api/v1/boards\",\n BOARDS_RANDOM: \"/api/v1/boards/random\",\n BOARD: (uuid: string) => `/api/v1/boards/${uuid}`,\n\n // Dailies\n DAILIES: \"/api/v1/dailies\",\n DAILIES_TODAY: \"/api/v1/dailies/today\",\n DAILIES_DATE: (date: string) => `/api/v1/dailies/date/${date}`,\n DAILY: (uuid: string) => `/api/v1/dailies/${uuid}`,\n\n // Challenges\n CHALLENGES: \"/api/v1/challenges\",\n CHALLENGES_RANDOM: \"/api/v1/challenges/random\",\n CHALLENGE: (uuid: string) => `/api/v1/challenges/${uuid}`,\n\n // Users\n USER: (userId: string) => `/api/v1/users/${userId}`,\n USER_SUBSCRIPTIONS: (userId: string) =>\n `/api/v1/users/${userId}/subscriptions`,\n\n // Solver\n SOLVER_SOLVE: \"/api/v1/solver/solve\",\n SOLVER_VALIDATE: \"/api/v1/solver/validate\",\n SOLVER_GENERATE: \"/api/v1/solver/generate\",\n\n // Practices\n PRACTICES: \"/api/v1/practices\",\n PRACTICES_COUNTS: \"/api/v1/practices/counts\",\n PRACTICE_RANDOM: (technique: number) =>\n `/api/v1/practices/technique/${technique}/random`,\n\n // Examples\n EXAMPLES: \"/api/v1/examples\",\n EXAMPLES_COUNTS: \"/api/v1/examples/counts\",\n\n // Boards counts\n BOARDS_COUNTS: \"/api/v1/boards/counts\",\n BOARDS_COUNTS_BY_TECHNIQUE: \"/api/v1/boards/counts/by-technique\",\n BOARDS_UPDATE_STATS: \"/api/v1/boards/update-stats\",\n\n // Play (game sessions)\n PLAY_START: \"/api/v1/play/start\",\n PLAY_FINISH: \"/api/v1/play/finish\",\n\n // Gamification\n GAMIFICATION_STATS: \"/api/v1/gamification/stats\",\n GAMIFICATION_BADGES: \"/api/v1/gamification/badges\",\n GAMIFICATION_HISTORY: \"/api/v1/gamification/history\",\n },\n DEFAULT_HEADERS: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n});\n\n// =============================================================================\n// Sudojo Client Class\n// =============================================================================\n\n/**\n * Type-safe client for the Sudojo REST API.\n *\n * Provides methods for all Sudojo API endpoints including levels, techniques,\n * boards, dailies, challenges, users, solver, practices, examples, and gamification.\n *\n * ## Error Handling\n *\n * All methods throw errors on failure:\n * - **Network errors**: Thrown by the underlying `NetworkClient` (e.g., connection refused, timeout)\n * - **Empty response**: Throws `Error(\"No data received from server\")` when the server returns no data\n * - **Validation errors**: Thrown before the request for invalid parameters (e.g., invalid UUID, level out of range)\n * - **HTTP 402**: `solverSolve()` throws {@link HintAccessDeniedError} when the hint level exceeds the user's tier\n * - **Other HTTP errors**: Depend on the `NetworkClient` implementation - typically thrown as generic `Error`\n *\n * ## Authentication\n *\n * Most methods accept a `token` parameter (Firebase ID token). The token is sent\n * as a `Bearer` token in the `Authorization` header. Public endpoints (health,\n * levels, boards, etc.) accept but do not require a token. User-specific endpoints\n * (subscriptions, gamification) require a valid token.\n *\n * ## Usage\n *\n * ```typescript\n * const client = new SudojoClient(networkClient, \"https://api.sudojo.com\");\n * const levels = await client.getLevels(token);\n * const daily = await client.getDailyByDate(token, \"2024-01-15\");\n * ```\n */\nexport class SudojoClient {\n private baseUrl: string;\n private headers: Record<string, string>;\n private networkClient: NetworkClient;\n private config: ReturnType<typeof createApiConfig>;\n\n /**\n * Create a SudojoClient instance.\n *\n * @param networkClient - Network client for making HTTP requests (from `@sudobility/types`)\n * @param baseUrl - Base URL for the Sudojo API (e.g., \"https://api.sudojo.com\")\n */\n constructor(networkClient: NetworkClient, baseUrl: string) {\n this.config = createApiConfig(baseUrl);\n this.baseUrl = this.config.BASE_URL;\n this.networkClient = networkClient;\n\n this.headers = {\n ...this.config.DEFAULT_HEADERS,\n };\n }\n\n // ===========================================================================\n // Private Request Method\n // ===========================================================================\n\n private async request<T>(\n endpoint: string,\n options: {\n method?: Optional<\"GET\" | \"POST\" | \"PUT\" | \"DELETE\">;\n body?: Optional<Record<string, unknown>>;\n headers?: Optional<Record<string, string>>;\n token?: Optional<string>;\n timeout?: Optional<number>;\n } = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n ...options.headers,\n };\n\n // Add authorization header if token is provided\n if (options.token) {\n requestHeaders[\"Authorization\"] = `Bearer ${options.token}`;\n }\n\n const requestOptions: {\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n headers: Record<string, string>;\n body?: string;\n timeout?: number;\n } = {\n method: options.method || \"GET\",\n headers: requestHeaders,\n };\n\n // Add body for POST/PUT/DELETE requests\n if (options.body && options.method !== \"GET\") {\n requestOptions.body = JSON.stringify(options.body);\n }\n\n // Add timeout if specified\n if (options.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await this.networkClient.request<T>(url, requestOptions);\n\n if (response.data === undefined) {\n throw new Error(\"No data received from server\");\n }\n\n return (await decryptSolutionFields(response.data)) as T;\n }\n\n // ===========================================================================\n // Health Check\n // ===========================================================================\n\n async getHealth(): Promise<BaseResponse<HealthCheckData>> {\n return this.request<BaseResponse<HealthCheckData>>(\n this.config.ENDPOINTS.HEALTH,\n );\n }\n\n // ===========================================================================\n // Levels\n // ===========================================================================\n\n async getLevels(token: string): Promise<BaseResponse<Level[]>> {\n return this.request<BaseResponse<Level[]>>(this.config.ENDPOINTS.LEVELS, {\n token,\n });\n }\n\n async getLevel(token: string, level: number): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n { token },\n );\n }\n\n async createLevel(\n token: string,\n data: LevelCreateRequest,\n ): Promise<BaseResponse<Level>> {\n return this.request<BaseResponse<Level>>(this.config.ENDPOINTS.LEVELS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateLevel(\n token: string,\n level: number,\n data: LevelUpdateRequest,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLevel(\n token: string,\n level: number,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Techniques\n // ===========================================================================\n\n async getTechniques(\n token: string,\n queryParams?: TechniqueQueryParams,\n ): Promise<BaseResponse<Technique[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.TECHNIQUES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Technique[]>>(endpoint, { token });\n }\n\n async getTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n { token },\n );\n }\n\n async createTechnique(\n token: string,\n data: TechniqueCreateRequest,\n ): Promise<BaseResponse<Technique>> {\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateTechnique(\n token: string,\n technique: number,\n data: TechniqueUpdateRequest,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Learning\n // ===========================================================================\n\n async getLearning(\n token: string,\n queryParams?: LearningQueryParams,\n ): Promise<BaseResponse<Learning[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n if (queryParams?.language_code) {\n params.append(\"language_code\", queryParams.language_code);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.LEARNING}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Learning[]>>(endpoint, { token });\n }\n\n async getLearningItem(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n { token },\n );\n }\n\n async createLearning(\n token: string,\n data: LearningCreateRequest,\n ): Promise<BaseResponse<Learning>> {\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateLearning(\n token: string,\n uuid: string,\n data: LearningUpdateRequest,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLearning(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Boards\n // ===========================================================================\n\n async getBoards(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.limit !== undefined) {\n params.append(\"limit\", String(queryParams.limit));\n }\n if (queryParams?.offset !== undefined) {\n params.append(\"offset\", String(queryParams.offset));\n }\n if (queryParams?.techniques !== undefined) {\n params.append(\"techniques\", String(queryParams.techniques));\n }\n if (queryParams?.technique_bit !== undefined) {\n params.append(\"technique_bit\", String(queryParams.technique_bit));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board[]>>(endpoint, { token });\n }\n\n async getRandomBoard(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n if (queryParams?.symmetrical !== undefined) {\n params.append(\"symmetrical\", String(queryParams.symmetrical));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board>>(endpoint, { token });\n }\n\n async getBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n { token },\n );\n }\n\n async createBoard(\n token: string,\n data: BoardCreateRequest,\n ): Promise<BaseResponse<Board>> {\n return this.request<BaseResponse<Board>>(this.config.ENDPOINTS.BOARDS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateBoard(\n token: string,\n uuid: string,\n data: BoardUpdateRequest,\n ): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Dailies\n // ===========================================================================\n\n async getDailies(token: string): Promise<BaseResponse<Daily[]>> {\n return this.request<BaseResponse<Daily[]>>(this.config.ENDPOINTS.DAILIES, {\n token,\n });\n }\n\n async getTodayDaily(token: string): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_TODAY,\n { token },\n );\n }\n\n async getDailyByDate(\n token: string,\n date: string,\n ): Promise<BaseResponse<Daily>> {\n // Validate date format (YYYY-MM-DD)\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n throw new Error(\n `Invalid date format: \"${date}\". Expected YYYY-MM-DD format`,\n );\n }\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_DATE(date),\n { token },\n );\n }\n\n async getDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n { token },\n );\n }\n\n async createDaily(\n token: string,\n data: DailyCreateRequest,\n ): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(this.config.ENDPOINTS.DAILIES, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateDaily(\n token: string,\n uuid: string,\n data: DailyUpdateRequest,\n ): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Challenges\n // ===========================================================================\n\n async getChallenges(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge[]>>(endpoint, { token });\n }\n\n async getRandomChallenge(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge>>(endpoint, { token });\n }\n\n async getChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n { token },\n );\n }\n\n async createChallenge(\n token: string,\n data: ChallengeCreateRequest,\n ): Promise<BaseResponse<Challenge>> {\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateChallenge(\n token: string,\n uuid: string,\n data: ChallengeUpdateRequest,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Users\n // ===========================================================================\n\n async getUser(\n token: string,\n userId: string,\n ): Promise<BaseResponse<UserInfoResponse>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n return this.request<BaseResponse<UserInfoResponse>>(\n this.config.ENDPOINTS.USER(userId),\n {\n token,\n },\n );\n }\n\n async getUserSubscription(\n token: string,\n userId: string,\n testMode?: boolean,\n ): Promise<BaseResponse<SubscriptionResult>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n const endpoint = testMode\n ? `${this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId)}?testMode=true`\n : this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId);\n return this.request<BaseResponse<SubscriptionResult>>(endpoint, {\n token,\n });\n }\n\n // ===========================================================================\n // Practices\n // ===========================================================================\n\n /**\n * Get practice counts for all techniques\n */\n async getPracticeCounts(\n token: string,\n ): Promise<BaseResponse<TechniquePracticeCountItem[]>> {\n return this.request<BaseResponse<TechniquePracticeCountItem[]>>(\n this.config.ENDPOINTS.PRACTICES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get a random practice for a specific technique\n */\n async getRandomPractice(\n token: string,\n technique: number,\n ): Promise<BaseResponse<TechniquePractice>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICE_RANDOM(technique),\n { token },\n );\n }\n\n /**\n * Create a new practice (admin only)\n */\n async createPractice(\n token: string,\n data: TechniquePracticeCreateRequest,\n ): Promise<BaseResponse<TechniquePractice>> {\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Delete all practices (admin only, requires confirm=true)\n */\n async deleteAllPractices(\n token: string,\n ): Promise<BaseResponse<PracticesBulkDeleteData>> {\n return this.request<BaseResponse<PracticesBulkDeleteData>>(\n `${this.config.ENDPOINTS.PRACTICES}?confirm=true`,\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Examples\n // ===========================================================================\n\n /**\n * Get example counts for all techniques\n */\n async getExampleCounts(\n token: string,\n ): Promise<BaseResponse<ExampleCountsData>> {\n return this.request<BaseResponse<ExampleCountsData>>(\n this.config.ENDPOINTS.EXAMPLES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get examples, optionally filtered by technique\n */\n async getExamples(\n token: string,\n queryParams?: TechniqueExampleQueryParams,\n ): Promise<BaseResponse<TechniqueExample[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.EXAMPLES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<TechniqueExample[]>>(endpoint, { token });\n }\n\n /**\n * Create a new example (admin only)\n */\n async createExample(\n token: string,\n data: TechniqueExampleCreateRequest,\n ): Promise<BaseResponse<TechniqueExample>> {\n return this.request<BaseResponse<TechniqueExample>>(\n this.config.ENDPOINTS.EXAMPLES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Board Counts\n // ===========================================================================\n\n /**\n * Get board counts (total and without techniques)\n */\n async getBoardCounts(token: string): Promise<BaseResponse<BoardCountsData>> {\n return this.request<BaseResponse<BoardCountsData>>(\n this.config.ENDPOINTS.BOARDS_COUNTS,\n { token },\n );\n }\n\n /**\n * Get board counts by technique (count of boards with each technique bit set)\n * Returns Record<number, number> where key is technique ID and value is count\n */\n async getBoardCountsByTechnique(\n token: string,\n ): Promise<BaseResponse<BoardCountsByTechniqueData>> {\n return this.request<BaseResponse<BoardCountsByTechniqueData>>(\n this.config.ENDPOINTS.BOARDS_COUNTS_BY_TECHNIQUE,\n { token },\n );\n }\n\n /**\n * Calculate and update puzzle stats (percentages) on levels and techniques.\n * Requires admin authentication.\n */\n async updatePuzzleStats(\n token: string,\n ): Promise<BaseResponse<UpdateStatsData>> {\n return this.request<BaseResponse<UpdateStatsData>>(\n this.config.ENDPOINTS.BOARDS_UPDATE_STATS,\n {\n method: \"POST\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Solver\n // ===========================================================================\n\n /**\n * Builds an endpoint path with query parameters for solver endpoints\n */\n private buildSolverUrl(\n endpoint: string,\n params: Record<string, string | boolean | undefined>,\n ): string {\n const searchParams = createURLSearchParams();\n // Sort keys alphabetically to match Kotlin behavior\n const sortedKeys = Object.keys(params).sort();\n for (const key of sortedKeys) {\n const value = params[key];\n if (value !== undefined) {\n searchParams.append(key, String(value));\n }\n }\n const query = searchParams.toString();\n // Return endpoint + query only, baseUrl is added by request()\n return `${endpoint}${query ? `?${query}` : \"\"}`;\n }\n\n /**\n * Get hints for solving a Sudoku puzzle\n * @throws {HintAccessDeniedError} When hint level exceeds user's subscription tier\n */\n async solverSolve(\n token: string,\n options: SolveOptions,\n ): Promise<BaseResponse<SolveData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_SOLVE, {\n original: options.original,\n user: options.user,\n autopencilmarks: options.autoPencilmarks,\n pencilmarks: options.pencilmarks,\n filters: options.filters,\n techniques: options.techniques,\n });\n\n const fullUrl = `${this.baseUrl}${url}`;\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n };\n\n if (token) {\n requestHeaders[\"Authorization\"] = `Bearer ${token}`;\n }\n\n // Use 120 second timeout for solve (advanced techniques can be slow)\n const response = await this.networkClient.request<\n BaseResponse<SolveData> | HintAccessDeniedResponse\n >(fullUrl, {\n method: \"GET\",\n headers: requestHeaders,\n timeout: 120000,\n });\n\n // Check for hint access denied (402)\n if (response.status === 402 && response.data) {\n const errorResponse = response.data as HintAccessDeniedResponse;\n if (errorResponse.error?.code === \"HINT_ACCESS_DENIED\") {\n throw new HintAccessDeniedError(errorResponse.error);\n }\n }\n\n // Check for other errors\n if (!response.ok || response.data === undefined) {\n throw new Error(\"Failed to get hints from solver\");\n }\n\n return (await decryptSolutionFields(\n response.data,\n )) as BaseResponse<SolveData>;\n }\n\n /**\n * Validate that a Sudoku puzzle has a unique solution.\n * Uses a longer timeout (120s) because validation involves iterative solving.\n */\n async solverValidate(\n token: string,\n options: ValidateOptions,\n ): Promise<BaseResponse<ValidateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_VALIDATE, {\n original: options.original,\n });\n\n // Use 120 second timeout for validation (iterative solving can be slow)\n return this.request<BaseResponse<ValidateData>>(url, {\n token,\n timeout: 120000,\n });\n }\n\n /**\n * Generate a new random Sudoku puzzle\n */\n async solverGenerate(\n token: string,\n options: GenerateOptions = {},\n ): Promise<BaseResponse<GenerateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_GENERATE, {\n symmetrical: options.symmetrical,\n });\n\n return this.request<BaseResponse<GenerateData>>(url, { token });\n }\n\n // ===========================================================================\n // Play (Game Session) Endpoints\n // ===========================================================================\n\n /**\n * Start a new game session\n */\n async playStart(\n token: string,\n data: GameStartRequest,\n ): Promise<BaseResponse<GameStartResponse>> {\n return this.request<BaseResponse<GameStartResponse>>(\n this.config.ENDPOINTS.PLAY_START,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Finish the current game session and get rewards\n */\n async playFinish(\n token: string,\n data: GameFinishRequest,\n ): Promise<BaseResponse<GameFinishResponse>> {\n return this.request<BaseResponse<GameFinishResponse>>(\n this.config.ENDPOINTS.PLAY_FINISH,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Gamification Endpoints\n // ===========================================================================\n\n /**\n * Get user's gamification stats (points, level, badges)\n */\n async getGamificationStats(\n token: string,\n ): Promise<BaseResponse<GamificationStats>> {\n return this.request<BaseResponse<GamificationStats>>(\n this.config.ENDPOINTS.GAMIFICATION_STATS,\n { token },\n );\n }\n\n /**\n * Get all badge definitions (public)\n */\n async getBadgeDefinitions(): Promise<BaseResponse<BadgeDefinition[]>> {\n return this.request<BaseResponse<BadgeDefinition[]>>(\n this.config.ENDPOINTS.GAMIFICATION_BADGES,\n );\n }\n\n /**\n * Get user's point transaction history\n */\n async getPointHistory(\n token: string,\n options?: { limit?: number; offset?: number },\n ): Promise<BaseResponse<PointTransaction[]>> {\n let endpoint = this.config.ENDPOINTS.GAMIFICATION_HISTORY;\n if (options?.limit || options?.offset) {\n const params = createURLSearchParams();\n if (options.limit) params.append(\"limit\", String(options.limit));\n if (options.offset) params.append(\"offset\", String(options.offset));\n endpoint = `${endpoint}?${params.toString()}`;\n }\n return this.request<BaseResponse<PointTransaction[]>>(endpoint, { token });\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Factory function to create a new SudojoClient instance.\n *\n * Equivalent to `new SudojoClient(networkClient, baseUrl)` but useful\n * for dependency injection and functional composition patterns.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL for the Sudojo API\n * @returns A new SudojoClient instance\n */\nexport const createSudojoClient = (\n networkClient: NetworkClient,\n baseUrl: string,\n): SudojoClient => {\n return new SudojoClient(networkClient, baseUrl);\n};\n\n// =============================================================================\n// Utility Exports\n// =============================================================================\n\n/**\n * Re-exported UUID validation utilities from `@sudobility/sudojo_types`.\n *\n * These are used internally by the SudojoClient for parameter validation\n * and are also exported for consumer convenience. Use `isValidUUID` for\n * boolean checks and `validateUUID` when you want an error thrown on invalid input.\n *\n * - `isValidUUID(value)` - Returns true if the string is a valid UUID v4\n * - `validateUUID(value, label)` - Returns the UUID or throws an Error with the label\n */\nexport { isValidUUID, validateUUID };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/sudojo_client",
3
- "version": "0.0.98",
3
+ "version": "0.0.99",
4
4
  "description": "TypeScript client library for Sudojo API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "license": "BUSL-1.1",
38
38
  "peerDependencies": {
39
39
  "@sudobility/di": "^1.5.52",
40
- "@sudobility/sudojo_types": "^1.2.48",
40
+ "@sudobility/sudojo_types": "^1.2.49",
41
41
  "@sudobility/types": "^1.9.61",
42
42
  "@tanstack/react-query": ">=5.0.0",
43
43
  "react": ">=18.0.0"
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@eslint/js": "^9.38.0",
47
47
  "@sudobility/di": "^1.5.52",
48
- "@sudobility/sudojo_types": "^1.2.48",
48
+ "@sudobility/sudojo_types": "^1.2.49",
49
49
  "@sudobility/types": "^1.9.61",
50
50
  "@tanstack/react-query": "^5.90.5",
51
51
  "@testing-library/react": "^16.3.0",