From 2ec2d213ae10a9576da78927771768a11a05409b Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Fri, 6 Sep 2024 18:36:37 -0400 Subject: [PATCH] `dataFormat` is a mutable property (#892) `dataFormat` is a mutable record property --- .changeset/fuzzy-apes-cheer.md | 5 +++++ packages/api/src/record.ts | 6 +++++- packages/api/tests/record.spec.ts | 32 ++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .changeset/fuzzy-apes-cheer.md diff --git a/.changeset/fuzzy-apes-cheer.md b/.changeset/fuzzy-apes-cheer.md new file mode 100644 index 000000000..196413b00 --- /dev/null +++ b/.changeset/fuzzy-apes-cheer.md @@ -0,0 +1,5 @@ +--- +"@web5/api": patch +--- + +dataFormat is a mutible record property diff --git a/packages/api/src/record.ts b/packages/api/src/record.ts index 0e185eaaf..b63bd8450 100644 --- a/packages/api/src/record.ts +++ b/packages/api/src/record.ts @@ -140,6 +140,9 @@ export type RecordUpdateParams = { */ dataCid?: DwnMessageDescriptor[DwnInterface.RecordsWrite]['dataCid']; + /** The data format/MIME type of the supplied data */ + dataFormat?: string; + /** The size of the data in bytes. */ dataSize?: DwnMessageDescriptor[DwnInterface.RecordsWrite]['dataSize']; @@ -155,6 +158,7 @@ export type RecordUpdateParams = { /** The published status of the record. */ published?: DwnMessageDescriptor[DwnInterface.RecordsWrite]['published']; + /** The tags associated with the updated record */ tags?: DwnMessageDescriptor[DwnInterface.RecordsWrite]['tags']; } @@ -730,7 +734,7 @@ export class Record implements RecordModel { // Throw an error if an attempt is made to modify immutable properties. // Note: `data` and `dateModified` have already been handled. - const mutableDescriptorProperties = new Set(['data', 'dataCid', 'dataSize', 'datePublished', 'messageTimestamp', 'published', 'tags']); + const mutableDescriptorProperties = new Set(['data', 'dataCid', 'dataFormat', 'dataSize', 'datePublished', 'messageTimestamp', 'published', 'tags']); Record.verifyPermittedMutation(Object.keys(params), mutableDescriptorProperties); // If `published` is set to false, ensure that `datePublished` is undefined. Otherwise, DWN SDK's schema validation diff --git a/packages/api/tests/record.spec.ts b/packages/api/tests/record.spec.ts index 29f94bd57..4b4807814 100644 --- a/packages/api/tests/record.spec.ts +++ b/packages/api/tests/record.spec.ts @@ -2756,7 +2756,7 @@ describe('Record', () => { try { // @ts-expect-error because this test intentionally specifies an immutable property that is not present in RecordUpdateOptions. - await record!.update({ dataFormat: 'application/json' }); + await record!.update({ schema: 'bar/baz' }); expect.fail('Expected an exception to be thrown'); } catch (error: any) { expect(error.message).to.include('is an immutable property. Its value cannot be changed.'); @@ -2876,6 +2876,36 @@ describe('Record', () => { expect(updateResultWithNullTags.status.code).to.equal(202); expect(record.tags).to.not.exist; // removed }); + + it('should allow updating the dataFormat of a record', async () => { + // alice writes a record with the data format set to text/plain + const { status, record } = await dwnAlice.records.write({ + data : 'Hello, world!', + message : { + protocol : protocolDefinition.protocol, + protocolPath : 'thread', + schema : protocolDefinition.types.thread.schema, + dataFormat : 'text/plain' + } + }); + + expect(status.code).to.equal(202); + expect(record).to.not.be.undefined; + expect(record.dataFormat).to.equal('text/plain'); + expect(await record.data.text()).to.equal('Hello, world!'); + + // update the record to JSON + const updateResult = await record!.update({ dataFormat: 'application/json', data: { subject: 'some subject', body: 'some body' } }); + expect(updateResult.status.code).to.equal(202); + expect(record.dataFormat).to.equal('application/json'); + expect(await record.data.json()).to.deep.equal({ subject: 'some subject', body: 'some body' }); + + // update again without changing the dataFormat + const updateResult2 = await record!.update({ data: { subject: 'another subject', body: 'another body' } }); + expect(updateResult2.status.code).to.equal(202); + expect(record.dataFormat).to.equal('application/json'); + expect(await record.data.json()).to.deep.equal({ subject: 'another subject', body: 'another body' }); + }); }); describe('delete()', () => {