Skip to content

Commit db9936e

Browse files
authored
Standardise content type handling in MSC3089 createFile() and createNewVersion() (#2014)
* Provide cross platform compatible versions of createFile() and createNewVersion() The exist implementations are deprecated as they only work in a browser and support a different type of contents from MatrixClient.uploadContent() * Fix MSC3089 content upload meta data in NodeJS runtime * Break unstable createFile() and createNewVersion() instead of deprecating Test using NodeJS types instead of mocked browser Blob * chore: remove incorrect comment
1 parent 7dcee2e commit db9936e

File tree

5 files changed

+17
-50
lines changed

5 files changed

+17
-50
lines changed

spec/MockBlob.ts

-27
This file was deleted.

spec/unit/models/MSC3089Branch.spec.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,7 @@ describe("MSC3089Branch", () => {
244244

245245
it('should create new versions of itself', async () => {
246246
const canaryName = "canary";
247-
const fileContents = "contents go here";
248-
const canaryContents = Uint8Array.from(Array.from(fileContents).map((_, i) => fileContents.charCodeAt(i)));
247+
const canaryContents = "contents go here";
249248
const canaryFile = {} as IEncryptedFile;
250249
const canaryAddl = { canary: true };
251250
indexEvent.getContent = () => ({ active: true, retained: true });

spec/unit/models/MSC3089TreeSpace.spec.ts

+6-15
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
TreePermissions,
2525
} from "../../../src/models/MSC3089TreeSpace";
2626
import { DEFAULT_ALPHABET } from "../../../src/utils";
27-
import { MockBlob } from "../../MockBlob";
2827
import { MatrixError } from "../../../src/http-api";
2928

3029
describe("MSC3089TreeSpace", () => {
@@ -887,12 +886,8 @@ describe("MSC3089TreeSpace", () => {
887886
const fileName = "My File.txt";
888887
const fileContents = "This is a test file";
889888

890-
// Mock out Blob for the test environment
891-
(<any>global).Blob = MockBlob;
892-
893-
const uploadFn = jest.fn().mockImplementation((contents: Blob, opts: any) => {
894-
expect(contents).toBeInstanceOf(Blob);
895-
expect(contents.size).toEqual(fileContents.length);
889+
const uploadFn = jest.fn().mockImplementation((contents: Buffer, opts: any) => {
890+
expect(contents.length).toEqual(fileContents.length);
896891
expect(opts).toMatchObject({
897892
includeFilename: false,
898893
onlyContentUri: true, // because the tests rely on this - we shouldn't really be testing for this.
@@ -930,7 +925,7 @@ describe("MSC3089TreeSpace", () => {
930925
});
931926
client.sendStateEvent = sendStateFn;
932927

933-
const buf = Uint8Array.from(Array.from(fileContents).map((_, i) => fileContents.charCodeAt(i)));
928+
const buf = Buffer.from(fileContents);
934929

935930
// We clone the file info just to make sure it doesn't get mutated for the test.
936931
const result = await tree.createFile(fileName, buf, Object.assign({}, fileInfo), { metadata: true });
@@ -951,12 +946,8 @@ describe("MSC3089TreeSpace", () => {
951946
const fileName = "My File.txt";
952947
const fileContents = "This is a test file";
953948

954-
// Mock out Blob for the test environment
955-
(<any>global).Blob = MockBlob;
956-
957-
const uploadFn = jest.fn().mockImplementation((contents: Blob, opts: any) => {
958-
expect(contents).toBeInstanceOf(Blob);
959-
expect(contents.size).toEqual(fileContents.length);
949+
const uploadFn = jest.fn().mockImplementation((contents: Buffer, opts: any) => {
950+
expect(contents.length).toEqual(fileContents.length);
960951
expect(opts).toMatchObject({
961952
includeFilename: false,
962953
onlyContentUri: true, // because the tests rely on this - we shouldn't really be testing for this.
@@ -997,7 +988,7 @@ describe("MSC3089TreeSpace", () => {
997988
});
998989
client.sendStateEvent = sendStateFn;
999990

1000-
const buf = Uint8Array.from(Array.from(fileContents).map((_, i) => fileContents.charCodeAt(i)));
991+
const buf = Buffer.from(fileContents);
1001992

1002993
// We clone the file info just to make sure it doesn't get mutated for the test.
1003994
const result = await tree.createFile(fileName, buf, Object.assign({}, fileInfo), { "m.new_content": true });

src/models/MSC3089Branch.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { MatrixClient } from "../client";
1818
import { IEncryptedFile, RelationType, UNSTABLE_MSC3089_BRANCH } from "../@types/event";
1919
import { IContent, MatrixEvent } from "./event";
2020
import { MSC3089TreeSpace } from "./MSC3089TreeSpace";
21+
import type { ReadStream } from "fs";
2122

2223
/**
2324
* Represents a [MSC3089](https://github.com/matrix-org/matrix-doc/pull/3089) branch - a reference
@@ -142,16 +143,16 @@ export class MSC3089Branch {
142143
}
143144

144145
/**
145-
* Creates a new version of this file.
146+
* Creates a new version of this file with contents in a type that is compatible with MatrixClient.uploadContent().
146147
* @param {string} name The name of the file.
147-
* @param {ArrayBuffer} encryptedContents The encrypted contents.
148+
* @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents.
148149
* @param {Partial<IEncryptedFile>} info The encrypted file information.
149150
* @param {IContent} additionalContent Optional event content fields to include in the message.
150151
* @returns {Promise<void>} Resolves when uploaded.
151152
*/
152153
public async createNewVersion(
153154
name: string,
154-
encryptedContents: ArrayBuffer,
155+
encryptedContents: File | String | Buffer | ReadStream | Blob,
155156
info: Partial<IEncryptedFile>,
156157
additionalContent?: IContent,
157158
): Promise<void> {

src/models/MSC3089TreeSpace.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { MSC3089Branch } from "./MSC3089Branch";
3131
import promiseRetry from "p-retry";
3232
import { isRoomSharedHistory } from "../crypto/algorithms/megolm";
3333
import { ISendEventResponse } from "../@types/requests";
34+
import type { ReadStream } from "fs";
3435

3536
/**
3637
* The recommended defaults for a tree space's power levels. Note that this
@@ -449,21 +450,23 @@ export class MSC3089TreeSpace {
449450

450451
/**
451452
* Creates (uploads) a new file to this tree. The file must have already been encrypted for the room.
453+
* The file contents are in a type that is compatible with MatrixClient.uploadContent().
452454
* @param {string} name The name of the file.
453-
* @param {ArrayBuffer} encryptedContents The encrypted contents.
455+
* @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents.
454456
* @param {Partial<IEncryptedFile>} info The encrypted file information.
455457
* @param {IContent} additionalContent Optional event content fields to include in the message.
456458
* @returns {Promise<ISendEventResponse>} Resolves to the file event's sent response.
457459
*/
458460
public async createFile(
459461
name: string,
460-
encryptedContents: ArrayBuffer,
462+
encryptedContents: File | String | Buffer | ReadStream | Blob,
461463
info: Partial<IEncryptedFile>,
462464
additionalContent?: IContent,
463465
): Promise<ISendEventResponse> {
464-
const mxc = await this.client.uploadContent(new Blob([encryptedContents]), {
466+
const mxc = await this.client.uploadContent(encryptedContents, {
465467
includeFilename: false,
466468
onlyContentUri: true,
469+
rawResponse: false, // make this explicit otherwise behaviour is different on browser vs NodeJS
467470
});
468471
info.url = mxc;
469472

0 commit comments

Comments
 (0)