diff --git a/packages/source-memory/src/__test__/source.memory.test.ts b/packages/source-memory/src/__test__/source.memory.test.ts index 7c2461cc..3b4b984e 100644 --- a/packages/source-memory/src/__test__/source.memory.test.ts +++ b/packages/source-memory/src/__test__/source.memory.test.ts @@ -17,6 +17,17 @@ o.spec('FsMemory', () => { o(b.toString()).equals('a'); }); + o('should write with metadata', async () => { + await memory.write('memory://foo.png', Buffer.from('a'), { + contentType: 'text/plain', + metadata: { 'X-LINZ-TEST': '123' }, + }); + + const head = await memory.head('memory://foo.png'); + o(head?.contentType).equals('text/plain'); + o(head?.metadata).deepEquals({ 'X-LINZ-TEST': '123' }); + }); + o('should stream files', async () => { await memory.write('memory://foo.png', Buffer.from('a')); diff --git a/packages/source-memory/src/memory.fs.ts b/packages/source-memory/src/memory.fs.ts index b84924d4..529c02d1 100644 --- a/packages/source-memory/src/memory.fs.ts +++ b/packages/source-memory/src/memory.fs.ts @@ -1,4 +1,4 @@ -import { CompositeError, FileInfo, FileSystem, ListOptions, SourceMemory } from '@chunkd/core'; +import { CompositeError, FileInfo, FileSystem, ListOptions, SourceMemory, WriteOptions } from '@chunkd/core'; import { Readable } from 'stream'; export function toReadable(r: string | Buffer | Readable): Readable { @@ -6,6 +6,12 @@ export function toReadable(r: string | Buffer | Readable): Readable { return Readable.from(r); } +async function getBuffer(buffer: string | Buffer | Readable): Promise { + if (typeof buffer === 'string') return Buffer.from(buffer); + if (Buffer.isBuffer(buffer)) return buffer; + return await toBuffer(buffer); +} + export async function toBuffer(stream: Readable): Promise { return new Promise((resolve, reject) => { const buf: Buffer[] = []; @@ -19,31 +25,22 @@ export async function toBuffer(stream: Readable): Promise { export class FsMemory implements FileSystem { protocol = 'memory'; - files: Map = new Map(); + files: Map = new Map(); async read(filePath: string): Promise { const data = this.files.get(filePath); if (data == null) throw new CompositeError('Not found', 404, new Error()); - return data; + return data.buffer; } stream(filePath: string): Readable { const buf = this.files.get(filePath); if (buf == null) throw new CompositeError('Not found', 404, new Error()); - return toReadable(buf); + return toReadable(buf.buffer); } - async write(filePath: string, buffer: string | Buffer | Readable): Promise { - if (typeof buffer === 'string') { - this.files.set(filePath, Buffer.from(buffer)); - return; - } - if (Buffer.isBuffer(buffer)) { - this.files.set(filePath, buffer); - return; - } - const buf = await toBuffer(buffer); - this.files.set(filePath, buf); + async write(filePath: string, buffer: string | Buffer | Readable, opts?: WriteOptions): Promise { + this.files.set(filePath, { opts: opts, buffer: await getBuffer(buffer) }); } async *list(filePath: string, opt?: ListOptions): AsyncGenerator { @@ -84,9 +81,15 @@ export class FsMemory implements FileSystem { } async head(filePath: string): Promise { - const buf = this.files.get(filePath); - if (buf == null) return null; - return { path: filePath, size: buf.length }; + const obj = this.files.get(filePath); + if (obj == null) return null; + return { + path: filePath, + size: obj.buffer.length, + metadata: obj.opts?.metadata, + contentType: obj.opts?.contentType, + contentEncoding: obj.opts?.contentEncoding, + }; } async delete(filePath: string): Promise { @@ -94,9 +97,9 @@ export class FsMemory implements FileSystem { } source(filePath: string): SourceMemory { - const bytes = this.files.get(filePath); - if (bytes == null) throw new CompositeError('File not found', 404, new Error()); - const source = new SourceMemory(filePath, bytes); + const obj = this.files.get(filePath); + if (obj == null) throw new CompositeError('File not found', 404, new Error()); + const source = new SourceMemory(filePath, obj.buffer); return source; } }