stratal 0.0.17 → 0.0.18

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.
Files changed (178) hide show
  1. package/dist/{base-email.provider-DypUAfWm.mjs → base-email.provider-Cuw4OAB0.mjs} +1 -1
  2. package/dist/{base-email.provider-DypUAfWm.mjs.map → base-email.provider-Cuw4OAB0.mjs.map} +1 -1
  3. package/dist/bin/cloudflare-workers-loader.mjs +33 -1
  4. package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
  5. package/dist/bin/quarry.mjs +182 -5
  6. package/dist/bin/quarry.mjs.map +1 -1
  7. package/dist/cache/index.d.mts +2 -2
  8. package/dist/cache/index.d.mts.map +1 -1
  9. package/dist/cache/index.mjs +3 -10
  10. package/dist/cache/index.mjs.map +1 -1
  11. package/dist/{colors-Y7WIFXs7.mjs → colors-BTAnQRGU.mjs} +1 -1
  12. package/dist/{colors-Y7WIFXs7.mjs.map → colors-BTAnQRGU.mjs.map} +1 -1
  13. package/dist/{command-TnkPYWta.d.mts → command-B1YuV-UZ.d.mts} +2 -2
  14. package/dist/{command-TnkPYWta.d.mts.map → command-B1YuV-UZ.d.mts.map} +1 -1
  15. package/dist/{command-B1CPgsrU.mjs → command-DjGqCYHv.mjs} +3 -3
  16. package/dist/command-DjGqCYHv.mjs.map +1 -0
  17. package/dist/config/index.d.mts +2 -2
  18. package/dist/config/index.mjs +12 -19
  19. package/dist/config/index.mjs.map +1 -1
  20. package/dist/{consumer-registry-Bymm6ff4.d.mts → consumer-registry-BkuHXR_u.d.mts} +1 -1
  21. package/dist/{consumer-registry-Bymm6ff4.d.mts.map → consumer-registry-BkuHXR_u.d.mts.map} +1 -1
  22. package/dist/cron/index.d.mts +2 -2
  23. package/dist/cron/index.d.mts.map +1 -1
  24. package/dist/cron/index.mjs +1 -3
  25. package/dist/{cron-manager-CFBamKKk.mjs → cron-manager-1KnZvojs.mjs} +3 -3
  26. package/dist/{cron-manager-CFBamKKk.mjs.map → cron-manager-1KnZvojs.mjs.map} +1 -1
  27. package/dist/{cron-manager-D7imGwUT.d.mts → cron-manager-BnEZquBL.d.mts} +2 -2
  28. package/dist/{cron-manager-D7imGwUT.d.mts.map → cron-manager-BnEZquBL.d.mts.map} +1 -1
  29. package/dist/di/index.d.mts +2 -2
  30. package/dist/di/index.mjs +3 -3
  31. package/dist/email/index.d.mts +3 -3
  32. package/dist/email/index.mjs +8 -16
  33. package/dist/email/index.mjs.map +1 -1
  34. package/dist/{en-DaewN8hc.mjs → en-3QnZwP-u.mjs} +10 -1
  35. package/dist/en-3QnZwP-u.mjs.map +1 -0
  36. package/dist/errors/index.d.mts +2 -2
  37. package/dist/errors/index.mjs +2 -3
  38. package/dist/errors--RBIvDXr.mjs +1560 -0
  39. package/dist/errors--RBIvDXr.mjs.map +1 -0
  40. package/dist/{errors-DuAR5Wke.mjs → errors-B7hCnXgB.mjs} +2 -2
  41. package/dist/{errors-DuAR5Wke.mjs.map → errors-B7hCnXgB.mjs.map} +1 -1
  42. package/dist/events/index.d.mts +2 -2
  43. package/dist/events/index.mjs +1 -2
  44. package/dist/{events-CvUSgEuN.mjs → events-UTJliZhl.mjs} +2 -2
  45. package/dist/{events-CvUSgEuN.mjs.map → events-UTJliZhl.mjs.map} +1 -1
  46. package/dist/{gateway-context-CNOLkLUC.mjs → gateway-context-BdBFoQd8.mjs} +66 -10
  47. package/dist/gateway-context-BdBFoQd8.mjs.map +1 -0
  48. package/dist/guards/index.d.mts +3 -3
  49. package/dist/guards/index.d.mts.map +1 -1
  50. package/dist/guards/index.mjs +1 -1
  51. package/dist/{guards-DUk_Kzst.mjs → guards-MtDgcHnF.mjs} +1 -1
  52. package/dist/{guards-DUk_Kzst.mjs.map → guards-MtDgcHnF.mjs.map} +1 -1
  53. package/dist/i18n/index.d.mts +3 -3
  54. package/dist/i18n/index.mjs +3 -16
  55. package/dist/i18n/messages/en/index.d.mts +1 -1
  56. package/dist/i18n/messages/en/index.mjs +1 -1
  57. package/dist/i18n/utils/index.d.mts +30 -0
  58. package/dist/i18n/utils/index.d.mts.map +1 -0
  59. package/dist/i18n/utils/index.mjs +2 -0
  60. package/dist/i18n/validation/index.d.mts +1 -1
  61. package/dist/i18n/validation/index.mjs +1 -1
  62. package/dist/i18n.module-BpLLLCTg.mjs +2462 -0
  63. package/dist/i18n.module-BpLLLCTg.mjs.map +1 -0
  64. package/dist/{index-D_w_Rmtd.d.mts → index-BDh9J2KD.d.mts} +10 -1
  65. package/dist/{index-D_w_Rmtd.d.mts.map → index-BDh9J2KD.d.mts.map} +1 -1
  66. package/dist/{index-Dp6A5ywM.d.mts → index-BR23zDMy.d.mts} +1 -1
  67. package/dist/{index-Dp6A5ywM.d.mts.map → index-BR23zDMy.d.mts.map} +1 -1
  68. package/dist/index-BrmS34sa.d.mts +4287 -0
  69. package/dist/index-BrmS34sa.d.mts.map +1 -0
  70. package/dist/{index-DGRe6Yoa.d.mts → index-DPxmo6AY.d.mts} +4 -4
  71. package/dist/{index-DGRe6Yoa.d.mts.map → index-DPxmo6AY.d.mts.map} +1 -1
  72. package/dist/{index-NGxg-KP_.d.mts → index-Dfpd_ypO.d.mts} +36 -7
  73. package/dist/index-Dfpd_ypO.d.mts.map +1 -0
  74. package/dist/index.d.mts +4 -3
  75. package/dist/index.d.mts.map +1 -1
  76. package/dist/index.mjs +1 -20
  77. package/dist/{is-command-DJVI6wEJ.mjs → is-command-PvULqiTa.mjs} +2 -2
  78. package/dist/{is-command-DJVI6wEJ.mjs.map → is-command-PvULqiTa.mjs.map} +1 -1
  79. package/dist/{is-seeder-D5MIEcdz.mjs → is-seeder-BN9Ej1r7.mjs} +1 -1
  80. package/dist/{is-seeder-D5MIEcdz.mjs.map → is-seeder-BN9Ej1r7.mjs.map} +1 -1
  81. package/dist/logger/index.d.mts +1 -1
  82. package/dist/logger/index.mjs +1 -1
  83. package/dist/{logger-CGT91VY6.mjs → logger-c0ftIK4G.mjs} +29 -29
  84. package/dist/logger-c0ftIK4G.mjs.map +1 -0
  85. package/dist/module/index.d.mts +3 -4
  86. package/dist/module/index.d.mts.map +1 -1
  87. package/dist/module/index.mjs +1 -10
  88. package/dist/module-C3YZ-kZN.mjs +719 -0
  89. package/dist/module-C3YZ-kZN.mjs.map +1 -0
  90. package/dist/openapi/index.d.mts +3 -3
  91. package/dist/openapi/index.mjs +2 -15
  92. package/dist/{openapi-tools.service-B3TxYKoQ.mjs → openapi-tools.service-B77QXD56.mjs} +1 -1
  93. package/dist/{openapi-tools.service-B3TxYKoQ.mjs.map → openapi-tools.service-B77QXD56.mjs.map} +1 -1
  94. package/dist/{openapi.service-DGnX3Fc4.d.mts → openapi.service-6yj0BUY4.d.mts} +9 -17
  95. package/dist/openapi.service-6yj0BUY4.d.mts.map +1 -0
  96. package/dist/quarry/index.d.mts +25 -11
  97. package/dist/quarry/index.d.mts.map +1 -1
  98. package/dist/quarry/index.mjs +4 -8
  99. package/dist/{quarry-registry-B2rkO-JS.mjs → quarry-registry-CQCIlYTO.mjs} +37 -34
  100. package/dist/quarry-registry-CQCIlYTO.mjs.map +1 -0
  101. package/dist/queue/index.d.mts +2 -2
  102. package/dist/queue/index.mjs +3 -13
  103. package/dist/queue/index.mjs.map +1 -1
  104. package/dist/{queue.module-BtI8f4Jo.mjs → queue.module-DIjD6nr-.mjs} +39 -42
  105. package/dist/queue.module-DIjD6nr-.mjs.map +1 -0
  106. package/dist/{resend.provider-bXMEkdRJ.mjs → resend.provider-Bvw36rQy.mjs} +2 -4
  107. package/dist/{resend.provider-bXMEkdRJ.mjs.map → resend.provider-Bvw36rQy.mjs.map} +1 -1
  108. package/dist/router/index.d.mts +2 -2
  109. package/dist/router/index.mjs +5 -16
  110. package/dist/{s3-storage.provider-CttzNnDR.mjs → s3-storage.provider-BAhHDMI3.mjs} +13 -5
  111. package/dist/s3-storage.provider-BAhHDMI3.mjs.map +1 -0
  112. package/dist/seeder/index.d.mts +3 -4
  113. package/dist/seeder/index.d.mts.map +1 -1
  114. package/dist/seeder/index.mjs +2 -6
  115. package/dist/{seeder-R7RXJC35.mjs → seeder-D7VXULXB.mjs} +5 -5
  116. package/dist/{seeder-R7RXJC35.mjs.map → seeder-D7VXULXB.mjs.map} +1 -1
  117. package/dist/setup-BRIN-iYT.mjs +37 -0
  118. package/dist/setup-BRIN-iYT.mjs.map +1 -0
  119. package/dist/{smtp.provider-DrbHQztF.mjs → smtp.provider-CAwpvzvD.mjs} +2 -4
  120. package/dist/{smtp.provider-DrbHQztF.mjs.map → smtp.provider-CAwpvzvD.mjs.map} +1 -1
  121. package/dist/storage/index.d.mts +2 -2
  122. package/dist/storage/index.d.mts.map +1 -1
  123. package/dist/storage/index.mjs +2 -13
  124. package/dist/storage/providers/index.d.mts +2 -1
  125. package/dist/storage/providers/index.d.mts.map +1 -1
  126. package/dist/storage/providers/index.mjs +1 -4
  127. package/dist/{storage-CZKHOhci.mjs → storage-CJ-QOwNv.mjs} +8 -9
  128. package/dist/storage-CJ-QOwNv.mjs.map +1 -0
  129. package/dist/{storage-provider.interface-0IqcdhBf.d.mts → storage-provider.interface-YRtyYBxV.d.mts} +8 -2
  130. package/dist/storage-provider.interface-YRtyYBxV.d.mts.map +1 -0
  131. package/dist/stratal-B7G4i9-N.mjs +502 -0
  132. package/dist/stratal-B7G4i9-N.mjs.map +1 -0
  133. package/dist/{types-DahElfUw.d.mts → types-CN0zONAZ.d.mts} +2 -2
  134. package/dist/types-CN0zONAZ.d.mts.map +1 -0
  135. package/dist/{usage-generator-CVIsENuE.mjs → usage-generator-Cl1HPlUp.mjs} +2 -2
  136. package/dist/{usage-generator-CVIsENuE.mjs.map → usage-generator-Cl1HPlUp.mjs.map} +1 -1
  137. package/dist/{validation-DQTC259A.mjs → validation-B4bePOa_.mjs} +2 -2
  138. package/dist/{validation-DQTC259A.mjs.map → validation-B4bePOa_.mjs.map} +1 -1
  139. package/dist/websocket/index.d.mts +2 -2
  140. package/dist/websocket/index.d.mts.map +1 -1
  141. package/dist/websocket/index.mjs +1 -4
  142. package/dist/workers/index.d.mts +1 -1
  143. package/dist/workers/index.d.mts.map +1 -1
  144. package/dist/workers/index.mjs +2 -20
  145. package/dist/workers/index.mjs.map +1 -1
  146. package/package.json +34 -31
  147. package/dist/application-DfPtIzxF.d.mts +0 -177
  148. package/dist/application-DfPtIzxF.d.mts.map +0 -1
  149. package/dist/command-B1CPgsrU.mjs.map +0 -1
  150. package/dist/en-DaewN8hc.mjs.map +0 -1
  151. package/dist/errors-DSKapqD8.mjs +0 -707
  152. package/dist/errors-DSKapqD8.mjs.map +0 -1
  153. package/dist/gateway-context-CNOLkLUC.mjs.map +0 -1
  154. package/dist/i18n.module-Dn9SrFdS.mjs +0 -1841
  155. package/dist/i18n.module-Dn9SrFdS.mjs.map +0 -1
  156. package/dist/index-BFCxSp_f.d.mts +0 -2625
  157. package/dist/index-BFCxSp_f.d.mts.map +0 -1
  158. package/dist/index-NGxg-KP_.d.mts.map +0 -1
  159. package/dist/logger-CGT91VY6.mjs.map +0 -1
  160. package/dist/middleware/index.d.mts +0 -2
  161. package/dist/middleware/index.mjs +0 -5
  162. package/dist/middleware-Bl-b5pkt.mjs +0 -362
  163. package/dist/middleware-Bl-b5pkt.mjs.map +0 -1
  164. package/dist/module-registry-CmjBX6ol.d.mts +0 -121
  165. package/dist/module-registry-CmjBX6ol.d.mts.map +0 -1
  166. package/dist/module-tUtyVJ5E.mjs +0 -371
  167. package/dist/module-tUtyVJ5E.mjs.map +0 -1
  168. package/dist/openapi.service-DGnX3Fc4.d.mts.map +0 -1
  169. package/dist/quarry-registry-B2rkO-JS.mjs.map +0 -1
  170. package/dist/queue.module-BtI8f4Jo.mjs.map +0 -1
  171. package/dist/router-context-D9R1v2Ac.mjs +0 -267
  172. package/dist/router-context-D9R1v2Ac.mjs.map +0 -1
  173. package/dist/s3-storage.provider-CttzNnDR.mjs.map +0 -1
  174. package/dist/storage-CZKHOhci.mjs.map +0 -1
  175. package/dist/storage-provider.interface-0IqcdhBf.d.mts.map +0 -1
  176. package/dist/stratal-D5smIU1y.mjs +0 -315
  177. package/dist/stratal-D5smIU1y.mjs.map +0 -1
  178. package/dist/types-DahElfUw.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"seeder-R7RXJC35.mjs","names":[],"sources":["../src/seeder/errors.ts","../src/seeder/seeder-registry.ts","../src/seeder/commands/db-seed-list.command.ts","../src/seeder/commands/db-seed.command.ts"],"sourcesContent":["import { ApplicationError, ERROR_CODES } from '../errors'\n\nexport class SeederNotRegisteredError extends ApplicationError {\n constructor(name: string) {\n super(\n 'errors.seederNotRegistered',\n ERROR_CODES.SYSTEM.SEEDER_NOT_REGISTERED,\n { name },\n )\n }\n}\n\nexport class SeederNameCollisionError extends ApplicationError {\n constructor(name: string) {\n super(\n 'errors.seederNameCollision',\n ERROR_CODES.SYSTEM.SEEDER_NAME_COLLISION,\n { name },\n )\n }\n}\n","import type { Application } from '../application'\nimport type { Container } from '../di/container'\nimport type { Constructor } from '../types'\nimport { SeederNameCollisionError, SeederNotRegisteredError } from './errors'\nimport { type Seeder, SEEDER_INTERNALS } from './seeder'\n\nexport const SEEDER_TOKENS = {\n SeederRegistry: Symbol.for('stratal:seeders:registry'),\n} as const\n\nexport class SeederRegistry {\n private seeders = new Set<Constructor<Seeder>>()\n private nameIndex = new Map<string, Constructor<Seeder>>()\n\n constructor(private app: Application) { }\n\n register(SeederClass: Constructor<Seeder>): void {\n const existing = this.nameIndex.get(SeederClass.name)\n if (existing && existing !== SeederClass) {\n throw new SeederNameCollisionError(SeederClass.name)\n }\n this.seeders.add(SeederClass)\n this.nameIndex.set(SeederClass.name, SeederClass)\n }\n\n async run(SeederClass: Constructor<Seeder>, options?: { container?: Container }): Promise<void> {\n if (!this.seeders.has(SeederClass)) {\n throw new SeederNotRegisteredError(SeederClass.name)\n }\n\n const execute = async (container: Container) => {\n const seeder = container.resolve<Seeder>(SeederClass)\n seeder[SEEDER_INTERNALS] = {\n run: (cls) => this.run(cls, { container }),\n container,\n }\n await seeder.run()\n }\n\n if (options?.container) {\n await execute(options.container)\n } else {\n const mockContext = this.app.createMockRouterContext('en')\n await this.app.container.runInRequestScope(mockContext, execute)\n }\n }\n\n async runAll(options?: { container?: Container }): Promise<void> {\n for (const SeederClass of this.seeders) {\n await this.run(SeederClass, options)\n }\n }\n\n find(name: string): Constructor<Seeder> | undefined {\n return this.nameIndex.get(name)\n }\n\n has(SeederClass: Constructor<Seeder>): boolean {\n return this.seeders.has(SeederClass)\n }\n\n list(): { className: string }[] {\n return [...this.seeders].map(cls => ({ className: cls.name }))\n }\n}\n","import { inject } from 'tsyringe'\nimport { Command } from '../../quarry/command'\nimport { type SeederRegistry, SEEDER_TOKENS } from '../seeder-registry'\n\nexport class DbSeedListCommand extends Command {\n static command = 'db:seed:list'\n static description = 'List available database seeders'\n\n constructor(@inject(SEEDER_TOKENS.SeederRegistry) private seeders: SeederRegistry) {\n super()\n }\n\n handle(): undefined | number {\n const list = this.seeders.list()\n if (list.length === 0) {\n this.info('No seeders found')\n return 0\n }\n this.table(['Class'], list.map(s => [s.className]))\n\n return undefined\n }\n}\n","import { inject } from 'tsyringe'\nimport { Command } from '../../quarry/command'\nimport { type SeederRegistry, SEEDER_TOKENS } from '../seeder-registry'\n\nexport class DbSeedCommand extends Command {\n static command = 'db:seed {names* : Seeder class names} {--a|all : Run all seeders} {--dry-run : Preview without executing}'\n static description = 'Run database seeders'\n\n constructor(@inject(SEEDER_TOKENS.SeederRegistry) private seeders: SeederRegistry) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const names = this.array('names')\n const all = this.boolean('all')\n const dryRun = this.boolean('dry-run')\n\n if (names.length > 0 && all) {\n this.warn(`Ignoring \"${names.join(', ')}\" because --all takes precedence`)\n }\n\n if (names.length === 0 && !all) {\n this.fail('Specify one or more seeder class names or use --all')\n return 1\n }\n\n if (dryRun) {\n if (all) {\n const list = this.seeders.list()\n this.info('Dry run — would execute:')\n for (const s of list) {\n this.info(` ${s.className}`)\n }\n } else {\n this.info('Dry run — would execute:')\n for (const name of names) {\n const SeederClass = this.seeders.find(name)\n if (!SeederClass) {\n this.fail(`Seeder \"${name}\" not found`)\n return 1\n }\n this.info(` ${SeederClass.name}`)\n }\n }\n return 0\n }\n\n if (all) {\n await this.seeders.runAll()\n this.success('All seeders completed')\n } else {\n for (const name of names) {\n const SeederClass = this.seeders.find(name)\n if (!SeederClass) {\n this.fail(`Seeder \"${name}\" not found`)\n return 1\n }\n await this.seeders.run(SeederClass)\n this.success(`Seeder \"${name}\" completed`)\n }\n }\n\n return 0\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"seeder-D7VXULXB.mjs","names":[],"sources":["../src/seeder/errors.ts","../src/seeder/seeder-registry.ts","../src/seeder/commands/db-seed-list.command.ts","../src/seeder/commands/db-seed.command.ts"],"sourcesContent":["import { ApplicationError, ERROR_CODES } from '../errors'\n\nexport class SeederNotRegisteredError extends ApplicationError {\n constructor(name: string) {\n super(\n 'errors.seederNotRegistered',\n ERROR_CODES.SYSTEM.SEEDER_NOT_REGISTERED,\n { name },\n )\n }\n}\n\nexport class SeederNameCollisionError extends ApplicationError {\n constructor(name: string) {\n super(\n 'errors.seederNameCollision',\n ERROR_CODES.SYSTEM.SEEDER_NAME_COLLISION,\n { name },\n )\n }\n}\n","import type { Application } from '../application'\nimport type { Container } from '../di/container'\nimport type { Constructor } from '../types'\nimport { SeederNameCollisionError, SeederNotRegisteredError } from './errors'\nimport { type Seeder, SEEDER_INTERNALS } from './seeder'\n\nexport const SEEDER_TOKENS = {\n SeederRegistry: Symbol.for('stratal:seeders:registry'),\n} as const\n\nexport class SeederRegistry {\n private seeders = new Set<Constructor<Seeder>>()\n private nameIndex = new Map<string, Constructor<Seeder>>()\n\n constructor(private app: Application) { }\n\n register(SeederClass: Constructor<Seeder>): void {\n const existing = this.nameIndex.get(SeederClass.name)\n if (existing && existing !== SeederClass) {\n throw new SeederNameCollisionError(SeederClass.name)\n }\n this.seeders.add(SeederClass)\n this.nameIndex.set(SeederClass.name, SeederClass)\n }\n\n async run(SeederClass: Constructor<Seeder>, options?: { container?: Container }): Promise<void> {\n if (!this.seeders.has(SeederClass)) {\n throw new SeederNotRegisteredError(SeederClass.name)\n }\n\n const execute = async (container: Container) => {\n const seeder = container.resolve<Seeder>(SeederClass)\n seeder[SEEDER_INTERNALS] = {\n run: (cls) => this.run(cls, { container }),\n container,\n }\n await seeder.run()\n }\n\n if (options?.container) {\n await execute(options.container)\n } else {\n const mockContext = this.app.createMockRouterContext('en')\n await this.app.container.runInRequestScope(mockContext, execute)\n }\n }\n\n async runAll(options?: { container?: Container }): Promise<void> {\n for (const SeederClass of this.seeders) {\n await this.run(SeederClass, options)\n }\n }\n\n find(name: string): Constructor<Seeder> | undefined {\n return this.nameIndex.get(name)\n }\n\n has(SeederClass: Constructor<Seeder>): boolean {\n return this.seeders.has(SeederClass)\n }\n\n list(): { className: string }[] {\n return [...this.seeders].map(cls => ({ className: cls.name }))\n }\n}\n","import { inject } from 'tsyringe'\nimport { Command } from '../../quarry/command'\nimport { type SeederRegistry, SEEDER_TOKENS } from '../seeder-registry'\n\nexport class DbSeedListCommand extends Command {\n static command = 'db:seed:list'\n static description = 'List available database seeders'\n\n constructor(@inject(SEEDER_TOKENS.SeederRegistry) private seeders: SeederRegistry) {\n super()\n }\n\n handle(): undefined | number {\n const list = this.seeders.list()\n if (list.length === 0) {\n this.info('No seeders found')\n return 0\n }\n this.table(['Class'], list.map(s => [s.className]))\n\n return undefined\n }\n}\n","import { inject } from 'tsyringe'\nimport { Command } from '../../quarry/command'\nimport { type SeederRegistry, SEEDER_TOKENS } from '../seeder-registry'\n\nexport class DbSeedCommand extends Command {\n static command = 'db:seed {names* : Seeder class names} {--a|all : Run all seeders} {--dry-run : Preview without executing}'\n static description = 'Run database seeders'\n\n constructor(@inject(SEEDER_TOKENS.SeederRegistry) private seeders: SeederRegistry) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const names = this.array('names')\n const all = this.boolean('all')\n const dryRun = this.boolean('dry-run')\n\n if (names.length > 0 && all) {\n this.warn(`Ignoring \"${names.join(', ')}\" because --all takes precedence`)\n }\n\n if (names.length === 0 && !all) {\n this.fail('Specify one or more seeder class names or use --all')\n return 1\n }\n\n if (dryRun) {\n if (all) {\n const list = this.seeders.list()\n this.info('Dry run — would execute:')\n for (const s of list) {\n this.info(` ${s.className}`)\n }\n } else {\n this.info('Dry run — would execute:')\n for (const name of names) {\n const SeederClass = this.seeders.find(name)\n if (!SeederClass) {\n this.fail(`Seeder \"${name}\" not found`)\n return 1\n }\n this.info(` ${SeederClass.name}`)\n }\n }\n return 0\n }\n\n if (all) {\n await this.seeders.runAll()\n this.success('All seeders completed')\n } else {\n for (const name of names) {\n const SeederClass = this.seeders.find(name)\n if (!SeederClass) {\n this.fail(`Seeder \"${name}\" not found`)\n return 1\n }\n await this.seeders.run(SeederClass)\n this.success(`Seeder \"${name}\" completed`)\n }\n }\n\n return 0\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { compile, registerMessageCompiler } from "@intlify/core-base";
2
+ //#region src/i18n/utils/setup.ts
3
+ /**
4
+ * I18n Setup - Message Compiler Registration
5
+ *
6
+ * Registers a JIT (Just-In-Time) message compiler for @intlify/core-base
7
+ * that works in Cloudflare Workers edge runtime.
8
+ *
9
+ * This must be called ONCE at application startup, before any I18nService instances are created.
10
+ */
11
+ let isRegistered = false;
12
+ /**
13
+ * Setup JIT message compiler for i18n
14
+ *
15
+ * Registers a message compiler that uses JIT compilation mode.
16
+ * In @intlify/core-base v10+, JIT mode is enabled by default, which generates
17
+ * AST (Abstract Syntax Tree) instead of JavaScript code, making it compatible
18
+ * with CSP-restricted environments like Cloudflare Workers.
19
+ *
20
+ * **IMPORTANT:** Call this function once at application startup before creating
21
+ * any I18nService instances. Safe to call multiple times (only registers once).
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // In application entry point (before app.initialize())
26
+ * setupI18nCompiler()
27
+ * ```
28
+ */
29
+ function setupI18nCompiler() {
30
+ if (isRegistered) return;
31
+ registerMessageCompiler(compile);
32
+ isRegistered = true;
33
+ }
34
+ //#endregion
35
+ export { setupI18nCompiler as t };
36
+
37
+ //# sourceMappingURL=setup-BRIN-iYT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-BRIN-iYT.mjs","names":[],"sources":["../src/i18n/utils/setup.ts"],"sourcesContent":["/**\n * I18n Setup - Message Compiler Registration\n *\n * Registers a JIT (Just-In-Time) message compiler for @intlify/core-base\n * that works in Cloudflare Workers edge runtime.\n *\n * This must be called ONCE at application startup, before any I18nService instances are created.\n */\n\nimport { compile, registerMessageCompiler } from '@intlify/core-base'\n\nlet isRegistered = false\n\n/**\n * Setup JIT message compiler for i18n\n *\n * Registers a message compiler that uses JIT compilation mode.\n * In @intlify/core-base v10+, JIT mode is enabled by default, which generates\n * AST (Abstract Syntax Tree) instead of JavaScript code, making it compatible\n * with CSP-restricted environments like Cloudflare Workers.\n *\n * **IMPORTANT:** Call this function once at application startup before creating\n * any I18nService instances. Safe to call multiple times (only registers once).\n *\n * @example\n * ```typescript\n * // In application entry point (before app.initialize())\n * setupI18nCompiler()\n * ```\n */\nexport function setupI18nCompiler(): void {\n // Guard against multiple registrations\n if (isRegistered) {\n return\n }\n\n // Register the compile function from @intlify/core-base as the message compiler\n // In v11+, compile() uses JIT mode by default, generating AST instead of JavaScript code\n // This avoids CSP violations (no eval/new Function) in Cloudflare Workers\n registerMessageCompiler(compile)\n\n isRegistered = true\n}\n"],"mappings":";;;;;;;;;;AAWA,IAAI,eAAe;;;;;;;;;;;;;;;;;;AAmBnB,SAAgB,oBAA0B;AAExC,KAAI,aACF;AAMF,yBAAwB,QAAQ;AAEhC,gBAAe"}
@@ -1,7 +1,5 @@
1
- import "./errors-DSKapqD8.mjs";
2
- import "./logger-CGT91VY6.mjs";
3
1
  import { EmailSmtpConnectionFailedError, SmtpConfigurationMissingError, SmtpHostMissingError } from "./email/index.mjs";
4
- import { t as BaseEmailProvider } from "./base-email.provider-DypUAfWm.mjs";
2
+ import { t as BaseEmailProvider } from "./base-email.provider-Cuw4OAB0.mjs";
5
3
  import * as nodemailer from "nodemailer";
6
4
  import { Readable } from "stream";
7
5
  //#region src/email/providers/smtp.provider.ts
@@ -74,4 +72,4 @@ var SmtpProvider = class extends BaseEmailProvider {
74
72
  //#endregion
75
73
  export { SmtpProvider };
76
74
 
77
- //# sourceMappingURL=smtp.provider-DrbHQztF.mjs.map
75
+ //# sourceMappingURL=smtp.provider-CAwpvzvD.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"smtp.provider-DrbHQztF.mjs","names":[],"sources":["../src/email/providers/smtp.provider.ts"],"sourcesContent":["import type { Transporter } from 'nodemailer'\nimport * as nodemailer from 'nodemailer'\nimport type SMTPTransport from 'nodemailer/lib/smtp-transport'\nimport { Readable } from 'stream'\nimport type { ResolvedEmailAttachment, ResolvedEmailMessage } from '../contracts'\nimport type { EmailModuleOptions } from '../email.module'\nimport { EmailSmtpConnectionFailedError, SmtpConfigurationMissingError, SmtpHostMissingError } from '../errors'\nimport { BaseEmailProvider } from './base-email.provider'\nimport type { EmailSendResult } from './email-provider.interface'\n\n/**\n * SMTP Email Provider\n *\n * Implementation of IEmailProvider using SMTP/nodemailer\n * Supports any SMTP server configured via SMTP_URL\n */\nexport class SmtpProvider extends BaseEmailProvider {\n private readonly transporter: Transporter<SMTPTransport.SentMessageInfo>\n private readonly defaultFrom: { name: string; email: string }\n\n constructor(\n private readonly options: EmailModuleOptions\n ) {\n super()\n\n // Validate SMTP configuration\n if (!this.options.smtp) {\n throw new SmtpConfigurationMissingError()\n }\n\n if (!this.options.smtp.host) {\n throw new SmtpHostMissingError()\n }\n\n // Create nodemailer transporter\n this.transporter = nodemailer.createTransport({\n host: this.options.smtp.host,\n port: this.options.smtp.port,\n secure: this.options.smtp.secure,\n auth: this.options.smtp.username && this.options.smtp.password\n ? {\n user: this.options.smtp.username,\n pass: this.options.smtp.password,\n }\n : undefined,\n })\n\n this.defaultFrom = this.options.from\n }\n\n async send(message: ResolvedEmailMessage): Promise<EmailSendResult> {\n try {\n const from = message.from\n ? `${message.from.name} <${message.from.email}>`\n : `${this.defaultFrom.name} <${this.defaultFrom.email}>`\n\n const info = await this.transporter.sendMail({\n from,\n to: Array.isArray(message.to) ? message.to.join(', ') : message.to,\n subject: message.subject,\n html: message.html,\n text: message.text,\n replyTo: message.replyTo,\n cc: message.cc?.join(', '),\n bcc: message.bcc?.join(', '),\n attachments: message.attachments?.map(attachment => ({\n filename: attachment.filename,\n content: this.toNodeStream(attachment.content),\n contentType: attachment.contentType,\n })),\n })\n\n return {\n messageId: info.messageId,\n accepted: true,\n metadata: {\n provider: 'smtp',\n response: info.response,\n },\n }\n } catch {\n throw new EmailSmtpConnectionFailedError(\n this.options.smtp?.host ?? '',\n this.options.smtp?.port ?? 587\n )\n }\n }\n\n /**\n * Convert attachment content to Node.js stream format\n *\n * Nodemailer expects Node.js Readable streams, not web ReadableStream.\n * Buffer is passed through as-is since nodemailer supports it directly.\n */\n private toNodeStream(content: ResolvedEmailAttachment['content']): Buffer | Readable {\n if (Buffer.isBuffer(content)) {\n return content\n }\n // Convert web ReadableStream to Node.js Readable\n return Readable.fromWeb(content as Parameters<typeof Readable.fromWeb>[0])\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAgBA,IAAa,eAAb,cAAkC,kBAAkB;CAClD;CACA;CAEA,YACE,SACA;AACA,SAAO;AAFU,OAAA,UAAA;AAKjB,MAAI,CAAC,KAAK,QAAQ,KAChB,OAAM,IAAI,+BAA+B;AAG3C,MAAI,CAAC,KAAK,QAAQ,KAAK,KACrB,OAAM,IAAI,sBAAsB;AAIlC,OAAK,cAAc,WAAW,gBAAgB;GAC5C,MAAM,KAAK,QAAQ,KAAK;GACxB,MAAM,KAAK,QAAQ,KAAK;GACxB,QAAQ,KAAK,QAAQ,KAAK;GAC1B,MAAM,KAAK,QAAQ,KAAK,YAAY,KAAK,QAAQ,KAAK,WAClD;IACA,MAAM,KAAK,QAAQ,KAAK;IACxB,MAAM,KAAK,QAAQ,KAAK;IACzB,GACC,KAAA;GACL,CAAC;AAEF,OAAK,cAAc,KAAK,QAAQ;;CAGlC,MAAM,KAAK,SAAyD;AAClE,MAAI;GACF,MAAM,OAAO,QAAQ,OACjB,GAAG,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,MAAM,KAC5C,GAAG,KAAK,YAAY,KAAK,IAAI,KAAK,YAAY,MAAM;GAExD,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS;IAC3C;IACA,IAAI,MAAM,QAAQ,QAAQ,GAAG,GAAG,QAAQ,GAAG,KAAK,KAAK,GAAG,QAAQ;IAChE,SAAS,QAAQ;IACjB,MAAM,QAAQ;IACd,MAAM,QAAQ;IACd,SAAS,QAAQ;IACjB,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC1B,KAAK,QAAQ,KAAK,KAAK,KAAK;IAC5B,aAAa,QAAQ,aAAa,KAAI,gBAAe;KACnD,UAAU,WAAW;KACrB,SAAS,KAAK,aAAa,WAAW,QAAQ;KAC9C,aAAa,WAAW;KACzB,EAAE;IACJ,CAAC;AAEF,UAAO;IACL,WAAW,KAAK;IAChB,UAAU;IACV,UAAU;KACR,UAAU;KACV,UAAU,KAAK;KAChB;IACF;UACK;AACN,SAAM,IAAI,+BACR,KAAK,QAAQ,MAAM,QAAQ,IAC3B,KAAK,QAAQ,MAAM,QAAQ,IAC5B;;;;;;;;;CAUL,aAAqB,SAAgE;AACnF,MAAI,OAAO,SAAS,QAAQ,CAC1B,QAAO;AAGT,SAAO,SAAS,QAAQ,QAAkD"}
1
+ {"version":3,"file":"smtp.provider-CAwpvzvD.mjs","names":[],"sources":["../src/email/providers/smtp.provider.ts"],"sourcesContent":["import type { Transporter } from 'nodemailer'\nimport * as nodemailer from 'nodemailer'\nimport type SMTPTransport from 'nodemailer/lib/smtp-transport'\nimport { Readable } from 'stream'\nimport type { ResolvedEmailAttachment, ResolvedEmailMessage } from '../contracts'\nimport type { EmailModuleOptions } from '../email.module'\nimport { EmailSmtpConnectionFailedError, SmtpConfigurationMissingError, SmtpHostMissingError } from '../errors'\nimport { BaseEmailProvider } from './base-email.provider'\nimport type { EmailSendResult } from './email-provider.interface'\n\n/**\n * SMTP Email Provider\n *\n * Implementation of IEmailProvider using SMTP/nodemailer\n * Supports any SMTP server configured via SMTP_URL\n */\nexport class SmtpProvider extends BaseEmailProvider {\n private readonly transporter: Transporter<SMTPTransport.SentMessageInfo>\n private readonly defaultFrom: { name: string; email: string }\n\n constructor(\n private readonly options: EmailModuleOptions\n ) {\n super()\n\n // Validate SMTP configuration\n if (!this.options.smtp) {\n throw new SmtpConfigurationMissingError()\n }\n\n if (!this.options.smtp.host) {\n throw new SmtpHostMissingError()\n }\n\n // Create nodemailer transporter\n this.transporter = nodemailer.createTransport({\n host: this.options.smtp.host,\n port: this.options.smtp.port,\n secure: this.options.smtp.secure,\n auth: this.options.smtp.username && this.options.smtp.password\n ? {\n user: this.options.smtp.username,\n pass: this.options.smtp.password,\n }\n : undefined,\n })\n\n this.defaultFrom = this.options.from\n }\n\n async send(message: ResolvedEmailMessage): Promise<EmailSendResult> {\n try {\n const from = message.from\n ? `${message.from.name} <${message.from.email}>`\n : `${this.defaultFrom.name} <${this.defaultFrom.email}>`\n\n const info = await this.transporter.sendMail({\n from,\n to: Array.isArray(message.to) ? message.to.join(', ') : message.to,\n subject: message.subject,\n html: message.html,\n text: message.text,\n replyTo: message.replyTo,\n cc: message.cc?.join(', '),\n bcc: message.bcc?.join(', '),\n attachments: message.attachments?.map(attachment => ({\n filename: attachment.filename,\n content: this.toNodeStream(attachment.content),\n contentType: attachment.contentType,\n })),\n })\n\n return {\n messageId: info.messageId,\n accepted: true,\n metadata: {\n provider: 'smtp',\n response: info.response,\n },\n }\n } catch {\n throw new EmailSmtpConnectionFailedError(\n this.options.smtp?.host ?? '',\n this.options.smtp?.port ?? 587\n )\n }\n }\n\n /**\n * Convert attachment content to Node.js stream format\n *\n * Nodemailer expects Node.js Readable streams, not web ReadableStream.\n * Buffer is passed through as-is since nodemailer supports it directly.\n */\n private toNodeStream(content: ResolvedEmailAttachment['content']): Buffer | Readable {\n if (Buffer.isBuffer(content)) {\n return content\n }\n // Convert web ReadableStream to Node.js Readable\n return Readable.fromWeb(content as Parameters<typeof Readable.fromWeb>[0])\n }\n}\n"],"mappings":";;;;;;;;;;;AAgBA,IAAa,eAAb,cAAkC,kBAAkB;CAClD;CACA;CAEA,YACE,SACA;AACA,SAAO;AAFU,OAAA,UAAA;AAKjB,MAAI,CAAC,KAAK,QAAQ,KAChB,OAAM,IAAI,+BAA+B;AAG3C,MAAI,CAAC,KAAK,QAAQ,KAAK,KACrB,OAAM,IAAI,sBAAsB;AAIlC,OAAK,cAAc,WAAW,gBAAgB;GAC5C,MAAM,KAAK,QAAQ,KAAK;GACxB,MAAM,KAAK,QAAQ,KAAK;GACxB,QAAQ,KAAK,QAAQ,KAAK;GAC1B,MAAM,KAAK,QAAQ,KAAK,YAAY,KAAK,QAAQ,KAAK,WAClD;IACA,MAAM,KAAK,QAAQ,KAAK;IACxB,MAAM,KAAK,QAAQ,KAAK;IACzB,GACC,KAAA;GACL,CAAC;AAEF,OAAK,cAAc,KAAK,QAAQ;;CAGlC,MAAM,KAAK,SAAyD;AAClE,MAAI;GACF,MAAM,OAAO,QAAQ,OACjB,GAAG,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,MAAM,KAC5C,GAAG,KAAK,YAAY,KAAK,IAAI,KAAK,YAAY,MAAM;GAExD,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS;IAC3C;IACA,IAAI,MAAM,QAAQ,QAAQ,GAAG,GAAG,QAAQ,GAAG,KAAK,KAAK,GAAG,QAAQ;IAChE,SAAS,QAAQ;IACjB,MAAM,QAAQ;IACd,MAAM,QAAQ;IACd,SAAS,QAAQ;IACjB,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC1B,KAAK,QAAQ,KAAK,KAAK,KAAK;IAC5B,aAAa,QAAQ,aAAa,KAAI,gBAAe;KACnD,UAAU,WAAW;KACrB,SAAS,KAAK,aAAa,WAAW,QAAQ;KAC9C,aAAa,WAAW;KACzB,EAAE;IACJ,CAAC;AAEF,UAAO;IACL,WAAW,KAAK;IAChB,UAAU;IACV,UAAU;KACR,UAAU;KACV,UAAU,KAAK;KAChB;IACF;UACK;AACN,SAAM,IAAI,+BACR,KAAK,QAAQ,MAAM,QAAQ,IAC3B,KAAK,QAAQ,MAAM,QAAQ,IAC5B;;;;;;;;;CAUL,aAAqB,SAAgE;AACnF,MAAI,OAAO,SAAS,QAAQ,CAC1B,QAAO;AAGT,SAAO,SAAS,QAAQ,QAAkD"}
@@ -1,5 +1,5 @@
1
- import { at as DynamicModule, rt as AsyncModuleOptions, s as ApplicationError } from "../index-BFCxSp_f.mjs";
2
- import { _ as StorageEntry, a as uploadResultSchema, c as getPresignedUrlInputSchema, d as fileExistsInputSchema, f as DownloadResult, g as StorageConfig, h as PresignedUrlConfig, i as UploadResult, l as presignedUrlResultSchema, m as deleteFileInputSchema, n as StreamingBlobPayloadInputTypes, o as GetPresignedUrlInput, p as DeleteFileInput, r as UploadOptions, s as PresignedUrlResult, t as IStorageProvider, u as FileExistsInput } from "../storage-provider.interface-0IqcdhBf.mjs";
1
+ import { d as ApplicationError, fn as AsyncModuleOptions, mn as DynamicModule } from "../index-BrmS34sa.mjs";
2
+ import { _ as StorageEntry, a as uploadResultSchema, c as getPresignedUrlInputSchema, d as fileExistsInputSchema, f as DownloadResult, g as StorageConfig, h as PresignedUrlConfig, i as UploadResult, l as presignedUrlResultSchema, m as deleteFileInputSchema, n as StreamingBlobPayloadInputTypes, o as GetPresignedUrlInput, p as DeleteFileInput, r as UploadOptions, s as PresignedUrlResult, t as IStorageProvider, u as FileExistsInput } from "../storage-provider.interface-YRtyYBxV.mjs";
3
3
 
4
4
  //#region src/storage/storage.module.d.ts
5
5
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/storage/storage.module.ts","../../src/storage/storage.tokens.ts","../../src/storage/services/storage-manager.service.ts","../../src/storage/services/storage.service.ts","../../src/storage/errors/disk-not-configured.error.ts","../../src/storage/errors/file-not-found.error.ts","../../src/storage/errors/file-too-large.error.ts","../../src/storage/errors/invalid-disk.error.ts","../../src/storage/errors/invalid-file-type.error.ts","../../src/storage/errors/presigned-url-invalid-expiry.error.ts","../../src/storage/errors/storage-provider-not-supported.error.ts","../../src/storage/errors/storage-response-body-missing.error.ts"],"mappings":";;;;;;;AAoBA;KAFY,oBAAA,GAAuB,aAAA;AAAA,cAMtB,aAAA;EAgBa;;;;;;;;;;;;;;;EAAA,OAAjB,OAAA,CAAQ,OAAA,EAAS,oBAAA,GAAuB,aAAA;EA6BsC;;;;;ACjEvF;;;;;;;;;;;;ACQA;;;EFyDuF,OAA9E,YAAA,CAAa,OAAA,EAAS,kBAAA,CAAmB,oBAAA,IAAwB,aAAA;AAAA;;;;;;;cCjE7D,cAAA;EAAA;;;;;;;;;ADcb;;cELa,qBAAA;EAAA,iBAOQ,OAAA;EAAA,iBANF,SAAA;EAAA,iBACA,gBAAA;EAAA,iBACA,WAAA;cAIE,OAAA,EAAS,aAAA;EFoBJ;;;EAAA,QEZhB,qBAAA;EFyCgE;;;;;;EE7BlE,WAAA,CAAY,QAAA,WAAmB,OAAA,CAAQ,gBAAA;EF6BtC;;;;;;EAAA,QEWO,cAAA;;;;AD5EhB;;EC8FE,aAAA,CAAc,QAAA,WAAmB,YAAA;ED1FzB;;;;;ECuGR,OAAA,CAAQ,QAAA;;;;AAnGV;EA2GE,iBAAA,CAAA;AAAA;;;;AFrGF;;;;;AAEA;;;;;;;;cGOa,cAAA;EAAA,mBAGU,cAAA,EAAgB,qBAAA;EAAA,mBAEhB,OAAA,EAAS,aAAA;cAFT,cAAA,EAAgB,qBAAA,EAEhB,OAAA,EAAS,aAAA;EHQf;;;;;;;;EGGT,MAAA,CACJ,IAAA,EAAM,8BAAA,EACN,YAAA,UACA,OAAA,EAAS,aAAA,EACT,IAAA,YACC,OAAA,CAAQ,YAAA;;;;AF5Cb;;;EE0DQ,QAAA,CAAS,YAAA,UAAsB,IAAA,YAAgB,OAAA,CAAQ,cAAA;;;;;;EAavD,MAAA,CAAO,YAAA,UAAsB,IAAA,YAAgB,OAAA;;;AD/DrD;;;;EC6EQ,MAAA,CAAO,YAAA,UAAsB,IAAA,YAAgB,OAAA;EDjDd;;;;;;;ECgE/B,uBAAA,CACJ,YAAA,UACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;;;;;;;;EAWL,qBAAA,CACJ,YAAA,UACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;ED3CG;;;;;;;ECsDR,qBAAA,CACJ,YAAA,UACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;EDnBM;;;;AC7FnB;;;;ED6FmB,UC+BD,eAAA,CACd,YAAA,UACA,MAAA,qCACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;EA7H0B;;;;;EAAA,UA2I3B,WAAA,CAAY,IAAA;EA3GuC;;;;;;EAAA,UA2HnD,aAAA,CAAc,YAAA,UAAsB,QAAA;EA9D3C;;;;;;;EAAA,UAkFO,2BAAA,CAA4B,IAAA;EA4D3B;;;;;EAAA,UA3CD,iBAAA,CAAkB,SAAA;EA9LP;;;;EAiNrB,iBAAA,CAAA;EAjN8B;;;;;;;;;;;;;;;EAoOxB,aAAA,CACJ,IAAA,EAAM,8BAAA,EACN,YAAA,UACA,OAAA,EAAS,IAAA,CAAK,aAAA;IAA2B,IAAA;EAAA,GACzC,IAAA,YACC,OAAA,CAAQ,YAAA;AAAA;;;cCvQA,sBAAA,SAA+B,gBAAA;cAC9B,IAAA;AAAA;;;cCAD,iBAAA,SAA0B,gBAAA;cACzB,IAAA;AAAA;;;cCDD,iBAAA,SAA0B,gBAAA;cACzB,IAAA,UAAc,OAAA;AAAA;;;cCDf,gBAAA,SAAyB,gBAAA;cACxB,IAAA;AAAA;;;cCDD,oBAAA,SAA6B,gBAAA;cAC5B,QAAA;AAAA;;;cCDD,8BAAA,SAAuC,gBAAA;cACtC,SAAA,UAAmB,GAAA,UAAa,GAAA;AAAA;;;cCDjC,gCAAA,SAAyC,gBAAA;cACxC,QAAA;AAAA;;;cCDD,+BAAA,SAAwC,gBAAA;cACvC,IAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/storage/storage.module.ts","../../src/storage/storage.tokens.ts","../../src/storage/services/storage-manager.service.ts","../../src/storage/services/storage.service.ts","../../src/storage/errors/disk-not-configured.error.ts","../../src/storage/errors/file-not-found.error.ts","../../src/storage/errors/file-too-large.error.ts","../../src/storage/errors/invalid-disk.error.ts","../../src/storage/errors/invalid-file-type.error.ts","../../src/storage/errors/presigned-url-invalid-expiry.error.ts","../../src/storage/errors/storage-provider-not-supported.error.ts","../../src/storage/errors/storage-response-body-missing.error.ts"],"mappings":";;;;;;AAoBA;;KAFY,oBAAA,GAAuB,aAAA;AAAA,cAMtB,aAAA;EAgBoC;;;;;;;;;;;;;;;EAAA,OAAxC,OAAA,CAAQ,OAAA,EAAS,oBAAA,GAAuB,aAAA;EA6BsC;;;;ACjEvF;;;;;;;;;;;;ACQA;;;;EFyDuF,OAA9E,YAAA,CAAa,OAAA,EAAS,kBAAA,CAAmB,oBAAA,IAAwB,aAAA;AAAA;;;;;;;cCjE7D,cAAA;EAAA;;;;;;;;ADcb;;;cELa,qBAAA;EAAA,iBAOQ,OAAA;EAAA,iBANF,SAAA;EAAA,iBACA,gBAAA;EAAA,iBACA,WAAA;cAIE,OAAA,EAAS,aAAA;EFoBmB;;;EAAA,QEZvC,qBAAA;EFyC6E;;;;;;EE7B/E,WAAA,CAAY,QAAA,WAAmB,OAAA,CAAQ,gBAAA;EF6BhB;;;;;;EAAA,QEWf,cAAA;;;AD5EhB;;;EC8FE,aAAA,CAAc,QAAA,WAAmB,YAAA;;;;;;EAajC,OAAA,CAAQ,QAAA;;;AAnGV;;EA2GE,iBAAA,CAAA;AAAA;;;AFrGF;;;;;AAEA;;;;;;;;;AAFA,cGSa,cAAA;EAAA,mBAGU,cAAA,EAAgB,qBAAA;EAAA,mBAEhB,OAAA,EAAS,aAAA;cAFT,cAAA,EAAgB,qBAAA,EAEhB,OAAA,EAAS,aAAA;EHQiB;;;;;;;;EGGzC,MAAA,CACJ,IAAA,EAAM,8BAAA,EACN,YAAA,UACA,OAAA,EAAS,aAAA,EACT,IAAA,YACC,OAAA,CAAQ,YAAA;;;AF5Cb;;;;EE0DQ,QAAA,CAAS,YAAA,UAAsB,IAAA,YAAgB,OAAA,CAAQ,cAAA;;;;;;EAavD,MAAA,CAAO,YAAA,UAAsB,IAAA,YAAgB,OAAA;;AD/DrD;;;;;EC6EQ,MAAA,CAAO,YAAA,UAAsB,IAAA,YAAgB,OAAA;EDSlB;;;;;;;ECM3B,uBAAA,CACJ,YAAA,UACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;EDxFiB;;;;;;;ECmGtB,qBAAA,CACJ,YAAA,UACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;EDzBX;;;;;;;ECoCM,qBAAA,CACJ,YAAA,UACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;;;;AAhHb;;;;;YA4HkB,eAAA,CACd,YAAA,UACA,MAAA,qCACA,SAAA,WACA,IAAA,YACC,OAAA,CAAQ,kBAAA;EA3HmB;;;;;EAAA,UAyIpB,WAAA,CAAY,IAAA;EA3G+B;;;;;;EAAA,UA2H3C,aAAA,CAAc,YAAA,UAAsB,QAAA;EA/CnC;;;;;;;EAAA,UAmED,2BAAA,CAA4B,IAAA;EA4DnC;;;;;EAAA,UA3CO,iBAAA,CAAkB,SAAA;EA9LE;;;;EAiN9B,iBAAA,CAAA;EAjNqB;;;;;;;;;;;;;;;EAoOf,aAAA,CACJ,IAAA,EAAM,8BAAA,EACN,YAAA,UACA,OAAA,EAAS,IAAA,CAAK,aAAA;IAA2B,IAAA;EAAA,GACzC,IAAA,YACC,OAAA,CAAQ,YAAA;AAAA;;;cCvQA,sBAAA,SAA+B,gBAAA;cAC9B,IAAA;AAAA;;;cCAD,iBAAA,SAA0B,gBAAA;cACzB,IAAA;AAAA;;;cCDD,iBAAA,SAA0B,gBAAA;cACzB,IAAA,UAAc,OAAA;AAAA;;;cCDf,gBAAA,SAAyB,gBAAA;cACxB,IAAA;AAAA;;;cCDD,oBAAA,SAA6B,gBAAA;cAC5B,QAAA;AAAA;;;cCDD,8BAAA,SAAuC,gBAAA;cACtC,SAAA,UAAmB,GAAA,UAAa,GAAA;AAAA;;;cCDjC,gCAAA,SAAyC,gBAAA;cACxC,QAAA;AAAA;;;cCDD,+BAAA,SAAwC,gBAAA;cACvC,IAAA;AAAA"}
@@ -1,14 +1,3 @@
1
- import "../errors-DSKapqD8.mjs";
2
- import "../logger-CGT91VY6.mjs";
3
- import "../module-tUtyVJ5E.mjs";
4
- import "../events-CvUSgEuN.mjs";
5
- import "../middleware-Bl-b5pkt.mjs";
6
- import "../router-context-D9R1v2Ac.mjs";
7
- import "../colors-Y7WIFXs7.mjs";
8
- import "../command-B1CPgsrU.mjs";
9
- import "../is-command-DJVI6wEJ.mjs";
10
- import "../is-seeder-D5MIEcdz.mjs";
11
- import "../validation-DQTC259A.mjs";
12
- import { a as InvalidDiskError, c as DiskNotConfiguredError, i as InvalidFileTypeError, n as StorageProviderNotSupportedError, o as FileTooLargeError, r as PresignedUrlInvalidExpiryError, s as FileNotFoundError, t as StorageResponseBodyMissingError } from "../errors-DuAR5Wke.mjs";
13
- import { a as deleteFileInputSchema, c as StorageManagerService, i as fileExistsInputSchema, l as STORAGE_TOKENS, n as getPresignedUrlInputSchema, o as StorageModule, r as presignedUrlResultSchema, s as StorageService, t as uploadResultSchema } from "../storage-CZKHOhci.mjs";
1
+ import { a as InvalidDiskError, c as DiskNotConfiguredError, i as InvalidFileTypeError, n as StorageProviderNotSupportedError, o as FileTooLargeError, r as PresignedUrlInvalidExpiryError, s as FileNotFoundError, t as StorageResponseBodyMissingError } from "../errors-B7hCnXgB.mjs";
2
+ import { a as deleteFileInputSchema, c as StorageManagerService, i as fileExistsInputSchema, l as STORAGE_TOKENS, n as getPresignedUrlInputSchema, o as StorageModule, r as presignedUrlResultSchema, s as StorageService, t as uploadResultSchema } from "../storage-CJ-QOwNv.mjs";
14
3
  export { DiskNotConfiguredError, FileNotFoundError, FileTooLargeError, InvalidDiskError, InvalidFileTypeError, PresignedUrlInvalidExpiryError, STORAGE_TOKENS, StorageManagerService, StorageModule, StorageProviderNotSupportedError, StorageResponseBodyMissingError, StorageService, deleteFileInputSchema, fileExistsInputSchema, getPresignedUrlInputSchema, presignedUrlResultSchema, uploadResultSchema };
@@ -1,4 +1,4 @@
1
- import { _ as StorageEntry, f as DownloadResult, i as UploadResult, n as StreamingBlobPayloadInputTypes, r as UploadOptions, s as PresignedUrlResult, t as IStorageProvider } from "../../storage-provider.interface-0IqcdhBf.mjs";
1
+ import { _ as StorageEntry, f as DownloadResult, i as UploadResult, n as StreamingBlobPayloadInputTypes, r as UploadOptions, s as PresignedUrlResult, t as IStorageProvider } from "../../storage-provider.interface-YRtyYBxV.mjs";
2
2
 
3
3
  //#region src/storage/providers/s3-multipart-provider.interface.d.ts
4
4
  /**
@@ -204,6 +204,7 @@ interface IS3MultipartProvider extends IStorageProvider {
204
204
  */
205
205
  declare class S3StorageProvider implements IS3MultipartProvider {
206
206
  private readonly client;
207
+ private readonly presigningClient;
207
208
  private readonly bucket;
208
209
  private readonly disk;
209
210
  constructor(config: StorageEntry);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/storage/providers/s3-multipart-provider.interface.ts","../../../src/storage/providers/s3-storage.provider.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/storage/providers/s3-multipart-provider.interface.ts","../../../src/storage/providers/s3-storage.provider.ts"],"mappings":"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"}
@@ -1,5 +1,2 @@
1
- import "../../errors-DSKapqD8.mjs";
2
- import "../../logger-CGT91VY6.mjs";
3
- import "../../errors-DuAR5Wke.mjs";
4
- import { t as S3StorageProvider } from "../../s3-storage.provider-CttzNnDR.mjs";
1
+ import { t as S3StorageProvider } from "../../s3-storage.provider-BAhHDMI3.mjs";
5
2
  export { S3StorageProvider };
@@ -1,8 +1,8 @@
1
- import { s as Scope } from "./errors-DSKapqD8.mjs";
2
- import { a as __decorate, d as Transient, o as __decorateParam, s as __decorateMetadata } from "./logger-CGT91VY6.mjs";
3
- import { r as Module } from "./module-tUtyVJ5E.mjs";
4
- import { a as withI18n, i as z } from "./validation-DQTC259A.mjs";
5
- import { a as InvalidDiskError, c as DiskNotConfiguredError, n as StorageProviderNotSupportedError, r as PresignedUrlInvalidExpiryError } from "./errors-DuAR5Wke.mjs";
1
+ import { A as Scope } from "./errors--RBIvDXr.mjs";
2
+ import { a as __decorate, o as __decorateParam, p as Transient, s as __decorateMetadata } from "./logger-c0ftIK4G.mjs";
3
+ import { S as Module } from "./module-C3YZ-kZN.mjs";
4
+ import { a as withI18n, i as z } from "./validation-B4bePOa_.mjs";
5
+ import { a as InvalidDiskError, c as DiskNotConfiguredError, n as StorageProviderNotSupportedError, r as PresignedUrlInvalidExpiryError } from "./errors-B7hCnXgB.mjs";
6
6
  import { inject } from "tsyringe";
7
7
  //#region src/storage/storage.tokens.ts
8
8
  /**
@@ -63,7 +63,7 @@ let StorageManagerService = class StorageManagerService {
63
63
  async createProvider(config) {
64
64
  switch (config.provider) {
65
65
  case "s3": {
66
- const { S3StorageProvider } = await import("./s3-storage.provider-CttzNnDR.mjs").then((n) => n.n);
66
+ const { S3StorageProvider } = await import("./s3-storage.provider-BAhHDMI3.mjs").then((n) => n.n);
67
67
  return new S3StorageProvider(config);
68
68
  }
69
69
  case "gcs": throw new StorageProviderNotSupportedError(config.provider);
@@ -103,7 +103,6 @@ StorageManagerService = __decorate([
103
103
  ], StorageManagerService);
104
104
  //#endregion
105
105
  //#region src/storage/services/storage.service.ts
106
- var _ref;
107
106
  let StorageService = class StorageService {
108
107
  constructor(storageManager, options) {
109
108
  this.storageManager = storageManager;
@@ -285,7 +284,7 @@ StorageService = __decorate([
285
284
  Transient(STORAGE_TOKENS.StorageService),
286
285
  __decorateParam(0, inject(STORAGE_TOKENS.StorageManager)),
287
286
  __decorateParam(1, inject(STORAGE_TOKENS.Options)),
288
- __decorateMetadata("design:paramtypes", [typeof (_ref = typeof StorageManagerService !== "undefined" && StorageManagerService) === "function" ? _ref : Object, Object])
287
+ __decorateMetadata("design:paramtypes", [Object, Object])
289
288
  ], StorageService);
290
289
  //#endregion
291
290
  //#region src/storage/storage.module.ts
@@ -408,4 +407,4 @@ const uploadResultSchema = z.object({
408
407
  //#endregion
409
408
  export { deleteFileInputSchema as a, StorageManagerService as c, fileExistsInputSchema as i, STORAGE_TOKENS as l, getPresignedUrlInputSchema as n, StorageModule as o, presignedUrlResultSchema as r, StorageService as s, uploadResultSchema as t };
410
409
 
411
- //# sourceMappingURL=storage-CZKHOhci.mjs.map
410
+ //# sourceMappingURL=storage-CJ-QOwNv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-CJ-QOwNv.mjs","names":[],"sources":["../src/storage/storage.tokens.ts","../src/storage/services/storage-manager.service.ts","../src/storage/services/storage.service.ts","../src/storage/storage.module.ts","../src/storage/contracts/delete-file.input.ts","../src/storage/contracts/file-exists.input.ts","../src/storage/contracts/get-presigned-url.input.ts","../src/storage/contracts/upload-file.input.ts"],"sourcesContent":["/**\n * Dependency injection tokens for the Storage module\n * Using Symbol-based tokens to avoid magic strings\n */\nexport const STORAGE_TOKENS = {\n Options: Symbol.for('stratal:storage:options'),\n StorageService: Symbol.for('stratal:storage:service'),\n StorageManager: Symbol.for('stratal:storage:manager'),\n} as const\n","import { inject } from 'tsyringe'\nimport { Transient } from '../../di/decorators'\nimport { DiskNotConfiguredError, StorageProviderNotSupportedError } from '../errors'\nimport type { IStorageProvider } from '../providers/storage-provider.interface'\nimport { STORAGE_TOKENS } from '../storage.tokens'\nimport type { StorageConfig, StorageEntry } from '../types'\n\n/**\n * Storage Manager Service\n * Manages multiple storage providers (one per disk)\n * Handles lazy initialization and caching of S3Clients\n */\n@Transient(STORAGE_TOKENS.StorageManager)\nexport class StorageManagerService {\n private readonly providers = new Map<string, IStorageProvider>()\n private readonly creationPromises = new Map<string, Promise<IStorageProvider>>()\n private readonly diskConfigs = new Map<string, StorageEntry>()\n\n constructor(\n @inject(STORAGE_TOKENS.Options)\n private readonly options: StorageConfig\n ) {\n this.initializeDiskConfigs()\n }\n\n /**\n * Initialize disk configurations from options\n */\n private initializeDiskConfigs(): void {\n for (const entry of this.options.storage) {\n this.diskConfigs.set(entry.disk, entry)\n }\n }\n\n /**\n * Get provider for a specific disk\n * Lazily initializes provider on first access\n * @param diskName - Name of the disk\n * @returns Storage provider instance\n */\n async getProvider(diskName: string): Promise<IStorageProvider> {\n // Return cached provider if exists\n const cached = this.providers.get(diskName)\n if (cached) {\n return cached\n }\n\n // Return in-flight creation promise to deduplicate concurrent calls\n const inflight = this.creationPromises.get(diskName)\n if (inflight) {\n return inflight\n }\n\n // Get disk configuration\n const diskConfig = this.diskConfigs.get(diskName)\n if (!diskConfig) {\n throw new DiskNotConfiguredError(diskName)\n }\n\n // Create provider and deduplicate concurrent calls\n const promise = this.createProvider(diskConfig).then((provider) => {\n this.providers.set(diskName, provider)\n this.creationPromises.delete(diskName)\n return provider\n }).catch((error: unknown) => {\n this.creationPromises.delete(diskName)\n throw error\n })\n\n this.creationPromises.set(diskName, promise)\n\n return promise\n }\n\n /**\n * Create a provider instance based on configuration\n * Dynamically imports S3StorageProvider to avoid loading AWS SDK at module evaluation time\n * @param config - Storage entry configuration\n * @returns Storage provider instance\n */\n private async createProvider(config: StorageEntry): Promise<IStorageProvider> {\n switch (config.provider) {\n case 's3': {\n const { S3StorageProvider } = await import('../providers/s3-storage.provider')\n return new S3StorageProvider(config)\n }\n case 'gcs':\n throw new StorageProviderNotSupportedError(config.provider)\n default:\n throw new StorageProviderNotSupportedError(config.provider)\n }\n }\n\n /**\n * Get disk configuration\n * @param diskName - Name of the disk\n * @returns Storage entry configuration\n */\n getDiskConfig(diskName: string): StorageEntry {\n const config = this.diskConfigs.get(diskName)\n if (!config) {\n throw new DiskNotConfiguredError(diskName)\n }\n return config\n }\n\n /**\n * Check if a disk exists\n * @param diskName - Name of the disk\n * @returns True if disk exists, false otherwise\n */\n hasDisk(diskName: string): boolean {\n return this.diskConfigs.has(diskName)\n }\n\n /**\n * Get all available disk names\n * @returns Array of disk names\n */\n getAvailableDisks(): string[] {\n return Array.from(this.diskConfigs.keys())\n }\n}\n","import { inject } from 'tsyringe'\nimport { Transient } from '../../di/decorators'\nimport type { DownloadResult, PresignedUrlResult, UploadOptions, UploadResult } from '../contracts'\nimport {\n InvalidDiskError,\n PresignedUrlInvalidExpiryError,\n} from '../errors'\nimport type { StreamingBlobPayloadInputTypes } from '../providers/storage-provider.interface'\nimport { STORAGE_TOKENS } from '../storage.tokens'\nimport type { StorageConfig } from '../types'\nimport { type StorageManagerService } from './storage-manager.service'\n\n/**\n * Storage Service\n *\n * Main facade for storage operations.\n * Request-scoped for proper isolation.\n *\n * @example\n * ```typescript\n * @inject(STORAGE_TOKENS.StorageService)\n * private readonly storage: StorageService\n *\n * await this.storage.upload(file, 'documents/report.pdf')\n * ```\n */\n@Transient(STORAGE_TOKENS.StorageService)\nexport class StorageService {\n constructor(\n @inject(STORAGE_TOKENS.StorageManager)\n protected readonly storageManager: StorageManagerService,\n @inject(STORAGE_TOKENS.Options)\n protected readonly options: StorageConfig\n ) { }\n\n /**\n * Upload content to storage\n * @param body - Content to upload (stream, buffer, or string)\n * @param relativePath - Relative path within the disk\n * @param options - Upload options including size and mime type\n * @param disk - Optional disk name (uses default if not provided)\n * @returns Upload result with metadata\n */\n async upload(\n body: StreamingBlobPayloadInputTypes,\n relativePath: string,\n options: UploadOptions,\n disk?: string\n ): Promise<UploadResult> {\n const diskName = this.resolveDisk(disk)\n const provider = await this.storageManager.getProvider(diskName)\n const fullPath = this.buildFullPath(relativePath, diskName)\n\n return provider.upload(body, fullPath, options)\n }\n\n /**\n * Download a file from storage\n * @param relativePath - Relative path within the disk\n * @param disk - Optional disk name (uses default if not provided)\n * @returns Download result with stream and metadata\n */\n async download(relativePath: string, disk?: string): Promise<DownloadResult> {\n const diskName = this.resolveDisk(disk)\n const provider = await this.storageManager.getProvider(diskName)\n const fullPath = this.buildFullPath(relativePath, diskName)\n\n return provider.download(fullPath)\n }\n\n /**\n * Delete a file from storage\n * @param relativePath - Relative path within the disk\n * @param disk - Optional disk name (uses default if not provided)\n */\n async delete(relativePath: string, disk?: string): Promise<void> {\n const diskName = this.resolveDisk(disk)\n const provider = await this.storageManager.getProvider(diskName)\n const fullPath = this.buildFullPath(relativePath, diskName)\n\n await provider.delete(fullPath)\n }\n\n /**\n * Check if a file exists in storage\n * @param relativePath - Relative path within the disk\n * @param disk - Optional disk name (uses default if not provided)\n * @returns True if file exists, false otherwise\n */\n async exists(relativePath: string, disk?: string): Promise<boolean> {\n const diskName = this.resolveDisk(disk)\n const provider = await this.storageManager.getProvider(diskName)\n const fullPath = this.buildFullPath(relativePath, diskName)\n\n return provider.exists(fullPath)\n }\n\n /**\n * Generate a presigned download URL\n * @param relativePath - Relative path within the disk\n * @param expiresIn - Optional expiry time in seconds (uses default if not provided)\n * @param disk - Optional disk name (uses default if not provided)\n * @returns Presigned URL result\n */\n async getPresignedDownloadUrl(\n relativePath: string,\n expiresIn?: number,\n disk?: string\n ): Promise<PresignedUrlResult> {\n return this.getPresignedUrl(relativePath, 'GET', expiresIn, disk)\n }\n\n /**\n * Generate a presigned upload URL\n * @param relativePath - Relative path within the disk\n * @param expiresIn - Optional expiry time in seconds (uses default if not provided)\n * @param disk - Optional disk name (uses default if not provided)\n * @returns Presigned URL result\n */\n async getPresignedUploadUrl(\n relativePath: string,\n expiresIn?: number,\n disk?: string\n ): Promise<PresignedUrlResult> {\n return this.getPresignedUrl(relativePath, 'PUT', expiresIn, disk)\n }\n\n /**\n * Generate a presigned delete URL\n * @param relativePath - Relative path within the disk\n * @param expiresIn - Optional expiry time in seconds (uses default if not provided)\n * @param disk - Optional disk name (uses default if not provided)\n * @returns Presigned URL result\n */\n async getPresignedDeleteUrl(\n relativePath: string,\n expiresIn?: number,\n disk?: string\n ): Promise<PresignedUrlResult> {\n return this.getPresignedUrl(relativePath, 'DELETE', expiresIn, disk)\n }\n\n /**\n * Generate a presigned URL for any method\n * @param relativePath - Relative path within the disk\n * @param method - HTTP method (GET, PUT, DELETE, HEAD)\n * @param expiresIn - Optional expiry time in seconds (uses default if not provided)\n * @param disk - Optional disk name (uses default if not provided)\n * @returns Presigned URL result\n */\n protected async getPresignedUrl(\n relativePath: string,\n method: 'GET' | 'PUT' | 'DELETE' | 'HEAD',\n expiresIn?: number,\n disk?: string\n ): Promise<PresignedUrlResult> {\n const diskName = this.resolveDisk(disk)\n const provider = await this.storageManager.getProvider(diskName)\n const fullPath = this.buildFullPath(relativePath, diskName)\n const validatedExpiresIn = this.validateExpiresIn(expiresIn)\n\n return provider.getPresignedUrl(fullPath, method, validatedExpiresIn)\n }\n\n /**\n * Resolve disk name (use default if not provided)\n * @param disk - Optional disk name\n * @returns Resolved disk name\n */\n protected resolveDisk(disk?: string): string {\n const diskName = disk ?? this.options.defaultStorageDisk\n\n if (!this.storageManager.hasDisk(diskName)) {\n throw new InvalidDiskError(diskName)\n }\n\n return diskName\n }\n\n /**\n * Build full path with disk root and path template substitution\n * @param relativePath - Relative path within the disk\n * @param diskName - Name of the disk\n * @returns Full path including disk root\n */\n protected buildFullPath(relativePath: string, diskName: string): string {\n const diskConfig = this.storageManager.getDiskConfig(diskName)\n let root = diskConfig.root || ''\n\n // Substitute template variables\n root = this.substituteTemplateVariables(root)\n\n // Combine root and relative path\n const fullPath = `${root}/${relativePath}`.replace(/\\/+/g, '/').replace(/^\\//, '')\n\n return fullPath\n }\n\n /**\n * Substitute template variables in path\n * Override this method in subclasses to add custom substitutions\n *\n * @param path - Path with template variables\n * @returns Path with substituted variables\n */\n protected substituteTemplateVariables(path: string): string {\n let result = path\n\n // Substitute {date}, {year}, {month}\n const now = new Date()\n result = result.replace(/{date}/g, now.toISOString().split('T')[0])\n result = result.replace(/{year}/g, now.getFullYear().toString())\n result = result.replace(/{month}/g, (now.getMonth() + 1).toString().padStart(2, '0'))\n\n return result\n }\n\n /**\n * Validate expiry time for presigned URLs\n * @param expiresIn - Optional expiry time in seconds\n * @returns Validated expiry time\n */\n protected validateExpiresIn(expiresIn?: number): number {\n const presignedUrlConfig = this.options.presignedUrl\n const validatedExpiresIn = expiresIn ?? presignedUrlConfig.defaultExpiry\n\n // S3 presigned URL limits: 1 second to 7 days (604800 seconds)\n const minExpiry = 1\n const maxExpiry = presignedUrlConfig.maxExpiry\n\n if (validatedExpiresIn < minExpiry || validatedExpiresIn > maxExpiry) {\n throw new PresignedUrlInvalidExpiryError(validatedExpiresIn, minExpiry, maxExpiry)\n }\n\n return validatedExpiresIn\n }\n\n /**\n * Get all available disk names\n * @returns Array of disk names\n */\n getAvailableDisks(): string[] {\n return this.storageManager.getAvailableDisks()\n }\n\n /**\n * Chunked upload for streaming data without known size\n * Uses multipart upload under the hood - handles retries and large files\n *\n * Use this method when:\n * - Content-Length is unknown or unreliable\n * - Uploading from streams that can't be rewound\n * - Need automatic retry handling for transient failures\n *\n * @param body - Content to upload (stream or buffer)\n * @param relativePath - Relative path within the disk\n * @param options - Upload options (mimeType required, size optional)\n * @param disk - Optional disk name (uses default if not provided)\n * @returns Upload result with metadata\n */\n async chunkedUpload(\n body: StreamingBlobPayloadInputTypes,\n relativePath: string,\n options: Omit<UploadOptions, 'size'> & { size?: number },\n disk?: string\n ): Promise<UploadResult> {\n const diskName = this.resolveDisk(disk)\n const provider = await this.storageManager.getProvider(diskName)\n const fullPath = this.buildFullPath(relativePath, diskName)\n\n return provider.chunkedUpload(body, fullPath, options)\n }\n}\n","/**\n * Storage Module\n * Provides file storage capabilities using AWS S3\n * Supports multiple disk configurations with dynamic path templates\n */\n\nimport { Scope } from '../di/types'\nimport { Module } from '../module'\nimport type { AsyncModuleOptions, DynamicModule } from '../module/types'\nimport { StorageManagerService } from './services/storage-manager.service'\nimport { StorageService } from './services/storage.service'\nimport { STORAGE_TOKENS } from './storage.tokens'\nimport type { StorageConfig } from './types'\n\n/**\n * Storage module options\n * Same as StorageConfig from types.ts\n */\nexport type StorageModuleOptions = StorageConfig\n\n@Module({\n providers: [{ provide: STORAGE_TOKENS.StorageManager, useClass: StorageManagerService, scope: Scope.Singleton },\n { provide: STORAGE_TOKENS.StorageService, useClass: StorageService },],\n})\nexport class StorageModule {\n /**\n * Configure StorageModule with static options\n *\n * @param options - Storage configuration options\n * @returns Dynamic module with storage infrastructure\n *\n * @example\n * ```typescript\n * StorageModule.forRoot({\n * storage: [{ disk: 'uploads', provider: 's3', ... }],\n * defaultStorageDisk: 'uploads',\n * presignedUrl: { defaultExpiry: 3600, maxExpiry: 86400 }\n * })\n * ```\n */\n static forRoot(options: StorageModuleOptions): DynamicModule {\n return {\n module: StorageModule,\n providers: [\n { provide: STORAGE_TOKENS.Options, useValue: options },\n ],\n }\n }\n\n /**\n * Configure StorageModule with async factory\n *\n * Use when configuration depends on other services.\n *\n * @param options - Async configuration with factory and inject tokens\n * @returns Dynamic module with storage infrastructure\n *\n * @example\n * ```typescript\n * StorageModule.forRootAsync({\n * inject: [storageConfig.KEY],\n * useFactory: (storage) => ({\n * storage: storage.storage,\n * defaultStorageDisk: storage.defaultStorageDisk,\n * presignedUrl: storage.presignedUrl\n * })\n * })\n * ```\n */\n static forRootAsync(options: AsyncModuleOptions<StorageModuleOptions>): DynamicModule {\n return {\n module: StorageModule,\n providers: [\n {\n provide: STORAGE_TOKENS.Options,\n useFactory: options.useFactory,\n inject: options.inject,\n },\n ],\n }\n }\n}\n","import { z, withI18n } from '../../i18n/validation'\n\nexport const deleteFileInputSchema = z.object({\n path: z.string().min(1, withI18n('zodI18n.errors.custom.filePathRequired')),\n disk: z.string().optional(),\n})\n\nexport type DeleteFileInput = z.infer<typeof deleteFileInputSchema>\n","import { z, withI18n } from '../../i18n/validation'\n\nexport const fileExistsInputSchema = z.object({\n path: z.string().min(1, withI18n('zodI18n.errors.custom.filePathRequired')),\n disk: z.string().optional(),\n})\n\nexport type FileExistsInput = z.infer<typeof fileExistsInputSchema>\n","import { z, withI18n } from '../../i18n/validation'\n\nexport const getPresignedUrlInputSchema = z.object({\n path: z.string().min(1, withI18n('zodI18n.errors.custom.filePathRequired')),\n method: z.enum(['GET', 'PUT', 'DELETE', 'HEAD']).default('GET'),\n expiresIn: z.number().int().min(1).max(604800).optional(),\n disk: z.string().optional(),\n})\n\nexport type GetPresignedUrlInput = z.infer<typeof getPresignedUrlInputSchema>\n\nexport const presignedUrlResultSchema = z.object({\n url: z.string().url(),\n expiresIn: z.number(),\n expiresAt: z.date(),\n method: z.enum(['GET', 'PUT', 'DELETE', 'HEAD']),\n})\n\nexport type PresignedUrlResult = z.infer<typeof presignedUrlResultSchema>\n","import { z } from '../../i18n/validation'\n\n/**\n * Upload options for streaming uploads\n */\nexport interface UploadOptions {\n /**\n * Size of the content in bytes\n */\n size: number\n /**\n * MIME type of the content\n */\n mimeType?: string\n /**\n * Custom metadata to store with the object (S3-specific)\n * Stored as S3 object metadata headers\n */\n metadata?: Record<string, string>\n /**\n * Object tagging for lifecycle policies (S3-specific)\n * Format: key=value (e.g., \"Tus-Completed=true\")\n */\n tagging?: string\n}\n\nexport const uploadResultSchema = z.object({\n path: z.string(),\n disk: z.string(),\n fullPath: z.string(),\n size: z.number(),\n mimeType: z.string(),\n uploadedAt: z.date(),\n})\n\nexport type UploadResult = z.infer<typeof uploadResultSchema>\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { o as z } from "./index-NGxg-KP_.mjs";
1
+ import { o as z } from "./index-Dfpd_ypO.mjs";
2
2
  import { PutObjectCommandInput } from "@aws-sdk/client-s3";
3
3
 
4
4
  //#region src/storage/types.d.ts
@@ -10,6 +10,12 @@ interface StorageEntry {
10
10
  disk: string;
11
11
  provider: 's3' | 'gcs';
12
12
  endpoint: string;
13
+ /**
14
+ * Base URL for generating presigned/temporary URLs (client-accessible).
15
+ * When set, presigned URLs use this host instead of `endpoint`.
16
+ * Useful when the S3 API endpoint differs from the client-facing URL.
17
+ */
18
+ url?: string;
13
19
  bucket: string;
14
20
  region: string;
15
21
  accessKeyId: string;
@@ -194,4 +200,4 @@ interface IStorageProvider {
194
200
  }
195
201
  //#endregion
196
202
  export { StorageEntry as _, uploadResultSchema as a, getPresignedUrlInputSchema as c, fileExistsInputSchema as d, DownloadResult as f, StorageConfig as g, PresignedUrlConfig as h, UploadResult as i, presignedUrlResultSchema as l, deleteFileInputSchema as m, StreamingBlobPayloadInputTypes as n, GetPresignedUrlInput as o, DeleteFileInput as p, UploadOptions as r, PresignedUrlResult as s, IStorageProvider as t, FileExistsInput as u };
197
- //# sourceMappingURL=storage-provider.interface-0IqcdhBf.d.mts.map
203
+ //# sourceMappingURL=storage-provider.interface-YRtyYBxV.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-provider.interface-YRtyYBxV.d.mts","names":[],"sources":["../src/storage/types.ts","../src/storage/contracts/delete-file.input.ts","../src/storage/contracts/download-result.ts","../src/storage/contracts/file-exists.input.ts","../src/storage/contracts/get-presigned-url.input.ts","../src/storage/contracts/upload-file.input.ts","../src/storage/providers/storage-provider.interface.ts"],"mappings":";;;;;;;;UAIiB,YAAA;EAChB,IAAA;EACA,QAAA;EACA,QAAA;EAFA;;;;;EAQA,GAAA;EACA,MAAA;EACA,MAAA;EACA,WAAA;EACA,eAAA;EACA,IAAA;EACA,UAAA;AAAA;;;;UAMgB,kBAAA;EAChB,aAAA;EACA,SAAA;AAAA;;;;UAMgB,aAAA;EAChB,OAAA,EAAS,YAAA;EACT,kBAAA;EACA,YAAA,EAAc,kBAAA;AAAA;;;cClCF,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;KAKtB,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,qBAAA;;;;;;;ADH7C;;UEEiB,cAAA;EFFY;;;EEM3B,QAAA,gBAAwB,cAAA,CAAe,UAAA;EAEvC,QAAA,gBAAwB,OAAA;EAExB,aAAA,gBAA6B,OAAA,CAAQ,UAAA;EFCtC;;;EEIC,WAAA;EFAD;;;EEKC,IAAA;EFCiC;;;;EEKjC,QAAA,GAAW,MAAA;AAAA;;;cC5BA,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;KAKtB,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,qBAAA;;;cCLhC,0BAAA,EAA0B,CAAA,CAAA,SAAA;;;;;;;;;;;KAO3B,oBAAA,GAAuB,CAAA,CAAE,KAAA,QAAa,0BAAA;AAAA,cAErC,wBAAA,EAAwB,CAAA,CAAA,SAAA;;;;;;;;;;;KAOzB,kBAAA,GAAqB,CAAA,CAAE,KAAA,QAAa,wBAAA;;;;;;UCb/B,aAAA;ELDY;;;EKK3B,IAAA;ELHD;;;EKOC,QAAA;ELED;;;;EKGC,QAAA,GAAW,MAAA;ELCF;;AAMX;;EKFE,OAAA;AAAA;AAAA,cAGW,kBAAA,EAAkB,CAAA,CAAA,SAAA;;;;;;;;KASnB,YAAA,GAAe,CAAA,CAAE,KAAA,QAAa,kBAAA;;;;;AL/B1C;;KMGY,8BAAA,GAAiC,qBAAA;;;;;UAM5B,gBAAA;ENChB;;;;;;;EMOC,MAAA,CAAO,IAAA,EAAM,8BAAA,EAAgC,IAAA,UAAc,OAAA,EAAS,aAAA,GAAgB,OAAA,CAAQ,YAAA;ENI7E;;;;;EMGf,QAAA,CAAS,IAAA,WAAe,OAAA,CAAQ,cAAA;ENKJ;;;;EMC5B,MAAA,CAAO,IAAA,WAAe,OAAA;ENCvB;;;;;EMMC,MAAA,CAAO,IAAA,WAAe,OAAA;;;ALvCxB;;;;;EKgDE,eAAA,CACE,IAAA,UACA,MAAA,qCACA,SAAA,WACC,OAAA,CAAQ,kBAAA;;;;;;;;;EAUX,aAAA,CACE,IAAA,EAAM,8BAAA,EACN,IAAA,UACA,OAAA,EAAS,IAAA,CAAK,aAAA;IAA2B,IAAA;EAAA,IACxC,OAAA,CAAQ,YAAA;AAAA"}