UNPKG

@dudousxd/nestjs-media

Version:

Filesystem + media-library for NestJS — one package

1 lines 38.8 kB
{"version":3,"sources":["../src/index.ts","../src/media.module.ts","../src/media-direct-upload.controller.ts","../src/tokens.ts","../src/media-multipart-upload.controller.ts","../src/media-upload.controller.ts","../src/media.service.ts"],"sourcesContent":["export * from './media.module';\nexport * from './media.service';\nexport * from './media-upload.controller';\nexport * from './media-multipart-upload.controller';\nexport * from './media-direct-upload.controller';\nexport * from './tokens';\nexport {\n ConversionNotDefinedError,\n FileNotFoundError,\n ImageProcessorMissingError,\n InvalidPartNumberError,\n MediaNotFoundError,\n MimeNotAllowedError,\n ResumableUploadManager,\n UnknownDiskError,\n UnsupportedOperationError,\n UploadOffsetConflictError,\n UploadSessionNotFoundError,\n mediaDiagnosticKey,\n publishMedia,\n} from '@dudousxd/nestjs-media-core';\nexport type {\n AttachInput,\n CreateUploadInput,\n DriverCapabilities,\n ListEntry,\n ListOptions,\n ListResult,\n MediaCollectionConfig,\n MediaDiagnosticEvent,\n MediaLibrary,\n MediaRecord,\n MediaStore,\n MultipartPart,\n PutOptions,\n StatResult,\n StorageDriver,\n StorageManager,\n TemporaryUrlOptions,\n UploadSession,\n UploadSessionListFilter,\n UploadSessionStore,\n Visibility,\n} from '@dudousxd/nestjs-media-core';\n","import {\n AttachmentManager,\n DirectUploadManager,\n type ImageProcessor,\n type MediaCollectionConfig,\n MediaLibrary,\n type MediaStore,\n ResumableUploadManager,\n StorageManager,\n type StorageManagerOptions,\n TusUploadHandler,\n type UploadSessionStore,\n} from '@dudousxd/nestjs-media-core';\nimport {\n type CanActivate,\n type DynamicModule,\n Global,\n Module,\n type Provider,\n type Type,\n} from '@nestjs/common';\nimport { MediaDirectUploadController } from './media-direct-upload.controller';\nimport { MediaMultipartUploadController } from './media-multipart-upload.controller';\nimport { MediaUploadController } from './media-upload.controller';\nimport { MediaService } from './media.service';\nimport {\n MEDIA_ATTACHMENTS,\n MEDIA_DIRECT,\n MEDIA_LIBRARY,\n MEDIA_STORAGE,\n MEDIA_STORAGE_SHARED,\n MEDIA_STORE,\n MEDIA_TUS,\n MEDIA_UPLOADS,\n MEDIA_UPLOAD_SESSIONS,\n} from './tokens';\n\nexport interface MediaTusOptions {\n disk: string;\n basePath?: string;\n maxSize?: number;\n keyFor?: (filename: string, token: string, metadata: Record<string, string>) => string;\n}\n\nexport interface MediaDirectOptions {\n disk: string;\n basePath?: string;\n partSize?: number;\n}\n\nexport interface MediaModuleOptions extends StorageManagerOptions {\n /** Enable the media-library layer (layer 2) by providing a persistence store. */\n store?: MediaStore;\n collections?: MediaCollectionConfig[];\n imageProcessor?: ImageProcessor;\n /** Enable resumable (proxy) uploads by providing a session store. */\n uploadSessions?: UploadSessionStore;\n uploadTmpPrefix?: string;\n /** Mount the tus HTTP controller (requires uploadSessions). */\n tus?: MediaTusOptions;\n /** Mount the direct (S3 multipart presign) upload controller. */\n direct?: MediaDirectOptions;\n /**\n * Guard(s) for the upload controllers. A plain array gates ALL THREE (tus,\n * multipart, direct) uniformly; the per-surface object form gates each\n * controller with its own list (upload surfaces often carry different\n * sensitivity — e.g. session creation admin-only, part PUTs any authenticated\n * user). Third-party controller classes can't be annotated with `@UseGuards`\n * by consumers, so without this option the upload surface is mounted with NO\n * auth: anyone who can reach the app can upload. **Uploads are\n * unauthenticated by default — set `guards` (or otherwise gate these routes,\n * e.g. with a global guard) before exposing this module.**\n *\n * Guard classes are added to this module's `providers` so Nest can DI-instantiate\n * them; if a guard has its own dependencies, pass the modules that provide them\n * via `imports`.\n */\n guards?: Type<CanActivate>[] | MediaUploadGuards;\n /**\n * Modules providing dependencies for `guards` (or anything else you inject into\n * them). `forRoot` doesn't otherwise import anything, so this exists purely as\n * an `imports` passthrough for guard wiring.\n */\n imports?: DynamicModule['imports'];\n}\n\nexport interface MediaModuleAsyncOptions {\n imports?: any[];\n inject?: any[];\n useFactory: (...args: any[]) => MediaModuleOptions | Promise<MediaModuleOptions>;\n /**\n * Guard(s) for the upload controllers — plain array gates all three\n * uniformly, the per-surface object form gates each controller with its own\n * list (see `MediaModuleOptions.guards`). This is a STATIC field on\n * the async config object itself — NOT part of the options resolved by\n * `useFactory` — because controllers (and the enhancers bound to them) are\n * wired at module build time, before any async factory has run. If you need\n * the guard to read async-resolved config (e.g. a secret from a ConfigService),\n * have the guard itself inject that service via DI (see `imports`/`inject`\n * above) rather than trying to pass it through `useFactory`.\n *\n * Same default-open caveat as `MediaModuleOptions.guards`: **omitting this\n * leaves the upload surface unauthenticated.**\n */\n guards?: Type<CanActivate>[] | MediaUploadGuards;\n /**\n * Static, build-time control over which upload controllers get mounted at\n * all. Unlike `guards`, this can't be deferred to the async factory either —\n * Nest registers controllers when the module is built, before `useFactory`\n * runs — so `forRootAsync` mounts all three by default (each 501s when its\n * underlying feature is left unconfigured by the factory). Set the ones you\n * never configure to `false` so they don't exist as dead surface at all, e.g.\n * `mount: { direct: false }` when you don't configure `direct` uploads.\n */\n mount?: {\n tus?: boolean;\n multipart?: boolean;\n direct?: boolean;\n };\n}\n\n/**\n * Per-surface guard lists. Each key gates one upload controller; an omitted key\n * leaves that controller UNGUARDED (equivalent to `[]`), it does not fall back\n * to some other surface's guards. Use the plain-array form of `guards` to gate\n * all three uniformly.\n */\nexport interface MediaUploadGuards {\n /** Guards for `MediaUploadController` (tus session create/HEAD/PATCH). */\n tus?: Type<CanActivate>[];\n /** Guards for `MediaMultipartUploadController` (part PUTs + /complete). */\n multipart?: Type<CanActivate>[];\n /** Guards for `MediaDirectUploadController` (S3 presign endpoints). */\n direct?: Type<CanActivate>[];\n}\n\nfunction perSurfaceGuards(\n guards: Type<CanActivate>[] | MediaUploadGuards | undefined,\n): Required<MediaUploadGuards> {\n if (Array.isArray(guards)) return { tus: guards, multipart: guards, direct: guards };\n return {\n tus: guards?.tus ?? [],\n multipart: guards?.multipart ?? [],\n direct: guards?.direct ?? [],\n };\n}\n\n/** Every distinct guard class across the three surfaces, for the module's `providers`. */\nfunction guardProviders(\n guards: Type<CanActivate>[] | MediaUploadGuards | undefined,\n): Type<CanActivate>[] {\n const bySurface = perSurfaceGuards(guards);\n return [...new Set([...bySurface.tus, ...bySurface.multipart, ...bySurface.direct])];\n}\n\n/**\n * Nest's `GUARDS_METADATA` key (`@nestjs/common/constants`), inlined as a literal:\n * `@nestjs/common` has no `exports` map and its ESM-facing files are CJS, so a deep\n * `import ... from '@nestjs/common/constants'` in our ESM build is emitted\n * extensionless and rejected by Node's strict ESM resolver (surfaced by a consumer's\n * vitest externalizing this package). `media-guards.spec.ts` asserts this literal\n * still matches the real constant, so upstream drift fails loudly.\n */\nconst GUARDS_METADATA = '__guards__';\n\n/**\n * Stamp (or clear) `@UseGuards`-equivalent metadata on the three shared upload\n * controller classes.\n *\n * Mechanism: `@UseGuards(...guards)` on a controller just does\n * `Reflect.defineMetadata(GUARDS_METADATA, guards, ControllerClass)` (via Nest's\n * `extendArrayMetadata`, which *appends* to any existing array). We call\n * `Reflect.defineMetadata` directly instead of going through `UseGuards`/`extendArrayMetadata`,\n * so each `forRoot`/`forRootAsync` call REPLACES the metadata rather than\n * appending to it — appending would leak guards across repeated module\n * registrations in the same process (every test file that calls `forRoot`\n * more than once, for instance) since these controller classes are\n * module-level singletons shared by every registration.\n *\n * Nest's `GuardsConsumer` reads this metadata per-request via `Reflector`, not\n * once at boot, so the *last* call to stamp it before a request is served wins\n * for that controller class in this process — replace semantics make that\n * \"last write\" deterministic instead of an ever-growing guard list. The\n * remaining sharp edge: two Nest applications running CONCURRENTLY in the same\n * process with different `guards` on `MediaModule` would still clobber each\n * other (there is exactly one metadata slot per controller class, process-wide).\n * That's a non-issue for a normal app (one `MediaModule` registration) and for\n * this repo's tests (vitest isolates test files, and within a file tests run\n * sequentially against a freshly-compiled `TestingModule` each time).\n */\nfunction applyGuards(guards: Type<CanActivate>[] | MediaUploadGuards | undefined): void {\n const bySurface = perSurfaceGuards(guards);\n Reflect.defineMetadata(GUARDS_METADATA, bySurface.tus, MediaUploadController);\n Reflect.defineMetadata(GUARDS_METADATA, bySurface.multipart, MediaMultipartUploadController);\n Reflect.defineMetadata(GUARDS_METADATA, bySurface.direct, MediaDirectUploadController);\n}\n\nfunction buildLibrary(manager: StorageManager, options: MediaModuleOptions): MediaLibrary | null {\n if (!options.store) return null;\n return new MediaLibrary({\n storage: manager,\n store: options.store,\n ...(options.collections ? { collections: options.collections } : {}),\n ...(options.imageProcessor ? { imageProcessor: options.imageProcessor } : {}),\n });\n}\n\nfunction buildAttachments(manager: StorageManager, options: MediaModuleOptions): AttachmentManager {\n return new AttachmentManager({\n storage: manager,\n ...(options.imageProcessor ? { imageProcessor: options.imageProcessor } : {}),\n });\n}\n\nfunction buildUploads(\n manager: StorageManager,\n options: MediaModuleOptions,\n): ResumableUploadManager | null {\n if (!options.uploadSessions) return null;\n return new ResumableUploadManager({\n storage: manager,\n sessions: options.uploadSessions,\n ...(options.uploadTmpPrefix ? { tmpPrefix: options.uploadTmpPrefix } : {}),\n });\n}\n\nfunction buildTus(\n uploads: ResumableUploadManager | null,\n options: MediaModuleOptions,\n): TusUploadHandler | null {\n if (!uploads || !options.tus) return null;\n return new TusUploadHandler({\n manager: uploads,\n disk: options.tus.disk,\n basePath: options.tus.basePath ?? '/media/uploads',\n ...(options.tus.maxSize ? { maxSize: options.tus.maxSize } : {}),\n ...(options.tus.keyFor ? { keyFor: options.tus.keyFor } : {}),\n });\n}\n\nfunction buildDirect(\n manager: StorageManager,\n options: MediaModuleOptions,\n): DirectUploadManager | null {\n if (!options.direct) return null;\n return new DirectUploadManager({\n storage: manager,\n ...(options.direct.partSize ? { defaultPartSize: options.direct.partSize } : {}),\n });\n}\n\n@Global()\n@Module({})\nexport class MediaModule {\n static forRoot(options: MediaModuleOptions): DynamicModule {\n const manager = new StorageManager(options);\n const uploads = buildUploads(manager, options);\n const tus = buildTus(uploads, options);\n const direct = buildDirect(manager, options);\n applyGuards(options.guards);\n return {\n module: MediaModule,\n imports: options.imports ?? [],\n providers: [\n { provide: MEDIA_STORAGE, useValue: manager },\n { provide: MEDIA_STORAGE_SHARED, useExisting: MEDIA_STORAGE },\n { provide: MEDIA_LIBRARY, useValue: buildLibrary(manager, options) },\n { provide: MEDIA_UPLOADS, useValue: uploads },\n { provide: MEDIA_TUS, useValue: tus },\n { provide: MEDIA_ATTACHMENTS, useValue: buildAttachments(manager, options) },\n { provide: MEDIA_DIRECT, useValue: direct },\n { provide: MEDIA_STORE, useValue: options.store ?? null },\n { provide: MEDIA_UPLOAD_SESSIONS, useValue: options.uploadSessions ?? null },\n ...guardProviders(options.guards),\n MediaService,\n ],\n controllers: [\n ...(tus ? [MediaUploadController] : []),\n ...(uploads ? [MediaMultipartUploadController] : []),\n ...(direct ? [MediaDirectUploadController] : []),\n ],\n exports: [\n MediaService,\n MEDIA_STORAGE,\n MEDIA_STORAGE_SHARED,\n MEDIA_LIBRARY,\n MEDIA_UPLOADS,\n MEDIA_TUS,\n MEDIA_ATTACHMENTS,\n MEDIA_DIRECT,\n MEDIA_STORE,\n MEDIA_UPLOAD_SESSIONS,\n ],\n };\n }\n\n static forRootAsync(options: MediaModuleAsyncOptions): DynamicModule {\n const providers: Provider[] = [\n {\n provide: MEDIA_STORAGE,\n inject: options.inject ?? [],\n useFactory: async (...args: any[]) => new StorageManager(await options.useFactory(...args)),\n },\n { provide: MEDIA_STORAGE_SHARED, useExisting: MEDIA_STORAGE },\n {\n provide: MEDIA_LIBRARY,\n inject: [MEDIA_STORAGE, ...(options.inject ?? [])],\n useFactory: async (manager: StorageManager, ...args: any[]) =>\n buildLibrary(manager, await options.useFactory(...args)),\n },\n {\n provide: MEDIA_UPLOADS,\n inject: [MEDIA_STORAGE, ...(options.inject ?? [])],\n useFactory: async (manager: StorageManager, ...args: any[]) =>\n buildUploads(manager, await options.useFactory(...args)),\n },\n {\n provide: MEDIA_TUS,\n inject: [MEDIA_UPLOADS, ...(options.inject ?? [])],\n useFactory: async (uploads: ResumableUploadManager | null, ...args: any[]) =>\n buildTus(uploads, await options.useFactory(...args)),\n },\n {\n provide: MEDIA_ATTACHMENTS,\n inject: [MEDIA_STORAGE, ...(options.inject ?? [])],\n useFactory: async (manager: StorageManager, ...args: any[]) =>\n buildAttachments(manager, await options.useFactory(...args)),\n },\n {\n provide: MEDIA_DIRECT,\n inject: [MEDIA_STORAGE, ...(options.inject ?? [])],\n useFactory: async (manager: StorageManager, ...args: any[]) =>\n buildDirect(manager, await options.useFactory(...args)),\n },\n {\n provide: MEDIA_STORE,\n inject: options.inject ?? [],\n useFactory: async (...args: any[]) => (await options.useFactory(...args)).store ?? null,\n },\n {\n provide: MEDIA_UPLOAD_SESSIONS,\n inject: options.inject ?? [],\n useFactory: async (...args: any[]) =>\n (await options.useFactory(...args)).uploadSessions ?? null,\n },\n ...guardProviders(options.guards),\n MediaService,\n ];\n applyGuards(options.guards);\n return {\n module: MediaModule,\n imports: options.imports ?? [],\n providers,\n // Unlike `forRoot`, async options are resolved at runtime by `useFactory`,\n // so we cannot know at module-build time whether `tus`/`direct` are configured\n // and therefore cannot mount these controllers conditionally. Each mounted\n // controller injects its nullable manager token (MEDIA_TUS / MEDIA_UPLOADS /\n // MEDIA_DIRECT) and cleanly responds 501 NotImplemented when its feature is\n // left unconfigured by the factory. `mount` is a separate, STATIC escape\n // hatch (see its JSDoc on `MediaModuleAsyncOptions`) for dropping a\n // controller's route surface entirely instead of leaving it mounted-but-501.\n controllers: [\n ...(options.mount?.tus === false ? [] : [MediaUploadController]),\n ...(options.mount?.multipart === false ? [] : [MediaMultipartUploadController]),\n ...(options.mount?.direct === false ? [] : [MediaDirectUploadController]),\n ],\n exports: [\n MediaService,\n MEDIA_STORAGE,\n MEDIA_STORAGE_SHARED,\n MEDIA_LIBRARY,\n MEDIA_UPLOADS,\n MEDIA_TUS,\n MEDIA_ATTACHMENTS,\n MEDIA_DIRECT,\n MEDIA_STORE,\n MEDIA_UPLOAD_SESSIONS,\n ],\n };\n }\n}\n","import type { DirectUploadManager, MultipartPart } from '@dudousxd/nestjs-media-core';\nimport {\n Body,\n Controller,\n Delete,\n Inject,\n NotImplementedException,\n Param,\n Post,\n Query,\n} from '@nestjs/common';\nimport { MEDIA_DIRECT } from './tokens';\n\ninterface InitiateBody {\n key: string;\n contentType?: string;\n size?: number;\n partSize?: number;\n disk?: string;\n}\n\ninterface CompleteBody {\n key: string;\n parts: MultipartPart[];\n disk?: string;\n}\n\n@Controller('media/uploads/direct')\nexport class MediaDirectUploadController {\n constructor(@Inject(MEDIA_DIRECT) private readonly manager: DirectUploadManager | null) {}\n\n @Post('initiate')\n initiate(@Body() body: InitiateBody) {\n if (!this.manager) throw new NotImplementedException('Direct uploads are not configured.');\n return this.manager.createUpload({\n key: body.key,\n ...(body.contentType !== undefined ? { contentType: body.contentType } : {}),\n ...(body.size !== undefined ? { size: body.size } : {}),\n ...(body.partSize !== undefined ? { partSize: body.partSize } : {}),\n ...(body.disk !== undefined ? { disk: body.disk } : {}),\n });\n }\n\n @Post(':uploadId/parts/:partNumber')\n presignPart(\n @Param('uploadId') uploadId: string,\n @Param('partNumber') partNumber: string,\n @Query('key') keyQuery: string | undefined,\n @Query('disk') diskQuery: string | undefined,\n @Body() body: { key?: string; disk?: string },\n ) {\n if (!this.manager) throw new NotImplementedException('Direct uploads are not configured.');\n const key = keyQuery ?? body.key;\n if (!key) throw new NotImplementedException('key is required');\n return this.manager.presignPart({\n key,\n uploadId,\n partNumber: Number(partNumber),\n ...(diskQuery !== undefined\n ? { disk: diskQuery }\n : body.disk !== undefined\n ? { disk: body.disk }\n : {}),\n });\n }\n\n @Post(':uploadId/complete')\n complete(@Param('uploadId') uploadId: string, @Body() body: CompleteBody) {\n if (!this.manager) throw new NotImplementedException('Direct uploads are not configured.');\n return this.manager.completeUpload({\n key: body.key,\n uploadId,\n parts: body.parts,\n ...(body.disk !== undefined ? { disk: body.disk } : {}),\n });\n }\n\n @Delete(':uploadId')\n abort(\n @Param('uploadId') uploadId: string,\n @Query('key') keyQuery: string | undefined,\n @Query('disk') diskQuery: string | undefined,\n @Body() body: { key?: string; disk?: string },\n ) {\n if (!this.manager) throw new NotImplementedException('Direct uploads are not configured.');\n const key = keyQuery ?? body.key;\n if (!key) throw new NotImplementedException('key is required');\n return this.manager.abortUpload({\n key,\n uploadId,\n ...(diskQuery !== undefined\n ? { disk: diskQuery }\n : body.disk !== undefined\n ? { disk: body.disk }\n : {}),\n });\n }\n}\n","export const MEDIA_STORAGE = Symbol('MEDIA_STORAGE');\nexport const MEDIA_LIBRARY = Symbol('MEDIA_LIBRARY');\nexport const MEDIA_UPLOADS = Symbol('MEDIA_UPLOADS');\nexport const MEDIA_TUS = Symbol('MEDIA_TUS');\nexport const MEDIA_ATTACHMENTS = Symbol('MEDIA_ATTACHMENTS');\nexport const MEDIA_DIRECT = Symbol('MEDIA_DIRECT');\n\n// Cross-package tokens: `Symbol.for` (global registry) so the telescope extension can\n// resolve them by value without importing this package (dodges the ESM/CJS dual-copy).\n/** The configured `MediaStore` (or `null`). Consumed by the media telescope dashboard. */\nexport const MEDIA_STORE = Symbol.for('nestjs-media:store');\n/** The configured `UploadSessionStore` (or `null`). Consumed by the media telescope dashboard. */\nexport const MEDIA_UPLOAD_SESSIONS = Symbol.for('nestjs-media:upload-sessions');\n/** Alias for {@link MEDIA_STORAGE} (the `StorageManager`). Consumed by the media telescope dashboard. */\nexport const MEDIA_STORAGE_SHARED = Symbol.for('nestjs-media:storage');\n","import type { ResumableUploadManager } from '@dudousxd/nestjs-media-core';\nimport {\n BadRequestException,\n Controller,\n Get,\n Inject,\n NotImplementedException,\n Param,\n Post,\n Put,\n Req,\n} from '@nestjs/common';\nimport { MEDIA_UPLOADS } from './tokens';\n\n/** Express-like request exposing the raw body Buffer (host must mount a raw parser on the parts path). */\ninterface ReqLike {\n body?: Buffer;\n}\n\n/**\n * Proxy-parallel multipart routes. Bytes flow through the backend: the client\n * PUTs each part (by explicit number) and the backend forwards it to a native\n * S3 multipart part, then a single complete call assembles them. The key/disk\n * are resolved from the session id — never from the client — so this is\n * GameWarden-safe and cannot be pointed at another object.\n *\n * The app MUST mount a raw-body parser with a per-part size cap on\n * `…/media/uploads/:id/parts/:n` so the PUT body arrives as a Buffer.\n */\n@Controller('media/uploads')\nexport class MediaMultipartUploadController {\n constructor(@Inject(MEDIA_UPLOADS) private readonly manager: ResumableUploadManager | null) {}\n\n private requireManager(): ResumableUploadManager {\n if (!this.manager) throw new NotImplementedException('Uploads are not configured.');\n return this.manager;\n }\n\n @Put(':id/parts/:partNumber')\n async uploadPart(\n @Param('id') id: string,\n @Param('partNumber') partNumber: string,\n @Req() req: ReqLike,\n ) {\n const manager = this.requireManager();\n if (!req.body || req.body.byteLength === 0) {\n throw new BadRequestException(\n 'Empty upload part body — ensure a raw-body parser with a size cap is mounted on this route.',\n );\n }\n return manager.writePart(id, Number(partNumber), req.body);\n }\n\n @Post(':id/complete')\n async complete(@Param('id') id: string) {\n const manager = this.requireManager();\n return manager.complete(id);\n }\n\n @Get(':id/parts')\n async listParts(@Param('id') id: string): Promise<{ parts: number[] }> {\n const manager = this.requireManager();\n const parts = await manager.listParts(id);\n return { parts: parts.map((part) => part.partNumber) };\n }\n}\n","import type { TusRequest, TusUploadHandler } from '@dudousxd/nestjs-media-core';\nimport {\n Controller,\n Delete,\n Head,\n Headers,\n Inject,\n NotImplementedException,\n Options,\n Param,\n Patch,\n Post,\n Req,\n Res,\n} from '@nestjs/common';\nimport { MEDIA_TUS } from './tokens';\n\n/** Minimal Express-like response surface this controller writes to. */\ninterface ResLike {\n status(code: number): ResLike;\n setHeader(name: string, value: string): void;\n send(body?: string): void;\n end(): void;\n}\ninterface ReqLike {\n body?: Buffer;\n}\n\n/**\n * tus endpoints. The app must register a raw-body parser for\n * `application/offset+octet-stream` (e.g. `express.raw({ type: 'application/offset+octet-stream' })`)\n * so PATCH bodies arrive as Buffers.\n */\n@Controller('media/uploads')\nexport class MediaUploadController {\n constructor(@Inject(MEDIA_TUS) private readonly handler: TusUploadHandler | null) {}\n\n @Options()\n options(@Res() res: ResLike, @Headers() headers: Record<string, string>): Promise<void> {\n return this.run({ method: 'OPTIONS', headers }, res);\n }\n\n @Post()\n create(@Res() res: ResLike, @Headers() headers: Record<string, string>): Promise<void> {\n return this.run({ method: 'POST', headers }, res);\n }\n\n @Head(':id')\n head(\n @Param('id') id: string,\n @Res() res: ResLike,\n @Headers() headers: Record<string, string>,\n ): Promise<void> {\n return this.run({ method: 'HEAD', uploadId: id, headers }, res);\n }\n\n @Patch(':id')\n patch(\n @Param('id') id: string,\n @Req() req: ReqLike,\n @Res() res: ResLike,\n @Headers() headers: Record<string, string>,\n ): Promise<void> {\n return this.run(\n { method: 'PATCH', uploadId: id, headers, ...(req.body ? { body: req.body } : {}) },\n res,\n );\n }\n\n @Delete(':id')\n remove(\n @Param('id') id: string,\n @Res() res: ResLike,\n @Headers() headers: Record<string, string>,\n ): Promise<void> {\n return this.run({ method: 'DELETE', uploadId: id, headers }, res);\n }\n\n private async run(req: TusRequest, res: ResLike): Promise<void> {\n if (!this.handler) throw new NotImplementedException('Tus uploads are not configured.');\n const result = await this.handler.handle(req);\n res.status(result.status);\n for (const [name, value] of Object.entries(result.headers)) res.setHeader(name, value);\n if (result.body !== undefined) res.send(result.body);\n else res.end();\n }\n}\n","import type {\n AttachmentManager,\n DirectUploadManager,\n MediaLibrary,\n ResumableUploadManager,\n StorageDriver,\n StorageManager,\n} from '@dudousxd/nestjs-media-core';\nimport { Inject, Injectable } from '@nestjs/common';\nimport {\n MEDIA_ATTACHMENTS,\n MEDIA_DIRECT,\n MEDIA_LIBRARY,\n MEDIA_STORAGE,\n MEDIA_UPLOADS,\n} from './tokens';\n\n@Injectable()\nexport class MediaService {\n constructor(\n @Inject(MEDIA_STORAGE) private readonly manager: StorageManager,\n @Inject(MEDIA_LIBRARY) private readonly mediaLibrary: MediaLibrary | null,\n @Inject(MEDIA_UPLOADS) private readonly uploadManager: ResumableUploadManager | null,\n @Inject(MEDIA_ATTACHMENTS) private readonly attachmentManager: AttachmentManager,\n @Inject(MEDIA_DIRECT) private readonly directManager: DirectUploadManager | null,\n ) {}\n\n /** Attachment-as-column API (adonis-attachment style): `media.attachments.createFromFile(...)`. */\n get attachments(): AttachmentManager {\n return this.attachmentManager;\n }\n\n /** Storage layer (layer 1): `media.disk('s3').put(...)`. */\n disk(name?: string): StorageDriver {\n return this.manager.disk(name);\n }\n\n /** Names of the configured disks (delegates to the storage manager). */\n diskNames(): string[] {\n return this.manager.diskNames();\n }\n\n /** Media-library layer (layer 2). Throws if no store was configured. */\n get library(): MediaLibrary {\n if (!this.mediaLibrary) {\n throw new Error(\n 'MediaLibrary is not configured. Pass a `store` to MediaModule.forRoot to enable the media-library layer.',\n );\n }\n return this.mediaLibrary;\n }\n\n /** Resumable (proxy) uploads. Throws if no upload session store was configured. */\n get uploads(): ResumableUploadManager {\n if (!this.uploadManager) {\n throw new Error(\n 'Resumable uploads are not configured. Pass `uploadSessions` to MediaModule.forRoot to enable them.',\n );\n }\n return this.uploadManager;\n }\n\n /** Direct (S3 multipart presign) uploads. Throws if not configured. */\n get directUploads(): DirectUploadManager {\n if (!this.directManager) {\n throw new Error(\n 'Direct uploads are not configured. Pass `direct` to MediaModule.forRoot to enable them.',\n );\n }\n return this.directManager;\n }\n}\n"],"mappings":"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","names":["import_common","MEDIA_STORAGE","Symbol","MEDIA_LIBRARY","MEDIA_UPLOADS","MEDIA_TUS","MEDIA_ATTACHMENTS","MEDIA_DIRECT","MEDIA_STORE","for","MEDIA_UPLOAD_SESSIONS","MEDIA_STORAGE_SHARED","MediaDirectUploadController","manager","initiate","body","NotImplementedException","createUpload","key","contentType","undefined","size","partSize","disk","presignPart","uploadId","partNumber","keyQuery","diskQuery","Number","complete","completeUpload","parts","abort","abortUpload","import_common","MediaMultipartUploadController","manager","requireManager","NotImplementedException","uploadPart","id","partNumber","req","body","byteLength","BadRequestException","writePart","Number","complete","listParts","parts","map","part","import_common","MediaUploadController","handler","options","res","headers","run","method","create","head","id","uploadId","patch","req","body","remove","NotImplementedException","result","handle","status","name","value","Object","entries","setHeader","undefined","send","end","import_common","MediaService","manager","mediaLibrary","uploadManager","attachmentManager","directManager","attachments","disk","name","diskNames","library","Error","uploads","directUploads","perSurfaceGuards","guards","Array","isArray","tus","multipart","direct","guardProviders","bySurface","Set","GUARDS_METADATA","applyGuards","Reflect","defineMetadata","MediaUploadController","MediaMultipartUploadController","MediaDirectUploadController","buildLibrary","manager","options","store","MediaLibrary","storage","collections","imageProcessor","buildAttachments","AttachmentManager","buildUploads","uploadSessions","ResumableUploadManager","sessions","uploadTmpPrefix","tmpPrefix","buildTus","uploads","TusUploadHandler","disk","basePath","maxSize","keyFor","buildDirect","DirectUploadManager","partSize","defaultPartSize","MediaModule","forRoot","StorageManager","module","imports","providers","provide","MEDIA_STORAGE","useValue","MEDIA_STORAGE_SHARED","useExisting","MEDIA_LIBRARY","MEDIA_UPLOADS","MEDIA_TUS","MEDIA_ATTACHMENTS","MEDIA_DIRECT","MEDIA_STORE","MEDIA_UPLOAD_SESSIONS","MediaService","controllers","exports","forRootAsync","inject","useFactory","args","mount","import_nestjs_media_core"]}