Skip to content

Commit

Permalink
feat(source-memory): support writing with metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
blacha committed May 4, 2023
1 parent fd9a7c1 commit 5001dcc
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 21 deletions.
11 changes: 11 additions & 0 deletions packages/source-memory/src/__test__/source.memory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'));

Expand Down
45 changes: 24 additions & 21 deletions packages/source-memory/src/memory.fs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
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 {
if (typeof r === 'string') r = Buffer.from(r);
return Readable.from(r);
}

async function getBuffer(buffer: string | Buffer | Readable): Promise<Buffer> {
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<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
const buf: Buffer[] = [];
Expand All @@ -19,31 +25,22 @@ export async function toBuffer(stream: Readable): Promise<Buffer> {
export class FsMemory implements FileSystem<SourceMemory> {
protocol = 'memory';

files: Map<string, Buffer> = new Map();
files: Map<string, { buffer: Buffer; opts?: WriteOptions }> = new Map();

async read(filePath: string): Promise<Buffer> {
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<void> {
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<void> {
this.files.set(filePath, { opts: opts, buffer: await getBuffer(buffer) });
}

async *list(filePath: string, opt?: ListOptions): AsyncGenerator<string> {
Expand Down Expand Up @@ -84,19 +81,25 @@ export class FsMemory implements FileSystem<SourceMemory> {
}

async head(filePath: string): Promise<FileInfo | null> {
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<void> {
this.files.delete(filePath);
}

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;
}
}

0 comments on commit 5001dcc

Please sign in to comment.