Skip to content

Commit

Permalink
feat: add KeyValueStore.recordExists() method (#510)
Browse files Browse the repository at this point in the history
Closes #507
  • Loading branch information
barjin authored Feb 13, 2024
1 parent 80bf885 commit 069d620
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
24 changes: 24 additions & 0 deletions src/resource_clients/key_value_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,30 @@ export class KeyValueStoreClient extends ResourceClient {
return cast(parseDateFields(pluckData(response.data)));
}

/**
* Tests whether a record with the given key exists in the key-value store without retrieving its value.
*
* https://docs.apify.com/api/v2#/reference/key-value-stores/record/get-record
* @param key The queried record key.
* @returns `true` if the record exists, `false` if it does not.
*/
async recordExists(key: string): Promise<boolean> {
const requestOpts: Record<string, unknown> = {
url: this._url(`records/${key}`),
method: 'HEAD',
params: this._params(),
};

try {
await this.httpClient.call(requestOpts);
return true;
} catch (err) {
catchNotFoundOrThrow(err as ApifyApiError);
}

return false;
}

/**
* You can use the `buffer` option to get the value in a Buffer (Node.js)
* or ArrayBuffer (browser) format. In Node.js (not in browser) you can also
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function pluckData<R>(obj: MaybeData<R>): R {
*/
export function catchNotFoundOrThrow(err: ApifyApiError): void {
const isNotFoundStatus = err.statusCode === NOT_FOUND_STATUS_CODE;
const isNotFoundMessage = err.type === RECORD_NOT_FOUND_TYPE || err.type === RECORD_OR_TOKEN_NOT_FOUND_TYPE;
const isNotFoundMessage = err.type === RECORD_NOT_FOUND_TYPE || err.type === RECORD_OR_TOKEN_NOT_FOUND_TYPE || err.httpMethod === 'head';
const isNotFoundError = isNotFoundStatus && isNotFoundMessage;
if (!isNotFoundError) throw err;
}
Expand Down
46 changes: 46 additions & 0 deletions test/key_value_stores.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,52 @@ describe('Key-Value Store methods', () => {
validateRequest(query, { storeId });
});

test('recordExists() works', async () => {
const key = 'some-key';
const storeId = 'some-id';

const expectedBody = null;
const expectedContentType = 'application/json; charset=utf-8';
const expectedHeaders = {
'content-type': expectedContentType,
};

mockServer.setResponse({ headers: expectedHeaders, body: expectedBody, status: 200 });

const res = await client.keyValueStore(storeId).recordExists(key);
const expectedResult = true;

expect(res).toEqual(expectedResult);
validateRequest({}, { storeId, key });

const browserRes = await page.evaluate((id, k) => client.keyValueStore(id).recordExists(k), storeId, key);
expect(browserRes).toEqual(res);
validateRequest({}, { storeId, key });
});

test('recordExists() works with a missing record', async () => {
const key = 'missing-key';
const storeId = 'some-id';

const expectedBody = null;
const expectedContentType = 'application/json; charset=utf-8';
const expectedHeaders = {
'content-type': expectedContentType,
};

mockServer.setResponse({ headers: expectedHeaders, body: expectedBody, statusCode: 404 });

const res = await client.keyValueStore(storeId).recordExists(key);
const expectedResult = false;

expect(res).toEqual(expectedResult);
validateRequest({}, { storeId, key });

const browserRes = await page.evaluate((id, k) => client.keyValueStore(id).recordExists(k), storeId, key);
expect(browserRes).toEqual(res);
validateRequest({}, { storeId, key });
});

test('getRecord() works', async () => {
const key = 'some-key';
const storeId = 'some-id';
Expand Down

0 comments on commit 069d620

Please sign in to comment.