keeperboard 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -93,6 +93,7 @@ interface HealthResult {
93
93
  version: string;
94
94
  timestamp: string;
95
95
  }
96
+ type ErrorCode = 'PROFANITY_DETECTED' | 'RATE_LIMITED' | 'INVALID_REQUEST' | 'NOT_FOUND' | 'INTERNAL_ERROR';
96
97
  interface SessionConfig {
97
98
  /** API key from the KeeperBoard dashboard */
98
99
  apiKey: string;
@@ -120,6 +121,14 @@ type SessionScoreResult = {
120
121
  } | {
121
122
  success: false;
122
123
  error: string;
124
+ errorCode?: ErrorCode;
125
+ };
126
+ type UpdateNameResult = {
127
+ success: true;
128
+ } | {
129
+ success: false;
130
+ error: string;
131
+ errorCode?: ErrorCode;
123
132
  };
124
133
  interface SnapshotEntry {
125
134
  rank: number;
@@ -139,8 +148,6 @@ interface NameValidationOptions {
139
148
  minLength?: number;
140
149
  /** Maximum length — input is truncated to this (default 12). */
141
150
  maxLength?: number;
142
- /** Convert to uppercase (default true). */
143
- uppercase?: boolean;
144
151
  /** Regex of allowed characters applied after case conversion (default /[^A-Z0-9_]/g removes non-matching). */
145
152
  allowedPattern?: RegExp;
146
153
  }
@@ -336,9 +343,9 @@ declare class KeeperBoardSession {
336
343
  }): Promise<SnapshotResult>;
337
344
  /**
338
345
  * Update the player's name on the server and locally.
339
- * Returns true on success, false on failure.
346
+ * Returns `{ success: true }` on success, or `{ success: false, error, errorCode }` on failure.
340
347
  */
341
- updatePlayerName(newName: string): Promise<boolean>;
348
+ updatePlayerName(newName: string): Promise<UpdateNameResult>;
342
349
  /**
343
350
  * Retry submitting a pending score (from a previous failed submission).
344
351
  * Call this on app startup.
@@ -424,14 +431,13 @@ declare class PlayerIdentity {
424
431
  * Validate and sanitize a player name.
425
432
  *
426
433
  * 1. Trims whitespace
427
- * 2. Optionally converts to uppercase (default: yes)
428
- * 3. Strips characters not matching `allowedPattern`
429
- * 4. Truncates to `maxLength`
430
- * 5. Returns `null` if result is shorter than `minLength`
434
+ * 2. Strips characters not matching `allowedPattern`
435
+ * 3. Truncates to `maxLength`
436
+ * 4. Returns `null` if result is shorter than `minLength`
431
437
  *
432
438
  * @example
433
- * validateName(' Ace Pilot! ') // 'ACE_PILOT' → wait, no spaces allowed → 'ACEPILOT'
434
- * validateName('ab') // 'AB'
439
+ * validateName(' Ace Pilot! ') // 'AcePilot'
440
+ * validateName('ab') // 'ab'
435
441
  * validateName('x') // null (too short)
436
442
  */
437
443
  declare function validateName(input: string, options?: NameValidationOptions): string | null;
@@ -513,4 +519,4 @@ declare class RetryQueue {
513
519
  clear(): void;
514
520
  }
515
521
 
516
- export { Cache, type ClaimResponse, type ClaimResult, type ClaimScoreOptions, type GetLeaderboardOptions, type GetPlayerRankOptions, type HealthResponse, type HealthResult, KeeperBoardClient, type KeeperBoardConfig, KeeperBoardError, KeeperBoardSession, type LeaderboardEntry, type LeaderboardResponse, type LeaderboardResult, type NameValidationOptions, PlayerIdentity, type PlayerIdentityConfig, type PlayerResponse, type PlayerResult, type ResetSchedule, RetryQueue, type ScoreResponse, type ScoreResult, type ScoreSubmission, type SessionConfig, type SessionScoreResult, type SnapshotEntry, type SnapshotResult, type SubmitScoreOptions, type UpdatePlayerNameOptions, generatePlayerName, validateName };
522
+ export { Cache, type ClaimResponse, type ClaimResult, type ClaimScoreOptions, type ErrorCode, type GetLeaderboardOptions, type GetPlayerRankOptions, type HealthResponse, type HealthResult, KeeperBoardClient, type KeeperBoardConfig, KeeperBoardError, KeeperBoardSession, type LeaderboardEntry, type LeaderboardResponse, type LeaderboardResult, type NameValidationOptions, PlayerIdentity, type PlayerIdentityConfig, type PlayerResponse, type PlayerResult, type ResetSchedule, RetryQueue, type ScoreResponse, type ScoreResult, type ScoreSubmission, type SessionConfig, type SessionScoreResult, type SnapshotEntry, type SnapshotResult, type SubmitScoreOptions, type UpdateNameResult, type UpdatePlayerNameOptions, generatePlayerName, validateName };
package/dist/index.d.ts CHANGED
@@ -93,6 +93,7 @@ interface HealthResult {
93
93
  version: string;
94
94
  timestamp: string;
95
95
  }
96
+ type ErrorCode = 'PROFANITY_DETECTED' | 'RATE_LIMITED' | 'INVALID_REQUEST' | 'NOT_FOUND' | 'INTERNAL_ERROR';
96
97
  interface SessionConfig {
97
98
  /** API key from the KeeperBoard dashboard */
98
99
  apiKey: string;
@@ -120,6 +121,14 @@ type SessionScoreResult = {
120
121
  } | {
121
122
  success: false;
122
123
  error: string;
124
+ errorCode?: ErrorCode;
125
+ };
126
+ type UpdateNameResult = {
127
+ success: true;
128
+ } | {
129
+ success: false;
130
+ error: string;
131
+ errorCode?: ErrorCode;
123
132
  };
124
133
  interface SnapshotEntry {
125
134
  rank: number;
@@ -139,8 +148,6 @@ interface NameValidationOptions {
139
148
  minLength?: number;
140
149
  /** Maximum length — input is truncated to this (default 12). */
141
150
  maxLength?: number;
142
- /** Convert to uppercase (default true). */
143
- uppercase?: boolean;
144
151
  /** Regex of allowed characters applied after case conversion (default /[^A-Z0-9_]/g removes non-matching). */
145
152
  allowedPattern?: RegExp;
146
153
  }
@@ -336,9 +343,9 @@ declare class KeeperBoardSession {
336
343
  }): Promise<SnapshotResult>;
337
344
  /**
338
345
  * Update the player's name on the server and locally.
339
- * Returns true on success, false on failure.
346
+ * Returns `{ success: true }` on success, or `{ success: false, error, errorCode }` on failure.
340
347
  */
341
- updatePlayerName(newName: string): Promise<boolean>;
348
+ updatePlayerName(newName: string): Promise<UpdateNameResult>;
342
349
  /**
343
350
  * Retry submitting a pending score (from a previous failed submission).
344
351
  * Call this on app startup.
@@ -424,14 +431,13 @@ declare class PlayerIdentity {
424
431
  * Validate and sanitize a player name.
425
432
  *
426
433
  * 1. Trims whitespace
427
- * 2. Optionally converts to uppercase (default: yes)
428
- * 3. Strips characters not matching `allowedPattern`
429
- * 4. Truncates to `maxLength`
430
- * 5. Returns `null` if result is shorter than `minLength`
434
+ * 2. Strips characters not matching `allowedPattern`
435
+ * 3. Truncates to `maxLength`
436
+ * 4. Returns `null` if result is shorter than `minLength`
431
437
  *
432
438
  * @example
433
- * validateName(' Ace Pilot! ') // 'ACE_PILOT' → wait, no spaces allowed → 'ACEPILOT'
434
- * validateName('ab') // 'AB'
439
+ * validateName(' Ace Pilot! ') // 'AcePilot'
440
+ * validateName('ab') // 'ab'
435
441
  * validateName('x') // null (too short)
436
442
  */
437
443
  declare function validateName(input: string, options?: NameValidationOptions): string | null;
@@ -513,4 +519,4 @@ declare class RetryQueue {
513
519
  clear(): void;
514
520
  }
515
521
 
516
- export { Cache, type ClaimResponse, type ClaimResult, type ClaimScoreOptions, type GetLeaderboardOptions, type GetPlayerRankOptions, type HealthResponse, type HealthResult, KeeperBoardClient, type KeeperBoardConfig, KeeperBoardError, KeeperBoardSession, type LeaderboardEntry, type LeaderboardResponse, type LeaderboardResult, type NameValidationOptions, PlayerIdentity, type PlayerIdentityConfig, type PlayerResponse, type PlayerResult, type ResetSchedule, RetryQueue, type ScoreResponse, type ScoreResult, type ScoreSubmission, type SessionConfig, type SessionScoreResult, type SnapshotEntry, type SnapshotResult, type SubmitScoreOptions, type UpdatePlayerNameOptions, generatePlayerName, validateName };
522
+ export { Cache, type ClaimResponse, type ClaimResult, type ClaimScoreOptions, type ErrorCode, type GetLeaderboardOptions, type GetPlayerRankOptions, type HealthResponse, type HealthResult, KeeperBoardClient, type KeeperBoardConfig, KeeperBoardError, KeeperBoardSession, type LeaderboardEntry, type LeaderboardResponse, type LeaderboardResult, type NameValidationOptions, PlayerIdentity, type PlayerIdentityConfig, type PlayerResponse, type PlayerResult, type ResetSchedule, RetryQueue, type ScoreResponse, type ScoreResult, type ScoreSubmission, type SessionConfig, type SessionScoreResult, type SnapshotEntry, type SnapshotResult, type SubmitScoreOptions, type UpdateNameResult, type UpdatePlayerNameOptions, generatePlayerName, validateName };
package/dist/index.js CHANGED
@@ -720,16 +720,12 @@ var RetryQueue = class {
720
720
  var DEFAULTS = {
721
721
  minLength: 2,
722
722
  maxLength: 12,
723
- uppercase: true,
724
- allowedPattern: /[^A-Z0-9_]/g
723
+ allowedPattern: /[^A-Za-z0-9_]/g
725
724
  };
726
725
  function validateName(input, options) {
727
726
  const opts = { ...DEFAULTS, ...options };
728
727
  let name = input.trim();
729
- if (opts.uppercase) {
730
- name = name.toUpperCase();
731
- }
732
- const pattern = options?.allowedPattern ?? (opts.uppercase ? /[^A-Z0-9_]/g : /[^A-Za-z0-9_]/g);
728
+ const pattern = options?.allowedPattern ?? /[^A-Za-z0-9_]/g;
733
729
  name = name.replace(pattern, "");
734
730
  name = name.substring(0, opts.maxLength);
735
731
  if (name.length < opts.minLength) {
@@ -814,10 +810,14 @@ var KeeperBoardSession = class {
814
810
  isNewHighScore: result.isNewHighScore
815
811
  };
816
812
  } catch (error) {
817
- this.retryQueue?.save(score, metadata);
813
+ const errorCode = error instanceof KeeperBoardError ? error.code : void 0;
814
+ if (errorCode !== "PROFANITY_DETECTED") {
815
+ this.retryQueue?.save(score, metadata);
816
+ }
818
817
  return {
819
818
  success: false,
820
- error: error instanceof Error ? error.message : "Unknown error"
819
+ error: error instanceof Error ? error.message : "Unknown error",
820
+ errorCode
821
821
  };
822
822
  } finally {
823
823
  this.isSubmitting = false;
@@ -844,7 +844,7 @@ var KeeperBoardSession = class {
844
844
  }
845
845
  /**
846
846
  * Update the player's name on the server and locally.
847
- * Returns true on success, false on failure.
847
+ * Returns `{ success: true }` on success, or `{ success: false, error, errorCode }` on failure.
848
848
  */
849
849
  async updatePlayerName(newName) {
850
850
  try {
@@ -857,9 +857,14 @@ var KeeperBoardSession = class {
857
857
  this.cache.invalidate();
858
858
  this.cachedLimit = 0;
859
859
  }
860
- return true;
861
- } catch {
862
- return false;
860
+ return { success: true };
861
+ } catch (error) {
862
+ const errorCode = error instanceof KeeperBoardError ? error.code : void 0;
863
+ return {
864
+ success: false,
865
+ error: error instanceof Error ? error.message : "Unknown error",
866
+ errorCode
867
+ };
863
868
  }
864
869
  }
865
870
  /**
package/dist/index.mjs CHANGED
@@ -687,16 +687,12 @@ var RetryQueue = class {
687
687
  var DEFAULTS = {
688
688
  minLength: 2,
689
689
  maxLength: 12,
690
- uppercase: true,
691
- allowedPattern: /[^A-Z0-9_]/g
690
+ allowedPattern: /[^A-Za-z0-9_]/g
692
691
  };
693
692
  function validateName(input, options) {
694
693
  const opts = { ...DEFAULTS, ...options };
695
694
  let name = input.trim();
696
- if (opts.uppercase) {
697
- name = name.toUpperCase();
698
- }
699
- const pattern = options?.allowedPattern ?? (opts.uppercase ? /[^A-Z0-9_]/g : /[^A-Za-z0-9_]/g);
695
+ const pattern = options?.allowedPattern ?? /[^A-Za-z0-9_]/g;
700
696
  name = name.replace(pattern, "");
701
697
  name = name.substring(0, opts.maxLength);
702
698
  if (name.length < opts.minLength) {
@@ -781,10 +777,14 @@ var KeeperBoardSession = class {
781
777
  isNewHighScore: result.isNewHighScore
782
778
  };
783
779
  } catch (error) {
784
- this.retryQueue?.save(score, metadata);
780
+ const errorCode = error instanceof KeeperBoardError ? error.code : void 0;
781
+ if (errorCode !== "PROFANITY_DETECTED") {
782
+ this.retryQueue?.save(score, metadata);
783
+ }
785
784
  return {
786
785
  success: false,
787
- error: error instanceof Error ? error.message : "Unknown error"
786
+ error: error instanceof Error ? error.message : "Unknown error",
787
+ errorCode
788
788
  };
789
789
  } finally {
790
790
  this.isSubmitting = false;
@@ -811,7 +811,7 @@ var KeeperBoardSession = class {
811
811
  }
812
812
  /**
813
813
  * Update the player's name on the server and locally.
814
- * Returns true on success, false on failure.
814
+ * Returns `{ success: true }` on success, or `{ success: false, error, errorCode }` on failure.
815
815
  */
816
816
  async updatePlayerName(newName) {
817
817
  try {
@@ -824,9 +824,14 @@ var KeeperBoardSession = class {
824
824
  this.cache.invalidate();
825
825
  this.cachedLimit = 0;
826
826
  }
827
- return true;
828
- } catch {
829
- return false;
827
+ return { success: true };
828
+ } catch (error) {
829
+ const errorCode = error instanceof KeeperBoardError ? error.code : void 0;
830
+ return {
831
+ success: false,
832
+ error: error instanceof Error ? error.message : "Unknown error",
833
+ errorCode
834
+ };
830
835
  }
831
836
  }
832
837
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keeperboard",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "TypeScript client SDK for KeeperBoard leaderboard-as-a-service",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",