nextly 0.0.1 → 0.0.2-alpha.0

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 (268) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +122 -0
  3. package/dist/_dts-chunks/collections-handler.d-DjgO74Wt.d.ts +20540 -0
  4. package/dist/_dts-chunks/config.d-DNwsDnjs.d.ts +2589 -0
  5. package/dist/_dts-chunks/define-component.d-BUgTHmt3.d.ts +1149 -0
  6. package/dist/_dts-chunks/image-processor.d-OO1PmMrv.d.ts +335 -0
  7. package/dist/_dts-chunks/index.d-axCAzZ7m.d.ts +17842 -0
  8. package/dist/_dts-chunks/media.d-DjDOZo4B.d.ts +117 -0
  9. package/dist/_dts-chunks/on-error.d-CHIKWNxd.d.ts +38 -0
  10. package/dist/_dts-chunks/storage.d-BUhQ2we_.d.ts +404 -0
  11. package/dist/actions/index.d.ts +239 -0
  12. package/dist/actions/index.mjs +281 -0
  13. package/dist/api/auth-state.d.ts +5 -0
  14. package/dist/api/auth-state.mjs +131 -0
  15. package/dist/api/collections-schema-detail.d.ts +56 -0
  16. package/dist/api/collections-schema-detail.mjs +244 -0
  17. package/dist/api/collections-schema-export.d.ts +56 -0
  18. package/dist/api/collections-schema-export.mjs +129 -0
  19. package/dist/api/collections-schema.d.ts +59 -0
  20. package/dist/api/collections-schema.mjs +207 -0
  21. package/dist/api/components-detail.d.ts +50 -0
  22. package/dist/api/components-detail.mjs +132 -0
  23. package/dist/api/components.d.ts +69 -0
  24. package/dist/api/components.mjs +144 -0
  25. package/dist/api/email-providers-default.d.ts +40 -0
  26. package/dist/api/email-providers-default.mjs +75 -0
  27. package/dist/api/email-providers-detail.d.ts +81 -0
  28. package/dist/api/email-providers-detail.mjs +109 -0
  29. package/dist/api/email-providers-test.d.ts +43 -0
  30. package/dist/api/email-providers-test.mjs +114 -0
  31. package/dist/api/email-providers.d.ts +69 -0
  32. package/dist/api/email-providers.mjs +110 -0
  33. package/dist/api/email-send-template.d.ts +41 -0
  34. package/dist/api/email-send-template.mjs +58 -0
  35. package/dist/api/email-send.d.ts +42 -0
  36. package/dist/api/email-send.mjs +58 -0
  37. package/dist/api/email-templates-detail.d.ts +74 -0
  38. package/dist/api/email-templates-detail.mjs +112 -0
  39. package/dist/api/email-templates-layout.d.ts +55 -0
  40. package/dist/api/email-templates-layout.mjs +92 -0
  41. package/dist/api/email-templates-preview.d.ts +48 -0
  42. package/dist/api/email-templates-preview.mjs +93 -0
  43. package/dist/api/email-templates.d.ts +61 -0
  44. package/dist/api/email-templates.mjs +118 -0
  45. package/dist/api/health.d.ts +68 -0
  46. package/dist/api/health.mjs +67 -0
  47. package/dist/api/index.d.ts +54 -0
  48. package/dist/api/index.mjs +16 -0
  49. package/dist/api/media-bulk.d.ts +74 -0
  50. package/dist/api/media-bulk.mjs +196 -0
  51. package/dist/api/media-folders.d.ts +112 -0
  52. package/dist/api/media-folders.mjs +187 -0
  53. package/dist/api/media-handlers.d.ts +102 -0
  54. package/dist/api/media-handlers.mjs +437 -0
  55. package/dist/api/media.d.ts +117 -0
  56. package/dist/api/media.mjs +242 -0
  57. package/dist/api/singles-detail.d.ts +87 -0
  58. package/dist/api/singles-detail.mjs +170 -0
  59. package/dist/api/singles-schema-detail.d.ts +54 -0
  60. package/dist/api/singles-schema-detail.mjs +182 -0
  61. package/dist/api/singles.d.ts +34 -0
  62. package/dist/api/singles.mjs +94 -0
  63. package/dist/api/storage-upload-url.d.ts +48 -0
  64. package/dist/api/storage-upload-url.mjs +202 -0
  65. package/dist/api/uploads.d.ts +109 -0
  66. package/dist/api/uploads.mjs +359 -0
  67. package/dist/auth/index.d.ts +425 -0
  68. package/dist/auth/index.mjs +199 -0
  69. package/dist/boot-apply-PQSYLDIN.mjs +7 -0
  70. package/dist/chunk-2OALJTK6.mjs +489 -0
  71. package/dist/chunk-2Q2SX2CS.mjs +365 -0
  72. package/dist/chunk-2TFX4ND3.mjs +13 -0
  73. package/dist/chunk-2TWPDSYD.mjs +87 -0
  74. package/dist/chunk-2W3DVD7S.mjs +647 -0
  75. package/dist/chunk-2ZFKXPQM.mjs +88 -0
  76. package/dist/chunk-3FA7FKAV.mjs +832 -0
  77. package/dist/chunk-3NZ2KMBL.mjs +58 -0
  78. package/dist/chunk-4MJLT6PZ.mjs +0 -0
  79. package/dist/chunk-56WO4WX7.mjs +0 -0
  80. package/dist/chunk-5APFUGAD.mjs +89 -0
  81. package/dist/chunk-5HMZ644B.mjs +108 -0
  82. package/dist/chunk-67GXH6PR.mjs +32 -0
  83. package/dist/chunk-6JNEPWRW.mjs +14368 -0
  84. package/dist/chunk-6NFHQIJD.mjs +45 -0
  85. package/dist/chunk-7P6ASYW6.mjs +9 -0
  86. package/dist/chunk-A3WPLSDT.mjs +1364 -0
  87. package/dist/chunk-AGJ6F2T3.mjs +144 -0
  88. package/dist/chunk-AK6Z23OX.mjs +1464 -0
  89. package/dist/chunk-APKKRD2G.mjs +102 -0
  90. package/dist/chunk-B2GV2BWH.mjs +73 -0
  91. package/dist/chunk-D5HQBNUB.mjs +74 -0
  92. package/dist/chunk-DNNG377Z.mjs +204 -0
  93. package/dist/chunk-DP3G27G5.mjs +135 -0
  94. package/dist/chunk-DV6WVX2Q.mjs +0 -0
  95. package/dist/chunk-DXGGXIUZ.mjs +57 -0
  96. package/dist/chunk-EGXBZCGC.mjs +943 -0
  97. package/dist/chunk-ERCNLX3V.mjs +176 -0
  98. package/dist/chunk-FQULBZ53.mjs +850 -0
  99. package/dist/chunk-G2AA4QLC.mjs +262 -0
  100. package/dist/chunk-GDBJ5JCU.mjs +488 -0
  101. package/dist/chunk-GJNSJU4S.mjs +19 -0
  102. package/dist/chunk-GZ6DCQKC.mjs +69 -0
  103. package/dist/chunk-H26B4FYG.mjs +167 -0
  104. package/dist/chunk-I4JMR3UR.mjs +21 -0
  105. package/dist/chunk-INV7QKLG.mjs +508 -0
  106. package/dist/chunk-IUDOC7N7.mjs +46 -0
  107. package/dist/chunk-IZWPRDC3.mjs +206 -0
  108. package/dist/chunk-KIMNCZGV.mjs +15 -0
  109. package/dist/chunk-L6HW2DA7.mjs +15 -0
  110. package/dist/chunk-LAZXX4HR.mjs +100 -0
  111. package/dist/chunk-LDKCUMHK.mjs +95 -0
  112. package/dist/chunk-LRXMECUA.mjs +0 -0
  113. package/dist/chunk-M52VMPGA.mjs +119 -0
  114. package/dist/chunk-MGUWEEI6.mjs +160 -0
  115. package/dist/chunk-NRUWQ5Z7.mjs +419 -0
  116. package/dist/chunk-NSEFNNU4.mjs +25360 -0
  117. package/dist/chunk-NTHVDFGO.mjs +138 -0
  118. package/dist/chunk-O3QHXMOX.mjs +3166 -0
  119. package/dist/chunk-P7NH2OSC.mjs +2605 -0
  120. package/dist/chunk-PKMABBB5.mjs +184 -0
  121. package/dist/chunk-PWS6XGJK.mjs +76 -0
  122. package/dist/chunk-R6JJQHFC.mjs +20 -0
  123. package/dist/chunk-RJLLGGPG.mjs +0 -0
  124. package/dist/chunk-SBACDPNX.mjs +689 -0
  125. package/dist/chunk-TO5AFLVQ.mjs +124 -0
  126. package/dist/chunk-TS7GHTG2.mjs +5436 -0
  127. package/dist/chunk-UJ2IMJ4W.mjs +133 -0
  128. package/dist/chunk-UOP63Q54.mjs +102 -0
  129. package/dist/chunk-UUOFWCM6.mjs +78 -0
  130. package/dist/chunk-V4EQTOA4.mjs +893 -0
  131. package/dist/chunk-VJ66NCL4.mjs +193 -0
  132. package/dist/chunk-VQJQHVEV.mjs +29 -0
  133. package/dist/chunk-VTJADRO3.mjs +141 -0
  134. package/dist/chunk-VWF3JO32.mjs +0 -0
  135. package/dist/chunk-W4MGXIRR.mjs +27 -0
  136. package/dist/chunk-W5KKPZT5.mjs +1204 -0
  137. package/dist/chunk-WD34YQ6T.mjs +381 -0
  138. package/dist/chunk-WZBYMYVW.mjs +14 -0
  139. package/dist/chunk-X23WKS3Z.mjs +50 -0
  140. package/dist/chunk-X7TXCYYN.mjs +6496 -0
  141. package/dist/chunk-XGI4EMS3.mjs +140 -0
  142. package/dist/chunk-XZKLBMN6.mjs +1153 -0
  143. package/dist/chunk-YB7INWPY.mjs +0 -0
  144. package/dist/chunk-YV4Y7SDL.mjs +83 -0
  145. package/dist/chunk-YZNBLFIW.mjs +1688 -0
  146. package/dist/chunk-YZZCTONM.mjs +263 -0
  147. package/dist/chunk-ZE6A3FYH.mjs +289 -0
  148. package/dist/cli/nextly.mjs +68 -0
  149. package/dist/cli/utils/index.d.ts +449 -0
  150. package/dist/cli/utils/index.mjs +49 -0
  151. package/dist/component-schema-service-5577KVW6.mjs +11 -0
  152. package/dist/config-loader-23YEMC3Z.mjs +23 -0
  153. package/dist/config.d.ts +44 -0
  154. package/dist/config.mjs +109 -0
  155. package/dist/container-ORGFGYSZ.mjs +9 -0
  156. package/dist/database/index.d.ts +12 -0
  157. package/dist/database/index.mjs +40 -0
  158. package/dist/database/seeders/index.d.ts +93 -0
  159. package/dist/database/seeders/index.mjs +47 -0
  160. package/dist/db-sync-demote-LJGKLB3S.mjs +117 -0
  161. package/dist/db-sync-promote-B26VSYQF.mjs +113 -0
  162. package/dist/dev-reload-broadcaster-B73IQ53V.mjs +25 -0
  163. package/dist/dist-M2NOU37V.mjs +19 -0
  164. package/dist/drizzle-kit-lazy-D2M2PXR2.mjs +13 -0
  165. package/dist/dynamic-collection-schema-service-IEXTPIZ7.mjs +8 -0
  166. package/dist/errors/index.d.ts +159 -0
  167. package/dist/errors/index.mjs +10 -0
  168. package/dist/factory-IWMBKUJM.mjs +15 -0
  169. package/dist/first-run-QIVKWJIF.mjs +63 -0
  170. package/dist/fresh-push-NR67DC3R.mjs +8 -0
  171. package/dist/index.d.ts +4175 -0
  172. package/dist/index.mjs +1336 -0
  173. package/dist/local-plugin-PTET4NAT.mjs +7 -0
  174. package/dist/logger-NU46DXNY.mjs +15 -0
  175. package/dist/logger-YE4TC7ZN.mjs +9 -0
  176. package/dist/migration-journal-EP532Y4L.mjs +139 -0
  177. package/dist/migrations/mysql/0000_eager_sentry.sql +174 -0
  178. package/dist/migrations/mysql/0001_soft_giant_girl.sql +27 -0
  179. package/dist/migrations/mysql/0002_media_table.sql +24 -0
  180. package/dist/migrations/mysql/0003_dynamic_singles.sql +37 -0
  181. package/dist/migrations/mysql/0004_dynamic_components.sql +35 -0
  182. package/dist/migrations/mysql/0005_user_management_tables.sql +92 -0
  183. package/dist/migrations/mysql/0006_api_keys.sql +36 -0
  184. package/dist/migrations/mysql/0007_general_settings.sql +20 -0
  185. package/dist/migrations/mysql/0008_site_settings_logo_url.sql +9 -0
  186. package/dist/migrations/mysql/0009_activity_log.sql +30 -0
  187. package/dist/migrations/mysql/0010_site_settings_sidebar.sql +13 -0
  188. package/dist/migrations/mysql/0011_missing_tables_and_columns.sql +54 -0
  189. package/dist/migrations/mysql/0012_image_sizes_and_focal_point.sql +30 -0
  190. package/dist/migrations/mysql/0012_media_folders.sql +43 -0
  191. package/dist/migrations/mysql/0013_user_brute_force_protection.sql +31 -0
  192. package/dist/migrations/mysql/0014_email_template_attachments.sql +12 -0
  193. package/dist/migrations/mysql/0015_media_uploaded_by_nullable.sql +15 -0
  194. package/dist/migrations/mysql/20260429_000000_000_initial_journal.sql +22 -0
  195. package/dist/migrations/mysql/20260501_000000_journal_batch.sql +17 -0
  196. package/dist/migrations/mysql/20260501_000001_audit_log.sql +24 -0
  197. package/dist/migrations/mysql/20260504_000000_nextly_meta.sql +21 -0
  198. package/dist/migrations/mysql/meta/0000_snapshot.json +1005 -0
  199. package/dist/migrations/mysql/meta/0001_snapshot.json +1099 -0
  200. package/dist/migrations/mysql/meta/_journal.json +41 -0
  201. package/dist/migrations/postgresql/0000_misty_king_bedlam.sql +169 -0
  202. package/dist/migrations/postgresql/0001_perpetual_captain_marvel.sql +8 -0
  203. package/dist/migrations/postgresql/0002_sad_spectrum.sql +16 -0
  204. package/dist/migrations/postgresql/0003_hesitant_ultron.sql +17 -0
  205. package/dist/migrations/postgresql/0004_media_table.sql +24 -0
  206. package/dist/migrations/postgresql/0005_media_folders.sql +36 -0
  207. package/dist/migrations/postgresql/0006_dynamic_collections_update.sql +50 -0
  208. package/dist/migrations/postgresql/0007_dynamic_singles.sql +38 -0
  209. package/dist/migrations/postgresql/0008_dynamic_components.sql +37 -0
  210. package/dist/migrations/postgresql/0009_user_management_tables.sql +95 -0
  211. package/dist/migrations/postgresql/0010_api_keys.sql +34 -0
  212. package/dist/migrations/postgresql/0011_general_settings.sql +20 -0
  213. package/dist/migrations/postgresql/0012_site_settings_logo_url.sql +9 -0
  214. package/dist/migrations/postgresql/0013_activity_log.sql +29 -0
  215. package/dist/migrations/postgresql/0014_image_sizes_and_focal_point.sql +33 -0
  216. package/dist/migrations/postgresql/0014_site_settings_sidebar.sql +13 -0
  217. package/dist/migrations/postgresql/0015_user_brute_force_protection.sql +29 -0
  218. package/dist/migrations/postgresql/0016_email_template_attachments.sql +12 -0
  219. package/dist/migrations/postgresql/0017_media_uploaded_by_nullable.sql +15 -0
  220. package/dist/migrations/postgresql/20260429_000000_000_initial_journal.sql +24 -0
  221. package/dist/migrations/postgresql/20260501_000000_journal_batch.sql +17 -0
  222. package/dist/migrations/postgresql/20260501_000001_audit_log.sql +24 -0
  223. package/dist/migrations/postgresql/20260504_000000_nextly_meta.sql +22 -0
  224. package/dist/migrations/postgresql/meta/0000_snapshot.json +1286 -0
  225. package/dist/migrations/postgresql/meta/0001_snapshot.json +1407 -0
  226. package/dist/migrations/postgresql/meta/0002_snapshot.json +1552 -0
  227. package/dist/migrations/postgresql/meta/0003_snapshot.json +1695 -0
  228. package/dist/migrations/postgresql/meta/0010_snapshot.json +2345 -0
  229. package/dist/migrations/postgresql/meta/_journal.json +90 -0
  230. package/dist/migrations/sqlite/0000_api_keys.sql +34 -0
  231. package/dist/migrations/sqlite/0001_general_settings.sql +20 -0
  232. package/dist/migrations/sqlite/0002_site_settings_logo_url.sql +9 -0
  233. package/dist/migrations/sqlite/0003_activity_log.sql +29 -0
  234. package/dist/migrations/sqlite/0004_image_sizes_and_focal_point.sql +29 -0
  235. package/dist/migrations/sqlite/0004_site_settings_sidebar.sql +11 -0
  236. package/dist/migrations/sqlite/0005_user_brute_force_protection.sql +29 -0
  237. package/dist/migrations/sqlite/0006_email_template_attachments.sql +12 -0
  238. package/dist/migrations/sqlite/0007_media_uploaded_by_nullable.sql +111 -0
  239. package/dist/migrations/sqlite/20260429_000000_000_initial_journal.sql +24 -0
  240. package/dist/migrations/sqlite/20260501_000000_journal_batch.sql +19 -0
  241. package/dist/migrations/sqlite/20260501_000001_audit_log.sql +24 -0
  242. package/dist/migrations/sqlite/20260504_000000_nextly_meta.sql +21 -0
  243. package/dist/migrations/sqlite/20260505_000000_user_management_tables.sql +77 -0
  244. package/dist/next.d.ts +57 -0
  245. package/dist/next.mjs +55 -0
  246. package/dist/observability/index.d.ts +87 -0
  247. package/dist/observability/index.mjs +57 -0
  248. package/dist/permissions-3DZZQZMI.mjs +39 -0
  249. package/dist/pipeline-YOML7SWF.mjs +29 -0
  250. package/dist/preview-ZZTR3QGS.mjs +9 -0
  251. package/dist/program-PW6UB2ZC.mjs +5934 -0
  252. package/dist/reconcile-single-tables-7ENVXJGB.mjs +7 -0
  253. package/dist/register-SF6E6FVU.mjs +49 -0
  254. package/dist/reload-config-HWQ4G5MM.mjs +23 -0
  255. package/dist/resolve-single-table-name-JSOMUB3R.mjs +7 -0
  256. package/dist/routeHandler-UNMMJIBM.mjs +77 -0
  257. package/dist/runtime-schema-generator-NRA6A6Z6.mjs +8 -0
  258. package/dist/runtime.d.ts +120 -0
  259. package/dist/runtime.mjs +73 -0
  260. package/dist/schema-hash-FMMG6VPJ.mjs +13 -0
  261. package/dist/schema-registry-EQ36FZDP.mjs +7 -0
  262. package/dist/scripts/load-env.mjs +42 -0
  263. package/dist/storage/index.d.ts +566 -0
  264. package/dist/storage/index.mjs +45 -0
  265. package/dist/super-admin-G5ZK5F4T.mjs +39 -0
  266. package/dist/system-table-service-WGSRVEGT.mjs +17 -0
  267. package/dist/users-7KELGRYJ.mjs +38 -0
  268. package/package.json +308 -9
