diff --git a/package.json b/package.json index ed41c60..45dc574 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "ts-loader": "9.5.1", "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", - "typescript": "5.5.4", + "typescript": "5.6.2", "unplugin-swc": "1.5.1", "vitest": "2.0.5" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d506305..621301e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,7 +44,7 @@ importers: version: 10.4.4(@swc/cli@0.4.0(@swc/core@1.7.18)(chokidar@3.6.0))(@swc/core@1.7.18) '@nestjs/schematics': specifier: 10.1.4 - version: 10.1.4(chokidar@3.6.0)(typescript@5.5.4) + version: 10.1.4(chokidar@3.6.0)(typescript@5.6.2) '@nestjs/testing': specifier: 10.4.1 version: 10.4.1(@nestjs/common@10.4.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)) @@ -62,10 +62,10 @@ importers: version: 6.0.2 '@typescript-eslint/eslint-plugin': specifier: 6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2) '@typescript-eslint/parser': specifier: 6.21.0 - version: 6.21.0(eslint@8.57.0)(typescript@5.5.4) + version: 6.21.0(eslint@8.57.0)(typescript@5.6.2) '@vitest/coverage-v8': specifier: 2.0.5 version: 2.0.5(vitest@2.0.5(@types/node@20.16.1)(terser@5.31.6)) @@ -83,22 +83,22 @@ importers: version: 3.3.3 prettier-plugin-organize-imports: specifier: 3.2.4 - version: 3.2.4(prettier@3.3.3)(typescript@5.5.4) + version: 3.2.4(prettier@3.3.3)(typescript@5.6.2) source-map-support: specifier: 0.5.21 version: 0.5.21 ts-loader: specifier: 9.5.1 - version: 9.5.1(typescript@5.5.4)(webpack@5.93.0(@swc/core@1.7.18)) + version: 9.5.1(typescript@5.6.2)(webpack@5.93.0(@swc/core@1.7.18)) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.7.18)(@types/node@20.16.1)(typescript@5.5.4) + version: 10.9.2(@swc/core@1.7.18)(@types/node@20.16.1)(typescript@5.6.2) tsconfig-paths: specifier: 4.2.0 version: 4.2.0 typescript: - specifier: 5.5.4 - version: 5.5.4 + specifier: 5.6.2 + version: 5.6.2 unplugin-swc: specifier: 1.5.1 version: 1.5.1(@swc/core@1.7.18)(rollup@4.21.0) @@ -3033,8 +3033,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} engines: {node: '>=14.17'} hasBin: true @@ -4079,14 +4079,14 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/schematics@10.1.4(chokidar@3.6.0)(typescript@5.5.4)': + '@nestjs/schematics@10.1.4(chokidar@3.6.0)(typescript@5.6.2)': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) comment-json: 4.2.3 jsonc-parser: 3.3.1 pluralize: 8.0.0 - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - chokidar @@ -4643,13 +4643,13 @@ snapshots: '@types/methods': 1.1.4 '@types/superagent': 8.1.6 - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.6.2) '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.6.2) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.6.2) '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 eslint: 8.57.0 @@ -4657,22 +4657,22 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.6.2)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.2) '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 eslint: 8.57.0 optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color @@ -4681,21 +4681,21 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.6.2)': dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.4) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.2) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.6.2) debug: 4.3.4 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color '@typescript-eslint/types@6.21.0': {} - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.6.2)': dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 @@ -4704,20 +4704,20 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.5.4) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.5.4 + typescript: 5.6.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.6.2)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.2) eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: @@ -6215,10 +6215,10 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier-plugin-organize-imports@3.2.4(prettier@3.3.3)(typescript@5.5.4): + prettier-plugin-organize-imports@3.2.4(prettier@3.3.3)(typescript@5.6.2): dependencies: prettier: 3.3.3 - typescript: 5.5.4 + typescript: 5.6.2 prettier@3.3.3: {} @@ -6567,21 +6567,21 @@ snapshots: dependencies: escape-string-regexp: 5.0.0 - ts-api-utils@1.3.0(typescript@5.5.4): + ts-api-utils@1.3.0(typescript@5.6.2): dependencies: - typescript: 5.5.4 + typescript: 5.6.2 - ts-loader@9.5.1(typescript@5.5.4)(webpack@5.93.0(@swc/core@1.7.18)): + ts-loader@9.5.1(typescript@5.6.2)(webpack@5.93.0(@swc/core@1.7.18)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.16.0 micromatch: 4.0.5 semver: 7.6.0 source-map: 0.7.4 - typescript: 5.5.4 + typescript: 5.6.2 webpack: 5.93.0(@swc/core@1.7.18) - ts-node@10.9.2(@swc/core@1.7.18)(@types/node@20.16.1)(typescript@5.5.4): + ts-node@10.9.2(@swc/core@1.7.18)(@types/node@20.16.1)(typescript@5.6.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -6595,7 +6595,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.5.4 + typescript: 5.6.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: @@ -6629,7 +6629,7 @@ snapshots: typescript@5.3.3: {} - typescript@5.5.4: {} + typescript@5.6.2: {} uid@2.0.2: dependencies: diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 13ec325..7d9ffc5 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -14,8 +14,8 @@ const configurationSchema = z z.object({ STORAGE_PROVIDER: z.literal("s3"), S3_BUCKET: z.string(), - S3_ACCESS_KEY_ID: z.string(), - S3_SECRET_ACCESS_KEY: z.string(), + S3_ACCESS_KEY_ID: z.string().optional(), + S3_SECRET_ACCESS_KEY: z.string().optional(), S3_SESSION_TOKEN: z.string().optional(), S3_REGION: z.string().default("us-east-1"), S3_FORCE_PATH_STYLE: z.enum(["true", "false"]).default("false"), @@ -54,6 +54,21 @@ const configurationSchema = z export type ConfigurationSchema = z.infer; +export type S3KeyAuthCredentials = { + accessKeyId: string; + secretAccessKey: string; + sessionToken?: string; +}; + +export function isS3KeyAuthCredentials( + credentialConfig: any, +): credentialConfig is S3KeyAuthCredentials { + return ( + typeof credentialConfig.accessKeyId === "string" && + typeof credentialConfig.secretAccessKey === "string" + ); +} + export function validate(config: Record) { return configurationSchema.parse(config); } diff --git a/src/storage/storage.service.ts b/src/storage/storage.service.ts index 50ddec5..4124387 100644 --- a/src/storage/storage.service.ts +++ b/src/storage/storage.service.ts @@ -1,7 +1,10 @@ import { S3Client } from "@aws-sdk/client-s3"; import { Injectable, Logger } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; -import { ConfigurationSchema } from "src/config/configuration"; +import { + ConfigurationSchema, + isS3KeyAuthCredentials, +} from "src/config/configuration"; import { Readable } from "stream"; import { LocalStorageDriver } from "./providers/local.driver"; import { S3StorageDriver } from "./providers/s3.driver"; @@ -23,13 +26,23 @@ export class StorageService { } else if (storageConfig.provider === "s3") { const { bucket, credentials, region, forcePathStyle, endpoint } = storageConfig; - const s3Client = new S3Client({ - credentials, - region, - forcePathStyle, - endpoint, - }); - this.driver = new S3StorageDriver(bucket, s3Client); + + if (isS3KeyAuthCredentials(credentials)) { + const s3Client = new S3Client({ + credentials, + region, + forcePathStyle, + endpoint, + }); + this.driver = new S3StorageDriver(bucket, s3Client); + } else { + const s3Client = new S3Client({ + region, + forcePathStyle, + endpoint, + }); + this.driver = new S3StorageDriver(bucket, s3Client); + } } }