diff --git a/src/datatype/get-if-exists.js b/src/datatype/get-if-exists.js index b8cd7130..4f5f4f98 100644 --- a/src/datatype/get-if-exists.js +++ b/src/datatype/get-if-exists.js @@ -3,6 +3,20 @@ import { NotFoundError } from '../errors.js' /** @import { MapeoDocMap, MapeoValueMap } from '../types.js' */ /** @import { DataType, MapeoDocTables } from './index.js' */ +/** + * @template T + * @param {() => PromiseLike} fn + * @returns {Promise} + */ +async function nullIfNotFound(fn) { + try { + return await fn() + } catch (err) { + if (err instanceof NotFoundError) return null + throw err + } +} + /** * @template {MapeoDocTables} TTable * @template {TTable['_']['name']} TSchemaName @@ -12,11 +26,17 @@ import { NotFoundError } from '../errors.js' * @param {string} docId * @returns {Promise} */ -export async function getByDocIdIfExists(dataType, docId) { - try { - return await dataType.getByDocId(docId) - } catch (err) { - if (err instanceof NotFoundError) return null - throw err - } -} +export const getByDocIdIfExists = (dataType, docId) => + nullIfNotFound(() => dataType.getByDocId(docId)) + +/** + * @template {MapeoDocTables} TTable + * @template {TTable['_']['name']} TSchemaName + * @template {MapeoDocMap[TSchemaName]} TDoc + * @template {MapeoValueMap[TSchemaName]} TValue + * @param {DataType} dataType + * @param {string} versionId + * @returns {Promise} + */ +export const getByVersionIdIfExists = (dataType, versionId) => + nullIfNotFound(() => dataType.getByVersionId(versionId)) diff --git a/src/roles.js b/src/roles.js index 974b56eb..8df89781 100644 --- a/src/roles.js +++ b/src/roles.js @@ -2,8 +2,10 @@ import { currentSchemaVersions, parseVersionId } from '@comapeo/schema' import mapObject from 'map-obj' import { kCreateWithDocId, kDataStore } from './datatype/index.js' import { assert, setHas } from './utils.js' -import { NotFoundError } from './errors.js' -import { getByDocIdIfExists } from './datatype/get-if-exists.js' +import { + getByDocIdIfExists, + getByVersionIdIfExists, +} from './datatype/get-if-exists.js' import { TypedEmitter } from 'tiny-typed-emitter' /** @import { Role as RoleRecord } from '@comapeo/schema' */ /** @import { ReadonlyDeep } from 'type-fest' */ @@ -417,13 +419,8 @@ export class Roles extends TypedEmitter { * @param {string} versionId * @returns {Promise} */ - async #getRoleRecordByVersionId(versionId) { - try { - return await this.#dataType.getByVersionId(versionId) - } catch (err) { - if (err instanceof NotFoundError) return null - throw err - } + #getRoleRecordByVersionId(versionId) { + return getByVersionIdIfExists(this.#dataType, versionId) } /** diff --git a/test/data-type/get-if-exists.js b/test/data-type/get-if-exists.js index f34021e0..2a70a751 100644 --- a/test/data-type/get-if-exists.js +++ b/test/data-type/get-if-exists.js @@ -1,8 +1,11 @@ import { testenv } from './test-helpers.js' import test, { describe } from 'node:test' import assert from 'node:assert/strict' -import { getByDocIdIfExists } from '../../src/datatype/get-if-exists.js' -import { valueOf } from '@comapeo/schema' +import { + getByDocIdIfExists, + getByVersionIdIfExists, +} from '../../src/datatype/get-if-exists.js' +import { getVersionId, parseVersionId, valueOf } from '@comapeo/schema' import { generate } from '@mapeo/mock-data' describe('getByDocIdIfExists', () => { @@ -18,3 +21,25 @@ describe('getByDocIdIfExists', () => { assert(await getByDocIdIfExists(dataType, observation.docId)) }) }) + +describe('getByVersionIdIfExists', () => { + test('resolves with null if no document exists with that ID', async () => { + const { dataType } = await testenv() + + const fixture = valueOf(generate('observation')[0]) + const observation = await dataType.create(fixture) + const bogusVersionId = getVersionId({ + ...parseVersionId(observation.versionId), + index: 9999999, + }) + + assert.equal(await getByVersionIdIfExists(dataType, bogusVersionId), null) + }) + + test('resolves with the document if it exists', async () => { + const { dataType } = await testenv() + const fixture = valueOf(generate('observation')[0]) + const observation = await dataType.create(fixture) + assert(await getByVersionIdIfExists(dataType, observation.versionId)) + }) +})