@bsv/sdk 2.0.15 → 2.0.16
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/cjs/package.json +1 -1
- package/dist/cjs/src/kvstore/GlobalKVStore.js +16 -3
- package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/cjs/src/kvstore/types.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/kvstore/GlobalKVStore.js +16 -3
- package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
- package/dist/esm/src/kvstore/types.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/kvstore/GlobalKVStore.d.ts +7 -0
- package/dist/types/src/kvstore/GlobalKVStore.d.ts.map +1 -1
- package/dist/types/src/kvstore/types.d.ts +2 -1
- package/dist/types/src/kvstore/types.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/reference/kvstore.md +2 -1
- package/package.json +1 -1
- package/src/kvstore/GlobalKVStore.ts +19 -3
- package/src/kvstore/__tests/GlobalKVStore.test.ts +24 -1
- package/src/kvstore/types.ts +2 -1
|
@@ -249,7 +249,8 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
249
249
|
### Interface: KVStoreQuery
|
|
250
250
|
|
|
251
251
|
Query parameters for KVStore lookups from overlay services.
|
|
252
|
-
|
|
252
|
+
Must include at least one selector: key, controller, protocolID, or non-empty tags.
|
|
253
|
+
Pagination and ordering fields only refine selector-based lookups.
|
|
253
254
|
|
|
254
255
|
```ts
|
|
255
256
|
export interface KVStoreQuery {
|
package/package.json
CHANGED
|
@@ -106,9 +106,7 @@ export class GlobalKVStore {
|
|
|
106
106
|
* @returns {Promise<KVStoreEntry | KVStoreEntry[] | undefined>} Single entry for key+controller queries, array for all other queries
|
|
107
107
|
*/
|
|
108
108
|
async get (query: KVStoreQuery, options: KVStoreGetOptions = {}): Promise<KVStoreEntry | KVStoreEntry[] | undefined> {
|
|
109
|
-
|
|
110
|
-
throw new Error('Must specify either key, controller, or protocolID')
|
|
111
|
-
}
|
|
109
|
+
this.validateQuerySelectors(query)
|
|
112
110
|
if (query.key != null && query.controller != null) {
|
|
113
111
|
// Specific key+controller query - return single entry
|
|
114
112
|
const entries = await this.queryOverlay(query, options)
|
|
@@ -117,6 +115,24 @@ export class GlobalKVStore {
|
|
|
117
115
|
return await this.queryOverlay(query, options)
|
|
118
116
|
}
|
|
119
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Ensures lookup pagination and ordering options are only used with a real KV selector.
|
|
120
|
+
*
|
|
121
|
+
* @param {KVStoreQuery} query - Query parameters sent to overlay.
|
|
122
|
+
* @throws {Error} If the query does not include a valid selector.
|
|
123
|
+
*/
|
|
124
|
+
private validateQuerySelectors (query: KVStoreQuery): void {
|
|
125
|
+
const hasSelector =
|
|
126
|
+
(typeof query.key === 'string' && query.key.length > 0) ||
|
|
127
|
+
(typeof query.controller === 'string' && query.controller.length > 0) ||
|
|
128
|
+
(Array.isArray(query.protocolID) && query.protocolID.length === 2) ||
|
|
129
|
+
(Array.isArray(query.tags) && query.tags.length > 0)
|
|
130
|
+
|
|
131
|
+
if (!hasSelector) {
|
|
132
|
+
throw new Error('Must specify at least one selector: key, controller, protocolID, or tags')
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
120
136
|
/**
|
|
121
137
|
* Sets a key-value pair. The current user (wallet identity) becomes the controller.
|
|
122
138
|
*
|
|
@@ -577,7 +577,30 @@ describe('GlobalKVStore', () => {
|
|
|
577
577
|
|
|
578
578
|
describe('sad paths', () => {
|
|
579
579
|
it('rejects when no query parameters provided', async () => {
|
|
580
|
-
await expect(kvStore.get({})).rejects.toThrow(
|
|
580
|
+
await expect(kvStore.get({})).rejects.toThrow(
|
|
581
|
+
'Must specify at least one selector: key, controller, protocolID, or tags'
|
|
582
|
+
)
|
|
583
|
+
})
|
|
584
|
+
|
|
585
|
+
it('rejects pagination-only queries before resolving overlay hosts', async () => {
|
|
586
|
+
await expect(kvStore.get({ limit: 10 })).rejects.toThrow(
|
|
587
|
+
'Must specify at least one selector: key, controller, protocolID, or tags'
|
|
588
|
+
)
|
|
589
|
+
expect(mockResolver.query).not.toHaveBeenCalled()
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
it('rejects ordering-only queries before resolving overlay hosts', async () => {
|
|
593
|
+
await expect(kvStore.get({ sortOrder: 'desc' })).rejects.toThrow(
|
|
594
|
+
'Must specify at least one selector: key, controller, protocolID, or tags'
|
|
595
|
+
)
|
|
596
|
+
expect(mockResolver.query).not.toHaveBeenCalled()
|
|
597
|
+
})
|
|
598
|
+
|
|
599
|
+
it('rejects empty tag selector queries before resolving overlay hosts', async () => {
|
|
600
|
+
await expect(kvStore.get({ tags: [] })).rejects.toThrow(
|
|
601
|
+
'Must specify at least one selector: key, controller, protocolID, or tags'
|
|
602
|
+
)
|
|
603
|
+
expect(mockResolver.query).not.toHaveBeenCalled()
|
|
581
604
|
})
|
|
582
605
|
|
|
583
606
|
it('propagates overlay errors', async () => {
|
package/src/kvstore/types.ts
CHANGED
|
@@ -37,7 +37,8 @@ export interface KVStoreConfig {
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Query parameters for KVStore lookups from overlay services.
|
|
40
|
-
*
|
|
40
|
+
* Must include at least one selector: key, controller, protocolID, or non-empty tags.
|
|
41
|
+
* Pagination and ordering fields only refine selector-based lookups.
|
|
41
42
|
*/
|
|
42
43
|
export interface KVStoreQuery {
|
|
43
44
|
key?: string
|