@nestjs-dash/storage 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/local-disk.d.ts +21 -0
- package/dist/local-disk.d.ts.map +1 -0
- package/dist/local-disk.js +82 -0
- package/dist/local-disk.js.map +1 -0
- package/dist/s3-disk.d.ts +21 -0
- package/dist/s3-disk.d.ts.map +1 -0
- package/dist/s3-disk.js +94 -0
- package/dist/s3-disk.js.map +1 -0
- package/dist/storage.service.d.ts +28 -0
- package/dist/storage.service.d.ts.map +1 -0
- package/dist/storage.service.js +102 -0
- package/dist/storage.service.js.map +1 -0
- package/package.json +56 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LocalDiskConfig, StorageDisk, StoragePutResult, StorageVisibility } from '@nestjs-dash/nestjs';
|
|
2
|
+
export declare function signLocalUrl(secret: string, key: string, expiresAt: number): string;
|
|
3
|
+
export declare function verifyLocalUrlSignature(secret: string, key: string, expiresAt: number, signature: string): boolean;
|
|
4
|
+
export declare class LocalDisk implements StorageDisk {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly visibility: StorageVisibility;
|
|
7
|
+
private readonly root;
|
|
8
|
+
private readonly publicUrl;
|
|
9
|
+
private readonly signedUrlSecret;
|
|
10
|
+
private readonly signedUrlExpiresIn;
|
|
11
|
+
constructor(name: string, config: LocalDiskConfig);
|
|
12
|
+
put(key: string, body: Buffer, contentType: string): Promise<StoragePutResult>;
|
|
13
|
+
delete(key: string): Promise<void>;
|
|
14
|
+
exists(key: string): Promise<boolean>;
|
|
15
|
+
get(key: string): Promise<Buffer>;
|
|
16
|
+
url(key: string): string;
|
|
17
|
+
temporaryUrl(key: string, expiresInSeconds?: number): Promise<string>;
|
|
18
|
+
verifySignedRequest(key: string, expiresAt: number, signature: string): boolean;
|
|
19
|
+
getRoot(): string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=local-disk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-disk.d.ts","sourceRoot":"","sources":["../src/local-disk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACpB,MAAM,qBAAqB,CAAC;AAU7B,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAYT;AAED,qBAAa,SAAU,YAAW,WAAW;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;gBAEhC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe;IAS3C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO9E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASrC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ3E,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAS/E,OAAO,IAAI,MAAM;CAGlB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { access, mkdir, readFile, unlink, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
function joinKey(root, key) {
|
|
5
|
+
const normalized = key.replace(/^\/+/, '').replace(/\.\./g, '');
|
|
6
|
+
return path.join(root, normalized);
|
|
7
|
+
}
|
|
8
|
+
export function signLocalUrl(secret, key, expiresAt) {
|
|
9
|
+
return createHmac('sha256', secret).update(`${key}:${expiresAt}`).digest('hex');
|
|
10
|
+
}
|
|
11
|
+
export function verifyLocalUrlSignature(secret, key, expiresAt, signature) {
|
|
12
|
+
if (Date.now() / 1000 > expiresAt) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const expected = signLocalUrl(secret, key, expiresAt);
|
|
16
|
+
try {
|
|
17
|
+
const a = Buffer.from(expected, 'hex');
|
|
18
|
+
const b = Buffer.from(signature, 'hex');
|
|
19
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class LocalDisk {
|
|
26
|
+
constructor(name, config) {
|
|
27
|
+
this.name = name;
|
|
28
|
+
this.root = path.resolve(config.root);
|
|
29
|
+
this.publicUrl = (config.publicUrl ?? '/admin/_/files').replace(/\/$/, '');
|
|
30
|
+
this.visibility = config.visibility ?? 'public';
|
|
31
|
+
this.signedUrlSecret = config.signedUrlSecret ?? `nestjs-dash-local-${name}`;
|
|
32
|
+
this.signedUrlExpiresIn = config.signedUrlExpiresIn ?? 3600;
|
|
33
|
+
}
|
|
34
|
+
async put(key, body, contentType) {
|
|
35
|
+
const full = joinKey(this.root, key);
|
|
36
|
+
await mkdir(path.dirname(full), { recursive: true });
|
|
37
|
+
await writeFile(full, body);
|
|
38
|
+
return { path: key.replace(/^\/+/, ''), size: body.length, contentType };
|
|
39
|
+
}
|
|
40
|
+
async delete(key) {
|
|
41
|
+
const full = joinKey(this.root, key);
|
|
42
|
+
try {
|
|
43
|
+
await unlink(full);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const code = error.code;
|
|
47
|
+
if (code !== 'ENOENT') {
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async exists(key) {
|
|
53
|
+
try {
|
|
54
|
+
await access(joinKey(this.root, key));
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async get(key) {
|
|
62
|
+
return readFile(joinKey(this.root, key));
|
|
63
|
+
}
|
|
64
|
+
url(key) {
|
|
65
|
+
const clean = key.replace(/^\/+/, '');
|
|
66
|
+
return `${this.publicUrl}/${clean}`;
|
|
67
|
+
}
|
|
68
|
+
async temporaryUrl(key, expiresInSeconds) {
|
|
69
|
+
const expiresAt = Math.floor(Date.now() / 1000) + (expiresInSeconds ?? this.signedUrlExpiresIn);
|
|
70
|
+
const signature = signLocalUrl(this.signedUrlSecret, key.replace(/^\/+/, ''), expiresAt);
|
|
71
|
+
const base = this.url(key);
|
|
72
|
+
const sep = base.includes('?') ? '&' : '?';
|
|
73
|
+
return `${base}${sep}expires=${expiresAt}&signature=${signature}`;
|
|
74
|
+
}
|
|
75
|
+
verifySignedRequest(key, expiresAt, signature) {
|
|
76
|
+
return verifyLocalUrlSignature(this.signedUrlSecret, key.replace(/^\/+/, ''), expiresAt, signature);
|
|
77
|
+
}
|
|
78
|
+
getRoot() {
|
|
79
|
+
return this.root;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=local-disk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-disk.js","sourceRoot":"","sources":["../src/local-disk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { S3DiskConfig, StorageDisk, StoragePutResult, StorageVisibility } from '@nestjs-dash/nestjs';
|
|
2
|
+
export declare class S3Disk implements StorageDisk {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly visibility: StorageVisibility;
|
|
5
|
+
private readonly bucket;
|
|
6
|
+
private readonly root;
|
|
7
|
+
private readonly signedUrlExpiresIn;
|
|
8
|
+
private readonly publicUrl?;
|
|
9
|
+
private readonly region;
|
|
10
|
+
private clientPromise;
|
|
11
|
+
private readonly config;
|
|
12
|
+
constructor(name: string, config: S3DiskConfig);
|
|
13
|
+
private objectKey;
|
|
14
|
+
private getClient;
|
|
15
|
+
put(key: string, body: Buffer, contentType: string): Promise<StoragePutResult>;
|
|
16
|
+
delete(key: string): Promise<void>;
|
|
17
|
+
exists(key: string): Promise<boolean>;
|
|
18
|
+
url(key: string): string;
|
|
19
|
+
temporaryUrl(key: string, expiresInSeconds?: number): Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=s3-disk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-disk.d.ts","sourceRoot":"","sources":["../src/s3-disk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACpB,MAAM,qBAAqB,CAAC;AAU7B,qBAAa,MAAO,YAAW,WAAW;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY;IAW9C,OAAO,CAAC,SAAS;YAKH,SAAS;IAsBjB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAe9E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgB3C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAYlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAY5E"}
|
package/dist/s3-disk.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export class S3Disk {
|
|
2
|
+
constructor(name, config) {
|
|
3
|
+
this.clientPromise = null;
|
|
4
|
+
this.name = name;
|
|
5
|
+
this.config = config;
|
|
6
|
+
this.bucket = config.bucket;
|
|
7
|
+
this.root = (config.root ?? '').replace(/^\/+|\/+$/g, '');
|
|
8
|
+
this.visibility = config.visibility ?? 'private';
|
|
9
|
+
this.signedUrlExpiresIn = config.signedUrlExpiresIn ?? 3600;
|
|
10
|
+
this.publicUrl = config.publicUrl?.replace(/\/$/, '');
|
|
11
|
+
this.region = config.region ?? 'us-east-1';
|
|
12
|
+
}
|
|
13
|
+
objectKey(key) {
|
|
14
|
+
const clean = key.replace(/^\/+/, '');
|
|
15
|
+
return this.root ? `${this.root}/${clean}` : clean;
|
|
16
|
+
}
|
|
17
|
+
async getClient() {
|
|
18
|
+
if (!this.clientPromise) {
|
|
19
|
+
this.clientPromise = (async () => {
|
|
20
|
+
try {
|
|
21
|
+
const { S3Client } = await import('@aws-sdk/client-s3');
|
|
22
|
+
return new S3Client({
|
|
23
|
+
region: this.region,
|
|
24
|
+
endpoint: this.config.endpoint,
|
|
25
|
+
forcePathStyle: this.config.forcePathStyle ?? Boolean(this.config.endpoint),
|
|
26
|
+
credentials: this.config.credentials,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw new Error('S3Disk requires optional peers @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner', { cause: error });
|
|
31
|
+
}
|
|
32
|
+
})();
|
|
33
|
+
}
|
|
34
|
+
return this.clientPromise;
|
|
35
|
+
}
|
|
36
|
+
async put(key, body, contentType) {
|
|
37
|
+
const { PutObjectCommand } = await import('@aws-sdk/client-s3');
|
|
38
|
+
const client = await this.getClient();
|
|
39
|
+
const objectKey = this.objectKey(key);
|
|
40
|
+
await client.send(new PutObjectCommand({
|
|
41
|
+
Bucket: this.bucket,
|
|
42
|
+
Key: objectKey,
|
|
43
|
+
Body: body,
|
|
44
|
+
ContentType: contentType,
|
|
45
|
+
}));
|
|
46
|
+
return { path: key.replace(/^\/+/, ''), size: body.length, contentType };
|
|
47
|
+
}
|
|
48
|
+
async delete(key) {
|
|
49
|
+
const { DeleteObjectCommand } = await import('@aws-sdk/client-s3');
|
|
50
|
+
const client = await this.getClient();
|
|
51
|
+
await client.send(new DeleteObjectCommand({
|
|
52
|
+
Bucket: this.bucket,
|
|
53
|
+
Key: this.objectKey(key),
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
async exists(key) {
|
|
57
|
+
const { HeadObjectCommand } = await import('@aws-sdk/client-s3');
|
|
58
|
+
const client = await this.getClient();
|
|
59
|
+
try {
|
|
60
|
+
await client.send(new HeadObjectCommand({
|
|
61
|
+
Bucket: this.bucket,
|
|
62
|
+
Key: this.objectKey(key),
|
|
63
|
+
}));
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
url(key) {
|
|
71
|
+
const objectKey = this.objectKey(key);
|
|
72
|
+
if (this.publicUrl) {
|
|
73
|
+
return `${this.publicUrl}/${objectKey}`;
|
|
74
|
+
}
|
|
75
|
+
if (this.config.endpoint) {
|
|
76
|
+
const base = this.config.endpoint.replace(/\/$/, '');
|
|
77
|
+
return `${base}/${this.bucket}/${objectKey}`;
|
|
78
|
+
}
|
|
79
|
+
return `https://${this.bucket}.s3.${this.region}.amazonaws.com/${objectKey}`;
|
|
80
|
+
}
|
|
81
|
+
async temporaryUrl(key, expiresInSeconds) {
|
|
82
|
+
const { GetObjectCommand } = await import('@aws-sdk/client-s3');
|
|
83
|
+
const { getSignedUrl } = await import('@aws-sdk/s3-request-presigner');
|
|
84
|
+
const client = await this.getClient();
|
|
85
|
+
const command = new GetObjectCommand({
|
|
86
|
+
Bucket: this.bucket,
|
|
87
|
+
Key: this.objectKey(key),
|
|
88
|
+
});
|
|
89
|
+
return getSignedUrl(client, command, {
|
|
90
|
+
expiresIn: expiresInSeconds ?? this.signedUrlExpiresIn,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=s3-disk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-disk.js","sourceRoot":"","sources":["../src/s3-disk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type DiskConfig, type StorageConfig, type StorageDisk, type StorageVisibility } from '@nestjs-dash/nestjs';
|
|
2
|
+
import { LocalDisk } from './local-disk.js';
|
|
3
|
+
export declare function buildStorageKey(directory: string | undefined, originalName: string): string;
|
|
4
|
+
export declare function createDisk(name: string, config: DiskConfig): StorageDisk;
|
|
5
|
+
export declare class StorageService {
|
|
6
|
+
private readonly disks;
|
|
7
|
+
private readonly defaultDisk;
|
|
8
|
+
private readonly config;
|
|
9
|
+
constructor(config?: StorageConfig | null);
|
|
10
|
+
disk(name?: string): StorageDisk;
|
|
11
|
+
getDefaultDiskName(): string;
|
|
12
|
+
put(body: Buffer, options: {
|
|
13
|
+
disk?: string;
|
|
14
|
+
directory?: string;
|
|
15
|
+
fileName: string;
|
|
16
|
+
contentType: string;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
path: string;
|
|
19
|
+
url: string;
|
|
20
|
+
disk: string;
|
|
21
|
+
size: number;
|
|
22
|
+
contentType: string;
|
|
23
|
+
}>;
|
|
24
|
+
urlFor(diskName: string, key: string, visibility?: StorageVisibility): Promise<string>;
|
|
25
|
+
delete(diskName: string, key: string): Promise<void>;
|
|
26
|
+
getLocalDisk(name?: string): LocalDisk | null;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=storage.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.service.d.ts","sourceRoot":"","sources":["../src/storage.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACzB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAO5C,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAK3F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,WAAW,CAQxE;AAED,qBACa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAKrC,MAAM,GAAE,aAAa,GAAG,IAAW;IAoBrC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW;IAShC,kBAAkB,IAAI,MAAM;IAItB,GAAG,CACP,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,GACA,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAepF,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAStF,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAI9C"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { NESTJS_DASH_STORAGE_CONFIG, } from '@nestjs-dash/nestjs';
|
|
14
|
+
import { Inject, Injectable, Optional } from '@nestjs/common';
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
16
|
+
import { LocalDisk } from './local-disk.js';
|
|
17
|
+
import { S3Disk } from './s3-disk.js';
|
|
18
|
+
function sanitizeFileName(name) {
|
|
19
|
+
return name.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 180) || 'file';
|
|
20
|
+
}
|
|
21
|
+
export function buildStorageKey(directory, originalName) {
|
|
22
|
+
const safe = sanitizeFileName(originalName);
|
|
23
|
+
const prefix = (directory ?? '').replace(/^\/+|\/+$/g, '');
|
|
24
|
+
const file = `${randomUUID()}-${safe}`;
|
|
25
|
+
return prefix ? `${prefix}/${file}` : file;
|
|
26
|
+
}
|
|
27
|
+
export function createDisk(name, config) {
|
|
28
|
+
if (config.driver === 'local') {
|
|
29
|
+
return new LocalDisk(name, config);
|
|
30
|
+
}
|
|
31
|
+
if (config.driver === 's3') {
|
|
32
|
+
return new S3Disk(name, config);
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`Unknown storage driver for disk "${name}"`);
|
|
35
|
+
}
|
|
36
|
+
let StorageService = class StorageService {
|
|
37
|
+
constructor(config = null) {
|
|
38
|
+
this.disks = new Map();
|
|
39
|
+
this.config = config ?? { defaultDisk: 'local', disks: {} };
|
|
40
|
+
this.defaultDisk = this.config.defaultDisk ?? 'local';
|
|
41
|
+
const disks = this.config.disks ?? {};
|
|
42
|
+
if (!disks[this.defaultDisk] && this.defaultDisk === 'local') {
|
|
43
|
+
disks.local = {
|
|
44
|
+
driver: 'local',
|
|
45
|
+
root: './storage/uploads',
|
|
46
|
+
publicUrl: '/admin/_/files',
|
|
47
|
+
visibility: 'public',
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
for (const [name, diskConfig] of Object.entries(disks)) {
|
|
51
|
+
this.disks.set(name, createDisk(name, diskConfig));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
disk(name) {
|
|
55
|
+
const diskName = name ?? this.defaultDisk;
|
|
56
|
+
const disk = this.disks.get(diskName);
|
|
57
|
+
if (!disk) {
|
|
58
|
+
throw new Error(`Storage disk "${diskName}" is not configured`);
|
|
59
|
+
}
|
|
60
|
+
return disk;
|
|
61
|
+
}
|
|
62
|
+
getDefaultDiskName() {
|
|
63
|
+
return this.defaultDisk;
|
|
64
|
+
}
|
|
65
|
+
async put(body, options) {
|
|
66
|
+
const diskName = options.disk ?? this.defaultDisk;
|
|
67
|
+
const disk = this.disk(diskName);
|
|
68
|
+
const key = buildStorageKey(options.directory, options.fileName);
|
|
69
|
+
const result = await disk.put(key, body, options.contentType);
|
|
70
|
+
const url = await this.urlFor(diskName, result.path, disk.visibility);
|
|
71
|
+
return {
|
|
72
|
+
path: result.path,
|
|
73
|
+
url,
|
|
74
|
+
disk: diskName,
|
|
75
|
+
size: result.size,
|
|
76
|
+
contentType: result.contentType,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
async urlFor(diskName, key, visibility) {
|
|
80
|
+
const disk = this.disk(diskName);
|
|
81
|
+
const vis = visibility ?? disk.visibility;
|
|
82
|
+
if (vis === 'private') {
|
|
83
|
+
return disk.temporaryUrl(key);
|
|
84
|
+
}
|
|
85
|
+
return disk.url(key);
|
|
86
|
+
}
|
|
87
|
+
async delete(diskName, key) {
|
|
88
|
+
await this.disk(diskName).delete(key);
|
|
89
|
+
}
|
|
90
|
+
getLocalDisk(name) {
|
|
91
|
+
const disk = this.disk(name);
|
|
92
|
+
return disk instanceof LocalDisk ? disk : null;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
StorageService = __decorate([
|
|
96
|
+
Injectable(),
|
|
97
|
+
__param(0, Optional()),
|
|
98
|
+
__param(0, Inject(NESTJS_DASH_STORAGE_CONFIG)),
|
|
99
|
+
__metadata("design:paramtypes", [Object])
|
|
100
|
+
], StorageService);
|
|
101
|
+
export { StorageService };
|
|
102
|
+
//# sourceMappingURL=storage.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.service.js","sourceRoot":"","sources":["../src/storage.service.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nestjs-dash/storage",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "File storage plugin for NestJS Dash (local disk + S3-compatible disks, signed URLs)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@nestjs-dash/nestjs": "0.1.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@nestjs-dash/typescript-config": "0.1.0",
|
|
24
|
+
"@aws-sdk/client-s3": "^3.1130.0",
|
|
25
|
+
"@aws-sdk/s3-request-presigner": "^3.1130.0",
|
|
26
|
+
"@nestjs/common": "^12.0.1",
|
|
27
|
+
"typescript": "6.0.3",
|
|
28
|
+
"vitest": "^5.0.0"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
32
|
+
"@aws-sdk/s3-request-presigner": "^3.0.0",
|
|
33
|
+
"@nestjs/common": "^12.0.0",
|
|
34
|
+
"vitest": "^5.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"@aws-sdk/client-s3": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"@aws-sdk/s3-request-presigner": {
|
|
41
|
+
"optional": true
|
|
42
|
+
},
|
|
43
|
+
"vitest": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -p tsconfig.json",
|
|
49
|
+
"check-types": "tsc -p tsconfig.json --noEmit",
|
|
50
|
+
"format": "oxfmt",
|
|
51
|
+
"lint": "oxlint src",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:coverage": "vitest run --coverage",
|
|
54
|
+
"dev": "tsc -p tsconfig.json --watch"
|
|
55
|
+
}
|
|
56
|
+
}
|