@@ -0,0 +1,566 @@
1
+ import { I as IStorageAdapter, U as UploadOptions, c as UploadResult, e as StorageAdapterInfo, b as StoragePluginConfig, S as StoragePlugin, B as BulkDeleteResult } from '../_dts-chunks/image-processor.d-OO1PmMrv.d.ts';
2
+ export { d as ClientUploadData, C as CollectionStorageConfig, a as CollectionStorageMap, F as FileMetadata, f as ImageMetadata, g as ImageProcessor, P as ProcessedImage, h as StorageType, i as getImageProcessor, r as resetImageProcessor } from '../_dts-chunks/image-processor.d-OO1PmMrv.d.ts';
3
+ export { M as MediaStorage, a as MediaStorageConfig, g as getMediaStorage, i as initializeMediaStorage, r as resetMediaStorage } from '../_dts-chunks/storage.d-BUhQ2we_.d.ts';
4
+ import { I as ImageSizeVariant } from '../_dts-chunks/media.d-DjDOZo4B.d.ts';
5
+ import 'zod';
6
+
7
+ /**
8
+ * Base Storage Adapter
9
+ *
10
+ * BaseStorageAdapter abstract class with common functionality for storage
11
+ * adapters. Concrete adapters extend this class to inherit auto-detected
12
+ * capabilities, sanitizeFilename(), generateKey(), etc.
13
+ *
14
+ * For the IStorageAdapter interface itself, import from ../types directly.
15
+ */
16
+
17
+ /**
18
+ * Abstract base class for storage adapters.
19
+ *
20
+ * Provides common functionality and helper methods that all storage adapters
21
+ * can use. Concrete adapters should extend this class to inherit:
22
+ * - Default getInfo() implementation with auto-detected capabilities
23
+ * - sanitizeFilename() helper for secure filename handling
24
+ * - generateKey() helper for unique storage key generation
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * class MyStorageAdapter extends BaseStorageAdapter {
29
+ * async upload(buffer: Buffer, options: UploadOptions): Promise<UploadResult> {
30
+ * const key = this.generateKey(options.filename, options.folder);
31
+ * const sanitized = this.sanitizeFilename(options.filename);
32
+ * // ... upload logic
33
+ * }
34
+ *
35
+ * async delete(filePath: string): Promise<void> { ... }
36
+ * async exists(filePath: string): Promise<boolean> { ... }
37
+ * getPublicUrl(filePath: string): string { ... }
38
+ * getType(): string { return 'my-storage'; }
39
+ * }
40
+ * ```
41
+ */
42
+ declare abstract class BaseStorageAdapter implements IStorageAdapter {
43
+ /**
44
+ * Upload file buffer to storage.
45
+ * Must be implemented by concrete adapters.
46
+ */
47
+ abstract upload(buffer: Buffer, options: UploadOptions): Promise<UploadResult>;
48
+ /**
49
+ * Delete file from storage.
50
+ * Must be implemented by concrete adapters.
51
+ */
52
+ abstract delete(filePath: string): Promise<void>;
53
+ /**
54
+ * Check if file exists in storage.
55
+ * Must be implemented by concrete adapters.
56
+ */
57
+ abstract exists(filePath: string): Promise<boolean>;
58
+ /**
59
+ * Get public URL for file.
60
+ * Must be implemented by concrete adapters.
61
+ */
62
+ abstract getPublicUrl(filePath: string): string;
63
+ /**
64
+ * Get storage type identifier.
65
+ * Must be implemented by concrete adapters.
66
+ */
67
+ abstract getType(): string;
68
+ /**
69
+ * Get adapter info including capabilities.
70
+ *
71
+ * Default implementation that auto-detects capabilities by checking
72
+ * if getSignedUrl and getPresignedUploadUrl methods are implemented.
73
+ * Override in subclasses for more accurate capability reporting.
74
+ *
75
+ * @returns Adapter info with type, name, and capability flags
76
+ */
77
+ getInfo(): StorageAdapterInfo;
78
+ /**
79
+ * Sanitize filename to prevent directory traversal and storage issues.
80
+ *
81
+ * Security measures:
82
+ * - Remove path separators (/, \)
83
+ * - Keep only basename (no directories)
84
+ * - Replace problematic characters with hyphens
85
+ * - Preserve alphanumeric, dots, underscores, hyphens
86
+ *
87
+ * @param filename - Original filename to sanitize
88
+ * @returns Sanitized filename safe for storage
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * this.sanitizeFilename('../../../etc/passwd') // 'passwd'
93
+ * this.sanitizeFilename('my file (1).jpg') // 'my-file--1-.jpg'
94
+ * this.sanitizeFilename('photo.jpg') // 'photo.jpg'
95
+ * ```
96
+ */
97
+ protected sanitizeFilename(filename: string): string;
98
+ /**
99
+ * Generate a unique storage key with date-based prefix.
100
+ *
101
+ * Creates keys in format: {folder}/{year}/{month}/{uuid}-{sanitized-filename}
102
+ * This provides:
103
+ * - Unique keys via UUID to prevent collisions
104
+ * - Date-based organization for easier management
105
+ * - Readable filenames for debugging
106
+ *
107
+ * @param filename - Original filename (will be sanitized)
108
+ * @param folder - Optional folder/prefix for organizing uploads
109
+ * @returns Generated storage key
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * this.generateKey('photo.jpg')
114
+ * // 'uploads/2026/01/abc-123-...-photo.jpg'
115
+ *
116
+ * this.generateKey('doc.pdf', 'documents')
117
+ * // 'documents/2026/01/abc-123-...-doc.pdf'
118
+ * ```
119
+ */
120
+ protected generateKey(filename: string, folder?: string): string;
121
+ }
122
+
123
+ /**
124
+ * Local Disk Storage Types
125
+ *
126
+ * Configuration for the local filesystem storage adapter.
127
+ * Used as the default storage for development when no cloud env vars are set.
128
+ */
129
+
130
+ /**
131
+ * Local disk storage adapter configuration.
132
+ *
133
+ * @example Default (zero-config)
134
+ * ```typescript
135
+ * localStorage({ collections: { media: true } })
136
+ * ```
137
+ *
138
+ * @example Custom paths
139
+ * ```typescript
140
+ * localStorage({
141
+ * basePath: './public/media',
142
+ * baseUrl: '/media',
143
+ * collections: { media: true }
144
+ * })
145
+ * ```
146
+ */
147
+ interface LocalStorageConfig extends StoragePluginConfig {
148
+ /**
149
+ * Directory to store uploaded files.
150
+ * Relative to the project root or absolute path.
151
+ *
152
+ * @default './public/uploads'
153
+ */
154
+ basePath?: string;
155
+ /**
156
+ * Base URL prefix for serving files via Next.js static file serving.
157
+ * Files in `public/uploads/` are served at `/uploads/...` by Next.js.
158
+ *
159
+ * @default '/uploads'
160
+ */
161
+ baseUrl?: string;
162
+ }
163
+
164
+ /**
165
+ * Local Disk Storage Plugin
166
+ *
167
+ * Factory function that creates a storage plugin for local filesystem storage.
168
+ * Used as the default storage for development when no cloud env vars are set.
169
+ *
170
+ * @example Zero-config (auto-detected, no explicit config needed)
171
+ * ```typescript
172
+ * // In nextly.config.ts — local storage is used automatically when
173
+ * // no cloud env vars (BLOB_READ_WRITE_TOKEN, S3_BUCKET, etc.) are set.
174
+ * export default defineConfig({
175
+ * storage: await getStorageFromEnv()
176
+ * })
177
+ * ```
178
+ *
179
+ * @example Explicit configuration
180
+ * ```typescript
181
+ * import { localStorage } from 'nextly/storage'
182
+ *
183
+ * export default defineConfig({
184
+ * storage: [
185
+ * localStorage({
186
+ * basePath: './public/uploads',
187
+ * baseUrl: '/uploads',
188
+ * collections: { media: true }
189
+ * })
190
+ * ]
191
+ * })
192
+ * ```
193
+ */
194
+
195
+ /**
196
+ * Create a local disk storage plugin for Nextly.
197
+ *
198
+ * Files are stored on the local filesystem and served via Next.js
199
+ * static file serving. Best for development — use cloud storage
200
+ * (S3, Vercel Blob, Uploadthing) for production.
201
+ *
202
+ * @param config - Local storage configuration
203
+ * @returns A StoragePlugin that MediaStorage can register
204
+ */
205
+ declare function localStorage(config: LocalStorageConfig): StoragePlugin;
206
+
207
+ /**
208
+ * Local Disk Storage Adapter
209
+ *
210
+ * Stores files on the local filesystem. Used as the default storage adapter
211
+ * for development when no cloud storage env vars are detected.
212
+ *
213
+ * Files are stored in `./public/uploads/` by default and served via
214
+ * Next.js static file serving at `/uploads/...`.
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * const adapter = new LocalStorageAdapter({
219
+ * basePath: './public/uploads',
220
+ * baseUrl: '/uploads',
221
+ * });
222
+ *
223
+ * const result = await adapter.upload(buffer, {
224
+ * filename: 'photo.jpg',
225
+ * mimeType: 'image/jpeg',
226
+ * });
227
+ * // result.url = '/uploads/2026/04/abc-photo.jpg'
228
+ * ```
229
+ */
230
+
231
+ interface LocalAdapterConfig {
232
+ /** Directory to store files (default: ./public/uploads) */
233
+ basePath: string;
234
+ /** URL prefix for serving files (default: /uploads) */
235
+ baseUrl: string;
236
+ }
237
+ declare class LocalStorageAdapter extends BaseStorageAdapter {
238
+ private readonly basePath;
239
+ private readonly baseUrl;
240
+ constructor(config: LocalAdapterConfig);
241
+ /**
242
+ * Upload file to local disk.
243
+ * Creates directories as needed and writes the file buffer.
244
+ */
245
+ upload(buffer: Buffer, options: UploadOptions): Promise<UploadResult>;
246
+ /**
247
+ * Delete file from local disk.
248
+ * Silently succeeds if the file doesn't exist.
249
+ */
250
+ delete(filePath: string): Promise<void>;
251
+ /**
252
+ * Bulk delete files from local disk.
253
+ * Uses parallel unlinks with Promise.allSettled for best performance.
254
+ */
255
+ bulkDelete(filePaths: string[]): Promise<BulkDeleteResult>;
256
+ /**
257
+ * Check if file exists on local disk.
258
+ */
259
+ exists(filePath: string): Promise<boolean>;
260
+ /**
261
+ * Get public URL for a file.
262
+ * Returns baseUrl + relative path for Next.js static file serving.
263
+ */
264
+ getPublicUrl(filePath: string): string;
265
+ /**
266
+ * Get storage type identifier.
267
+ */
268
+ getType(): string;
269
+ /**
270
+ * Read file contents from local disk.
271
+ * Returns the file buffer, or null if file not found.
272
+ */
273
+ read(filePath: string): Promise<Buffer | null>;
274
+ /**
275
+ * Resolve a relative file path to an absolute path within basePath.
276
+ * Throws if the resolved path would escape basePath (path traversal attack).
277
+ */
278
+ private resolveAndValidate;
279
+ /**
280
+ * Auto-add the uploads directory to .gitignore on first upload.
281
+ * Prevents accidentally committing uploaded files to git.
282
+ */
283
+ private ensureGitignore;
284
+ }
285
+
286
+ /**
287
+ * Image Size Generation Pipeline
288
+ *
289
+ * Generates named image size variants for uploaded images.
290
+ * Uses Sharp (via ImageProcessor) for resizing and format conversion.
291
+ * Each variant is uploaded to the same storage adapter as the original.
292
+ */
293
+
294
+ /**
295
+ * Configuration for a single image size.
296
+ * Matches the image_sizes DB table structure.
297
+ */
298
+ interface ImageSizeConfig {
299
+ name: string;
300
+ width?: number | null;
301
+ height?: number | null;
302
+ fit: "cover" | "inside" | "contain" | "fill";
303
+ quality: number;
304
+ format: "auto" | "webp" | "jpeg" | "png" | "avif";
305
+ }
306
+ /**
307
+ * Options for generating image sizes.
308
+ */
309
+ interface GenerateImageSizesOptions {
310
+ /** Focal point X (0-100, percentage from left) */
311
+ focalX?: number | null;
312
+ /** Focal point Y (0-100, percentage from top) */
313
+ focalY?: number | null;
314
+ /** Collection slug for storage routing */
315
+ collection?: string;
316
+ /** Storage folder/prefix */
317
+ folder?: string;
318
+ }
319
+ /**
320
+ * Function signature for uploading a buffer to storage.
321
+ * Passed in to decouple from MediaStorage singleton.
322
+ */
323
+ type UploadFn = (buffer: Buffer, options: {
324
+ filename: string;
325
+ mimeType: string;
326
+ folder?: string;
327
+ collection?: string;
328
+ }) => Promise<UploadResult>;
329
+ /**
330
+ * Generate all configured image size variants for an uploaded image.
331
+ *
332
+ * For each size config:
333
+ * 1. Resize/crop the original buffer using ImageProcessor
334
+ * 2. Upload the variant via the provided upload function
335
+ * 3. Collect metadata (url, path, width, height, filesize, mimeType, filename)
336
+ *
337
+ * @param originalBuffer - The original image file buffer
338
+ * @param originalFilename - The original filename (used to derive variant filenames)
339
+ * @param sizes - Array of image size configurations
340
+ * @param uploadFn - Function to upload each variant to storage
341
+ * @param options - Focal point and routing options
342
+ * @returns Map of size name → variant metadata
343
+ */
344
+ declare function generateImageSizes(originalBuffer: Buffer, originalFilename: string, sizes: ImageSizeConfig[], uploadFn: UploadFn, options?: GenerateImageSizesOptions): Promise<Record<string, ImageSizeVariant>>;
345
+ /**
346
+ * Delete all size variants for a media item from storage.
347
+ *
348
+ * @param sizes - The sizes JSONB object from the media record
349
+ * @param deleteFn - Function to delete a file by its storage path
350
+ */
351
+ declare function deleteImageSizes(sizes: Record<string, ImageSizeVariant> | null | undefined, deleteFn: (path: string) => Promise<void>): Promise<void>;
352
+
353
+ /**
354
+ * Retry Utility for Storage Operations
355
+ *
356
+ * Provides exponential backoff retry logic for transient failures.
357
+ * Used by storage adapters for upload, delete, and other operations.
358
+ *
359
+ * Features:
360
+ * - Exponential backoff with jitter
361
+ * - Configurable max attempts
362
+ * - Custom retry condition
363
+ * - Timeout support
364
+ *
365
+ * @example
366
+ * ```typescript
367
+ * const result = await withRetry(
368
+ * () => storage.upload(buffer, options),
369
+ * {
370
+ * maxAttempts: 3,
371
+ * baseDelayMs: 1000,
372
+ * shouldRetry: (error) => isTransientError(error),
373
+ * }
374
+ * );
375
+ * ```
376
+ */
377
+ interface RetryOptions {
378
+ /** Maximum number of attempts (default: 3) */
379
+ maxAttempts?: number;
380
+ /** Base delay in milliseconds (default: 1000) */
381
+ baseDelayMs?: number;
382
+ /** Maximum delay in milliseconds (default: 30000) */
383
+ maxDelayMs?: number;
384
+ /** Exponential backoff factor (default: 2) */
385
+ backoffFactor?: number;
386
+ /** Add random jitter to delay (default: true) */
387
+ jitter?: boolean;
388
+ /** Custom function to determine if error is retryable */
389
+ shouldRetry?: (error: unknown, attempt: number) => boolean;
390
+ /** Callback called before each retry attempt */
391
+ onRetry?: (error: unknown, attempt: number, delayMs: number) => void;
392
+ }
393
+ /**
394
+ * Check if an error is a transient error that should be retried.
395
+ *
396
+ * Transient errors include:
397
+ * - Network timeouts
398
+ * - Connection resets
399
+ * - Rate limiting (429)
400
+ * - Server errors (5xx)
401
+ * - DNS resolution failures
402
+ */
403
+ declare function isTransientError(error: unknown): boolean;
404
+ /**
405
+ * Execute an async function with retry logic.
406
+ *
407
+ * Uses exponential backoff with jitter to handle transient failures.
408
+ *
409
+ * @param fn - Async function to execute
410
+ * @param options - Retry configuration options
411
+ * @returns Result of the function
412
+ * @throws Last error if all retries fail
413
+ *
414
+ * @example
415
+ * ```typescript
416
+ * // Basic usage
417
+ * const result = await withRetry(() => uploadFile(buffer));
418
+ *
419
+ * // With custom options
420
+ * const result = await withRetry(
421
+ * () => uploadFile(buffer),
422
+ * {
423
+ * maxAttempts: 5,
424
+ * baseDelayMs: 500,
425
+ * onRetry: (err, attempt) => console.log(`Retry ${attempt}:`, err.message),
426
+ * }
427
+ * );
428
+ * ```
429
+ */
430
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
431
+ /**
432
+ * Create a retryable version of an async function.
433
+ *
434
+ * Useful for wrapping multiple functions with the same retry config.
435
+ *
436
+ * @example
437
+ * ```typescript
438
+ * const retryableUpload = createRetryable(
439
+ * (buffer: Buffer, opts: UploadOptions) => storage.upload(buffer, opts),
440
+ * { maxAttempts: 3 }
441
+ * );
442
+ *
443
+ * await retryableUpload(buffer, { filename: 'test.jpg', mimeType: 'image/jpeg' });
444
+ * ```
445
+ */
446
+ declare function createRetryable<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => Promise<TResult>, options?: RetryOptions): (...args: TArgs) => Promise<TResult>;
447
+
448
+ /**
449
+ * SVG Security Utilities
450
+ *
451
+ * Provides CSP header constants and helpers for securing SVG file responses.
452
+ * SVG files can contain embedded `<script>` tags, event handlers, and
453
+ * `<foreignObject>` elements that execute JavaScript when the SVG is
454
+ * rendered directly in a browser (not via `<img>` tags, which are sandboxed).
455
+ *
456
+ * Since Nextly delegates file serving to cloud storage providers (S3, Vercel Blob),
457
+ * these headers cannot be applied at the application level. Instead:
458
+ *
459
+ * 1. **S3 uploads**: `Content-Disposition: attachment` is set automatically for SVGs,
460
+ * forcing browsers to download instead of render (preventing script execution).
461
+ *
462
+ * 2. **CDN configuration**: Use these exported constants to configure response header
463
+ * policies on your CDN (CloudFront, Cloudflare, Vercel Edge Config) for SVG files.
464
+ *
465
+ * @example CloudFront Response Header Policy
466
+ * ```
467
+ * // In your CloudFront distribution config, create a response header policy
468
+ * // that matches Content-Type: image/svg+xml and adds:
469
+ * Content-Security-Policy: script-src 'none'; style-src 'unsafe-inline'
470
+ * X-Content-Type-Options: nosniff
471
+ * ```
472
+ *
473
+ * @example Custom Next.js route (proxy pattern)
474
+ * ```typescript
475
+ * import { getSvgSecurityHeaders, isSvgMimeType } from 'nextly/storage';
476
+ *
477
+ * export async function GET(req: Request) {
478
+ * const file = await fetchFromStorage(req);
479
+ * const headers = new Headers();
480
+ * headers.set('Content-Type', file.mimeType);
481
+ *
482
+ * if (isSvgMimeType(file.mimeType)) {
483
+ * for (const [key, value] of Object.entries(getSvgSecurityHeaders())) {
484
+ * headers.set(key, value);
485
+ * }
486
+ * }
487
+ *
488
+ * return new Response(file.buffer, { headers });
489
+ * }
490
+ * ```
491
+ */
492
+ /**
493
+ * Content-Security-Policy header value for SVG responses.
494
+ *
495
+ * - `script-src 'none'` — blocks all JavaScript execution (inline scripts,
496
+ * event handlers, `<script>` tags, `<foreignObject>` scripts)
497
+ * - `style-src 'unsafe-inline'` — allows inline styles (SVGs commonly use
498
+ * `style` attributes and `<style>` elements for legitimate styling)
499
+ */
500
+ declare const SVG_CSP_HEADER: "script-src 'none'; style-src 'unsafe-inline'";
501
+ /**
502
+ * Check if a MIME type is SVG.
503
+ *
504
+ * @param mimeType - MIME type string to check
505
+ * @returns `true` if the MIME type is `image/svg+xml`
506
+ */
507
+ declare function isSvgMimeType(mimeType: string): boolean;
508
+ /**
509
+ * Get the full set of security headers that should be applied to SVG responses.
510
+ *
511
+ * Returns headers that prevent script execution while preserving SVG rendering:
512
+ * - `Content-Security-Policy` — blocks scripts
513
+ * - `X-Content-Type-Options: nosniff` — prevents MIME type sniffing
514
+ *
515
+ * @returns Record of header name → value pairs
516
+ */
517
+ declare function getSvgSecurityHeaders(): Record<string, string>;
518
+
519
+ /**
520
+ * Storage Environment Configuration
521
+ *
522
+ * Auto-detects and configures storage plugins based on environment variables.
523
+ * This simplifies the user's nextly.config.ts by handling the storage setup internally.
524
+ *
525
+ * @example
526
+ * ```typescript
527
+ * // In nextly.config.ts
528
+ * import { defineConfig } from "nextly/config";
529
+ * import { getStorageFromEnv } from "nextly/storage";
530
+ *
531
+ * export default defineConfig({
532
+ * storage: getStorageFromEnv(),
533
+ * });
534
+ * ```
535
+ */
536
+
537
+ /**
538
+ * Get storage plugins based on environment variables.
539
+ *
540
+ * Uses a cascade detection approach (first match wins):
541
+ * 1. BLOB_READ_WRITE_TOKEN → Vercel Blob
542
+ * 2. S3_BUCKET → S3 (also covers R2, MinIO, Supabase)
543
+ * 3. UPLOADTHING_TOKEN → Uploadthing
544
+ * 4. Nothing detected → Local disk (zero-config default)
545
+ *
546
+ * For Vercel Blob:
547
+ * - `BLOB_READ_WRITE_TOKEN`: Required token
548
+ *
549
+ * For S3/R2/MinIO:
550
+ * - `S3_BUCKET`: Required bucket name
551
+ * - `S3_REGION`: Required region
552
+ * - `AWS_ACCESS_KEY_ID`: Required access key
553
+ * - `AWS_SECRET_ACCESS_KEY`: Required secret key
554
+ * - `S3_ENDPOINT`: Optional custom endpoint (for R2, MinIO)
555
+ * - `S3_PUBLIC_URL`: Optional public URL prefix
556
+ * - `S3_FORCE_PATH_STYLE`: Optional "true" for path-style URLs (MinIO)
557
+ *
558
+ * For Uploadthing:
559
+ * - `UPLOADTHING_TOKEN`: Required API token
560
+ *
561
+ * @returns Array of configured storage plugins (always returns at least local storage)
562
+ */
563
+ declare function getStorageFromEnv(): Promise<StoragePlugin[]>;
564
+
565
+ export { BaseStorageAdapter, BulkDeleteResult, IStorageAdapter, LocalStorageAdapter, SVG_CSP_HEADER, StorageAdapterInfo, StoragePlugin, StoragePluginConfig, UploadOptions, UploadResult, createRetryable, deleteImageSizes, generateImageSizes, getStorageFromEnv, getSvgSecurityHeaders, isSvgMimeType, isTransientError, localStorage, withRetry };
566
+ export type { GenerateImageSizesOptions, ImageSizeConfig, LocalStorageConfig, RetryOptions, UploadFn };
@@ -0,0 +1,45 @@
1
+ import {
2
+ ImageProcessor,
3
+ MediaStorage,
4
+ SVG_CSP_HEADER,
5
+ createRetryable,
6
+ deleteImageSizes,
7
+ generateImageSizes,
8
+ getImageProcessor,
9
+ getMediaStorage,
10
+ getStorageFromEnv,
11
+ getSvgSecurityHeaders,
12
+ initializeMediaStorage,
13
+ isSvgMimeType,
14
+ isTransientError,
15
+ resetImageProcessor,
16
+ resetMediaStorage,
17
+ withRetry
18
+ } from "../chunk-EGXBZCGC.mjs";
19
+ import {
20
+ BaseStorageAdapter,
21
+ LocalStorageAdapter,
22
+ localStorage
23
+ } from "../chunk-G2AA4QLC.mjs";
24
+ import "../chunk-7P6ASYW6.mjs";
25
+ export {
26
+ BaseStorageAdapter,
27
+ ImageProcessor,
28
+ LocalStorageAdapter,
29
+ MediaStorage,
30
+ SVG_CSP_HEADER,
31
+ createRetryable,
32
+ deleteImageSizes,
33
+ generateImageSizes,
34
+ getImageProcessor,
35
+ getMediaStorage,
36
+ getStorageFromEnv,
37
+ getSvgSecurityHeaders,
38
+ initializeMediaStorage,
39
+ isSvgMimeType,
40
+ isTransientError,
41
+ localStorage,
42
+ resetImageProcessor,
43
+ resetMediaStorage,
44
+ withRetry
45
+ };
@@ -0,0 +1,39 @@
1
+ import {
2
+ seedSuperAdmin
3
+ } from "./chunk-PKMABBB5.mjs";
4
+ import "./chunk-NSEFNNU4.mjs";
5
+ import "./chunk-3FA7FKAV.mjs";
6
+ import "./chunk-AGJ6F2T3.mjs";
7
+ import "./chunk-KIMNCZGV.mjs";
8
+ import "./chunk-AK6Z23OX.mjs";
9
+ import "./chunk-INV7QKLG.mjs";
10
+ import "./chunk-GZ6DCQKC.mjs";
11
+ import "./chunk-SBACDPNX.mjs";
12
+ import "./chunk-RJLLGGPG.mjs";
13
+ import "./chunk-V4EQTOA4.mjs";
14
+ import "./chunk-I4JMR3UR.mjs";
15
+ import "./chunk-XZKLBMN6.mjs";
16
+ import "./chunk-IZWPRDC3.mjs";
17
+ import "./chunk-DNNG377Z.mjs";
18
+ import "./chunk-5HMZ644B.mjs";
19
+ import "./chunk-W5KKPZT5.mjs";
20
+ import "./chunk-56WO4WX7.mjs";
21
+ import "./chunk-2W3DVD7S.mjs";
22
+ import "./chunk-TS7GHTG2.mjs";
23
+ import "./chunk-H26B4FYG.mjs";
24
+ import "./chunk-DP3G27G5.mjs";
25
+ import "./chunk-DV6WVX2Q.mjs";
26
+ import "./chunk-UJ2IMJ4W.mjs";
27
+ import "./chunk-EGXBZCGC.mjs";
28
+ import "./chunk-G2AA4QLC.mjs";
29
+ import "./chunk-4MJLT6PZ.mjs";
30
+ import "./chunk-IUDOC7N7.mjs";
31
+ import "./chunk-LAZXX4HR.mjs";
32
+ import "./chunk-D5HQBNUB.mjs";
33
+ import "./chunk-NRUWQ5Z7.mjs";
34
+ import "./chunk-VTJADRO3.mjs";
35
+ import "./chunk-5APFUGAD.mjs";
36
+ import "./chunk-7P6ASYW6.mjs";
37
+ export {
38
+ seedSuperAdmin
39
+ };
@@ -0,0 +1,17 @@
1
+ import {
2
+ SystemTableService
3
+ } from "./chunk-INV7QKLG.mjs";
4
+ import "./chunk-56WO4WX7.mjs";
5
+ import "./chunk-2W3DVD7S.mjs";
6
+ import "./chunk-TS7GHTG2.mjs";
7
+ import "./chunk-H26B4FYG.mjs";
8
+ import "./chunk-DP3G27G5.mjs";
9
+ import "./chunk-DV6WVX2Q.mjs";
10
+ import "./chunk-UJ2IMJ4W.mjs";
11
+ import "./chunk-LAZXX4HR.mjs";
12
+ import "./chunk-D5HQBNUB.mjs";
13
+ import "./chunk-NRUWQ5Z7.mjs";
14
+ import "./chunk-7P6ASYW6.mjs";
15
+ export {
16
+ SystemTableService
17
+ };