Skip to content

Commit

Permalink
feat: expose streamToGetResult & unify fs & s3
Browse files Browse the repository at this point in the history
  • Loading branch information
fratzinger committed Apr 12, 2024
1 parent ec0c623 commit 50cf8bd
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 56 deletions.
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * from "./hooks";
export * from "./middleware";

export * from "./types";

export { streamToGetResult } from "./utils";
26 changes: 6 additions & 20 deletions src/services/ServiceFileStreamFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import path from "node:path";
import streamPomises from "node:stream/promises";
import type {
ServiceFileStream,
ServiceFileStreamCreateData,
ServiceFileStreamCreateResult,
ServiceFileStreamGetResult,
} from "../types";
import type { MaybeArray } from "../utility-types";
import { asArray } from "../utils";
import { asArray, streamToGetResult } from "../utils";
import mime from "mime-types";
import type { Readable } from "node:stream";

Expand Down Expand Up @@ -53,25 +52,12 @@ export class ServiceFileStreamFS implements ServiceFileStream {
const { root } = this.options;
const stream = createReadStream(path.join(root, id), { start, end });

const contentType = mime.lookup(id) || "application/octet-stream";

// const fileName = path.basename(id);

return {
header: {
"Accept-Ranges": "bytes",
"Content-Type": contentType,
"Content-disposition": "inline",
"Content-Length": contentLength,
...(contentRange
? {
"Content-Range": "bytes " + start + "-" + end + "/" + info.size,
}
: {}),
},
status: contentRange ? 206 : 200,
return streamToGetResult({
stream,
};
contentType: mime.lookup(id) || "application/octet-stream",
contentLength,
contentRange: contentRange ? `bytes ${start}-${end}/${contentLength}` : undefined,
});
}

async _create(
Expand Down
48 changes: 12 additions & 36 deletions src/services/ServiceFileStreamS3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {
ServiceFileStreamGetResult,
} from "../types";
import type { MaybeArray } from "../utility-types";
import { asArray } from "../utils";
import { asArray, streamToGetResult } from "../utils";

export type ServiceFileStreamS3Options = {
s3: S3Client;
Expand All @@ -33,8 +33,6 @@ export type ServiceFileStreamS3GetParams = {
[key: string]: any;
};

export type ServiceFileStreamS3GetResult = ServiceFileStreamGetResult;

export type ServiceFileStreamS3CreateData = ServiceFileStreamCreateData & {
size?: number;
mimeType?: string;
Expand Down Expand Up @@ -114,7 +112,7 @@ export class ServiceFileStreamS3 implements ServiceFileStream {
async _get(
id: string,
params?: ServiceFileStreamS3GetParams
): Promise<ServiceFileStreamS3GetResult> {
): Promise<ServiceFileStreamGetResult> {
const headResponse = await this.getHeadForObject(id, params);
const bucket = params?.bucket || this.bucket;

Expand All @@ -128,44 +126,22 @@ export class ServiceFileStreamS3 implements ServiceFileStream {
Range: range,
};

const header: Record<string, any> = {
ETag: headResponse.ETag,
"Content-Disposition": "inline",
};

if (headResponse.ContentLength) {
header["Content-Length"] = headResponse.ContentLength;
}

if (headResponse.ContentType) {
header["Content-Type"] = headResponse.ContentType;
}

if (headResponse.ContentEncoding) {
header["Content-Encoding"] = headResponse.ContentEncoding;
}

if (headResponse.AcceptRanges) {
header["Accept-Ranges"] = headResponse.AcceptRanges;
}

// Now get the object data and stream it
const response = await s3.send(new GetObjectCommand(params));

let status = 200;

if (response.ContentRange) {
header["Content-Range"] = response.ContentRange;
status = 206;
}

const stream = response.Body as Readable;

return {
header,
return streamToGetResult({
header: {
ETag: headResponse.ETag,
"Content-Encoding": headResponse.ContentEncoding,
"Accept-Ranges": headResponse.AcceptRanges,
},
contentLength: headResponse.ContentLength,
contentType: headResponse.ContentType,
contentRange: response.ContentRange,
stream,
status,
} as ServiceFileStreamS3GetResult;
});
} catch (err) {
this.errorHandler(err);
throw err;
Expand Down
37 changes: 37 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Readable } from "node:stream";
import type { ServiceFileStreamGetResult } from "./types";
import type { MaybeArray } from "./utility-types";

Expand All @@ -20,3 +21,39 @@ export const asArray = <T>(
export const isGetResult = (data: any): data is ServiceFileStreamGetResult => {
return data?.stream !== undefined;
};

type StreamToGetResult = {
stream: Readable;
contentType: string | undefined;
contentLength: number | undefined;
contentRange?: string | undefined;
header?: Record<string, string | undefined>;
}

export const streamToGetResult = (options: StreamToGetResult): ServiceFileStreamGetResult => {
const header = {};

for (const key in options.header) {
if (options.header[key] !== undefined) {
header[key] = options.header[key];
}
}

return {
header: {
...header,
"Accept-Ranges": "bytes",
...(options.contentType !== undefined ? { "Content-Type": options.contentType } : {}),
"Content-disposition": "inline",
...(options.contentLength !== undefined ? { "Content-Length": options.contentLength } : {}),
"Content-Length": options.contentLength,
...(options.contentRange !== undefined && options.contentLength !== undefined
? {
"Content-Range": options.contentRange,
}
: {}),
},
status: options.contentRange ? 206 : 200,
stream: options.stream,
};
};

0 comments on commit 50cf8bd

Please sign in to comment.