@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.
@@ -0,0 +1,4 @@
1
+ export { LocalDisk, signLocalUrl, verifyLocalUrlSignature } from './local-disk.js';
2
+ export { S3Disk } from './s3-disk.js';
3
+ export { buildStorageKey, createDisk, StorageService } from './storage.service.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -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,4 @@
1
+ export { LocalDisk, signLocalUrl, verifyLocalUrlSignature } from './local-disk.js';
2
+ export { S3Disk } from './s3-disk.js';
3
+ export { buildStorageKey, createDisk, StorageService } from './storage.service.js';
4
+ //# sourceMappingURL=index.js.map
@@ -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"}
@@ -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
+ }