@xivdyetools/test-utils 1.0.2 → 1.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/README.md CHANGED
@@ -139,6 +139,20 @@ const params = new URLSearchParams({
139
139
 
140
140
  This package includes full TypeScript support. Cloudflare Workers types are included via `@cloudflare/workers-types`.
141
141
 
142
+ ## Connect With Me
143
+
144
+ **Flash Galatine** | Balmung (Crystal)
145
+
146
+ 🎮 **FFXIV**: [Lodestone Character](https://na.finalfantasyxiv.com/lodestone/character/7677106/)
147
+ 📝 **Blog**: [Project Galatine](https://blog.projectgalatine.com/)
148
+ 💻 **GitHub**: [@FlashGalatine](https://github.com/FlashGalatine)
149
+ 🐦 **X / Twitter**: [@AsheJunius](https://x.com/AsheJunius)
150
+ 📺 **Twitch**: [flashgalatine](https://www.twitch.tv/flashgalatine)
151
+ 🌐 **BlueSky**: [projectgalatine.com](https://bsky.app/profile/projectgalatine.com)
152
+ ❤️ **Patreon**: [ProjectGalatine](https://patreon.com/ProjectGalatine)
153
+ ☕ **Ko-Fi**: [flashgalatine](https://ko-fi.com/flashgalatine)
154
+ 💬 **Discord**: [Join Server](https://discord.gg/5VUSKTZCe5)
155
+
142
156
  ## License
143
157
 
144
- MIT
158
+ MIT © 2025 Flash Galatine
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,gBAAgB,SAAO,EACvB,MAAM,SAA6B,GAClC,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAiD,GACzD,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAIjB"}
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,gBAAgB,SAAO,EACvB,MAAM,SAA6B,GAClC,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAiD,GACzD,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAIjB"}
package/dist/auth/jwt.js CHANGED
@@ -22,7 +22,7 @@
22
22
  * });
23
23
  * ```
24
24
  */
25
- import { base64UrlEncode } from '../utils/crypto.js';
25
+ import { base64UrlEncode, base64UrlEncodeBytes } from '../utils/crypto.js';
26
26
  /**
27
27
  * Creates a valid JWT for testing
28
28
  *
@@ -47,7 +47,8 @@ export async function createTestJWT(secret, payload, expiresInSeconds = 3600, is
47
47
  const signatureInput = `${encodedHeader}.${encodedPayload}`;
48
48
  const key = await crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
49
49
  const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(signatureInput));
50
- const encodedSignature = base64UrlEncode(String.fromCharCode(...new Uint8Array(signature)));
50
+ // Use base64UrlEncodeBytes for binary signature data to avoid UTF-8 encoding issues
51
+ const encodedSignature = base64UrlEncodeBytes(new Uint8Array(signature));
51
52
  return `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
52
53
  }
53
54
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AA4BrD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,OAAuB,EACvB,gBAAgB,GAAG,IAAI,EACvB,MAAM,GAAG,0BAA0B;IAEnC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,MAAM,WAAW,GAAmB;QAClC,GAAG,OAAO;QACV,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,gBAAgB;QAC3B,GAAG,EAAE,MAAM;KACZ,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IAEpE,MAAM,cAAc,GAAG,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC;IAE5D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EACtB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;IAExF,MAAM,gBAAgB,GAAG,eAAe,CACtC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAClD,CAAC;IAEF,OAAO,GAAG,aAAa,IAAI,cAAc,IAAI,gBAAgB,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,UAA0B,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE;IAE1D,uCAAuC;IACvC,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAc,EACd,OAAuB,EACvB,YAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,gBAAgB,GAAG,YAAY,GAAG,GAAG,CAAC;IAC5C,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AA4B3E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,OAAuB,EACvB,gBAAgB,GAAG,IAAI,EACvB,MAAM,GAAG,0BAA0B;IAEnC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,MAAM,WAAW,GAAmB;QAClC,GAAG,OAAO;QACV,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,gBAAgB;QAC3B,GAAG,EAAE,MAAM;KACZ,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IAEpE,MAAM,cAAc,GAAG,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC;IAE5D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EACtB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;IAExF,oFAAoF;IACpF,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAEzE,OAAO,GAAG,aAAa,IAAI,cAAc,IAAI,gBAAgB,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,UAA0B,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE;IAE1D,uCAAuC;IACvC,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAc,EACd,OAAuB,EACvB,YAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,gBAAgB,GAAG,YAAY,GAAG,GAAG,CAAC;IAC5C,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC1D,CAAC"}
@@ -8,11 +8,15 @@
8
8
  * ```typescript
9
9
  * const db = createMockD1Database();
10
10
  *
11
- * // Setup mock responses
11
+ * // Setup mock responses using regex patterns (TEST-DESIGN-002)
12
+ * // Use /^\s*SELECT/i to anchor to start and be case-insensitive
12
13
  * db._setupMock((query, bindings) => {
13
- * if (query.includes('SELECT') && query.includes('presets')) {
14
+ * if (/^\s*SELECT/i.test(query) && query.includes('presets')) {
14
15
  * return [{ id: 'preset-1', name: 'Test Preset' }];
15
16
  * }
17
+ * if (/^\s*INSERT/i.test(query)) {
18
+ * return { meta: { changes: 1, last_row_id: 1 } };
19
+ * }
16
20
  * return null;
17
21
  * });
18
22
  *
@@ -79,6 +83,13 @@ export interface MockD1DatabaseSession {
79
83
  /** Get constraint string for this session */
80
84
  getBookmark: () => string;
81
85
  }
86
+ /**
87
+ * Configuration options for the mock D1 database
88
+ */
89
+ export interface MockD1DatabaseConfig {
90
+ /** Maximum number of queries to keep in history (prevents memory leaks). Default: 1000 */
91
+ maxQueryHistory?: number;
92
+ }
82
93
  /**
83
94
  * Extended mock D1 database with test helpers
84
95
  */
@@ -92,9 +103,9 @@ export interface MockD1Database {
92
103
  dump: () => Promise<ArrayBuffer>;
93
104
  /** Start a session - returns a session object with same query methods */
94
105
  withSession: (constraintOrBookmark?: string) => MockD1DatabaseSession;
95
- /** Array of all queries executed (for assertions) */
106
+ /** Array of all queries executed (for assertions). Limited to maxQueryHistory entries. */
96
107
  _queries: string[];
97
- /** Array of all binding arrays passed to queries */
108
+ /** Array of all binding arrays passed to queries. Limited to maxQueryHistory entries. */
98
109
  _bindings: unknown[][];
99
110
  /** Setup a mock function to return custom responses */
100
111
  _setupMock: (fn: QueryMockFn) => void;
@@ -102,6 +113,13 @@ export interface MockD1Database {
102
113
  _reset: () => void;
103
114
  /** Current mock function (if any) */
104
115
  _mockFn?: QueryMockFn;
116
+ /**
117
+ * Set the ban status for ban-check middleware tests
118
+ * @param isBanned - true to simulate banned user, false or undefined for not banned
119
+ */
120
+ _setBanStatus: (isBanned: boolean) => void;
121
+ /** Set the maximum query history size (for memory management) */
122
+ _setMaxQueryHistory: (max: number) => void;
105
123
  }
106
124
  /**
107
125
  * Creates a mock D1 database for testing
@@ -109,9 +127,13 @@ export interface MockD1Database {
109
127
  * The mock tracks all queries and bindings for assertions, and supports
110
128
  * custom response functions for simulating database behavior.
111
129
  *
130
+ * TEST-OPT-003 FIX: Added maxQueryHistory config to prevent unbounded memory growth
131
+ * in long-running test suites. Default is 1000 queries.
132
+ *
133
+ * @param config - Optional configuration for the mock database
112
134
  * @returns A mock D1 database that can be cast to D1Database
113
135
  */
114
- export declare function createMockD1Database(): MockD1Database;
136
+ export declare function createMockD1Database(config?: MockD1DatabaseConfig): MockD1Database;
115
137
  /**
116
138
  * Creates a mock D1 database pre-cast as D1Database
117
139
  *
@@ -1 +1 @@
1
- {"version":3,"file":"d1.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"d1.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"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"}
@@ -8,11 +8,15 @@
8
8
  * ```typescript
9
9
  * const db = createMockD1Database();
10
10
  *
11
- * // Setup mock responses
11
+ * // Setup mock responses using regex patterns (TEST-DESIGN-002)
12
+ * // Use /^\s*SELECT/i to anchor to start and be case-insensitive
12
13
  * db._setupMock((query, bindings) => {
13
- * if (query.includes('SELECT') && query.includes('presets')) {
14
+ * if (/^\s*SELECT/i.test(query) && query.includes('presets')) {
14
15
  * return [{ id: 'preset-1', name: 'Test Preset' }];
15
16
  * }
17
+ * if (/^\s*INSERT/i.test(query)) {
18
+ * return { meta: { changes: 1, last_row_id: 1 } };
19
+ * }
16
20
  * return null;
17
21
  * });
18
22
  *
@@ -27,18 +31,36 @@
27
31
  * db._reset();
28
32
  * ```
29
33
  */
34
+ /** Default maximum query history size */
35
+ const DEFAULT_MAX_QUERY_HISTORY = 1000;
30
36
  /**
31
37
  * Creates a mock D1 database for testing
32
38
  *
33
39
  * The mock tracks all queries and bindings for assertions, and supports
34
40
  * custom response functions for simulating database behavior.
35
41
  *
42
+ * TEST-OPT-003 FIX: Added maxQueryHistory config to prevent unbounded memory growth
43
+ * in long-running test suites. Default is 1000 queries.
44
+ *
45
+ * @param config - Optional configuration for the mock database
36
46
  * @returns A mock D1 database that can be cast to D1Database
37
47
  */
38
- export function createMockD1Database() {
48
+ export function createMockD1Database(config) {
39
49
  const queries = [];
40
50
  const bindings = [];
41
51
  let mockFn;
52
+ let banStatus;
53
+ let maxQueryHistory = config?.maxQueryHistory ?? DEFAULT_MAX_QUERY_HISTORY;
54
+ /**
55
+ * Enforce max query history limit using FIFO eviction
56
+ * TEST-OPT-003 FIX: Prevents unbounded memory growth
57
+ */
58
+ const enforceMaxHistory = () => {
59
+ while (queries.length > maxQueryHistory) {
60
+ queries.shift();
61
+ bindings.shift();
62
+ }
63
+ };
42
64
  const createDefaultMeta = () => ({
43
65
  duration: 0,
44
66
  changes: 0,
@@ -58,6 +80,16 @@ export function createMockD1Database() {
58
80
  },
59
81
  first: async () => {
60
82
  queries.push(query);
83
+ enforceMaxHistory();
84
+ // Special handling for banned_users queries to prevent false ban detection
85
+ // Use _setBanStatus(true) to simulate a banned user in tests
86
+ if (query.includes('banned_users')) {
87
+ if (banStatus === true) {
88
+ return { 1: 1 }; // User is banned
89
+ }
90
+ // Default: user not banned (don't call mockFn to avoid side effects)
91
+ return null;
92
+ }
61
93
  if (mockFn) {
62
94
  const result = mockFn(query, boundValues);
63
95
  // If result is an array, return first element
@@ -70,6 +102,7 @@ export function createMockD1Database() {
70
102
  },
71
103
  all: async () => {
72
104
  queries.push(query);
105
+ enforceMaxHistory();
73
106
  if (mockFn) {
74
107
  const result = mockFn(query, boundValues);
75
108
  if (Array.isArray(result)) {
@@ -84,6 +117,7 @@ export function createMockD1Database() {
84
117
  },
85
118
  run: async () => {
86
119
  queries.push(query);
120
+ enforceMaxHistory();
87
121
  if (mockFn) {
88
122
  const result = mockFn(query, boundValues);
89
123
  if (result && typeof result === 'object' && 'meta' in result) {
@@ -98,6 +132,7 @@ export function createMockD1Database() {
98
132
  },
99
133
  raw: async (_options) => {
100
134
  queries.push(query);
135
+ enforceMaxHistory();
101
136
  if (mockFn) {
102
137
  const result = mockFn(query, boundValues);
103
138
  if (Array.isArray(result)) {
@@ -129,6 +164,7 @@ export function createMockD1Database() {
129
164
  },
130
165
  exec: async (query) => {
131
166
  queries.push(query);
167
+ enforceMaxHistory();
132
168
  return { count: 1, duration: 0 };
133
169
  },
134
170
  dump: async () => {
@@ -150,6 +186,7 @@ export function createMockD1Database() {
150
186
  },
151
187
  exec: async (query) => {
152
188
  queries.push(query);
189
+ enforceMaxHistory();
153
190
  return { count: 1, duration: 0 };
154
191
  },
155
192
  getBookmark: () => constraintOrBookmark ?? 'mock-bookmark',
@@ -164,10 +201,19 @@ export function createMockD1Database() {
164
201
  queries.length = 0;
165
202
  bindings.length = 0;
166
203
  mockFn = undefined;
204
+ banStatus = undefined;
167
205
  },
168
206
  get _mockFn() {
169
207
  return mockFn;
170
208
  },
209
+ _setBanStatus: (isBanned) => {
210
+ banStatus = isBanned;
211
+ },
212
+ _setMaxQueryHistory: (max) => {
213
+ maxQueryHistory = max;
214
+ // Immediately enforce the new limit
215
+ enforceMaxHistory();
216
+ },
171
217
  };
172
218
  return mockDb;
173
219
  }
@@ -1 +1 @@
1
- {"version":3,"file":"d1.js","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"d1.js","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"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"}
@@ -44,12 +44,19 @@ export interface MockResponseConfig {
44
44
  headers?: Record<string, string>;
45
45
  body?: unknown;
46
46
  }
47
+ /**
48
+ * Configuration options for the mock fetcher
49
+ */
50
+ export interface MockFetcherConfig {
51
+ /** Maximum number of calls to keep in history (prevents memory leaks). Default: 1000 */
52
+ maxCallHistory?: number;
53
+ }
47
54
  /**
48
55
  * Extended mock Fetcher with test helpers
49
56
  */
50
57
  export interface MockFetcher {
51
58
  fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
52
- /** Array of all fetch calls made (for assertions) */
59
+ /** Array of all fetch calls made (for assertions). Limited to maxCallHistory entries. */
53
60
  _calls: MockFetchCall[];
54
61
  /** Setup a response for a specific path pattern */
55
62
  _setupResponse: (pathPattern: string | RegExp, response: unknown, config?: Omit<MockResponseConfig, 'body'>) => void;
@@ -59,6 +66,8 @@ export interface MockFetcher {
59
66
  _reset: () => void;
60
67
  /** Set default response for unmatched requests */
61
68
  _setDefaultResponse: (response: unknown, config?: Omit<MockResponseConfig, 'body'>) => void;
69
+ /** Set the maximum call history size (for memory management) */
70
+ _setMaxCallHistory: (max: number) => void;
62
71
  }
63
72
  /**
64
73
  * Creates a mock Fetcher for testing Service Bindings
@@ -66,7 +75,8 @@ export interface MockFetcher {
66
75
  * The mock tracks all fetch calls and supports configuring
67
76
  * responses for specific URL patterns.
68
77
  *
78
+ * @param config - Optional configuration for the mock fetcher
69
79
  * @returns A mock Fetcher that can be cast to Fetcher
70
80
  */
71
- export declare function createMockFetcher(): MockFetcher;
81
+ export declare function createMockFetcher(config?: MockFetcherConfig): MockFetcher;
72
82
  //# sourceMappingURL=fetcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/cloudflare/fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE3E,qDAAqD;IACrD,MAAM,EAAE,aAAa,EAAE,CAAC;IAExB,mDAAmD;IACnD,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAErH,sCAAsC;IACtC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,KAAK,IAAI,CAAC;IAEpG,8CAA8C;IAC9C,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB,kDAAkD;IAClD,mBAAmB,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CAC7F;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAiH/C"}
1
+ {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/cloudflare/fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE3E,yFAAyF;IACzF,MAAM,EAAE,aAAa,EAAE,CAAC;IAExB,mDAAmD;IACnD,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAErH,sCAAsC;IACtC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,KAAK,IAAI,CAAC;IAEpG,8CAA8C;IAC9C,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB,kDAAkD;IAClD,mBAAmB,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAE5F,gEAAgE;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAKD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,WAAW,CA+HzE"}
@@ -26,15 +26,18 @@
26
26
  * presetsApi._reset();
27
27
  * ```
28
28
  */
29
+ /** Default maximum call history size */
30
+ const DEFAULT_MAX_CALL_HISTORY = 1000;
29
31
  /**
30
32
  * Creates a mock Fetcher for testing Service Bindings
31
33
  *
32
34
  * The mock tracks all fetch calls and supports configuring
33
35
  * responses for specific URL patterns.
34
36
  *
37
+ * @param config - Optional configuration for the mock fetcher
35
38
  * @returns A mock Fetcher that can be cast to Fetcher
36
39
  */
37
- export function createMockFetcher() {
40
+ export function createMockFetcher(config) {
38
41
  const calls = [];
39
42
  const responses = new Map();
40
43
  let customHandler;
@@ -42,6 +45,7 @@ export function createMockFetcher() {
42
45
  status: 200,
43
46
  body: { success: true },
44
47
  };
48
+ let maxCallHistory = config?.maxCallHistory ?? DEFAULT_MAX_CALL_HISTORY;
45
49
  const createResponse = (config) => {
46
50
  const { status = 200, headers = {}, body } = config;
47
51
  const responseBody = body !== undefined ? JSON.stringify(body) : '';
@@ -89,7 +93,7 @@ export function createMockFetcher() {
89
93
  Object.assign(headers, init.headers);
90
94
  }
91
95
  }
92
- // Record the call
96
+ // Record the call (with memory limit enforcement)
93
97
  calls.push({
94
98
  url,
95
99
  method,
@@ -97,6 +101,10 @@ export function createMockFetcher() {
97
101
  body: init?.body?.toString(),
98
102
  timestamp: Date.now(),
99
103
  });
104
+ // Enforce max history limit (FIFO eviction) to prevent memory leaks
105
+ while (calls.length > maxCallHistory) {
106
+ calls.shift();
107
+ }
100
108
  // Use custom handler if provided
101
109
  if (customHandler) {
102
110
  return customHandler(url, init);
@@ -131,6 +139,13 @@ export function createMockFetcher() {
131
139
  body: response,
132
140
  };
133
141
  },
142
+ _setMaxCallHistory: (max) => {
143
+ maxCallHistory = max;
144
+ // Immediately enforce the new limit
145
+ while (calls.length > maxCallHistory) {
146
+ calls.shift();
147
+ }
148
+ },
134
149
  };
135
150
  }
136
151
  //# sourceMappingURL=fetcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../../src/cloudflare/fetcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../../src/cloudflare/fetcher.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../../src/cloudflare/kv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;GAEG;AACH,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,UAAU,YAAY;IACpB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9G,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClI,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAChG,eAAe,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IAExH,4CAA4C;IAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE5B,sDAAsD;IACtD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3B,4BAA4B;IAC5B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEhC,wBAAwB;IACxB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,eAAe,CAmH9C"}
1
+ {"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../../src/cloudflare/kv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;GAEG;AACH,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,UAAU,YAAY;IACpB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9G,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClI,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAChG,eAAe,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IAExH,4CAA4C;IAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE5B,sDAAsD;IACtD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3B,4BAA4B;IAC5B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEhC,wBAAwB;IACxB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,eAAe,CA+I9C"}
@@ -37,20 +37,32 @@ export function createMockKV() {
37
37
  const ttls = new Map();
38
38
  const metadata = new Map();
39
39
  /**
40
- * Check if a key has expired
40
+ * Check if a key has expired using a snapshot timestamp
41
+ * This prevents race conditions when time advances during async operations
42
+ *
43
+ * @param key - The key to check
44
+ * @param nowSeconds - Snapshot of current time in seconds (use Date.now() / 1000)
41
45
  */
42
- const isExpired = (key) => {
46
+ const isExpiredAt = (key, nowSeconds) => {
43
47
  const expiration = ttls.get(key);
44
48
  if (expiration === undefined)
45
49
  return false;
46
- return Date.now() > expiration * 1000; // TTL is in seconds, convert to ms
50
+ return nowSeconds > expiration;
51
+ };
52
+ /**
53
+ * Clean up an expired key from all stores
54
+ */
55
+ const cleanupKey = (key) => {
56
+ store.delete(key);
57
+ ttls.delete(key);
58
+ metadata.delete(key);
47
59
  };
48
60
  return {
49
61
  get: async (key, options) => {
50
- if (isExpired(key)) {
51
- store.delete(key);
52
- ttls.delete(key);
53
- metadata.delete(key);
62
+ // Capture timestamp once to prevent race conditions with mocked time
63
+ const nowSeconds = Date.now() / 1000;
64
+ if (isExpiredAt(key, nowSeconds)) {
65
+ cleanupKey(key);
54
66
  return null;
55
67
  }
56
68
  const value = store.get(key) ?? null;
@@ -91,21 +103,34 @@ export function createMockKV() {
91
103
  metadata.delete(key);
92
104
  },
93
105
  list: async (options) => {
106
+ // Capture timestamp once for consistent TTL checks across all keys
107
+ const nowSeconds = Date.now() / 1000;
94
108
  const keys = [];
95
109
  const prefix = options?.prefix ?? '';
96
110
  const limit = options?.limit ?? 1000;
111
+ const expiredKeys = [];
97
112
  for (const [key, _value] of store.entries()) {
98
- if (key.startsWith(prefix) && !isExpired(key)) {
99
- keys.push({
100
- name: key,
101
- expiration: ttls.get(key),
102
- metadata: metadata.get(key),
103
- });
104
- if (keys.length >= limit) {
105
- break;
113
+ if (key.startsWith(prefix)) {
114
+ if (isExpiredAt(key, nowSeconds)) {
115
+ // Collect expired keys for cleanup after iteration
116
+ expiredKeys.push(key);
117
+ }
118
+ else {
119
+ keys.push({
120
+ name: key,
121
+ expiration: ttls.get(key),
122
+ metadata: metadata.get(key),
123
+ });
124
+ if (keys.length >= limit) {
125
+ break;
126
+ }
106
127
  }
107
128
  }
108
129
  }
130
+ // Clean up expired keys after iteration to avoid modifying map during iteration
131
+ for (const key of expiredKeys) {
132
+ cleanupKey(key);
133
+ }
109
134
  return {
110
135
  keys,
111
136
  list_complete: keys.length < limit,
@@ -113,10 +138,10 @@ export function createMockKV() {
113
138
  };
114
139
  },
115
140
  getWithMetadata: async (key) => {
116
- if (isExpired(key)) {
117
- store.delete(key);
118
- ttls.delete(key);
119
- metadata.delete(key);
141
+ // Capture timestamp once to prevent race conditions with mocked time
142
+ const nowSeconds = Date.now() / 1000;
143
+ if (isExpiredAt(key, nowSeconds)) {
144
+ cleanupKey(key);
120
145
  return { value: null, metadata: null, cacheStatus: null };
121
146
  }
122
147
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"kv.js","sourceRoot":"","sources":["../../src/cloudflare/kv.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kv.js","sourceRoot":"","sources":["../../src/cloudflare/kv.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,12 @@
2
2
  * Domain object factories for testing
3
3
  *
4
4
  * Provides factory functions to create mock domain objects
5
- * with sensible defaults and auto-incrementing IDs.
5
+ * with sensible defaults and random IDs (TEST-DESIGN-001).
6
6
  */
7
7
  export * from './preset.js';
8
8
  export * from './category.js';
9
9
  export * from './vote.js';
10
10
  export * from './user.js';
11
11
  export * from './dye.js';
12
- export { resetCounters, resetCounter, getCounterValue } from '../utils/counters.js';
12
+ export { randomId, randomStringId, resetCounters, resetCounter, getCounterValue, } from '../utils/counters.js';
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAGzB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAIzB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
@@ -2,13 +2,14 @@
2
2
  * Domain object factories for testing
3
3
  *
4
4
  * Provides factory functions to create mock domain objects
5
- * with sensible defaults and auto-incrementing IDs.
5
+ * with sensible defaults and random IDs (TEST-DESIGN-001).
6
6
  */
7
7
  export * from './preset.js';
8
8
  export * from './category.js';
9
9
  export * from './vote.js';
10
10
  export * from './user.js';
11
11
  export * from './dye.js';
12
- // Re-export counter utilities for test setup
13
- export { resetCounters, resetCounter, getCounterValue } from '../utils/counters.js';
12
+ // Re-export ID utilities for test setup
13
+ // TEST-DESIGN-001: randomId and randomStringId are the recommended functions for parallel-safe tests
14
+ export { randomId, randomStringId, resetCounters, resetCounter, getCounterValue, } from '../utils/counters.js';
14
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAEzB,6CAA6C;AAC7C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAEzB,wCAAwC;AACxC,qGAAqG;AACrG,OAAO,EACL,QAAQ,EACR,cAAc,EACd,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
@@ -2,10 +2,11 @@
2
2
  * Vote factory functions for testing
3
3
  *
4
4
  * Provides functions to create mock votes.
5
+ * TEST-DESIGN-001: Uses random IDs for parallel test safety.
5
6
  *
6
7
  * @example
7
8
  * ```typescript
8
- * const vote = createMockVote({ preset_id: 'preset-1' });
9
+ * const vote = createMockVote({ preset_id: 'preset-xyz' });
9
10
  * const votes = createMockVotes(5, { user_discord_id: '123' });
10
11
  * ```
11
12
  */
@@ -20,6 +21,8 @@ export interface VoteRow {
20
21
  /**
21
22
  * Creates a mock vote row
22
23
  *
24
+ * TEST-DESIGN-001: Uses random preset IDs for parallel test safety.
25
+ *
23
26
  * @param overrides - Optional overrides for the default values
24
27
  * @returns A VoteRow object
25
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"vote.d.ts","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAS3E;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,0BAAoB,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAC/B,OAAO,EAAE,CAEX;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,EAAE,CAOX;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,EAAE,CAOX"}
1
+ {"version":3,"file":"vote.d.ts","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAO3E;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,0BAAoB,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAC/B,OAAO,EAAE,CAEX;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,EAAE,CAOX;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,EAAE,CAOX"}
@@ -2,24 +2,26 @@
2
2
  * Vote factory functions for testing
3
3
  *
4
4
  * Provides functions to create mock votes.
5
+ * TEST-DESIGN-001: Uses random IDs for parallel test safety.
5
6
  *
6
7
  * @example
7
8
  * ```typescript
8
- * const vote = createMockVote({ preset_id: 'preset-1' });
9
+ * const vote = createMockVote({ preset_id: 'preset-xyz' });
9
10
  * const votes = createMockVotes(5, { user_discord_id: '123' });
10
11
  * ```
11
12
  */
12
- import { nextId } from '../utils/counters.js';
13
+ import { randomStringId } from '../utils/counters.js';
13
14
  /**
14
15
  * Creates a mock vote row
15
16
  *
17
+ * TEST-DESIGN-001: Uses random preset IDs for parallel test safety.
18
+ *
16
19
  * @param overrides - Optional overrides for the default values
17
20
  * @returns A VoteRow object
18
21
  */
19
22
  export function createMockVoteRow(overrides = {}) {
20
- const voteNum = nextId('vote');
21
23
  return {
22
- preset_id: `preset-${voteNum}`,
24
+ preset_id: randomStringId('preset'),
23
25
  user_discord_id: '123456789',
24
26
  created_at: new Date().toISOString(),
25
27
  ...overrides,
@@ -1 +1 @@
1
- {"version":3,"file":"vote.js","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAW9C;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAA8B,EAAE;IAChE,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAE/B,OAAO;QACL,SAAS,EAAE,UAAU,OAAO,EAAE;QAC9B,eAAe,EAAE,WAAW;QAC5B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,YAA8B,EAAE;IAEhC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,SAAiB;IAEjB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAChD,iBAAiB,CAAC;QAChB,SAAS,EAAE,QAAQ;QACnB,eAAe,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;KACjC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,SAAmB;IAEnB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChC,iBAAiB,CAAC;QAChB,SAAS,EAAE,QAAQ;QACnB,eAAe,EAAE,MAAM;KACxB,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"vote.js","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAWtD;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAA8B,EAAE;IAChE,OAAO;QACL,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC;QACnC,eAAe,EAAE,WAAW;QAC5B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,YAA8B,EAAE;IAEhC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,SAAiB;IAEjB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAChD,iBAAiB,CAAC;QAChB,SAAS,EAAE,QAAQ;QACnB,eAAe,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;KACjC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,SAAmB;IAEnB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChC,iBAAiB,CAAC;QAChB,SAAS,EAAE,QAAQ;QACnB,eAAe,EAAE,MAAM;KACxB,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -1,19 +1,43 @@
1
1
  /**
2
- * Auto-increment counter management for test factories
2
+ * ID generation utilities for test factories
3
3
  *
4
- * Provides unique IDs for test objects while allowing reset between tests
5
- * to ensure test isolation.
4
+ * TEST-DESIGN-001: Uses random IDs to prevent race conditions in parallel test execution.
5
+ * Sequential counters are kept for backward compatibility but random IDs are now the default.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Recommended: Random IDs (safe for parallel tests)
10
+ * const id = randomStringId('preset'); // 'preset-a7x9k2m'
11
+ *
12
+ * // Legacy: Sequential IDs (call resetCounters() in beforeEach for isolation)
13
+ * const seqId = nextStringId('preset'); // 'preset-1'
14
+ * ```
15
+ */
16
+ /**
17
+ * Generate a random numeric ID
18
+ * TEST-DESIGN-001: Safe for parallel test execution
19
+ * @returns A random positive integer
20
+ */
21
+ export declare function randomId(): number;
22
+ /**
23
+ * Generate a random string ID with prefix
24
+ * TEST-DESIGN-001: Safe for parallel test execution
25
+ * @param prefix - The ID prefix (e.g., 'preset', 'category')
26
+ * @returns A string ID like 'preset-a7x9k2m'
6
27
  */
28
+ export declare function randomStringId(prefix: string): string;
7
29
  /**
8
- * Get the next value for a named counter
30
+ * Get the next value for a named counter (legacy)
31
+ * @deprecated Use randomId() for parallel-safe ID generation
9
32
  * @param name - The counter name (e.g., 'preset', 'category')
10
33
  * @returns The next sequential value
11
34
  */
12
35
  export declare function nextId(name: string): number;
13
36
  /**
14
- * Get a string ID with prefix
37
+ * Get a string ID with prefix (legacy)
38
+ * TEST-DESIGN-001: Now uses random IDs by default for parallel-safe execution
15
39
  * @param prefix - The ID prefix (e.g., 'preset', 'category')
16
- * @returns A string ID like 'preset-1', 'category-2'
40
+ * @returns A string ID like 'preset-a7x9k2m'
17
41
  */
18
42
  export declare function nextStringId(prefix: string): string;
19
43
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"counters.d.ts","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAIpC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"counters.d.ts","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAmBH;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAIpC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -1,13 +1,53 @@
1
1
  /**
2
- * Auto-increment counter management for test factories
2
+ * ID generation utilities for test factories
3
3
  *
4
- * Provides unique IDs for test objects while allowing reset between tests
5
- * to ensure test isolation.
4
+ * TEST-DESIGN-001: Uses random IDs to prevent race conditions in parallel test execution.
5
+ * Sequential counters are kept for backward compatibility but random IDs are now the default.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Recommended: Random IDs (safe for parallel tests)
10
+ * const id = randomStringId('preset'); // 'preset-a7x9k2m'
11
+ *
12
+ * // Legacy: Sequential IDs (call resetCounters() in beforeEach for isolation)
13
+ * const seqId = nextStringId('preset'); // 'preset-1'
14
+ * ```
6
15
  */
7
- // Counter storage
16
+ // Counter storage (legacy, for backward compatibility)
8
17
  const counters = {};
9
18
  /**
10
- * Get the next value for a named counter
19
+ * Generate a random alphanumeric string
20
+ * @param length - Length of the random string (default: 8)
21
+ * @returns Random alphanumeric string
22
+ */
23
+ function randomAlphanumeric(length = 8) {
24
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
25
+ let result = '';
26
+ for (let i = 0; i < length; i++) {
27
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
28
+ }
29
+ return result;
30
+ }
31
+ /**
32
+ * Generate a random numeric ID
33
+ * TEST-DESIGN-001: Safe for parallel test execution
34
+ * @returns A random positive integer
35
+ */
36
+ export function randomId() {
37
+ return Math.floor(Math.random() * 900000000) + 100000000; // 9-digit number
38
+ }
39
+ /**
40
+ * Generate a random string ID with prefix
41
+ * TEST-DESIGN-001: Safe for parallel test execution
42
+ * @param prefix - The ID prefix (e.g., 'preset', 'category')
43
+ * @returns A string ID like 'preset-a7x9k2m'
44
+ */
45
+ export function randomStringId(prefix) {
46
+ return `${prefix}-${randomAlphanumeric(8)}`;
47
+ }
48
+ /**
49
+ * Get the next value for a named counter (legacy)
50
+ * @deprecated Use randomId() for parallel-safe ID generation
11
51
  * @param name - The counter name (e.g., 'preset', 'category')
12
52
  * @returns The next sequential value
13
53
  */
@@ -19,12 +59,14 @@ export function nextId(name) {
19
59
  return counters[name];
20
60
  }
21
61
  /**
22
- * Get a string ID with prefix
62
+ * Get a string ID with prefix (legacy)
63
+ * TEST-DESIGN-001: Now uses random IDs by default for parallel-safe execution
23
64
  * @param prefix - The ID prefix (e.g., 'preset', 'category')
24
- * @returns A string ID like 'preset-1', 'category-2'
65
+ * @returns A string ID like 'preset-a7x9k2m'
25
66
  */
26
67
  export function nextStringId(prefix) {
27
- return `${prefix}-${nextId(prefix)}`;
68
+ // TEST-DESIGN-001: Use random IDs by default for parallel test safety
69
+ return randomStringId(prefix);
28
70
  }
29
71
  /**
30
72
  * Reset all counters to zero
@@ -1 +1 @@
1
- {"version":3,"file":"counters.js","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,kBAAkB;AAClB,MAAM,QAAQ,GAA2B,EAAE,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,IAAI,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"counters.js","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,uDAAuD;AACvD,MAAM,QAAQ,GAA2B,EAAE,CAAC;AAE5C;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,SAAiB,CAAC;IAC5C,MAAM,KAAK,GAAG,sCAAsC,CAAC;IACrD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,iBAAiB;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,GAAG,MAAM,IAAI,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,IAAI,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,sEAAsE;IACtE,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
@@ -18,11 +18,21 @@ export declare function base64UrlEncode(str: string): string;
18
18
  * @returns Base64URL encoded string
19
19
  */
20
20
  export declare function base64UrlEncodeBytes(bytes: Uint8Array): string;
21
+ /**
22
+ * Decode a Base64URL string to bytes
23
+ *
24
+ * @param str - The Base64URL string to decode
25
+ * @returns Decoded bytes as Uint8Array
26
+ */
27
+ export declare function base64UrlDecodeBytes(str: string): Uint8Array;
21
28
  /**
22
29
  * Decode a Base64URL string
23
30
  *
31
+ * NOTE: For proper UTF-8 roundtrip with base64UrlEncode(), this function
32
+ * decodes the binary bytes back to a UTF-8 string using TextDecoder.
33
+ *
24
34
  * @param str - The Base64URL string to decode
25
- * @returns Decoded string
35
+ * @returns Decoded UTF-8 string
26
36
  */
27
37
  export declare function base64UrlDecode(str: string): string;
28
38
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAMlD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAiB5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAMlD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD"}
@@ -32,18 +32,38 @@ export function base64UrlEncodeBytes(bytes) {
32
32
  return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
33
33
  }
34
34
  /**
35
- * Decode a Base64URL string
35
+ * Decode a Base64URL string to bytes
36
36
  *
37
37
  * @param str - The Base64URL string to decode
38
- * @returns Decoded string
38
+ * @returns Decoded bytes as Uint8Array
39
39
  */
40
- export function base64UrlDecode(str) {
40
+ export function base64UrlDecodeBytes(str) {
41
41
  // Add padding if needed
42
42
  let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
43
43
  while (base64.length % 4) {
44
44
  base64 += '=';
45
45
  }
46
- return atob(base64);
46
+ // Decode to binary string
47
+ const binary = atob(base64);
48
+ // Convert binary string to Uint8Array
49
+ const bytes = new Uint8Array(binary.length);
50
+ for (let i = 0; i < binary.length; i++) {
51
+ bytes[i] = binary.charCodeAt(i);
52
+ }
53
+ return bytes;
54
+ }
55
+ /**
56
+ * Decode a Base64URL string
57
+ *
58
+ * NOTE: For proper UTF-8 roundtrip with base64UrlEncode(), this function
59
+ * decodes the binary bytes back to a UTF-8 string using TextDecoder.
60
+ *
61
+ * @param str - The Base64URL string to decode
62
+ * @returns Decoded UTF-8 string
63
+ */
64
+ export function base64UrlDecode(str) {
65
+ const bytes = base64UrlDecodeBytes(str);
66
+ return new TextDecoder().decode(bytes);
47
67
  }
48
68
  /**
49
69
  * Convert a hex string to Uint8Array
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAiB;IACpD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,wBAAwB;IACxB,IAAI,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xivdyetools/test-utils",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Shared testing utilities for the xivdyetools ecosystem",
5
5
  "author": "XIV Dye Tools",
6
6
  "license": "MIT",
@@ -60,15 +60,15 @@
60
60
  }
61
61
  },
62
62
  "dependencies": {
63
- "@xivdyetools/types": "^1.0.0"
63
+ "@xivdyetools/types": "^1.1.1"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@cloudflare/workers-types": "^4.20241205.0",
67
67
  "@testing-library/dom": "^10.0.0",
68
- "@vitest/coverage-v8": "^2.0.0",
68
+ "@vitest/coverage-v8": "^4.0.15",
69
69
  "rimraf": "^5.0.5",
70
- "typescript": "^5.3.2",
71
- "vitest": "^2.0.0"
70
+ "typescript": "^5.9.3",
71
+ "vitest": "^4.0.15"
72
72
  },
73
73
  "engines": {
74
74
  "node": ">=18.0.0"
@@ -85,4 +85,4 @@
85
85
  "type": "git",
86
86
  "url": "https://github.com/xivdyetools/xivdyetools-test-utils.git"
87
87
  }
88
- }
88
+ }