From b079f855a2ae0539c08e828ad23975fa66b62445 Mon Sep 17 00:00:00 2001 From: Frank Hinek Date: Sun, 14 May 2023 23:51:43 -0400 Subject: [PATCH] Added dwn.records.read() from: Signed-off-by: Frank Hinek --- packages/web5/src/dwn-api.ts | 39 ++++++++++++------- packages/web5/src/web5.ts | 2 +- packages/web5/tests/fixtures/test-profiles.ts | 4 +- packages/web5/tests/web5-dwn.spec.ts | 31 ++++++++++++++- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/packages/web5/src/dwn-api.ts b/packages/web5/src/dwn-api.ts index 1f2a08046..03e9477fb 100644 --- a/packages/web5/src/dwn-api.ts +++ b/packages/web5/src/dwn-api.ts @@ -6,7 +6,6 @@ import type { RecordsDeleteOptions, RecordsQueryOptions, RecordsReadOptions, - RecordsReadReply, RecordsWriteDescriptor, RecordsWriteMessage, RecordsWriteOptions, @@ -56,7 +55,7 @@ export type RecordsQueryReplyEntry = { export type RecordsQueryRequest = { - /** where the query results will come from */ + /** The from property indicates the DID to query from and return results. */ from?: string; message: Omit; } @@ -67,6 +66,8 @@ export type RecordsQueryResponse = { }; export type RecordsReadRequest = { + /** The from property indicates the DID to read from and return results fro. */ + from?: string; message: Omit; } @@ -232,21 +233,31 @@ export class DwnApi { * TODO: Document method. */ read: async (request: RecordsReadRequest): Promise => { - const { message: requestMessage } = request; - - const messageOptions: Partial = { - ...requestMessage + const agentRequest = { + author : this.connectedDid, + messageOptions : request.message, + messageType : DwnInterfaceName.Records + DwnMethodName.Read, + target : request.from || this.connectedDid }; - const agentResponse = await this.web5Agent.processDwnRequest({ - author : this.connectedDid, - messageOptions, - messageType : DwnInterfaceName.Records + DwnMethodName.Read, - target : this.connectedDid - }); + let agentResponse; - const { reply } = agentResponse; - const { record: responseRecord, status } = reply as RecordsReadReply; + if (request.from) { + agentResponse = await this.web5Agent.sendDwnRequest(agentRequest); + } else { + agentResponse = await this.web5Agent.processDwnRequest(agentRequest); + } + + //! TODO: (Frank -> Moe): This quirk is the result of how 4XX errors are being returned by `dwn-server` + //! When DWN SDK returns 404, agentResponse is { status: { code: 404 }} and that's it. + //! Need to decide how to resolve. + let responseRecord; + let status; + if (agentResponse.reply) { + ({ reply: { record: responseRecord, status } } = agentResponse); + } else { + ({ status } = agentResponse); + } let record: Record; if (200 <= status.code && status.code <= 299) { diff --git a/packages/web5/src/web5.ts b/packages/web5/src/web5.ts index 67269bb1e..913d62f0d 100644 --- a/packages/web5/src/web5.ts +++ b/packages/web5/src/web5.ts @@ -2,8 +2,8 @@ import type { DidState, DidMethodApi, DidResolverCache } from '@tbd54566975/dids import type { Web5Agent } from '@tbd54566975/web5-agent'; // import { Web5ProxyAgent } from '@tbd54566975/web5-proxy-agent'; -import { Web5UserAgent, ProfileApi } from '@tbd54566975/web5-user-agent'; import { DidIonApi, DidKeyApi } from '@tbd54566975/dids'; +import { Web5UserAgent, ProfileApi } from '@tbd54566975/web5-user-agent'; import { DwnApi } from './dwn-api.js'; import { DidApi } from './did-api.js'; diff --git a/packages/web5/tests/fixtures/test-profiles.ts b/packages/web5/tests/fixtures/test-profiles.ts index 57dac6ed3..25fa50707 100644 --- a/packages/web5/tests/fixtures/test-profiles.ts +++ b/packages/web5/tests/fixtures/test-profiles.ts @@ -89,8 +89,8 @@ export const ionCreateOptions = { id : 'dwn', type : 'DecentralizedWebNode', serviceEndpoint : { - nodes : ['https://dwn.tbddev.org/dwn0'], - messageAttestationKeys : [`#${keyIds.did.service.dwn.attestation}`], + nodes : ['https://dwn.tbddev.org/dwn0'], + messageAuthorizationKeys : [`#${keyIds.did.service.dwn.authorization}`], } }] }; diff --git a/packages/web5/tests/web5-dwn.spec.ts b/packages/web5/tests/web5-dwn.spec.ts index 4df8fcc31..053a8020d 100644 --- a/packages/web5/tests/web5-dwn.spec.ts +++ b/packages/web5/tests/web5-dwn.spec.ts @@ -170,7 +170,27 @@ describe('web5.dwn', () => { }); describe('from: did', () => { - xit('tests needed'); + it('returns undefined record when requested record does not exit', async () => { + // Generate a recordId that will not be present on the did endpoint being read from. + const { record, status } = await dwn.records.write({ data: 'hi' }); + expect(status.code).to.equal(202); + + // Create a new DID to represent an external entity who has a remote DWN server defined in their DID document. + const ionCreateOptions = await testProfile.ionCreateOptions.services.dwn.authorization.keys(); + const { id: bobDid } = await testAgent.didIon.create(ionCreateOptions); + + // Attempt to read a record from Bob's DWN using the ID of a record that only exists in the connected agent's DWN. + const result = await dwn.records.read({ + from : bobDid, + message : { + recordId: record!.id + } + }); + + // Confirm that the record does not currently exist on Bob's DWN. + expect(result.status.code).to.equal(404); + expect(result.record).to.be.undefined; + }); }); }); @@ -224,6 +244,15 @@ describe('web5.dwn', () => { expect(deleteResult.status.code).to.equal(202); }); + + it('returns a 202 if the recordId does not exist', async () => { + let deleteResult = await dwn.records.delete({ + message: { + recordId: 'abcd1234' + } + }); + expect(deleteResult.status.code).to.equal(202); + }); }); describe('from: did', () => {