@sanity/cli-core 0.1.0-alpha.5 → 0.1.0-alpha.6

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.
@@ -1,400 +0,0 @@
1
- import { beforeEach, describe, expect, test, vi } from 'vitest';
2
- import { createExpiringConfig } from '../createExpiringConfig.js';
3
- describe('createExpiringConfig', ()=>{
4
- let mockStore;
5
- let fetchValue;
6
- let onCacheHit;
7
- let onFetch;
8
- let onRevalidate;
9
- beforeEach(()=>{
10
- // Mock ConfigStore
11
- mockStore = {
12
- delete: vi.fn(),
13
- get: vi.fn(),
14
- set: vi.fn()
15
- };
16
- // Reset all mocks
17
- fetchValue = vi.fn();
18
- onCacheHit = vi.fn();
19
- onFetch = vi.fn();
20
- onRevalidate = vi.fn();
21
- });
22
- test('returns fetched value when cache is empty', async ()=>{
23
- const testValue = 'test-value';
24
- const config = createExpiringConfig({
25
- fetchValue: fetchValue.mockResolvedValue(testValue),
26
- key: 'test-key',
27
- onCacheHit,
28
- onFetch,
29
- onRevalidate,
30
- store: mockStore,
31
- ttl: 5000
32
- });
33
- // Mock empty cache
34
- vi.mocked(mockStore.get).mockReturnValue(undefined);
35
- const result = await config.get();
36
- expect(result).toBe(testValue);
37
- expect(fetchValue).toHaveBeenCalledOnce();
38
- expect(onFetch).toHaveBeenCalledOnce();
39
- expect(onCacheHit).not.toHaveBeenCalled();
40
- expect(onRevalidate).not.toHaveBeenCalled();
41
- expect(mockStore.set).toHaveBeenCalledWith('test-key', {
42
- updatedAt: expect.any(Number),
43
- value: testValue
44
- });
45
- });
46
- test('returns cached value when it has not expired', async ()=>{
47
- const cachedValue = 'cached-value';
48
- const ttl = 5000;
49
- const updatedAt = Date.now() - 1000 // 1 second ago (not expired)
50
- ;
51
- const config = createExpiringConfig({
52
- fetchValue,
53
- key: 'test-key',
54
- onCacheHit,
55
- onFetch,
56
- onRevalidate,
57
- store: mockStore,
58
- ttl
59
- });
60
- // Mock cached value that hasn't expired
61
- vi.mocked(mockStore.get).mockReturnValue({
62
- updatedAt,
63
- value: cachedValue
64
- });
65
- const result = await config.get();
66
- expect(result).toBe(cachedValue);
67
- expect(fetchValue).not.toHaveBeenCalled();
68
- expect(onCacheHit).toHaveBeenCalledOnce();
69
- expect(onFetch).not.toHaveBeenCalled();
70
- expect(onRevalidate).not.toHaveBeenCalled();
71
- expect(mockStore.set).not.toHaveBeenCalled();
72
- });
73
- test('fetches new value when cached value has expired', async ()=>{
74
- const newValue = 'new-value';
75
- const ttl = 1000;
76
- const updatedAt = Date.now() - 2000 // 2 seconds ago (expired)
77
- ;
78
- const config = createExpiringConfig({
79
- fetchValue: fetchValue.mockResolvedValue(newValue),
80
- key: 'test-key',
81
- onCacheHit,
82
- onFetch,
83
- onRevalidate,
84
- store: mockStore,
85
- ttl
86
- });
87
- // Mock expired cached value
88
- vi.mocked(mockStore.get).mockReturnValue({
89
- updatedAt,
90
- value: 'old-value'
91
- });
92
- const result = await config.get();
93
- expect(result).toBe(newValue);
94
- expect(fetchValue).toHaveBeenCalledOnce();
95
- expect(onRevalidate).toHaveBeenCalledOnce();
96
- expect(onFetch).toHaveBeenCalledOnce();
97
- expect(onCacheHit).not.toHaveBeenCalled();
98
- expect(mockStore.set).toHaveBeenCalledWith('test-key', {
99
- updatedAt: expect.any(Number),
100
- value: newValue
101
- });
102
- });
103
- test('deletes cached value from store', ()=>{
104
- const config = createExpiringConfig({
105
- fetchValue,
106
- key: 'test-key',
107
- store: mockStore,
108
- ttl: 5000
109
- });
110
- config.delete();
111
- expect(mockStore.delete).toHaveBeenCalledWith('test-key');
112
- });
113
- test('handles concurrent get() calls correctly', async ()=>{
114
- const testValue = 'test-value';
115
- let resolvePromise;
116
- const delayedFetch = new Promise((resolve)=>{
117
- resolvePromise = resolve;
118
- });
119
- const config = createExpiringConfig({
120
- fetchValue: fetchValue.mockReturnValue(delayedFetch),
121
- key: 'test-key',
122
- onFetch,
123
- store: mockStore,
124
- ttl: 5000
125
- });
126
- // Mock empty cache
127
- vi.mocked(mockStore.get).mockReturnValue(undefined);
128
- // Start multiple concurrent get() calls
129
- const promise1 = config.get();
130
- const promise2 = config.get();
131
- const promise3 = config.get();
132
- // Resolve the fetch
133
- resolvePromise(testValue);
134
- const [result1, result2, result3] = await Promise.all([
135
- promise1,
136
- promise2,
137
- promise3
138
- ]);
139
- expect(result1).toBe(testValue);
140
- expect(result2).toBe(testValue);
141
- expect(result3).toBe(testValue);
142
- expect(fetchValue).toHaveBeenCalledOnce(); // Only one fetch should happen
143
- expect(onFetch).toHaveBeenCalledOnce();
144
- });
145
- test('handles synchronous fetchValue function', async ()=>{
146
- const testValue = 'sync-value';
147
- const syncFetchValue = vi.fn().mockReturnValue(testValue);
148
- const config = createExpiringConfig({
149
- fetchValue: syncFetchValue,
150
- key: 'test-key',
151
- store: mockStore,
152
- ttl: 5000
153
- });
154
- // Mock empty cache
155
- vi.mocked(mockStore.get).mockReturnValue(undefined);
156
- const result = await config.get();
157
- expect(result).toBe(testValue);
158
- expect(syncFetchValue).toHaveBeenCalledOnce();
159
- });
160
- test('handles fetchValue throwing an error', async ()=>{
161
- const error = new Error('Fetch failed');
162
- const config = createExpiringConfig({
163
- fetchValue: fetchValue.mockRejectedValue(error),
164
- key: 'test-key',
165
- store: mockStore,
166
- ttl: 5000
167
- });
168
- // Mock empty cache
169
- vi.mocked(mockStore.get).mockReturnValue(undefined);
170
- await expect(config.get()).rejects.toThrow('Fetch failed');
171
- expect(fetchValue).toHaveBeenCalledOnce();
172
- expect(mockStore.set).not.toHaveBeenCalled();
173
- });
174
- test('handles different data types as cached values', async ()=>{
175
- const objectValue = {
176
- key: 'value',
177
- number: 42
178
- };
179
- const config = createExpiringConfig({
180
- fetchValue: fetchValue.mockResolvedValue(objectValue),
181
- key: 'test-key',
182
- store: mockStore,
183
- ttl: 5000
184
- });
185
- // Mock empty cache
186
- vi.mocked(mockStore.get).mockReturnValue(undefined);
187
- const result = await config.get();
188
- expect(result).toEqual(objectValue);
189
- expect(mockStore.set).toHaveBeenCalledWith('test-key', {
190
- updatedAt: expect.any(Number),
191
- value: objectValue
192
- });
193
- });
194
- test('works with TTL of 0 (immediate expiration)', async ()=>{
195
- const testValue = 'test-value';
196
- const config = createExpiringConfig({
197
- fetchValue: fetchValue.mockResolvedValue(testValue),
198
- key: 'test-key',
199
- onRevalidate,
200
- store: mockStore,
201
- ttl: 0
202
- });
203
- // Mock cached value that would be immediately expired
204
- // Use a timestamp from 1ms ago to ensure it's > ttl (0)
205
- vi.mocked(mockStore.get).mockReturnValue({
206
- updatedAt: Date.now() - 1,
207
- value: 'old-value'
208
- });
209
- const result = await config.get();
210
- expect(result).toBe(testValue);
211
- expect(fetchValue).toHaveBeenCalledOnce();
212
- expect(onRevalidate).toHaveBeenCalledOnce();
213
- });
214
- test('works without optional callback functions', async ()=>{
215
- const testValue = 'test-value';
216
- const config = createExpiringConfig({
217
- fetchValue: fetchValue.mockResolvedValue(testValue),
218
- key: 'test-key',
219
- store: mockStore,
220
- ttl: 5000
221
- });
222
- // Mock empty cache
223
- vi.mocked(mockStore.get).mockReturnValue(undefined);
224
- const result = await config.get();
225
- expect(result).toBe(testValue);
226
- expect(fetchValue).toHaveBeenCalledOnce();
227
- });
228
- test('handles cached value without updatedAt timestamp', async ()=>{
229
- const newValue = 'new-value';
230
- const config = createExpiringConfig({
231
- fetchValue: fetchValue.mockResolvedValue(newValue),
232
- key: 'test-key',
233
- onFetch,
234
- store: mockStore,
235
- ttl: 5000
236
- });
237
- // Mock cached value without updatedAt (invalid cache entry)
238
- vi.mocked(mockStore.get).mockReturnValue({
239
- value: 'old-value'
240
- });
241
- const result = await config.get();
242
- expect(result).toBe(newValue);
243
- expect(fetchValue).toHaveBeenCalledOnce();
244
- expect(onFetch).toHaveBeenCalledOnce();
245
- });
246
- test('handles cached value without value property', async ()=>{
247
- const newValue = 'new-value';
248
- const config = createExpiringConfig({
249
- fetchValue: fetchValue.mockResolvedValue(newValue),
250
- key: 'test-key',
251
- onFetch,
252
- store: mockStore,
253
- ttl: 5000
254
- });
255
- // Mock cached entry without value property
256
- vi.mocked(mockStore.get).mockReturnValue({
257
- updatedAt: Date.now()
258
- });
259
- const result = await config.get();
260
- expect(result).toBe(newValue);
261
- expect(fetchValue).toHaveBeenCalledOnce();
262
- expect(onFetch).toHaveBeenCalledOnce();
263
- });
264
- test('stores timestamp correctly when caching new values', async ()=>{
265
- const testValue = 'test-value';
266
- const config = createExpiringConfig({
267
- fetchValue: fetchValue.mockResolvedValue(testValue),
268
- key: 'test-key',
269
- store: mockStore,
270
- ttl: 5000
271
- });
272
- // Mock empty cache
273
- vi.mocked(mockStore.get).mockReturnValue(undefined);
274
- await config.get();
275
- expect(mockStore.set).toHaveBeenCalledWith('test-key', {
276
- updatedAt: expect.any(Number),
277
- value: testValue
278
- });
279
- });
280
- test('subsequent requests after cache is populated use cached value', async ()=>{
281
- const testValue = 'test-value';
282
- const config = createExpiringConfig({
283
- fetchValue: fetchValue.mockResolvedValue(testValue),
284
- key: 'test-key',
285
- onCacheHit,
286
- onFetch,
287
- store: mockStore,
288
- ttl: 5000
289
- });
290
- // Mock empty cache for first request
291
- vi.mocked(mockStore.get).mockReturnValueOnce(undefined);
292
- // First request should fetch
293
- const result1 = await config.get();
294
- // Mock cache populated for subsequent request
295
- vi.mocked(mockStore.get).mockReturnValueOnce({
296
- updatedAt: Date.now(),
297
- value: testValue
298
- });
299
- // Second request should hit cache
300
- const result2 = await config.get();
301
- expect(result1).toBe(testValue);
302
- expect(result2).toBe(testValue);
303
- expect(fetchValue).toHaveBeenCalledOnce();
304
- expect(onFetch).toHaveBeenCalledOnce();
305
- expect(onCacheHit).toHaveBeenCalledOnce();
306
- });
307
- test('throws when cached value fails validateValue', async ()=>{
308
- const invalidCached = 123;
309
- const ttl = 10_000;
310
- const validateValue = vi.fn((v)=>typeof v === 'string');
311
- const config = createExpiringConfig({
312
- fetchValue,
313
- key: 'test-key',
314
- onCacheHit,
315
- onFetch,
316
- onRevalidate,
317
- store: mockStore,
318
- ttl,
319
- // @ts-expect-error vitest mocks don't jive with assertions
320
- validateValue
321
- });
322
- // Cached entry that is not expired but invalid per validateValue
323
- vi.mocked(mockStore.get).mockReturnValue({
324
- updatedAt: Date.now(),
325
- value: invalidCached
326
- });
327
- await expect(config.get()).rejects.toThrow('Stored value is invalid');
328
- expect(validateValue).toHaveBeenCalledOnce();
329
- expect(onCacheHit).not.toHaveBeenCalled();
330
- expect(onFetch).not.toHaveBeenCalled();
331
- expect(onRevalidate).not.toHaveBeenCalled();
332
- expect(mockStore.set).not.toHaveBeenCalled();
333
- });
334
- test('throws when fetched value fails validateValue (cache miss)', async ()=>{
335
- const validateValue = vi.fn((v)=>typeof v === 'string');
336
- const config = createExpiringConfig({
337
- fetchValue: fetchValue.mockResolvedValue(42),
338
- key: 'test-key',
339
- onFetch,
340
- store: mockStore,
341
- ttl: 5000,
342
- // @ts-expect-error vitest mocks don't jive with assertions
343
- validateValue
344
- });
345
- // Empty cache
346
- vi.mocked(mockStore.get).mockReturnValue(undefined);
347
- await expect(config.get()).rejects.toThrow('Fetched value is invalid');
348
- expect(onFetch).toHaveBeenCalledOnce();
349
- expect(validateValue).toHaveBeenCalledOnce();
350
- expect(mockStore.set).not.toHaveBeenCalled();
351
- });
352
- test('returns cached value when validateValue accepts it', async ()=>{
353
- const cachedValue = 'ok';
354
- const validateValue = vi.fn((v)=>typeof v === 'string');
355
- const config = createExpiringConfig({
356
- fetchValue,
357
- key: 'test-key',
358
- onCacheHit,
359
- store: mockStore,
360
- ttl: 5000,
361
- // @ts-expect-error vitest mocks don't jive with assertions
362
- validateValue
363
- });
364
- vi.mocked(mockStore.get).mockReturnValue({
365
- updatedAt: Date.now(),
366
- value: cachedValue
367
- });
368
- const result = await config.get();
369
- expect(result).toBe(cachedValue);
370
- expect(validateValue).toHaveBeenCalledOnce();
371
- expect(onCacheHit).toHaveBeenCalledOnce();
372
- expect(fetchValue).not.toHaveBeenCalled();
373
- });
374
- test('revalidation path validates fetched value and throws if invalid', async ()=>{
375
- const validateValue = vi.fn((v)=>typeof v === 'string');
376
- const config = createExpiringConfig({
377
- fetchValue: fetchValue.mockResolvedValue(99),
378
- key: 'test-key',
379
- onFetch,
380
- onRevalidate,
381
- store: mockStore,
382
- ttl: 1,
383
- // @ts-expect-error vitest mocks don't jive with assertions
384
- validateValue
385
- });
386
- // Cached value that has expired but is otherwise valid in shape and passes validate
387
- vi.mocked(mockStore.get).mockReturnValue({
388
- updatedAt: Date.now() - 10,
389
- value: 'stale'
390
- });
391
- await expect(config.get()).rejects.toThrow('Fetched value is invalid');
392
- expect(onRevalidate).toHaveBeenCalledOnce();
393
- expect(onFetch).toHaveBeenCalledOnce();
394
- // validateValue called for stored value and fetched value
395
- expect(validateValue).toHaveBeenCalledTimes(2);
396
- expect(mockStore.set).not.toHaveBeenCalled();
397
- });
398
- });
399
-
400
- //# sourceMappingURL=createExpiringConfig.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/util/__tests__/createExpiringConfig.test.ts"],"sourcesContent":["import type ConfigStore from 'configstore'\n\nimport {beforeEach, describe, expect, test, vi} from 'vitest'\n\nimport {createExpiringConfig} from '../createExpiringConfig.js'\n\ndescribe('createExpiringConfig', () => {\n let mockStore: ConfigStore\n let fetchValue: ReturnType<typeof vi.fn>\n let onCacheHit: ReturnType<typeof vi.fn>\n let onFetch: ReturnType<typeof vi.fn>\n let onRevalidate: ReturnType<typeof vi.fn>\n\n beforeEach(() => {\n // Mock ConfigStore\n mockStore = {\n delete: vi.fn(),\n get: vi.fn(),\n set: vi.fn(),\n } as unknown as ConfigStore\n\n // Reset all mocks\n fetchValue = vi.fn()\n onCacheHit = vi.fn()\n onFetch = vi.fn()\n onRevalidate = vi.fn()\n })\n\n test('returns fetched value when cache is empty', async () => {\n const testValue = 'test-value'\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(testValue),\n key: 'test-key',\n onCacheHit,\n onFetch,\n onRevalidate,\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n const result = await config.get()\n\n expect(result).toBe(testValue)\n expect(fetchValue).toHaveBeenCalledOnce()\n expect(onFetch).toHaveBeenCalledOnce()\n expect(onCacheHit).not.toHaveBeenCalled()\n expect(onRevalidate).not.toHaveBeenCalled()\n expect(mockStore.set).toHaveBeenCalledWith('test-key', {\n updatedAt: expect.any(Number),\n value: testValue,\n })\n })\n\n test('returns cached value when it has not expired', async () => {\n const cachedValue = 'cached-value'\n const ttl = 5000\n const updatedAt = Date.now() - 1000 // 1 second ago (not expired)\n\n const config = createExpiringConfig({\n fetchValue,\n key: 'test-key',\n onCacheHit,\n onFetch,\n onRevalidate,\n store: mockStore,\n ttl,\n })\n\n // Mock cached value that hasn't expired\n vi.mocked(mockStore.get).mockReturnValue({\n updatedAt,\n value: cachedValue,\n })\n\n const result = await config.get()\n\n expect(result).toBe(cachedValue)\n expect(fetchValue).not.toHaveBeenCalled()\n expect(onCacheHit).toHaveBeenCalledOnce()\n expect(onFetch).not.toHaveBeenCalled()\n expect(onRevalidate).not.toHaveBeenCalled()\n expect(mockStore.set).not.toHaveBeenCalled()\n })\n\n test('fetches new value when cached value has expired', async () => {\n const newValue = 'new-value'\n const ttl = 1000\n const updatedAt = Date.now() - 2000 // 2 seconds ago (expired)\n\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(newValue),\n key: 'test-key',\n onCacheHit,\n onFetch,\n onRevalidate,\n store: mockStore,\n ttl,\n })\n\n // Mock expired cached value\n vi.mocked(mockStore.get).mockReturnValue({\n updatedAt,\n value: 'old-value',\n })\n\n const result = await config.get()\n\n expect(result).toBe(newValue)\n expect(fetchValue).toHaveBeenCalledOnce()\n expect(onRevalidate).toHaveBeenCalledOnce()\n expect(onFetch).toHaveBeenCalledOnce()\n expect(onCacheHit).not.toHaveBeenCalled()\n expect(mockStore.set).toHaveBeenCalledWith('test-key', {\n updatedAt: expect.any(Number),\n value: newValue,\n })\n })\n\n test('deletes cached value from store', () => {\n const config = createExpiringConfig({\n fetchValue,\n key: 'test-key',\n store: mockStore,\n ttl: 5000,\n })\n\n config.delete()\n\n expect(mockStore.delete).toHaveBeenCalledWith('test-key')\n })\n\n test('handles concurrent get() calls correctly', async () => {\n const testValue = 'test-value'\n let resolvePromise: (value: string) => void\n const delayedFetch = new Promise<string>((resolve) => {\n resolvePromise = resolve\n })\n\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockReturnValue(delayedFetch),\n key: 'test-key',\n onFetch,\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n // Start multiple concurrent get() calls\n const promise1 = config.get()\n const promise2 = config.get()\n const promise3 = config.get()\n\n // Resolve the fetch\n resolvePromise!(testValue)\n\n const [result1, result2, result3] = await Promise.all([promise1, promise2, promise3])\n\n expect(result1).toBe(testValue)\n expect(result2).toBe(testValue)\n expect(result3).toBe(testValue)\n expect(fetchValue).toHaveBeenCalledOnce() // Only one fetch should happen\n expect(onFetch).toHaveBeenCalledOnce()\n })\n\n test('handles synchronous fetchValue function', async () => {\n const testValue = 'sync-value'\n const syncFetchValue = vi.fn().mockReturnValue(testValue)\n\n const config = createExpiringConfig({\n fetchValue: syncFetchValue,\n key: 'test-key',\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n const result = await config.get()\n\n expect(result).toBe(testValue)\n expect(syncFetchValue).toHaveBeenCalledOnce()\n })\n\n test('handles fetchValue throwing an error', async () => {\n const error = new Error('Fetch failed')\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockRejectedValue(error),\n key: 'test-key',\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n await expect(config.get()).rejects.toThrow('Fetch failed')\n expect(fetchValue).toHaveBeenCalledOnce()\n expect(mockStore.set).not.toHaveBeenCalled()\n })\n\n test('handles different data types as cached values', async () => {\n const objectValue = {key: 'value', number: 42}\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(objectValue),\n key: 'test-key',\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n const result = await config.get()\n\n expect(result).toEqual(objectValue)\n expect(mockStore.set).toHaveBeenCalledWith('test-key', {\n updatedAt: expect.any(Number),\n value: objectValue,\n })\n })\n\n test('works with TTL of 0 (immediate expiration)', async () => {\n const testValue = 'test-value'\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(testValue),\n key: 'test-key',\n onRevalidate,\n store: mockStore,\n ttl: 0,\n })\n\n // Mock cached value that would be immediately expired\n // Use a timestamp from 1ms ago to ensure it's > ttl (0)\n vi.mocked(mockStore.get).mockReturnValue({\n updatedAt: Date.now() - 1,\n value: 'old-value',\n })\n\n const result = await config.get()\n\n expect(result).toBe(testValue)\n expect(fetchValue).toHaveBeenCalledOnce()\n expect(onRevalidate).toHaveBeenCalledOnce()\n })\n\n test('works without optional callback functions', async () => {\n const testValue = 'test-value'\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(testValue),\n key: 'test-key',\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n const result = await config.get()\n\n expect(result).toBe(testValue)\n expect(fetchValue).toHaveBeenCalledOnce()\n })\n\n test('handles cached value without updatedAt timestamp', async () => {\n const newValue = 'new-value'\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(newValue),\n key: 'test-key',\n onFetch,\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock cached value without updatedAt (invalid cache entry)\n vi.mocked(mockStore.get).mockReturnValue({\n value: 'old-value',\n // updatedAt is missing\n })\n\n const result = await config.get()\n\n expect(result).toBe(newValue)\n expect(fetchValue).toHaveBeenCalledOnce()\n expect(onFetch).toHaveBeenCalledOnce()\n })\n\n test('handles cached value without value property', async () => {\n const newValue = 'new-value'\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(newValue),\n key: 'test-key',\n onFetch,\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock cached entry without value property\n vi.mocked(mockStore.get).mockReturnValue({\n updatedAt: Date.now(),\n // value is missing\n })\n\n const result = await config.get()\n\n expect(result).toBe(newValue)\n expect(fetchValue).toHaveBeenCalledOnce()\n expect(onFetch).toHaveBeenCalledOnce()\n })\n\n test('stores timestamp correctly when caching new values', async () => {\n const testValue = 'test-value'\n\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(testValue),\n key: 'test-key',\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n await config.get()\n\n expect(mockStore.set).toHaveBeenCalledWith('test-key', {\n updatedAt: expect.any(Number),\n value: testValue,\n })\n })\n\n test('subsequent requests after cache is populated use cached value', async () => {\n const testValue = 'test-value'\n const config = createExpiringConfig({\n fetchValue: fetchValue.mockResolvedValue(testValue),\n key: 'test-key',\n onCacheHit,\n onFetch,\n store: mockStore,\n ttl: 5000,\n })\n\n // Mock empty cache for first request\n vi.mocked(mockStore.get).mockReturnValueOnce(undefined)\n\n // First request should fetch\n const result1 = await config.get()\n\n // Mock cache populated for subsequent request\n vi.mocked(mockStore.get).mockReturnValueOnce({\n updatedAt: Date.now(),\n value: testValue,\n })\n\n // Second request should hit cache\n const result2 = await config.get()\n\n expect(result1).toBe(testValue)\n expect(result2).toBe(testValue)\n expect(fetchValue).toHaveBeenCalledOnce()\n expect(onFetch).toHaveBeenCalledOnce()\n expect(onCacheHit).toHaveBeenCalledOnce()\n })\n\n test('throws when cached value fails validateValue', async () => {\n const invalidCached = 123\n const ttl = 10_000\n\n const validateValue = vi.fn((v: unknown): v is string => typeof v === 'string')\n\n const config = createExpiringConfig<string>({\n fetchValue,\n key: 'test-key',\n onCacheHit,\n onFetch,\n onRevalidate,\n store: mockStore,\n ttl,\n // @ts-expect-error vitest mocks don't jive with assertions\n validateValue,\n })\n\n // Cached entry that is not expired but invalid per validateValue\n vi.mocked(mockStore.get).mockReturnValue({\n updatedAt: Date.now(),\n value: invalidCached,\n })\n\n await expect(config.get()).rejects.toThrow('Stored value is invalid')\n expect(validateValue).toHaveBeenCalledOnce()\n expect(onCacheHit).not.toHaveBeenCalled()\n expect(onFetch).not.toHaveBeenCalled()\n expect(onRevalidate).not.toHaveBeenCalled()\n expect(mockStore.set).not.toHaveBeenCalled()\n })\n\n test('throws when fetched value fails validateValue (cache miss)', async () => {\n const validateValue = vi.fn((v: unknown): v is string => typeof v === 'string')\n const config = createExpiringConfig<string>({\n fetchValue: fetchValue.mockResolvedValue(42 as unknown as string),\n key: 'test-key',\n onFetch,\n store: mockStore,\n ttl: 5000,\n // @ts-expect-error vitest mocks don't jive with assertions\n validateValue,\n })\n\n // Empty cache\n vi.mocked(mockStore.get).mockReturnValue(undefined)\n\n await expect(config.get()).rejects.toThrow('Fetched value is invalid')\n expect(onFetch).toHaveBeenCalledOnce()\n expect(validateValue).toHaveBeenCalledOnce()\n expect(mockStore.set).not.toHaveBeenCalled()\n })\n\n test('returns cached value when validateValue accepts it', async () => {\n const cachedValue = 'ok'\n const validateValue = vi.fn((v: unknown): v is string => typeof v === 'string')\n const config = createExpiringConfig<string>({\n fetchValue,\n key: 'test-key',\n onCacheHit,\n store: mockStore,\n ttl: 5000,\n // @ts-expect-error vitest mocks don't jive with assertions\n validateValue,\n })\n\n vi.mocked(mockStore.get).mockReturnValue({\n updatedAt: Date.now(),\n value: cachedValue,\n })\n\n const result = await config.get()\n\n expect(result).toBe(cachedValue)\n expect(validateValue).toHaveBeenCalledOnce()\n expect(onCacheHit).toHaveBeenCalledOnce()\n expect(fetchValue).not.toHaveBeenCalled()\n })\n\n test('revalidation path validates fetched value and throws if invalid', async () => {\n const validateValue = vi.fn((v: unknown): v is string => typeof v === 'string')\n const config = createExpiringConfig<string>({\n fetchValue: fetchValue.mockResolvedValue(99 as unknown as string),\n key: 'test-key',\n onFetch,\n onRevalidate,\n store: mockStore,\n ttl: 1, // ensure expiration\n // @ts-expect-error vitest mocks don't jive with assertions\n validateValue,\n })\n\n // Cached value that has expired but is otherwise valid in shape and passes validate\n vi.mocked(mockStore.get).mockReturnValue({\n updatedAt: Date.now() - 10,\n value: 'stale',\n })\n\n await expect(config.get()).rejects.toThrow('Fetched value is invalid')\n expect(onRevalidate).toHaveBeenCalledOnce()\n expect(onFetch).toHaveBeenCalledOnce()\n // validateValue called for stored value and fetched value\n expect(validateValue).toHaveBeenCalledTimes(2)\n expect(mockStore.set).not.toHaveBeenCalled()\n })\n})\n"],"names":["beforeEach","describe","expect","test","vi","createExpiringConfig","mockStore","fetchValue","onCacheHit","onFetch","onRevalidate","delete","fn","get","set","testValue","config","mockResolvedValue","key","store","ttl","mocked","mockReturnValue","undefined","result","toBe","toHaveBeenCalledOnce","not","toHaveBeenCalled","toHaveBeenCalledWith","updatedAt","any","Number","value","cachedValue","Date","now","newValue","resolvePromise","delayedFetch","Promise","resolve","promise1","promise2","promise3","result1","result2","result3","all","syncFetchValue","error","Error","mockRejectedValue","rejects","toThrow","objectValue","number","toEqual","mockReturnValueOnce","invalidCached","validateValue","v","toHaveBeenCalledTimes"],"mappings":"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"}
@@ -1,43 +0,0 @@
1
- import { describe, expect, test } from 'vitest';
2
- import { parseStringFlag } from '../parseStringFlag.js';
3
- describe('parseStringFlag', ()=>{
4
- test.each([
5
- {
6
- desc: 'returns undefined when input is undefined',
7
- expected: undefined,
8
- flagName: 'dataset',
9
- input: undefined
10
- },
11
- {
12
- desc: 'returns valid string when input is non-empty',
13
- expected: 'my-workspace',
14
- flagName: 'workspace',
15
- input: 'my-workspace'
16
- },
17
- {
18
- desc: 'returns string with spaces',
19
- expected: 'test value',
20
- flagName: 'tag',
21
- input: 'test value'
22
- }
23
- ])('$desc', async ({ expected, flagName, input })=>{
24
- const result = await parseStringFlag(flagName, input);
25
- expect(result).toBe(expected);
26
- });
27
- test.each([
28
- {
29
- desc: 'empty string',
30
- expectedError: 'dataset argument is empty',
31
- flagName: 'dataset',
32
- input: ''
33
- }
34
- ])('throws error when $desc', async ({ expectedError, flagName, input })=>{
35
- await expect(parseStringFlag(flagName, input)).rejects.toThrow(expectedError);
36
- });
37
- test('returns whitespace string as-is (no trimming)', async ()=>{
38
- const result = await parseStringFlag('workspace', ' ');
39
- expect(result).toBe(' ');
40
- });
41
- });
42
-
43
- //# sourceMappingURL=parseStringFlag.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/util/__tests__/parseStringFlag.test.ts"],"sourcesContent":["import {describe, expect, test} from 'vitest'\n\nimport {parseStringFlag} from '../parseStringFlag.js'\n\ndescribe('parseStringFlag', () => {\n test.each([\n {\n desc: 'returns undefined when input is undefined',\n expected: undefined,\n flagName: 'dataset',\n input: undefined,\n },\n {\n desc: 'returns valid string when input is non-empty',\n expected: 'my-workspace',\n flagName: 'workspace',\n input: 'my-workspace',\n },\n {\n desc: 'returns string with spaces',\n expected: 'test value',\n flagName: 'tag',\n input: 'test value',\n },\n ])('$desc', async ({expected, flagName, input}) => {\n const result = await parseStringFlag(flagName, input)\n expect(result).toBe(expected)\n })\n\n test.each([\n {\n desc: 'empty string',\n expectedError: 'dataset argument is empty',\n flagName: 'dataset',\n input: '',\n },\n ])('throws error when $desc', async ({expectedError, flagName, input}) => {\n await expect(parseStringFlag(flagName, input)).rejects.toThrow(expectedError)\n })\n\n test('returns whitespace string as-is (no trimming)', async () => {\n const result = await parseStringFlag('workspace', ' ')\n expect(result).toBe(' ')\n })\n})\n"],"names":["describe","expect","test","parseStringFlag","each","desc","expected","undefined","flagName","input","result","toBe","expectedError","rejects","toThrow"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,MAAM,EAAEC,IAAI,QAAO,SAAQ;AAE7C,SAAQC,eAAe,QAAO,wBAAuB;AAErDH,SAAS,mBAAmB;IAC1BE,KAAKE,IAAI,CAAC;QACR;YACEC,MAAM;YACNC,UAAUC;YACVC,UAAU;YACVC,OAAOF;QACT;QACA;YACEF,MAAM;YACNC,UAAU;YACVE,UAAU;YACVC,OAAO;QACT;QACA;YACEJ,MAAM;YACNC,UAAU;YACVE,UAAU;YACVC,OAAO;QACT;KACD,EAAE,SAAS,OAAO,EAACH,QAAQ,EAAEE,QAAQ,EAAEC,KAAK,EAAC;QAC5C,MAAMC,SAAS,MAAMP,gBAAgBK,UAAUC;QAC/CR,OAAOS,QAAQC,IAAI,CAACL;IACtB;IAEAJ,KAAKE,IAAI,CAAC;QACR;YACEC,MAAM;YACNO,eAAe;YACfJ,UAAU;YACVC,OAAO;QACT;KACD,EAAE,2BAA2B,OAAO,EAACG,aAAa,EAAEJ,QAAQ,EAAEC,KAAK,EAAC;QACnE,MAAMR,OAAOE,gBAAgBK,UAAUC,QAAQI,OAAO,CAACC,OAAO,CAACF;IACjE;IAEAV,KAAK,iDAAiD;QACpD,MAAMQ,SAAS,MAAMP,gBAAgB,aAAa;QAClDF,OAAOS,QAAQC,IAAI,CAAC;IACtB;AACF"}