From 24fc42826851e9e43292009407a1d57321804e1b Mon Sep 17 00:00:00 2001 From: Evan Hahn Date: Mon, 10 Jun 2024 21:23:31 +0000 Subject: [PATCH] feat: add `MapeoProject.prototype.$createdByToDeviceId` Turns `createdAt` into `deviceId`. Partly addresses [#136]. [#136]: https://github.com/digidem/mapeo-core-next/issues/136 --- src/mapeo-project.js | 14 ++++++++ test-e2e/created_by_to_device_id.js | 53 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 test-e2e/created_by_to_device_id.js diff --git a/src/mapeo-project.js b/src/mapeo-project.js index 99f9697ba..6f178ee91 100644 --- a/src/mapeo-project.js +++ b/src/mapeo-project.js @@ -555,6 +555,20 @@ export class MapeoProject extends TypedEmitter { return this.#roles.getRole(this.#deviceId) } + /** + * @param {string} createdBy The `createdBy` value from a document. + * @returns {Promise} The device ID for this creator. + * @throws When device ID cannot be found. + */ + async $createdByToDeviceId(createdBy) { + const discoveryKey = Buffer.from(createdBy, 'hex') + const coreId = this.#coreManager + .getCoreByDiscoveryKey(discoveryKey) + ?.key.toString('hex') + if (!coreId) throw new Error('NotFound') + return this.#coreOwnership.getOwner(coreId) + } + /** * Replicate a project to a @hyperswarm/secret-stream. Invites will not * function because the RPC channel is not connected for project replication, diff --git a/test-e2e/created_by_to_device_id.js b/test-e2e/created_by_to_device_id.js new file mode 100644 index 000000000..a5c90cbcc --- /dev/null +++ b/test-e2e/created_by_to_device_id.js @@ -0,0 +1,53 @@ +import assert from 'node:assert/strict' +import test from 'node:test' +import { + connectPeers, + createManagers, + invite, + waitForPeers, + waitForSync, +} from './utils.js' + +test('$createdByToDeviceId', async (t) => { + const managers = await createManagers(2, t) + + const disconnectPeers = connectPeers(managers) + t.after(disconnectPeers) + await waitForPeers(managers) + + const [creator, member] = managers + const projectId = await creator.createProject({ name: 'mapeo' }) + + await invite({ + invitor: creator, + invitees: [member], + projectId, + }) + + const projects = await Promise.all( + managers.map((m) => m.getProject(projectId)) + ) + const [creatorProject, memberProject] = projects + + creatorProject.$sync.start() + memberProject.$sync.start() + + const observation = await creatorProject.observation.create({ + schemaName: 'observation', + attachments: [], + tags: {}, + refs: [], + metadata: {}, + }) + + await waitForSync(projects, 'full') + + assert.equal( + await creatorProject.$createdByToDeviceId(observation.createdBy), + creator.deviceId + ) + assert.equal( + await memberProject.$createdByToDeviceId(observation.createdBy), + creator.deviceId + ) +})